aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-12-09 22:50:49 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2009-12-09 22:50:49 -0500
commit3e7468313758913c5e4d372f35b271b96bad1298 (patch)
treeeb612d252a9e2349a1173451cd779beebd18a33e /drivers/media/video
parent6825fbc4cb219f2c98bb7d157915d797cf5cb823 (diff)
parente97f4677961f68e29bd906022ebf60a6df7f530a (diff)
Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6
* 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6: (345 commits) V4L/DVB (13542): ir-keytable: Allow dynamic table change V4L/DVB (13541): atbm8830: replace 64-bit division and floating point usage V4L/DVB (13540): ir-common: Cleanup get key evdev code V4L/DVB (13539): ir-common: add __func__ for debug messages V4L/DVB (13538): ir-common: Use a dynamic keycode table V4L/DVB (13537): ir: Prepare the code for dynamic keycode table allocation V4L/DVB (13536): em28xx: Use the full RC5 code on HVR-950 Remote Controller V4L/DVB (13535): ir-common: Add a hauppauge new table with the complete RC5 code V4L/DVB (13534): ir-common: Remove some unused fields/structs V4L/DVB (13533): ir: use dynamic tables, instead of static ones V4L/DVB (13532): ir-common: Add infrastructure to use a dynamic keycode table V4L/DVB (13531): ir-common: rename the debug routine to allow exporting it V4L/DVB (13458): go7007: subdev conversion V4L/DVB (13457): s2250: subdev conversion V4L/DVB (13456): s2250: Change module structure V4L/DVB (13528): em28xx: add support for em2800 VC211A card em28xx: don't reduce scale to half size for em2800 em28xx: don't load audio modules when AC97 is mis-detected em28xx: em2800 chips support max width of 640 V4L/DVB (13523): dvb-bt8xx: fix compile warning ... Fix up trivial conflicts due to spelling fixes from the trivial tree in Documentation/video4linux/gspca.txt drivers/media/video/cx18/cx18-mailbox.h
Diffstat (limited to 'drivers/media/video')
-rw-r--r--drivers/media/video/Kconfig33
-rw-r--r--drivers/media/video/Makefile2
-rw-r--r--drivers/media/video/adv7180.c323
-rw-r--r--drivers/media/video/au0828/au0828-video.c2
-rw-r--r--drivers/media/video/bt819.c2
-rw-r--r--drivers/media/video/bt8xx/bttv-input.c15
-rw-r--r--drivers/media/video/cx18/cx18-av-core.c14
-rw-r--r--drivers/media/video/cx18/cx18-cards.h3
-rw-r--r--drivers/media/video/cx18/cx18-driver.c60
-rw-r--r--drivers/media/video/cx18/cx18-driver.h62
-rw-r--r--drivers/media/video/cx18/cx18-dvb.c9
-rw-r--r--drivers/media/video/cx18/cx18-fileops.c132
-rw-r--r--drivers/media/video/cx18/cx18-i2c.c25
-rw-r--r--drivers/media/video/cx18/cx18-ioctl.c3
-rw-r--r--drivers/media/video/cx18/cx18-mailbox.c62
-rw-r--r--drivers/media/video/cx18/cx18-mailbox.h6
-rw-r--r--drivers/media/video/cx18/cx18-queue.c346
-rw-r--r--drivers/media/video/cx18/cx18-queue.h41
-rw-r--r--drivers/media/video/cx18/cx18-scb.h4
-rw-r--r--drivers/media/video/cx18/cx18-streams.c92
-rw-r--r--drivers/media/video/cx18/cx18-streams.h10
-rw-r--r--drivers/media/video/cx18/cx18-vbi.c35
-rw-r--r--drivers/media/video/cx18/cx18-vbi.h2
-rw-r--r--drivers/media/video/cx18/cx18-version.h2
-rw-r--r--drivers/media/video/cx18/cx23418.h2
-rw-r--r--drivers/media/video/cx231xx/cx231xx-input.c11
-rw-r--r--drivers/media/video/cx231xx/cx231xx-video.c2
-rw-r--r--drivers/media/video/cx23885/Kconfig2
-rw-r--r--drivers/media/video/cx23885/Makefile3
-rw-r--r--drivers/media/video/cx23885/cx23885-417.c10
-rw-r--r--drivers/media/video/cx23885/cx23885-cards.c155
-rw-r--r--drivers/media/video/cx23885/cx23885-core.c115
-rw-r--r--drivers/media/video/cx23885/cx23885-dvb.c158
-rw-r--r--drivers/media/video/cx23885/cx23885-f300.c177
-rw-r--r--drivers/media/video/cx23885/cx23885-f300.h2
-rw-r--r--drivers/media/video/cx23885/cx23885-input.c427
-rw-r--r--drivers/media/video/cx23885/cx23885-input.h30
-rw-r--r--drivers/media/video/cx23885/cx23885-ioctl.c208
-rw-r--r--drivers/media/video/cx23885/cx23885-ioctl.h39
-rw-r--r--drivers/media/video/cx23885/cx23885-ir.c101
-rw-r--r--drivers/media/video/cx23885/cx23885-ir.h31
-rw-r--r--drivers/media/video/cx23885/cx23885-reg.h5
-rw-r--r--drivers/media/video/cx23885/cx23885-video.c44
-rw-r--r--drivers/media/video/cx23885/cx23885.h31
-rw-r--r--drivers/media/video/cx23885/cx23888-ir.c1239
-rw-r--r--drivers/media/video/cx23885/cx23888-ir.h28
-rw-r--r--drivers/media/video/cx25840/cx25840-audio.c463
-rw-r--r--drivers/media/video/cx25840/cx25840-core.c324
-rw-r--r--drivers/media/video/cx25840/cx25840-core.h22
-rw-r--r--drivers/media/video/cx25840/cx25840-firmware.c10
-rw-r--r--drivers/media/video/cx88/Kconfig2
-rw-r--r--drivers/media/video/cx88/cx88-cards.c19
-rw-r--r--drivers/media/video/cx88/cx88-dvb.c58
-rw-r--r--drivers/media/video/cx88/cx88-input.c47
-rw-r--r--drivers/media/video/cx88/cx88-video.c2
-rw-r--r--drivers/media/video/cx88/cx88.h1
-rw-r--r--drivers/media/video/davinci/vpfe_capture.c47
-rw-r--r--drivers/media/video/em28xx/em28xx-audio.c4
-rw-r--r--drivers/media/video/em28xx/em28xx-cards.c50
-rw-r--r--drivers/media/video/em28xx/em28xx-core.c22
-rw-r--r--drivers/media/video/em28xx/em28xx-dvb.c24
-rw-r--r--drivers/media/video/em28xx/em28xx-input.c27
-rw-r--r--drivers/media/video/em28xx/em28xx-reg.h1
-rw-r--r--drivers/media/video/em28xx/em28xx-video.c8
-rw-r--r--drivers/media/video/em28xx/em28xx.h7
-rw-r--r--drivers/media/video/gspca/Kconfig23
-rw-r--r--drivers/media/video/gspca/Makefile4
-rw-r--r--drivers/media/video/gspca/conex.c12
-rw-r--r--drivers/media/video/gspca/etoms.c10
-rw-r--r--drivers/media/video/gspca/finepix.c23
-rw-r--r--drivers/media/video/gspca/gl860/gl860-mi1320.c55
-rw-r--r--drivers/media/video/gspca/gl860/gl860-mi2020.c69
-rw-r--r--drivers/media/video/gspca/gl860/gl860-ov2640.c140
-rw-r--r--drivers/media/video/gspca/gl860/gl860-ov9655.c43
-rw-r--r--drivers/media/video/gspca/gl860/gl860.c61
-rw-r--r--drivers/media/video/gspca/gl860/gl860.h7
-rw-r--r--drivers/media/video/gspca/gspca.c137
-rw-r--r--drivers/media/video/gspca/gspca.h15
-rw-r--r--drivers/media/video/gspca/jeilinj.c34
-rw-r--r--drivers/media/video/gspca/m5602/m5602_core.c25
-rw-r--r--drivers/media/video/gspca/mars.c11
-rw-r--r--drivers/media/video/gspca/mr97310a.c602
-rw-r--r--drivers/media/video/gspca/ov519.c1495
-rw-r--r--drivers/media/video/gspca/ov534.c1537
-rw-r--r--drivers/media/video/gspca/pac207.c13
-rw-r--r--drivers/media/video/gspca/pac7302.c1272
-rw-r--r--drivers/media/video/gspca/pac7311.c716
-rw-r--r--drivers/media/video/gspca/pac_common.h91
-rw-r--r--drivers/media/video/gspca/sn9c20x.c11
-rw-r--r--drivers/media/video/gspca/sonixb.c21
-rw-r--r--drivers/media/video/gspca/sonixj.c660
-rw-r--r--drivers/media/video/gspca/spca500.c11
-rw-r--r--drivers/media/video/gspca/spca501.c14
-rw-r--r--drivers/media/video/gspca/spca505.c10
-rw-r--r--drivers/media/video/gspca/spca506.c12
-rw-r--r--drivers/media/video/gspca/spca508.c10
-rw-r--r--drivers/media/video/gspca/spca561.c14
-rw-r--r--drivers/media/video/gspca/sq905.c75
-rw-r--r--drivers/media/video/gspca/sq905c.c31
-rw-r--r--drivers/media/video/gspca/stk014.c11
-rw-r--r--drivers/media/video/gspca/stv0680.c364
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx.c11
-rw-r--r--drivers/media/video/gspca/sunplus.c11
-rw-r--r--drivers/media/video/gspca/t613.c7
-rw-r--r--drivers/media/video/gspca/tv8532.c7
-rw-r--r--drivers/media/video/gspca/vc032x.c23
-rw-r--r--drivers/media/video/gspca/w996Xcf.c609
-rw-r--r--drivers/media/video/gspca/zc3xx.c1470
-rw-r--r--drivers/media/video/hdpvr/hdpvr-video.c8
-rw-r--r--drivers/media/video/hexium_gemini.c2
-rw-r--r--drivers/media/video/hexium_orion.c2
-rw-r--r--drivers/media/video/ir-kbd-i2c.c19
-rw-r--r--drivers/media/video/ivtv/ivtv-cards.c16
-rw-r--r--drivers/media/video/ivtv/ivtv-cards.h51
-rw-r--r--drivers/media/video/ivtv/ivtv-driver.c23
-rw-r--r--drivers/media/video/ivtv/ivtv-driver.h6
-rw-r--r--drivers/media/video/ivtv/ivtv-i2c.c153
-rw-r--r--drivers/media/video/ivtv/ivtv-i2c.h1
-rw-r--r--drivers/media/video/mxb.c2
-rw-r--r--drivers/media/video/ov9640.c801
-rw-r--r--drivers/media/video/ov9640.h209
-rw-r--r--drivers/media/video/pms.c1425
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-debugifc.c17
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-devattr.c13
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-devattr.h1
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-encoder.c5
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h1
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-hdw.c63
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-hdw.h2
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-i2c-core.c1
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-v4l2.c15
-rw-r--r--drivers/media/video/pwc/pwc-if.c23
-rw-r--r--drivers/media/video/rj54n1cb0c.c1219
-rw-r--r--drivers/media/video/s2255drv.c2
-rw-r--r--drivers/media/video/saa7110.c2
-rw-r--r--drivers/media/video/saa7134/saa7134-cards.c55
-rw-r--r--drivers/media/video/saa7134/saa7134-core.c2
-rw-r--r--drivers/media/video/saa7134/saa7134-dvb.c66
-rw-r--r--drivers/media/video/saa7134/saa7134-input.c55
-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-dvb.c1
-rw-r--r--drivers/media/video/saa717x.c4
-rw-r--r--drivers/media/video/sh_mobile_ceu_camera.c83
-rw-r--r--drivers/media/video/tuner-core.c20
-rw-r--r--drivers/media/video/tvaudio.c2
-rw-r--r--drivers/media/video/tvp514x.c2
-rw-r--r--drivers/media/video/usbvideo/konicawc.c2
-rw-r--r--drivers/media/video/usbvideo/quickcam_messenger.c2
-rw-r--r--drivers/media/video/usbvision/usbvision-video.c2
-rw-r--r--drivers/media/video/uvc/uvc_ctrl.c36
-rw-r--r--drivers/media/video/uvc/uvc_driver.c428
-rw-r--r--drivers/media/video/uvc/uvc_v4l2.c60
-rw-r--r--drivers/media/video/uvc/uvc_video.c26
-rw-r--r--drivers/media/video/uvc/uvcvideo.h23
-rw-r--r--drivers/media/video/v4l2-common.c9
-rw-r--r--drivers/media/video/videobuf-core.c12
-rw-r--r--drivers/media/video/videobuf-dma-contig.c2
-rw-r--r--drivers/media/video/videobuf-dma-sg.c6
-rw-r--r--drivers/media/video/videobuf-dvb.c11
-rw-r--r--drivers/media/video/videobuf-vmalloc.c4
-rw-r--r--drivers/media/video/vpx3220.c2
-rw-r--r--drivers/media/video/zoran/zoran_driver.c2
-rw-r--r--drivers/media/video/zr364xx.c1
164 files changed, 15481 insertions, 4544 deletions
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index e6186b338a12..9dc74c93bf24 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -600,7 +600,7 @@ source "drivers/media/video/bt8xx/Kconfig"
600 600
601config VIDEO_PMS 601config VIDEO_PMS
602 tristate "Mediavision Pro Movie Studio Video For Linux" 602 tristate "Mediavision Pro Movie Studio Video For Linux"
603 depends on ISA && VIDEO_V4L1 603 depends on ISA && VIDEO_V4L2
604 help 604 help
605 Say Y if you have such a thing. 605 Say Y if you have such a thing.
606 606
@@ -847,6 +847,12 @@ config SOC_CAMERA_MT9V022
847 help 847 help
848 This driver supports MT9V022 cameras from Micron 848 This driver supports MT9V022 cameras from Micron
849 849
850config SOC_CAMERA_RJ54N1
851 tristate "rj54n1cb0c support"
852 depends on SOC_CAMERA && I2C
853 help
854 This is a rj54n1cb0c video driver
855
850config SOC_CAMERA_TW9910 856config SOC_CAMERA_TW9910
851 tristate "tw9910 support" 857 tristate "tw9910 support"
852 depends on SOC_CAMERA && I2C 858 depends on SOC_CAMERA && I2C
@@ -865,6 +871,12 @@ config SOC_CAMERA_OV772X
865 help 871 help
866 This is a ov772x camera driver 872 This is a ov772x camera driver
867 873
874config SOC_CAMERA_OV9640
875 tristate "ov9640 camera support"
876 depends on SOC_CAMERA && I2C
877 help
878 This is a ov9640 camera driver
879
868config MX1_VIDEO 880config MX1_VIDEO
869 bool 881 bool
870 882
@@ -939,9 +951,14 @@ source "drivers/media/video/usbvideo/Kconfig"
939source "drivers/media/video/et61x251/Kconfig" 951source "drivers/media/video/et61x251/Kconfig"
940 952
941config VIDEO_OVCAMCHIP 953config VIDEO_OVCAMCHIP
942 tristate "OmniVision Camera Chip support" 954 tristate "OmniVision Camera Chip support (DEPRECATED)"
943 depends on I2C && VIDEO_V4L1 955 depends on I2C && VIDEO_V4L1
944 ---help--- 956 ---help---
957 This driver is DEPRECATED please use the gspca ov519 module
958 instead. Note that for the ov511 / ov518 support of the gspca module
959 you need atleast version 0.6.0 of libv4l and for the w9968cf
960 atleast version 0.6.3 of libv4l.
961
945 Support for the OmniVision OV6xxx and OV7xxx series of camera chips. 962 Support for the OmniVision OV6xxx and OV7xxx series of camera chips.
946 This driver is intended to be used with the ov511 and w9968cf USB 963 This driver is intended to be used with the ov511 and w9968cf USB
947 camera drivers. 964 camera drivers.
@@ -950,9 +967,13 @@ config VIDEO_OVCAMCHIP
950 module will be called ovcamchip. 967 module will be called ovcamchip.
951 968
952config USB_W9968CF 969config USB_W9968CF
953 tristate "USB W996[87]CF JPEG Dual Mode Camera support" 970 tristate "USB W996[87]CF JPEG Dual Mode Camera support (DEPRECATED)"
954 depends on VIDEO_V4L1 && I2C && VIDEO_OVCAMCHIP 971 depends on VIDEO_V4L1 && I2C && VIDEO_OVCAMCHIP
955 ---help--- 972 ---help---
973 This driver is DEPRECATED please use the gspca ov519 module
974 instead. Note that for the w9968cf support of the gspca module
975 you need atleast version 0.6.3 of libv4l.
976
956 Say Y here if you want support for cameras based on OV681 or 977 Say Y here if you want support for cameras based on OV681 or
957 Winbond W9967CF/W9968CF JPEG USB Dual Mode Camera Chips. 978 Winbond W9967CF/W9968CF JPEG USB Dual Mode Camera Chips.
958 979
@@ -995,9 +1016,13 @@ config USB_SE401
995source "drivers/media/video/sn9c102/Kconfig" 1016source "drivers/media/video/sn9c102/Kconfig"
996 1017
997config USB_STV680 1018config USB_STV680
998 tristate "USB STV680 (Pencam) Camera support" 1019 tristate "USB STV680 (Pencam) Camera support (DEPRECATED)"
999 depends on VIDEO_V4L1 1020 depends on VIDEO_V4L1
1000 ---help--- 1021 ---help---
1022 This driver is DEPRECATED please use the gspca stv0680 module
1023 instead. Note that for the gspca stv0680 module you need
1024 atleast version 0.6.3 of libv4l.
1025
1001 Say Y here if you want to connect this type of camera to your 1026 Say Y here if you want to connect this type of camera to your
1002 computer's USB port. This includes the Pencam line of cameras. 1027 computer's USB port. This includes the Pencam line of cameras.
1003 See <file:Documentation/video4linux/stv680.txt> for more information 1028 See <file:Documentation/video4linux/stv680.txt> for more information
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile
index e541932a789b..7a2dcc34111c 100644
--- a/drivers/media/video/Makefile
+++ b/drivers/media/video/Makefile
@@ -77,6 +77,8 @@ obj-$(CONFIG_SOC_CAMERA_MT9M111) += mt9m111.o
77obj-$(CONFIG_SOC_CAMERA_MT9T031) += mt9t031.o 77obj-$(CONFIG_SOC_CAMERA_MT9T031) += mt9t031.o
78obj-$(CONFIG_SOC_CAMERA_MT9V022) += mt9v022.o 78obj-$(CONFIG_SOC_CAMERA_MT9V022) += mt9v022.o
79obj-$(CONFIG_SOC_CAMERA_OV772X) += ov772x.o 79obj-$(CONFIG_SOC_CAMERA_OV772X) += ov772x.o
80obj-$(CONFIG_SOC_CAMERA_OV9640) += ov9640.o
81obj-$(CONFIG_SOC_CAMERA_RJ54N1) += rj54n1cb0c.o
80obj-$(CONFIG_SOC_CAMERA_TW9910) += tw9910.o 82obj-$(CONFIG_SOC_CAMERA_TW9910) += tw9910.o
81 83
82# And now the v4l2 drivers: 84# And now the v4l2 drivers:
diff --git a/drivers/media/video/adv7180.c b/drivers/media/video/adv7180.c
index 1b3cbd02a7fd..0826f0dabc17 100644
--- a/drivers/media/video/adv7180.c
+++ b/drivers/media/video/adv7180.c
@@ -27,17 +27,40 @@
27#include <linux/videodev2.h> 27#include <linux/videodev2.h>
28#include <media/v4l2-device.h> 28#include <media/v4l2-device.h>
29#include <media/v4l2-chip-ident.h> 29#include <media/v4l2-chip-ident.h>
30#include <linux/mutex.h>
30 31
31#define DRIVER_NAME "adv7180" 32#define DRIVER_NAME "adv7180"
32 33
33#define ADV7180_INPUT_CONTROL_REG 0x00 34#define ADV7180_INPUT_CONTROL_REG 0x00
34#define ADV7180_INPUT_CONTROL_PAL_BG_NTSC_J_SECAM 0x00 35#define ADV7180_INPUT_CONTROL_AD_PAL_BG_NTSC_J_SECAM 0x00
35#define ADV7180_AUTODETECT_ENABLE_REG 0x07 36#define ADV7180_INPUT_CONTROL_AD_PAL_BG_NTSC_J_SECAM_PED 0x10
36#define ADV7180_AUTODETECT_DEFAULT 0x7f 37#define ADV7180_INPUT_CONTROL_AD_PAL_N_NTSC_J_SECAM 0x20
37 38#define ADV7180_INPUT_CONTROL_AD_PAL_N_NTSC_M_SECAM 0x30
38 39#define ADV7180_INPUT_CONTROL_NTSC_J 0x40
39#define ADV7180_STATUS1_REG 0x10 40#define ADV7180_INPUT_CONTROL_NTSC_M 0x50
40#define ADV7180_STATUS1_AUTOD_MASK 0x70 41#define ADV7180_INPUT_CONTROL_PAL60 0x60
42#define ADV7180_INPUT_CONTROL_NTSC_443 0x70
43#define ADV7180_INPUT_CONTROL_PAL_BG 0x80
44#define ADV7180_INPUT_CONTROL_PAL_N 0x90
45#define ADV7180_INPUT_CONTROL_PAL_M 0xa0
46#define ADV7180_INPUT_CONTROL_PAL_M_PED 0xb0
47#define ADV7180_INPUT_CONTROL_PAL_COMB_N 0xc0
48#define ADV7180_INPUT_CONTROL_PAL_COMB_N_PED 0xd0
49#define ADV7180_INPUT_CONTROL_PAL_SECAM 0xe0
50#define ADV7180_INPUT_CONTROL_PAL_SECAM_PED 0xf0
51
52#define ADV7180_EXTENDED_OUTPUT_CONTROL_REG 0x04
53#define ADV7180_EXTENDED_OUTPUT_CONTROL_NTSCDIS 0xC5
54
55#define ADV7180_AUTODETECT_ENABLE_REG 0x07
56#define ADV7180_AUTODETECT_DEFAULT 0x7f
57
58#define ADV7180_ADI_CTRL_REG 0x0e
59#define ADV7180_ADI_CTRL_IRQ_SPACE 0x20
60
61#define ADV7180_STATUS1_REG 0x10
62#define ADV7180_STATUS1_IN_LOCK 0x01
63#define ADV7180_STATUS1_AUTOD_MASK 0x70
41#define ADV7180_STATUS1_AUTOD_NTSM_M_J 0x00 64#define ADV7180_STATUS1_AUTOD_NTSM_M_J 0x00
42#define ADV7180_STATUS1_AUTOD_NTSC_4_43 0x10 65#define ADV7180_STATUS1_AUTOD_NTSC_4_43 0x10
43#define ADV7180_STATUS1_AUTOD_PAL_M 0x20 66#define ADV7180_STATUS1_AUTOD_PAL_M 0x20
@@ -50,18 +73,37 @@
50#define ADV7180_IDENT_REG 0x11 73#define ADV7180_IDENT_REG 0x11
51#define ADV7180_ID_7180 0x18 74#define ADV7180_ID_7180 0x18
52 75
76#define ADV7180_ICONF1_ADI 0x40
77#define ADV7180_ICONF1_ACTIVE_LOW 0x01
78#define ADV7180_ICONF1_PSYNC_ONLY 0x10
79#define ADV7180_ICONF1_ACTIVE_TO_CLR 0xC0
80
81#define ADV7180_IRQ1_LOCK 0x01
82#define ADV7180_IRQ1_UNLOCK 0x02
83#define ADV7180_ISR1_ADI 0x42
84#define ADV7180_ICR1_ADI 0x43
85#define ADV7180_IMR1_ADI 0x44
86#define ADV7180_IMR2_ADI 0x48
87#define ADV7180_IRQ3_AD_CHANGE 0x08
88#define ADV7180_ISR3_ADI 0x4A
89#define ADV7180_ICR3_ADI 0x4B
90#define ADV7180_IMR3_ADI 0x4C
91#define ADV7180_IMR4_ADI 0x50
53 92
54struct adv7180_state { 93struct adv7180_state {
55 struct v4l2_subdev sd; 94 struct v4l2_subdev sd;
95 struct work_struct work;
96 struct mutex mutex; /* mutual excl. when accessing chip */
97 int irq;
98 v4l2_std_id curr_norm;
99 bool autodetect;
56}; 100};
57 101
58static v4l2_std_id determine_norm(struct i2c_client *client) 102static v4l2_std_id adv7180_std_to_v4l2(u8 status1)
59{ 103{
60 u8 status1 = i2c_smbus_read_byte_data(client, ADV7180_STATUS1_REG);
61
62 switch (status1 & ADV7180_STATUS1_AUTOD_MASK) { 104 switch (status1 & ADV7180_STATUS1_AUTOD_MASK) {
63 case ADV7180_STATUS1_AUTOD_NTSM_M_J: 105 case ADV7180_STATUS1_AUTOD_NTSM_M_J:
64 return V4L2_STD_NTSC_M_JP; 106 return V4L2_STD_NTSC;
65 case ADV7180_STATUS1_AUTOD_NTSC_4_43: 107 case ADV7180_STATUS1_AUTOD_NTSC_4_43:
66 return V4L2_STD_NTSC_443; 108 return V4L2_STD_NTSC_443;
67 case ADV7180_STATUS1_AUTOD_PAL_M: 109 case ADV7180_STATUS1_AUTOD_PAL_M:
@@ -81,6 +123,53 @@ static v4l2_std_id determine_norm(struct i2c_client *client)
81 } 123 }
82} 124}
83 125
126static int v4l2_std_to_adv7180(v4l2_std_id std)
127{
128 if (std == V4L2_STD_PAL_60)
129 return ADV7180_INPUT_CONTROL_PAL60;
130 if (std == V4L2_STD_NTSC_443)
131 return ADV7180_INPUT_CONTROL_NTSC_443;
132 if (std == V4L2_STD_PAL_N)
133 return ADV7180_INPUT_CONTROL_PAL_N;
134 if (std == V4L2_STD_PAL_M)
135 return ADV7180_INPUT_CONTROL_PAL_M;
136 if (std == V4L2_STD_PAL_Nc)
137 return ADV7180_INPUT_CONTROL_PAL_COMB_N;
138
139 if (std & V4L2_STD_PAL)
140 return ADV7180_INPUT_CONTROL_PAL_BG;
141 if (std & V4L2_STD_NTSC)
142 return ADV7180_INPUT_CONTROL_NTSC_M;
143 if (std & V4L2_STD_SECAM)
144 return ADV7180_INPUT_CONTROL_PAL_SECAM;
145
146 return -EINVAL;
147}
148
149static u32 adv7180_status_to_v4l2(u8 status1)
150{
151 if (!(status1 & ADV7180_STATUS1_IN_LOCK))
152 return V4L2_IN_ST_NO_SIGNAL;
153
154 return 0;
155}
156
157static int __adv7180_status(struct i2c_client *client, u32 *status,
158 v4l2_std_id *std)
159{
160 int status1 = i2c_smbus_read_byte_data(client, ADV7180_STATUS1_REG);
161
162 if (status1 < 0)
163 return status1;
164
165 if (status)
166 *status = adv7180_status_to_v4l2(status1);
167 if (std)
168 *std = adv7180_std_to_v4l2(status1);
169
170 return 0;
171}
172
84static inline struct adv7180_state *to_state(struct v4l2_subdev *sd) 173static inline struct adv7180_state *to_state(struct v4l2_subdev *sd)
85{ 174{
86 return container_of(sd, struct adv7180_state, sd); 175 return container_of(sd, struct adv7180_state, sd);
@@ -88,10 +177,31 @@ static inline struct adv7180_state *to_state(struct v4l2_subdev *sd)
88 177
89static int adv7180_querystd(struct v4l2_subdev *sd, v4l2_std_id *std) 178static int adv7180_querystd(struct v4l2_subdev *sd, v4l2_std_id *std)
90{ 179{
91 struct i2c_client *client = v4l2_get_subdevdata(sd); 180 struct adv7180_state *state = to_state(sd);
181 int err = mutex_lock_interruptible(&state->mutex);
182 if (err)
183 return err;
184
185 /* when we are interrupt driven we know the state */
186 if (!state->autodetect || state->irq > 0)
187 *std = state->curr_norm;
188 else
189 err = __adv7180_status(v4l2_get_subdevdata(sd), NULL, std);
190
191 mutex_unlock(&state->mutex);
192 return err;
193}
92 194
93 *std = determine_norm(client); 195static int adv7180_g_input_status(struct v4l2_subdev *sd, u32 *status)
94 return 0; 196{
197 struct adv7180_state *state = to_state(sd);
198 int ret = mutex_lock_interruptible(&state->mutex);
199 if (ret)
200 return ret;
201
202 ret = __adv7180_status(v4l2_get_subdevdata(sd), status, NULL);
203 mutex_unlock(&state->mutex);
204 return ret;
95} 205}
96 206
97static int adv7180_g_chip_ident(struct v4l2_subdev *sd, 207static int adv7180_g_chip_ident(struct v4l2_subdev *sd,
@@ -102,12 +212,51 @@ static int adv7180_g_chip_ident(struct v4l2_subdev *sd,
102 return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_ADV7180, 0); 212 return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_ADV7180, 0);
103} 213}
104 214
215static int adv7180_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
216{
217 struct adv7180_state *state = to_state(sd);
218 struct i2c_client *client = v4l2_get_subdevdata(sd);
219 int ret = mutex_lock_interruptible(&state->mutex);
220 if (ret)
221 return ret;
222
223 /* all standards -> autodetect */
224 if (std == V4L2_STD_ALL) {
225 ret = i2c_smbus_write_byte_data(client,
226 ADV7180_INPUT_CONTROL_REG,
227 ADV7180_INPUT_CONTROL_AD_PAL_BG_NTSC_J_SECAM);
228 if (ret < 0)
229 goto out;
230
231 __adv7180_status(client, NULL, &state->curr_norm);
232 state->autodetect = true;
233 } else {
234 ret = v4l2_std_to_adv7180(std);
235 if (ret < 0)
236 goto out;
237
238 ret = i2c_smbus_write_byte_data(client,
239 ADV7180_INPUT_CONTROL_REG, ret);
240 if (ret < 0)
241 goto out;
242
243 state->curr_norm = std;
244 state->autodetect = false;
245 }
246 ret = 0;
247out:
248 mutex_unlock(&state->mutex);
249 return ret;
250}
251
105static const struct v4l2_subdev_video_ops adv7180_video_ops = { 252static const struct v4l2_subdev_video_ops adv7180_video_ops = {
106 .querystd = adv7180_querystd, 253 .querystd = adv7180_querystd,
254 .g_input_status = adv7180_g_input_status,
107}; 255};
108 256
109static const struct v4l2_subdev_core_ops adv7180_core_ops = { 257static const struct v4l2_subdev_core_ops adv7180_core_ops = {
110 .g_chip_ident = adv7180_g_chip_ident, 258 .g_chip_ident = adv7180_g_chip_ident,
259 .s_std = adv7180_s_std,
111}; 260};
112 261
113static const struct v4l2_subdev_ops adv7180_ops = { 262static const struct v4l2_subdev_ops adv7180_ops = {
@@ -115,12 +264,45 @@ static const struct v4l2_subdev_ops adv7180_ops = {
115 .video = &adv7180_video_ops, 264 .video = &adv7180_video_ops,
116}; 265};
117 266
267static void adv7180_work(struct work_struct *work)
268{
269 struct adv7180_state *state = container_of(work, struct adv7180_state,
270 work);
271 struct i2c_client *client = v4l2_get_subdevdata(&state->sd);
272 u8 isr3;
273
274 mutex_lock(&state->mutex);
275 i2c_smbus_write_byte_data(client, ADV7180_ADI_CTRL_REG,
276 ADV7180_ADI_CTRL_IRQ_SPACE);
277 isr3 = i2c_smbus_read_byte_data(client, ADV7180_ISR3_ADI);
278 /* clear */
279 i2c_smbus_write_byte_data(client, ADV7180_ICR3_ADI, isr3);
280 i2c_smbus_write_byte_data(client, ADV7180_ADI_CTRL_REG, 0);
281
282 if (isr3 & ADV7180_IRQ3_AD_CHANGE && state->autodetect)
283 __adv7180_status(client, NULL, &state->curr_norm);
284 mutex_unlock(&state->mutex);
285
286 enable_irq(state->irq);
287}
288
289static irqreturn_t adv7180_irq(int irq, void *devid)
290{
291 struct adv7180_state *state = devid;
292
293 schedule_work(&state->work);
294
295 disable_irq_nosync(state->irq);
296
297 return IRQ_HANDLED;
298}
299
118/* 300/*
119 * Generic i2c probe 301 * Generic i2c probe
120 * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1' 302 * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
121 */ 303 */
122 304
123static int adv7180_probe(struct i2c_client *client, 305static __devinit int adv7180_probe(struct i2c_client *client,
124 const struct i2c_device_id *id) 306 const struct i2c_device_id *id)
125{ 307{
126 struct adv7180_state *state; 308 struct adv7180_state *state;
@@ -135,32 +317,111 @@ static int adv7180_probe(struct i2c_client *client,
135 client->addr << 1, client->adapter->name); 317 client->addr << 1, client->adapter->name);
136 318
137 state = kzalloc(sizeof(struct adv7180_state), GFP_KERNEL); 319 state = kzalloc(sizeof(struct adv7180_state), GFP_KERNEL);
138 if (state == NULL) 320 if (state == NULL) {
139 return -ENOMEM; 321 ret = -ENOMEM;
322 goto err;
323 }
324
325 state->irq = client->irq;
326 INIT_WORK(&state->work, adv7180_work);
327 mutex_init(&state->mutex);
328 state->autodetect = true;
140 sd = &state->sd; 329 sd = &state->sd;
141 v4l2_i2c_subdev_init(sd, client, &adv7180_ops); 330 v4l2_i2c_subdev_init(sd, client, &adv7180_ops);
142 331
143 /* Initialize adv7180 */ 332 /* Initialize adv7180 */
144 /* enable autodetection */ 333 /* Enable autodetection */
145 ret = i2c_smbus_write_byte_data(client, ADV7180_INPUT_CONTROL_REG, 334 ret = i2c_smbus_write_byte_data(client, ADV7180_INPUT_CONTROL_REG,
146 ADV7180_INPUT_CONTROL_PAL_BG_NTSC_J_SECAM); 335 ADV7180_INPUT_CONTROL_AD_PAL_BG_NTSC_J_SECAM);
147 if (ret > 0) 336 if (ret < 0)
148 ret = i2c_smbus_write_byte_data(client, 337 goto err_unreg_subdev;
149 ADV7180_AUTODETECT_ENABLE_REG, 338
150 ADV7180_AUTODETECT_DEFAULT); 339 ret = i2c_smbus_write_byte_data(client, ADV7180_AUTODETECT_ENABLE_REG,
151 if (ret < 0) { 340 ADV7180_AUTODETECT_DEFAULT);
152 printk(KERN_ERR DRIVER_NAME 341 if (ret < 0)
153 ": Failed to communicate to chip: %d\n", ret); 342 goto err_unreg_subdev;
154 return ret; 343
344 /* ITU-R BT.656-4 compatible */
345 ret = i2c_smbus_write_byte_data(client,
346 ADV7180_EXTENDED_OUTPUT_CONTROL_REG,
347 ADV7180_EXTENDED_OUTPUT_CONTROL_NTSCDIS);
348 if (ret < 0)
349 goto err_unreg_subdev;
350
351 /* read current norm */
352 __adv7180_status(client, NULL, &state->curr_norm);
353
354 /* register for interrupts */
355 if (state->irq > 0) {
356 ret = request_irq(state->irq, adv7180_irq, 0, DRIVER_NAME,
357 state);
358 if (ret)
359 goto err_unreg_subdev;
360
361 ret = i2c_smbus_write_byte_data(client, ADV7180_ADI_CTRL_REG,
362 ADV7180_ADI_CTRL_IRQ_SPACE);
363 if (ret < 0)
364 goto err_unreg_subdev;
365
366 /* config the Interrupt pin to be active low */
367 ret = i2c_smbus_write_byte_data(client, ADV7180_ICONF1_ADI,
368 ADV7180_ICONF1_ACTIVE_LOW | ADV7180_ICONF1_PSYNC_ONLY);
369 if (ret < 0)
370 goto err_unreg_subdev;
371
372 ret = i2c_smbus_write_byte_data(client, ADV7180_IMR1_ADI, 0);
373 if (ret < 0)
374 goto err_unreg_subdev;
375
376 ret = i2c_smbus_write_byte_data(client, ADV7180_IMR2_ADI, 0);
377 if (ret < 0)
378 goto err_unreg_subdev;
379
380 /* enable AD change interrupts interrupts */
381 ret = i2c_smbus_write_byte_data(client, ADV7180_IMR3_ADI,
382 ADV7180_IRQ3_AD_CHANGE);
383 if (ret < 0)
384 goto err_unreg_subdev;
385
386 ret = i2c_smbus_write_byte_data(client, ADV7180_IMR4_ADI, 0);
387 if (ret < 0)
388 goto err_unreg_subdev;
389
390 ret = i2c_smbus_write_byte_data(client, ADV7180_ADI_CTRL_REG,
391 0);
392 if (ret < 0)
393 goto err_unreg_subdev;
155 } 394 }
156 395
157 return 0; 396 return 0;
397
398err_unreg_subdev:
399 mutex_destroy(&state->mutex);
400 v4l2_device_unregister_subdev(sd);
401 kfree(state);
402err:
403 printk(KERN_ERR DRIVER_NAME ": Failed to probe: %d\n", ret);
404 return ret;
158} 405}
159 406
160static int adv7180_remove(struct i2c_client *client) 407static __devexit int adv7180_remove(struct i2c_client *client)
161{ 408{
162 struct v4l2_subdev *sd = i2c_get_clientdata(client); 409 struct v4l2_subdev *sd = i2c_get_clientdata(client);
410 struct adv7180_state *state = to_state(sd);
411
412 if (state->irq > 0) {
413 free_irq(client->irq, state);
414 if (cancel_work_sync(&state->work)) {
415 /*
416 * Work was pending, therefore we need to enable
417 * IRQ here to balance the disable_irq() done in the
418 * interrupt handler.
419 */
420 enable_irq(state->irq);
421 }
422 }
163 423
424 mutex_destroy(&state->mutex);
164 v4l2_device_unregister_subdev(sd); 425 v4l2_device_unregister_subdev(sd);
165 kfree(to_state(sd)); 426 kfree(to_state(sd));
166 return 0; 427 return 0;
@@ -179,7 +440,7 @@ static struct i2c_driver adv7180_driver = {
179 .name = DRIVER_NAME, 440 .name = DRIVER_NAME,
180 }, 441 },
181 .probe = adv7180_probe, 442 .probe = adv7180_probe,
182 .remove = adv7180_remove, 443 .remove = __devexit_p(adv7180_remove),
183 .id_table = adv7180_id, 444 .id_table = adv7180_id,
184}; 445};
185 446
diff --git a/drivers/media/video/au0828/au0828-video.c b/drivers/media/video/au0828/au0828-video.c
index 51527d7b55a7..1485aee18d58 100644
--- a/drivers/media/video/au0828/au0828-video.c
+++ b/drivers/media/video/au0828/au0828-video.c
@@ -830,7 +830,7 @@ static int au0828_v4l2_close(struct file *filp)
830 au0828_uninit_isoc(dev); 830 au0828_uninit_isoc(dev);
831 831
832 /* Save some power by putting tuner to sleep */ 832 /* Save some power by putting tuner to sleep */
833 v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_standby); 833 v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_power, 0);
834 834
835 /* When close the device, set the usb intf0 into alt0 to free 835 /* When close the device, set the usb intf0 into alt0 to free
836 USB bandwidth */ 836 USB bandwidth */
diff --git a/drivers/media/video/bt819.c b/drivers/media/video/bt819.c
index f9330e3529c3..5bb0f9e71583 100644
--- a/drivers/media/video/bt819.c
+++ b/drivers/media/video/bt819.c
@@ -299,7 +299,7 @@ static int bt819_s_routing(struct v4l2_subdev *sd,
299 299
300 v4l2_dbg(1, debug, sd, "set input %x\n", input); 300 v4l2_dbg(1, debug, sd, "set input %x\n", input);
301 301
302 if (input < 0 || input > 7) 302 if (input > 7)
303 return -EINVAL; 303 return -EINVAL;
304 304
305 if (sd->v4l2_dev == NULL || sd->v4l2_dev->notify == NULL) 305 if (sd->v4l2_dev == NULL || sd->v4l2_dev->notify == NULL)
diff --git a/drivers/media/video/bt8xx/bttv-input.c b/drivers/media/video/bt8xx/bttv-input.c
index ebd51afe8761..84a957e52c4b 100644
--- a/drivers/media/video/bt8xx/bttv-input.c
+++ b/drivers/media/video/bt8xx/bttv-input.c
@@ -73,12 +73,12 @@ static void ir_handle_key(struct bttv *btv)
73 73
74 if ((ir->mask_keydown && (0 != (gpio & ir->mask_keydown))) || 74 if ((ir->mask_keydown && (0 != (gpio & ir->mask_keydown))) ||
75 (ir->mask_keyup && (0 == (gpio & ir->mask_keyup)))) { 75 (ir->mask_keyup && (0 == (gpio & ir->mask_keyup)))) {
76 ir_input_keydown(ir->dev,&ir->ir,data,data); 76 ir_input_keydown(ir->dev, &ir->ir, data);
77 } else { 77 } else {
78 /* HACK: Probably, ir->mask_keydown is missing 78 /* HACK: Probably, ir->mask_keydown is missing
79 for this board */ 79 for this board */
80 if (btv->c.type == BTTV_BOARD_WINFAST2000) 80 if (btv->c.type == BTTV_BOARD_WINFAST2000)
81 ir_input_keydown(ir->dev, &ir->ir, data, data); 81 ir_input_keydown(ir->dev, &ir->ir, data);
82 82
83 ir_input_nokey(ir->dev,&ir->ir); 83 ir_input_nokey(ir->dev,&ir->ir);
84 } 84 }
@@ -104,7 +104,7 @@ static void ir_enltv_handle_key(struct bttv *btv)
104 gpio, data, 104 gpio, data,
105 (gpio & ir->mask_keyup) ? " up" : "up/down"); 105 (gpio & ir->mask_keyup) ? " up" : "up/down");
106 106
107 ir_input_keydown(ir->dev, &ir->ir, data, data); 107 ir_input_keydown(ir->dev, &ir->ir, data);
108 if (keyup) 108 if (keyup)
109 ir_input_nokey(ir->dev, &ir->ir); 109 ir_input_nokey(ir->dev, &ir->ir);
110 } else { 110 } else {
@@ -118,7 +118,7 @@ static void ir_enltv_handle_key(struct bttv *btv)
118 if (keyup) 118 if (keyup)
119 ir_input_nokey(ir->dev, &ir->ir); 119 ir_input_nokey(ir->dev, &ir->ir);
120 else 120 else
121 ir_input_keydown(ir->dev, &ir->ir, data, data); 121 ir_input_keydown(ir->dev, &ir->ir, data);
122 } 122 }
123 123
124 ir->last_gpio = data | keyup; 124 ir->last_gpio = data | keyup;
@@ -368,7 +368,10 @@ int bttv_input_init(struct bttv *btv)
368 snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0", 368 snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0",
369 pci_name(btv->c.pci)); 369 pci_name(btv->c.pci));
370 370
371 ir_input_init(input_dev, &ir->ir, ir_type, ir_codes); 371 err = ir_input_init(input_dev, &ir->ir, ir_type, ir_codes);
372 if (err < 0)
373 goto err_out_free;
374
372 input_dev->name = ir->name; 375 input_dev->name = ir->name;
373 input_dev->phys = ir->phys; 376 input_dev->phys = ir->phys;
374 input_dev->id.bustype = BUS_PCI; 377 input_dev->id.bustype = BUS_PCI;
@@ -400,6 +403,7 @@ int bttv_input_init(struct bttv *btv)
400 bttv_ir_stop(btv); 403 bttv_ir_stop(btv);
401 btv->remote = NULL; 404 btv->remote = NULL;
402 err_out_free: 405 err_out_free:
406 ir_input_free(input_dev);
403 input_free_device(input_dev); 407 input_free_device(input_dev);
404 kfree(ir); 408 kfree(ir);
405 return err; 409 return err;
@@ -411,6 +415,7 @@ void bttv_input_fini(struct bttv *btv)
411 return; 415 return;
412 416
413 bttv_ir_stop(btv); 417 bttv_ir_stop(btv);
418 ir_input_free(btv->remote->dev);
414 input_unregister_device(btv->remote->dev); 419 input_unregister_device(btv->remote->dev);
415 kfree(btv->remote); 420 kfree(btv->remote);
416 btv->remote = NULL; 421 btv->remote = NULL;
diff --git a/drivers/media/video/cx18/cx18-av-core.c b/drivers/media/video/cx18/cx18-av-core.c
index 536dedb23ba3..4392c76af5df 100644
--- a/drivers/media/video/cx18/cx18-av-core.c
+++ b/drivers/media/video/cx18/cx18-av-core.c
@@ -99,10 +99,8 @@ int cx18_av_and_or4(struct cx18 *cx, u16 addr, u32 and_mask,
99 or_value); 99 or_value);
100} 100}
101 101
102static int cx18_av_init(struct v4l2_subdev *sd, u32 val) 102static void cx18_av_init(struct cx18 *cx)
103{ 103{
104 struct cx18 *cx = v4l2_get_subdevdata(sd);
105
106 /* 104 /*
107 * The crystal freq used in calculations in this driver will be 105 * The crystal freq used in calculations in this driver will be
108 * 28.636360 MHz. 106 * 28.636360 MHz.
@@ -125,7 +123,6 @@ static int cx18_av_init(struct v4l2_subdev *sd, u32 val)
125 123
126 /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x16 */ 124 /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x16 */
127 cx18_av_write(cx, CXADEC_I2S_MCLK, 0x56); 125 cx18_av_write(cx, CXADEC_I2S_MCLK, 0x56);
128 return 0;
129} 126}
130 127
131static void cx18_av_initialize(struct v4l2_subdev *sd) 128static void cx18_av_initialize(struct v4l2_subdev *sd)
@@ -198,7 +195,7 @@ static void cx18_av_initialize(struct v4l2_subdev *sd)
198 cx18_av_and_or4(cx, CXADEC_CHIP_CTRL, 0xFFFBFFFF, 0x00120000); 195 cx18_av_and_or4(cx, CXADEC_CHIP_CTRL, 0xFFFBFFFF, 0x00120000);
199 196
200 /* Setup the Video and and Aux/Audio PLLs */ 197 /* Setup the Video and and Aux/Audio PLLs */
201 cx18_av_init(sd, 0); 198 cx18_av_init(cx);
202 199
203 /* set video to auto-detect */ 200 /* set video to auto-detect */
204 /* Clear bits 11-12 to enable slow locking mode. Set autodetect mode */ 201 /* Clear bits 11-12 to enable slow locking mode. Set autodetect mode */
@@ -1355,7 +1352,6 @@ static int cx18_av_s_register(struct v4l2_subdev *sd,
1355static const struct v4l2_subdev_core_ops cx18_av_general_ops = { 1352static const struct v4l2_subdev_core_ops cx18_av_general_ops = {
1356 .g_chip_ident = cx18_av_g_chip_ident, 1353 .g_chip_ident = cx18_av_g_chip_ident,
1357 .log_status = cx18_av_log_status, 1354 .log_status = cx18_av_log_status,
1358 .init = cx18_av_init,
1359 .load_fw = cx18_av_load_fw, 1355 .load_fw = cx18_av_load_fw,
1360 .reset = cx18_av_reset, 1356 .reset = cx18_av_reset,
1361 .queryctrl = cx18_av_queryctrl, 1357 .queryctrl = cx18_av_queryctrl,
@@ -1399,6 +1395,7 @@ int cx18_av_probe(struct cx18 *cx)
1399{ 1395{
1400 struct cx18_av_state *state = &cx->av_state; 1396 struct cx18_av_state *state = &cx->av_state;
1401 struct v4l2_subdev *sd; 1397 struct v4l2_subdev *sd;
1398 int err;
1402 1399
1403 state->rev = cx18_av_read4(cx, CXADEC_CHIP_CTRL) & 0xffff; 1400 state->rev = cx18_av_read4(cx, CXADEC_CHIP_CTRL) & 0xffff;
1404 state->id = ((state->rev >> 4) == CXADEC_CHIP_TYPE_MAKO) 1401 state->id = ((state->rev >> 4) == CXADEC_CHIP_TYPE_MAKO)
@@ -1417,5 +1414,8 @@ int cx18_av_probe(struct cx18 *cx)
1417 snprintf(sd->name, sizeof(sd->name), 1414 snprintf(sd->name, sizeof(sd->name),
1418 "%s %03x", cx->v4l2_dev.name, (state->rev >> 4)); 1415 "%s %03x", cx->v4l2_dev.name, (state->rev >> 4));
1419 sd->grp_id = CX18_HW_418_AV; 1416 sd->grp_id = CX18_HW_418_AV;
1420 return v4l2_device_register_subdev(&cx->v4l2_dev, sd); 1417 err = v4l2_device_register_subdev(&cx->v4l2_dev, sd);
1418 if (!err)
1419 cx18_av_init(cx);
1420 return err;
1421} 1421}
diff --git a/drivers/media/video/cx18/cx18-cards.h b/drivers/media/video/cx18/cx18-cards.h
index 444e3c7c563e..af3d71607dc9 100644
--- a/drivers/media/video/cx18/cx18-cards.h
+++ b/drivers/media/video/cx18/cx18-cards.h
@@ -34,6 +34,9 @@
34#define CX18_HW_Z8F0811_IR_HAUP (CX18_HW_Z8F0811_IR_RX_HAUP | \ 34#define CX18_HW_Z8F0811_IR_HAUP (CX18_HW_Z8F0811_IR_RX_HAUP | \
35 CX18_HW_Z8F0811_IR_TX_HAUP) 35 CX18_HW_Z8F0811_IR_TX_HAUP)
36 36
37#define CX18_HW_IR_ANY (CX18_HW_Z8F0811_IR_RX_HAUP | \
38 CX18_HW_Z8F0811_IR_TX_HAUP)
39
37/* video inputs */ 40/* video inputs */
38#define CX18_CARD_INPUT_VID_TUNER 1 41#define CX18_CARD_INPUT_VID_TUNER 1
39#define CX18_CARD_INPUT_SVIDEO1 2 42#define CX18_CARD_INPUT_SVIDEO1 2
diff --git a/drivers/media/video/cx18/cx18-driver.c b/drivers/media/video/cx18/cx18-driver.c
index e12082b8a08d..7f65a47f12e1 100644
--- a/drivers/media/video/cx18/cx18-driver.c
+++ b/drivers/media/video/cx18/cx18-driver.c
@@ -87,7 +87,6 @@ static int enc_ts_bufsize = CX18_DEFAULT_ENC_TS_BUFSIZE;
87static int enc_mpg_bufsize = CX18_DEFAULT_ENC_MPG_BUFSIZE; 87static int enc_mpg_bufsize = CX18_DEFAULT_ENC_MPG_BUFSIZE;
88static int enc_idx_bufsize = CX18_DEFAULT_ENC_IDX_BUFSIZE; 88static int enc_idx_bufsize = CX18_DEFAULT_ENC_IDX_BUFSIZE;
89static int enc_yuv_bufsize = CX18_DEFAULT_ENC_YUV_BUFSIZE; 89static int enc_yuv_bufsize = CX18_DEFAULT_ENC_YUV_BUFSIZE;
90/* VBI bufsize based on standards supported by card tuner for now */
91static int enc_pcm_bufsize = CX18_DEFAULT_ENC_PCM_BUFSIZE; 90static int enc_pcm_bufsize = CX18_DEFAULT_ENC_PCM_BUFSIZE;
92 91
93static int enc_ts_bufs = -1; 92static int enc_ts_bufs = -1;
@@ -128,7 +127,6 @@ module_param(enc_ts_bufsize, int, 0644);
128module_param(enc_mpg_bufsize, int, 0644); 127module_param(enc_mpg_bufsize, int, 0644);
129module_param(enc_idx_bufsize, int, 0644); 128module_param(enc_idx_bufsize, int, 0644);
130module_param(enc_yuv_bufsize, int, 0644); 129module_param(enc_yuv_bufsize, int, 0644);
131/* VBI bufsize based on standards supported by card tuner for now */
132module_param(enc_pcm_bufsize, int, 0644); 130module_param(enc_pcm_bufsize, int, 0644);
133 131
134module_param(enc_ts_bufs, int, 0644); 132module_param(enc_ts_bufs, int, 0644);
@@ -211,7 +209,9 @@ MODULE_PARM_DESC(enc_yuv_buffers,
211 "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_YUV_BUFFERS)); 209 "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_YUV_BUFFERS));
212MODULE_PARM_DESC(enc_yuv_bufsize, 210MODULE_PARM_DESC(enc_yuv_bufsize,
213 "Size of an encoder YUV buffer (kB)\n" 211 "Size of an encoder YUV buffer (kB)\n"
214 "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_YUV_BUFSIZE)); 212 "\t\t\tAllowed values are multiples of 33.75 kB rounded up\n"
213 "\t\t\t(multiples of size required for 32 screen lines)\n"
214 "\t\t\tDefault: 102");
215MODULE_PARM_DESC(enc_yuv_bufs, 215MODULE_PARM_DESC(enc_yuv_bufs,
216 "Number of encoder YUV buffers\n" 216 "Number of encoder YUV buffers\n"
217 "\t\t\tDefault is computed from other enc_yuv_* parameters"); 217 "\t\t\tDefault is computed from other enc_yuv_* parameters");
@@ -220,7 +220,7 @@ MODULE_PARM_DESC(enc_vbi_buffers,
220 "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_VBI_BUFFERS)); 220 "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_VBI_BUFFERS));
221MODULE_PARM_DESC(enc_vbi_bufs, 221MODULE_PARM_DESC(enc_vbi_bufs,
222 "Number of encoder VBI buffers\n" 222 "Number of encoder VBI buffers\n"
223 "\t\t\tDefault is computed from enc_vbi_buffers & tuner std"); 223 "\t\t\tDefault is computed from enc_vbi_buffers");
224MODULE_PARM_DESC(enc_pcm_buffers, 224MODULE_PARM_DESC(enc_pcm_buffers,
225 "Encoder PCM buffer memory (MB). (enc_pcm_bufs can override)\n" 225 "Encoder PCM buffer memory (MB). (enc_pcm_bufs can override)\n"
226 "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_PCM_BUFFERS)); 226 "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_PCM_BUFFERS));
@@ -499,10 +499,27 @@ static void cx18_process_options(struct cx18 *cx)
499 continue; 499 continue;
500 } 500 }
501 /* 501 /*
502 * 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
504 * lines to maintain alignment in case of lost buffers
505 */
506 if (i == CX18_ENC_STREAM_TYPE_YUV) {
507 cx->stream_buf_size[i] *= 1024;
508 cx->stream_buf_size[i] -=
509 (cx->stream_buf_size[i] % CX18_UNIT_ENC_YUV_BUFSIZE);
510
511 if (cx->stream_buf_size[i] < CX18_UNIT_ENC_YUV_BUFSIZE)
512 cx->stream_buf_size[i] =
513 CX18_UNIT_ENC_YUV_BUFSIZE;
514 }
515 /*
516 * YUV is a special case where the stream_buf_size is
517 * now in bytes.
502 * VBI is a special case where the stream_buf_size is fixed 518 * VBI is a special case where the stream_buf_size is fixed
503 * and already in bytes 519 * and already in bytes
504 */ 520 */
505 if (i == CX18_ENC_STREAM_TYPE_VBI) { 521 if (i == CX18_ENC_STREAM_TYPE_VBI ||
522 i == CX18_ENC_STREAM_TYPE_YUV) {
506 if (cx->stream_buffers[i] < 0) { 523 if (cx->stream_buffers[i] < 0) {
507 cx->stream_buffers[i] = 524 cx->stream_buffers[i] =
508 cx->options.megabytes[i] * 1024 * 1024 525 cx->options.megabytes[i] * 1024 * 1024
@@ -513,18 +530,24 @@ static void cx18_process_options(struct cx18 *cx)
513 cx->stream_buffers[i] 530 cx->stream_buffers[i]
514 * cx->stream_buf_size[i]/(1024 * 1024); 531 * cx->stream_buf_size[i]/(1024 * 1024);
515 } 532 }
516 continue;
517 }
518 /* All other streams have stream_buf_size in kB at this point */
519 if (cx->stream_buffers[i] < 0) {
520 cx->stream_buffers[i] = cx->options.megabytes[i] * 1024
521 / cx->stream_buf_size[i];
522 } else { 533 } else {
523 /* N.B. This might round down to 0 */ 534 /* All other streams have stream_buf_size in kB here */
524 cx->options.megabytes[i] = 535 if (cx->stream_buffers[i] < 0) {
525 cx->stream_buffers[i] * cx->stream_buf_size[i] / 1024; 536 cx->stream_buffers[i] =
537 cx->options.megabytes[i] * 1024
538 / cx->stream_buf_size[i];
539 } else {
540 /* N.B. This might round down to 0 */
541 cx->options.megabytes[i] =
542 cx->stream_buffers[i]
543 * cx->stream_buf_size[i] / 1024;
544 }
545 /* convert from kB to bytes */
546 cx->stream_buf_size[i] *= 1024;
526 } 547 }
527 cx->stream_buf_size[i] *= 1024; /* convert from kB to bytes */ 548 CX18_DEBUG_INFO("Stream type %d options: %d MB, %d buffers, "
549 "%d bytes\n", i, cx->options.megabytes[i],
550 cx->stream_buffers[i], cx->stream_buf_size[i]);
528 } 551 }
529 552
530 cx->options.cardtype = cardtype[cx->instance]; 553 cx->options.cardtype = cardtype[cx->instance];
@@ -669,6 +692,12 @@ static int __devinit cx18_init_struct1(struct cx18 *cx)
669 cx->vbi.in.type = V4L2_BUF_TYPE_VBI_CAPTURE; 692 cx->vbi.in.type = V4L2_BUF_TYPE_VBI_CAPTURE;
670 cx->vbi.sliced_in = &cx->vbi.in.fmt.sliced; 693 cx->vbi.sliced_in = &cx->vbi.in.fmt.sliced;
671 694
695 /* IVTV style VBI insertion into MPEG streams */
696 INIT_LIST_HEAD(&cx->vbi.sliced_mpeg_buf.list);
697 INIT_LIST_HEAD(&cx->vbi.sliced_mpeg_mdl.list);
698 INIT_LIST_HEAD(&cx->vbi.sliced_mpeg_mdl.buf_list);
699 list_add(&cx->vbi.sliced_mpeg_buf.list,
700 &cx->vbi.sliced_mpeg_mdl.buf_list);
672 return 0; 701 return 0;
673} 702}
674 703
@@ -883,7 +912,6 @@ static int __devinit cx18_probe(struct pci_dev *pci_dev,
883 CX18_ERR("Could not register A/V decoder subdevice\n"); 912 CX18_ERR("Could not register A/V decoder subdevice\n");
884 goto free_map; 913 goto free_map;
885 } 914 }
886 cx18_call_hw(cx, CX18_HW_418_AV, core, init, 0);
887 915
888 /* Initialize GPIO Reset Controller to do chip resets during i2c init */ 916 /* Initialize GPIO Reset Controller to do chip resets during i2c init */
889 if (cx->card->hw_all & CX18_HW_GPIO_RESET_CTRL) { 917 if (cx->card->hw_all & CX18_HW_GPIO_RESET_CTRL) {
diff --git a/drivers/media/video/cx18/cx18-driver.h b/drivers/media/video/cx18/cx18-driver.h
index c6a1e907f63a..e3f7911a7385 100644
--- a/drivers/media/video/cx18/cx18-driver.h
+++ b/drivers/media/video/cx18/cx18-driver.h
@@ -50,6 +50,7 @@
50#include <media/v4l2-ioctl.h> 50#include <media/v4l2-ioctl.h>
51#include <media/v4l2-device.h> 51#include <media/v4l2-device.h>
52#include <media/tuner.h> 52#include <media/tuner.h>
53#include <media/ir-kbd-i2c.h>
53#include "cx18-mailbox.h" 54#include "cx18-mailbox.h"
54#include "cx18-av-core.h" 55#include "cx18-av-core.h"
55#include "cx23418.h" 56#include "cx23418.h"
@@ -120,12 +121,16 @@
120/* Maximum firmware DMA buffers per stream */ 121/* Maximum firmware DMA buffers per stream */
121#define CX18_MAX_FW_MDLS_PER_STREAM 63 122#define CX18_MAX_FW_MDLS_PER_STREAM 63
122 123
124/* YUV buffer sizes in bytes to ensure integer # of frames per buffer */
125#define CX18_UNIT_ENC_YUV_BUFSIZE (720 * 32 * 3 / 2) /* bytes */
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)
128
123/* DMA buffer, default size in kB allocated */ 129/* DMA buffer, default size in kB allocated */
124#define CX18_DEFAULT_ENC_TS_BUFSIZE 32 130#define CX18_DEFAULT_ENC_TS_BUFSIZE 32
125#define CX18_DEFAULT_ENC_MPG_BUFSIZE 32 131#define CX18_DEFAULT_ENC_MPG_BUFSIZE 32
126#define CX18_DEFAULT_ENC_IDX_BUFSIZE 32 132#define CX18_DEFAULT_ENC_IDX_BUFSIZE 32
127#define CX18_DEFAULT_ENC_YUV_BUFSIZE 128 133#define CX18_DEFAULT_ENC_YUV_BUFSIZE (CX18_UNIT_ENC_YUV_BUFSIZE * 3 / 1024 + 1)
128/* Default VBI bufsize based on standards supported by card tuner for now */
129#define CX18_DEFAULT_ENC_PCM_BUFSIZE 4 134#define CX18_DEFAULT_ENC_PCM_BUFSIZE 4
130 135
131/* i2c stuff */ 136/* i2c stuff */
@@ -246,8 +251,8 @@ struct cx18_options {
246 int radio; /* enable/disable radio */ 251 int radio; /* enable/disable radio */
247}; 252};
248 253
249/* per-buffer bit flags */ 254/* per-mdl bit flags */
250#define CX18_F_B_NEED_BUF_SWAP 0 /* this buffer should be byte swapped */ 255#define CX18_F_M_NEED_SWAP 0 /* mdl buffer data must be endianess swapped */
251 256
252/* per-stream, s_flags */ 257/* per-stream, s_flags */
253#define CX18_F_S_CLAIMED 3 /* this stream is claimed */ 258#define CX18_F_S_CLAIMED 3 /* this stream is claimed */
@@ -274,18 +279,29 @@ struct cx18_options {
274struct cx18_buffer { 279struct cx18_buffer {
275 struct list_head list; 280 struct list_head list;
276 dma_addr_t dma_handle; 281 dma_addr_t dma_handle;
277 u32 id;
278 unsigned long b_flags;
279 unsigned skipped;
280 char *buf; 282 char *buf;
281 283
282 u32 bytesused; 284 u32 bytesused;
283 u32 readpos; 285 u32 readpos;
284}; 286};
285 287
288struct cx18_mdl {
289 struct list_head list;
290 u32 id; /* index into cx->scb->cpu_mdl[] of 1st cx18_mdl_ent */
291
292 unsigned int skipped;
293 unsigned long m_flags;
294
295 struct list_head buf_list;
296 struct cx18_buffer *curr_buf; /* current buffer in list for reading */
297
298 u32 bytesused;
299 u32 readpos;
300};
301
286struct cx18_queue { 302struct cx18_queue {
287 struct list_head list; 303 struct list_head list;
288 atomic_t buffers; 304 atomic_t depth;
289 u32 bytesused; 305 u32 bytesused;
290 spinlock_t lock; 306 spinlock_t lock;
291}; 307};
@@ -337,7 +353,7 @@ struct cx18_stream {
337 const char *name; /* name of the stream */ 353 const char *name; /* name of the stream */
338 int type; /* stream type */ 354 int type; /* stream type */
339 u32 handle; /* task handle */ 355 u32 handle; /* task handle */
340 unsigned mdl_offset; 356 unsigned int mdl_base_idx;
341 357
342 u32 id; 358 u32 id;
343 unsigned long s_flags; /* status flags, see above */ 359 unsigned long s_flags; /* status flags, see above */
@@ -346,14 +362,20 @@ struct cx18_stream {
346 PCI_DMA_NONE */ 362 PCI_DMA_NONE */
347 wait_queue_head_t waitq; 363 wait_queue_head_t waitq;
348 364
349 /* Buffer Stats */ 365 /* Buffers */
350 u32 buffers; 366 struct list_head buf_pool; /* buffers not attached to an MDL */
351 u32 buf_size; 367 u32 buffers; /* total buffers owned by this stream */
368 u32 buf_size; /* size in bytes of a single buffer */
369
370 /* MDL sizes - all stream MDLs are the same size */
371 u32 bufs_per_mdl;
372 u32 mdl_size; /* total bytes in all buffers in a mdl */
352 373
353 /* Buffer Queues */ 374 /* MDL Queues */
354 struct cx18_queue q_free; /* free buffers */ 375 struct cx18_queue q_free; /* free - in rotation, not committed */
355 struct cx18_queue q_busy; /* busy buffers - in use by firmware */ 376 struct cx18_queue q_busy; /* busy - in use by firmware */
356 struct cx18_queue q_full; /* full buffers - data for user apps */ 377 struct cx18_queue q_full; /* full - data for user apps */
378 struct cx18_queue q_idle; /* idle - not in rotation */
357 379
358 struct work_struct out_work_order; 380 struct work_struct out_work_order;
359 381
@@ -481,10 +503,11 @@ struct vbi_info {
481 u32 inserted_frame; 503 u32 inserted_frame;
482 504
483 /* 505 /*
484 * A dummy driver stream transfer buffer with a copy of the next 506 * A dummy driver stream transfer mdl & buffer with a copy of the next
485 * sliced_mpeg_data[] buffer for output to userland apps. 507 * sliced_mpeg_data[] buffer for output to userland apps.
486 * Only used in cx18-fileops.c, but its state needs to persist at times. 508 * Only used in cx18-fileops.c, but its state needs to persist at times.
487 */ 509 */
510 struct cx18_mdl sliced_mpeg_mdl;
488 struct cx18_buffer sliced_mpeg_buf; 511 struct cx18_buffer sliced_mpeg_buf;
489}; 512};
490 513
@@ -511,10 +534,9 @@ struct cx18 {
511 u8 is_60hz; 534 u8 is_60hz;
512 u8 nof_inputs; /* number of video inputs */ 535 u8 nof_inputs; /* number of video inputs */
513 u8 nof_audio_inputs; /* number of audio inputs */ 536 u8 nof_audio_inputs; /* number of audio inputs */
514 u16 buffer_id; /* buffer ID counter */
515 u32 v4l2_cap; /* V4L2 capabilities of card */ 537 u32 v4l2_cap; /* V4L2 capabilities of card */
516 u32 hw_flags; /* Hardware description of the board */ 538 u32 hw_flags; /* Hardware description of the board */
517 unsigned mdl_offset; 539 unsigned int free_mdl_idx;
518 struct cx18_scb __iomem *scb; /* pointer to SCB */ 540 struct cx18_scb __iomem *scb; /* pointer to SCB */
519 struct mutex epu2apu_mb_lock; /* protect driver to chip mailbox in SCB*/ 541 struct mutex epu2apu_mb_lock; /* protect driver to chip mailbox in SCB*/
520 struct mutex epu2cpu_mb_lock; /* protect driver to chip mailbox in SCB*/ 542 struct mutex epu2cpu_mb_lock; /* protect driver to chip mailbox in SCB*/
@@ -585,6 +607,8 @@ struct cx18 {
585 struct i2c_algo_bit_data i2c_algo[2]; 607 struct i2c_algo_bit_data i2c_algo[2];
586 struct cx18_i2c_algo_callback_data i2c_algo_cb_data[2]; 608 struct cx18_i2c_algo_callback_data i2c_algo_cb_data[2];
587 609
610 struct IR_i2c_init_data ir_i2c_init_data;
611
588 /* gpio */ 612 /* gpio */
589 u32 gpio_dir; 613 u32 gpio_dir;
590 u32 gpio_val; 614 u32 gpio_val;
diff --git a/drivers/media/video/cx18/cx18-dvb.c b/drivers/media/video/cx18/cx18-dvb.c
index 51a0c33b25b7..71ad2d1b4c2c 100644
--- a/drivers/media/video/cx18/cx18-dvb.c
+++ b/drivers/media/video/cx18/cx18-dvb.c
@@ -61,6 +61,7 @@ static struct mxl5005s_config hauppauge_hvr1600_tuner = {
61 .top = MXL5005S_TOP_25P2, 61 .top = MXL5005S_TOP_25P2,
62 .mod_mode = MXL_DIGITAL_MODE, 62 .mod_mode = MXL_DIGITAL_MODE,
63 .if_mode = MXL_ZERO_IF, 63 .if_mode = MXL_ZERO_IF,
64 .qam_gain = 0x02,
64 .AgcMasterByte = 0x00, 65 .AgcMasterByte = 0x00,
65}; 66};
66 67
@@ -71,7 +72,8 @@ static struct s5h1409_config hauppauge_hvr1600_config = {
71 .qam_if = 44000, 72 .qam_if = 44000,
72 .inversion = S5H1409_INVERSION_OFF, 73 .inversion = S5H1409_INVERSION_OFF,
73 .status_mode = S5H1409_DEMODLOCKING, 74 .status_mode = S5H1409_DEMODLOCKING,
74 .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK 75 .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK,
76 .hvr1600_opt = S5H1409_HVR1600_OPTIMIZE
75}; 77};
76 78
77/* 79/*
@@ -360,9 +362,10 @@ int cx18_dvb_register(struct cx18_stream *stream)
360 dvb_net_init(dvb_adapter, &dvb->dvbnet, dmx); 362 dvb_net_init(dvb_adapter, &dvb->dvbnet, dmx);
361 363
362 CX18_INFO("DVB Frontend registered\n"); 364 CX18_INFO("DVB Frontend registered\n");
363 CX18_INFO("Registered DVB adapter%d for %s (%d x %d kB)\n", 365 CX18_INFO("Registered DVB adapter%d for %s (%d x %d.%02d kB)\n",
364 stream->dvb.dvb_adapter.num, stream->name, 366 stream->dvb.dvb_adapter.num, stream->name,
365 stream->buffers, stream->buf_size/1024); 367 stream->buffers, stream->buf_size/1024,
368 (stream->buf_size * 100 / 1024) % 100);
366 369
367 mutex_init(&dvb->feedlock); 370 mutex_init(&dvb->feedlock);
368 dvb->enabled = 1; 371 dvb->enabled = 1;
diff --git a/drivers/media/video/cx18/cx18-fileops.c b/drivers/media/video/cx18/cx18-fileops.c
index 04d9c2508b86..4e278db31cc9 100644
--- a/drivers/media/video/cx18/cx18-fileops.c
+++ b/drivers/media/video/cx18/cx18-fileops.c
@@ -166,11 +166,12 @@ static void cx18_dualwatch(struct cx18 *cx)
166} 166}
167 167
168 168
169static struct cx18_buffer *cx18_get_buffer(struct cx18_stream *s, int non_block, int *err) 169static struct cx18_mdl *cx18_get_mdl(struct cx18_stream *s, int non_block,
170 int *err)
170{ 171{
171 struct cx18 *cx = s->cx; 172 struct cx18 *cx = s->cx;
172 struct cx18_stream *s_vbi = &cx->streams[CX18_ENC_STREAM_TYPE_VBI]; 173 struct cx18_stream *s_vbi = &cx->streams[CX18_ENC_STREAM_TYPE_VBI];
173 struct cx18_buffer *buf; 174 struct cx18_mdl *mdl;
174 DEFINE_WAIT(wait); 175 DEFINE_WAIT(wait);
175 176
176 *err = 0; 177 *err = 0;
@@ -185,32 +186,33 @@ static struct cx18_buffer *cx18_get_buffer(struct cx18_stream *s, int non_block,
185 } 186 }
186 if (test_bit(CX18_F_S_INTERNAL_USE, &s_vbi->s_flags) && 187 if (test_bit(CX18_F_S_INTERNAL_USE, &s_vbi->s_flags) &&
187 !test_bit(CX18_F_S_APPL_IO, &s_vbi->s_flags)) { 188 !test_bit(CX18_F_S_APPL_IO, &s_vbi->s_flags)) {
188 while ((buf = cx18_dequeue(s_vbi, &s_vbi->q_full))) { 189 while ((mdl = cx18_dequeue(s_vbi,
190 &s_vbi->q_full))) {
189 /* byteswap and process VBI data */ 191 /* byteswap and process VBI data */
190 cx18_process_vbi_data(cx, buf, 192 cx18_process_vbi_data(cx, mdl,
191 s_vbi->type); 193 s_vbi->type);
192 cx18_stream_put_buf_fw(s_vbi, buf); 194 cx18_stream_put_mdl_fw(s_vbi, mdl);
193 } 195 }
194 } 196 }
195 buf = &cx->vbi.sliced_mpeg_buf; 197 mdl = &cx->vbi.sliced_mpeg_mdl;
196 if (buf->readpos != buf->bytesused) 198 if (mdl->readpos != mdl->bytesused)
197 return buf; 199 return mdl;
198 } 200 }
199 201
200 /* do we have new data? */ 202 /* do we have new data? */
201 buf = cx18_dequeue(s, &s->q_full); 203 mdl = cx18_dequeue(s, &s->q_full);
202 if (buf) { 204 if (mdl) {
203 if (!test_and_clear_bit(CX18_F_B_NEED_BUF_SWAP, 205 if (!test_and_clear_bit(CX18_F_M_NEED_SWAP,
204 &buf->b_flags)) 206 &mdl->m_flags))
205 return buf; 207 return mdl;
206 if (s->type == CX18_ENC_STREAM_TYPE_MPG) 208 if (s->type == CX18_ENC_STREAM_TYPE_MPG)
207 /* byteswap MPG data */ 209 /* byteswap MPG data */
208 cx18_buf_swap(buf); 210 cx18_mdl_swap(mdl);
209 else { 211 else {
210 /* byteswap and process VBI data */ 212 /* byteswap and process VBI data */
211 cx18_process_vbi_data(cx, buf, s->type); 213 cx18_process_vbi_data(cx, mdl, s->type);
212 } 214 }
213 return buf; 215 return mdl;
214 } 216 }
215 217
216 /* return if end of stream */ 218 /* return if end of stream */
@@ -229,7 +231,7 @@ static struct cx18_buffer *cx18_get_buffer(struct cx18_stream *s, int non_block,
229 prepare_to_wait(&s->waitq, &wait, TASK_INTERRUPTIBLE); 231 prepare_to_wait(&s->waitq, &wait, TASK_INTERRUPTIBLE);
230 /* New buffers might have become available before we were added 232 /* New buffers might have become available before we were added
231 to the waitqueue */ 233 to the waitqueue */
232 if (!atomic_read(&s->q_full.buffers)) 234 if (!atomic_read(&s->q_full.depth))
233 schedule(); 235 schedule();
234 finish_wait(&s->waitq, &wait); 236 finish_wait(&s->waitq, &wait);
235 if (signal_pending(current)) { 237 if (signal_pending(current)) {
@@ -241,21 +243,28 @@ static struct cx18_buffer *cx18_get_buffer(struct cx18_stream *s, int non_block,
241 } 243 }
242} 244}
243 245
244static void cx18_setup_sliced_vbi_buf(struct cx18 *cx) 246static void cx18_setup_sliced_vbi_mdl(struct cx18 *cx)
245{ 247{
248 struct cx18_mdl *mdl = &cx->vbi.sliced_mpeg_mdl;
249 struct cx18_buffer *buf = &cx->vbi.sliced_mpeg_buf;
246 int idx = cx->vbi.inserted_frame % CX18_VBI_FRAMES; 250 int idx = cx->vbi.inserted_frame % CX18_VBI_FRAMES;
247 251
248 cx->vbi.sliced_mpeg_buf.buf = cx->vbi.sliced_mpeg_data[idx]; 252 buf->buf = cx->vbi.sliced_mpeg_data[idx];
249 cx->vbi.sliced_mpeg_buf.bytesused = cx->vbi.sliced_mpeg_size[idx]; 253 buf->bytesused = cx->vbi.sliced_mpeg_size[idx];
250 cx->vbi.sliced_mpeg_buf.readpos = 0; 254 buf->readpos = 0;
255
256 mdl->curr_buf = NULL;
257 mdl->bytesused = cx->vbi.sliced_mpeg_size[idx];
258 mdl->readpos = 0;
251} 259}
252 260
253static size_t cx18_copy_buf_to_user(struct cx18_stream *s, 261static size_t cx18_copy_buf_to_user(struct cx18_stream *s,
254 struct cx18_buffer *buf, char __user *ubuf, size_t ucount) 262 struct cx18_buffer *buf, char __user *ubuf, size_t ucount, bool *stop)
255{ 263{
256 struct cx18 *cx = s->cx; 264 struct cx18 *cx = s->cx;
257 size_t len = buf->bytesused - buf->readpos; 265 size_t len = buf->bytesused - buf->readpos;
258 266
267 *stop = false;
259 if (len > ucount) 268 if (len > ucount)
260 len = ucount; 269 len = ucount;
261 if (cx->vbi.insert_mpeg && s->type == CX18_ENC_STREAM_TYPE_MPG && 270 if (cx->vbi.insert_mpeg && s->type == CX18_ENC_STREAM_TYPE_MPG &&
@@ -335,7 +344,8 @@ static size_t cx18_copy_buf_to_user(struct cx18_stream *s,
335 /* We declare we actually found a Program Pack*/ 344 /* We declare we actually found a Program Pack*/
336 cx->search_pack_header = 0; /* expect vid PES */ 345 cx->search_pack_header = 0; /* expect vid PES */
337 len = (char *)q - start; 346 len = (char *)q - start;
338 cx18_setup_sliced_vbi_buf(cx); 347 cx18_setup_sliced_vbi_mdl(cx);
348 *stop = true;
339 break; 349 break;
340 } 350 }
341 } 351 }
@@ -352,6 +362,60 @@ static size_t cx18_copy_buf_to_user(struct cx18_stream *s,
352 return len; 362 return len;
353} 363}
354 364
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,
378 struct cx18_mdl *mdl, char __user *ubuf, size_t ucount)
379{
380 size_t tot_written = 0;
381 int rc;
382 bool stop = false;
383
384 if (mdl->curr_buf == NULL)
385 mdl->curr_buf = list_first_entry(&mdl->buf_list,
386 struct cx18_buffer, list);
387
388 if (list_entry_is_past_end(mdl->curr_buf, &mdl->buf_list, list)) {
389 /*
390 * For some reason we've exhausted the buffers, but the MDL
391 * object still said some data was unread.
392 * Fix that and bail out.
393 */
394 mdl->readpos = mdl->bytesused;
395 return 0;
396 }
397
398 list_for_each_entry_from(mdl->curr_buf, &mdl->buf_list, list) {
399
400 if (mdl->curr_buf->readpos >= mdl->curr_buf->bytesused)
401 continue;
402
403 rc = cx18_copy_buf_to_user(s, mdl->curr_buf, ubuf + tot_written,
404 ucount - tot_written, &stop);
405 if (rc < 0)
406 return rc;
407 mdl->readpos += rc;
408 tot_written += rc;
409
410 if (stop || /* Forced stopping point for VBI insertion */
411 tot_written >= ucount || /* Reader request statisfied */
412 mdl->curr_buf->readpos < mdl->curr_buf->bytesused ||
413 mdl->readpos >= mdl->bytesused) /* MDL buffers drained */
414 break;
415 }
416 return tot_written;
417}
418
355static ssize_t cx18_read(struct cx18_stream *s, char __user *ubuf, 419static ssize_t cx18_read(struct cx18_stream *s, char __user *ubuf,
356 size_t tot_count, int non_block) 420 size_t tot_count, int non_block)
357{ 421{
@@ -373,12 +437,12 @@ static ssize_t cx18_read(struct cx18_stream *s, char __user *ubuf,
373 single_frame = 1; 437 single_frame = 1;
374 438
375 for (;;) { 439 for (;;) {
376 struct cx18_buffer *buf; 440 struct cx18_mdl *mdl;
377 int rc; 441 int rc;
378 442
379 buf = cx18_get_buffer(s, non_block, &rc); 443 mdl = cx18_get_mdl(s, non_block, &rc);
380 /* if there is no data available... */ 444 /* if there is no data available... */
381 if (buf == NULL) { 445 if (mdl == NULL) {
382 /* if we got data, then return that regardless */ 446 /* if we got data, then return that regardless */
383 if (tot_written) 447 if (tot_written)
384 break; 448 break;
@@ -392,20 +456,20 @@ static ssize_t cx18_read(struct cx18_stream *s, char __user *ubuf,
392 return rc; 456 return rc;
393 } 457 }
394 458
395 rc = cx18_copy_buf_to_user(s, buf, ubuf + tot_written, 459 rc = cx18_copy_mdl_to_user(s, mdl, ubuf + tot_written,
396 tot_count - tot_written); 460 tot_count - tot_written);
397 461
398 if (buf != &cx->vbi.sliced_mpeg_buf) { 462 if (mdl != &cx->vbi.sliced_mpeg_mdl) {
399 if (buf->readpos == buf->bytesused) 463 if (mdl->readpos == mdl->bytesused)
400 cx18_stream_put_buf_fw(s, buf); 464 cx18_stream_put_mdl_fw(s, mdl);
401 else 465 else
402 cx18_push(s, buf, &s->q_full); 466 cx18_push(s, mdl, &s->q_full);
403 } else if (buf->readpos == buf->bytesused) { 467 } else if (mdl->readpos == mdl->bytesused) {
404 int idx = cx->vbi.inserted_frame % CX18_VBI_FRAMES; 468 int idx = cx->vbi.inserted_frame % CX18_VBI_FRAMES;
405 469
406 cx->vbi.sliced_mpeg_size[idx] = 0; 470 cx->vbi.sliced_mpeg_size[idx] = 0;
407 cx->vbi.inserted_frame++; 471 cx->vbi.inserted_frame++;
408 cx->vbi_data_inserted += buf->bytesused; 472 cx->vbi_data_inserted += mdl->bytesused;
409 } 473 }
410 if (rc < 0) 474 if (rc < 0)
411 return rc; 475 return rc;
@@ -543,7 +607,7 @@ unsigned int cx18_v4l2_enc_poll(struct file *filp, poll_table *wait)
543 CX18_DEBUG_HI_FILE("Encoder poll\n"); 607 CX18_DEBUG_HI_FILE("Encoder poll\n");
544 poll_wait(filp, &s->waitq, wait); 608 poll_wait(filp, &s->waitq, wait);
545 609
546 if (atomic_read(&s->q_full.buffers)) 610 if (atomic_read(&s->q_full.depth))
547 return POLLIN | POLLRDNORM; 611 return POLLIN | POLLRDNORM;
548 if (eof) 612 if (eof)
549 return POLLHUP; 613 return POLLHUP;
diff --git a/drivers/media/video/cx18/cx18-i2c.c b/drivers/media/video/cx18/cx18-i2c.c
index 2477461e84d7..eecf29af916c 100644
--- a/drivers/media/video/cx18/cx18-i2c.c
+++ b/drivers/media/video/cx18/cx18-i2c.c
@@ -28,7 +28,6 @@
28#include "cx18-gpio.h" 28#include "cx18-gpio.h"
29#include "cx18-i2c.h" 29#include "cx18-i2c.h"
30#include "cx18-irq.h" 30#include "cx18-irq.h"
31#include <media/ir-kbd-i2c.h>
32 31
33#define CX18_REG_I2C_1_WR 0xf15000 32#define CX18_REG_I2C_1_WR 0xf15000
34#define CX18_REG_I2C_1_RD 0xf15008 33#define CX18_REG_I2C_1_RD 0xf15008
@@ -97,17 +96,11 @@ static const char * const hw_devicenames[] = {
97 "ir_rx_z8f0811_haup", 96 "ir_rx_z8f0811_haup",
98}; 97};
99 98
100static const struct IR_i2c_init_data z8f0811_ir_init_data = { 99static int cx18_i2c_new_ir(struct cx18 *cx, struct i2c_adapter *adap, u32 hw,
101 .ir_codes = &ir_codes_hauppauge_new_table, 100 const char *type, u8 addr)
102 .internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR,
103 .type = IR_TYPE_RC5,
104 .name = "CX23418 Z8F0811 Hauppauge",
105};
106
107static int cx18_i2c_new_ir(struct i2c_adapter *adap, u32 hw, const char *type,
108 u8 addr)
109{ 101{
110 struct i2c_board_info info; 102 struct i2c_board_info info;
103 struct IR_i2c_init_data *init_data = &cx->ir_i2c_init_data;
111 unsigned short addr_list[2] = { addr, I2C_CLIENT_END }; 104 unsigned short addr_list[2] = { addr, I2C_CLIENT_END };
112 105
113 memset(&info, 0, sizeof(struct i2c_board_info)); 106 memset(&info, 0, sizeof(struct i2c_board_info));
@@ -116,9 +109,11 @@ static int cx18_i2c_new_ir(struct i2c_adapter *adap, u32 hw, const char *type,
116 /* Our default information for ir-kbd-i2c.c to use */ 109 /* Our default information for ir-kbd-i2c.c to use */
117 switch (hw) { 110 switch (hw) {
118 case CX18_HW_Z8F0811_IR_RX_HAUP: 111 case CX18_HW_Z8F0811_IR_RX_HAUP:
119 info.platform_data = (void *) &z8f0811_ir_init_data; 112 init_data->ir_codes = &ir_codes_hauppauge_new_table;
120 break; 113 init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR;
121 default: 114 init_data->type = IR_TYPE_RC5;
115 init_data->name = cx->card_name;
116 info.platform_data = init_data;
122 break; 117 break;
123 } 118 }
124 119
@@ -154,8 +149,8 @@ int cx18_i2c_register(struct cx18 *cx, unsigned idx)
154 return sd != NULL ? 0 : -1; 149 return sd != NULL ? 0 : -1;
155 } 150 }
156 151
157 if (hw & CX18_HW_Z8F0811_IR_HAUP) 152 if (hw & CX18_HW_IR_ANY)
158 return cx18_i2c_new_ir(adap, hw, type, hw_addrs[idx]); 153 return cx18_i2c_new_ir(cx, adap, hw, type, hw_addrs[idx]);
159 154
160 /* Is it not an I2C device or one we do not wish to register? */ 155 /* Is it not an I2C device or one we do not wish to register? */
161 if (!hw_addrs[idx]) 156 if (!hw_addrs[idx])
diff --git a/drivers/media/video/cx18/cx18-ioctl.c b/drivers/media/video/cx18/cx18-ioctl.c
index fc76e4d6ffa7..3e4fc192fdec 100644
--- a/drivers/media/video/cx18/cx18-ioctl.c
+++ b/drivers/media/video/cx18/cx18-ioctl.c
@@ -910,7 +910,8 @@ static int cx18_log_status(struct file *file, void *fh)
910 continue; 910 continue;
911 CX18_INFO("Stream %s: status 0x%04lx, %d%% of %d KiB (%d buffers) in use\n", 911 CX18_INFO("Stream %s: status 0x%04lx, %d%% of %d KiB (%d buffers) in use\n",
912 s->name, s->s_flags, 912 s->name, s->s_flags,
913 atomic_read(&s->q_full.buffers) * 100 / s->buffers, 913 atomic_read(&s->q_full.depth) * s->bufs_per_mdl * 100
914 / s->buffers,
914 (s->buffers * s->buf_size) / 1024, s->buffers); 915 (s->buffers * s->buf_size) / 1024, s->buffers);
915 } 916 }
916 CX18_INFO("Read MPEG/VBI: %lld/%lld bytes\n", 917 CX18_INFO("Read MPEG/VBI: %lld/%lld bytes\n",
diff --git a/drivers/media/video/cx18/cx18-mailbox.c b/drivers/media/video/cx18/cx18-mailbox.c
index afe46c3d4057..f231dd09c720 100644
--- a/drivers/media/video/cx18/cx18-mailbox.c
+++ b/drivers/media/video/cx18/cx18-mailbox.c
@@ -131,13 +131,39 @@ static void dump_mb(struct cx18 *cx, struct cx18_mailbox *mb, char *name)
131 * Functions that run in a work_queue work handling context 131 * Functions that run in a work_queue work handling context
132 */ 132 */
133 133
134static void cx18_mdl_send_to_dvb(struct cx18_stream *s, struct cx18_mdl *mdl)
135{
136 struct cx18_buffer *buf;
137
138 if (!s->dvb.enabled || mdl->bytesused == 0)
139 return;
140
141 /* We ignore mdl and buf readpos accounting here - it doesn't matter */
142
143 /* The likely case */
144 if (list_is_singular(&mdl->buf_list)) {
145 buf = list_first_entry(&mdl->buf_list, struct cx18_buffer,
146 list);
147 if (buf->bytesused)
148 dvb_dmx_swfilter(&s->dvb.demux,
149 buf->buf, buf->bytesused);
150 return;
151 }
152
153 list_for_each_entry(buf, &mdl->buf_list, list) {
154 if (buf->bytesused == 0)
155 break;
156 dvb_dmx_swfilter(&s->dvb.demux, buf->buf, buf->bytesused);
157 }
158}
159
134static void epu_dma_done(struct cx18 *cx, struct cx18_in_work_order *order) 160static void epu_dma_done(struct cx18 *cx, struct cx18_in_work_order *order)
135{ 161{
136 u32 handle, mdl_ack_count, id; 162 u32 handle, mdl_ack_count, id;
137 struct cx18_mailbox *mb; 163 struct cx18_mailbox *mb;
138 struct cx18_mdl_ack *mdl_ack; 164 struct cx18_mdl_ack *mdl_ack;
139 struct cx18_stream *s; 165 struct cx18_stream *s;
140 struct cx18_buffer *buf; 166 struct cx18_mdl *mdl;
141 int i; 167 int i;
142 168
143 mb = &order->mb; 169 mb = &order->mb;
@@ -158,7 +184,7 @@ static void epu_dma_done(struct cx18 *cx, struct cx18_in_work_order *order)
158 id = mdl_ack->id; 184 id = mdl_ack->id;
159 /* 185 /*
160 * Simple integrity check for processing a stale (and possibly 186 * Simple integrity check for processing a stale (and possibly
161 * inconsistent mailbox): make sure the buffer id is in the 187 * inconsistent mailbox): make sure the MDL id is in the
162 * valid range for the stream. 188 * valid range for the stream.
163 * 189 *
164 * We go through the trouble of dealing with stale mailboxes 190 * We go through the trouble of dealing with stale mailboxes
@@ -169,44 +195,42 @@ static void epu_dma_done(struct cx18 *cx, struct cx18_in_work_order *order)
169 * There are occasions when we get a half changed mailbox, 195 * There are occasions when we get a half changed mailbox,
170 * which this check catches for a handle & id mismatch. If the 196 * which this check catches for a handle & id mismatch. If the
171 * handle and id do correspond, the worst case is that we 197 * handle and id do correspond, the worst case is that we
172 * completely lost the old buffer, but pick up the new buffer 198 * completely lost the old MDL, but pick up the new MDL
173 * early (but the new mdl_ack is guaranteed to be good in this 199 * early (but the new mdl_ack is guaranteed to be good in this
174 * case as the firmware wouldn't point us to a new mdl_ack until 200 * case as the firmware wouldn't point us to a new mdl_ack until
175 * it's filled in). 201 * it's filled in).
176 * 202 *
177 * cx18_queue_get buf() will detect the lost buffers 203 * cx18_queue_get_mdl() will detect the lost MDLs
178 * and send them back to q_free for fw rotation eventually. 204 * and send them back to q_free for fw rotation eventually.
179 */ 205 */
180 if ((order->flags & CX18_F_EWO_MB_STALE_UPON_RECEIPT) && 206 if ((order->flags & CX18_F_EWO_MB_STALE_UPON_RECEIPT) &&
181 !(id >= s->mdl_offset && 207 !(id >= s->mdl_base_idx &&
182 id < (s->mdl_offset + s->buffers))) { 208 id < (s->mdl_base_idx + s->buffers))) {
183 CX18_WARN("Fell behind! Ignoring stale mailbox with " 209 CX18_WARN("Fell behind! Ignoring stale mailbox with "
184 " inconsistent data. Lost buffer for mailbox " 210 " inconsistent data. Lost MDL for mailbox "
185 "seq no %d\n", mb->request); 211 "seq no %d\n", mb->request);
186 break; 212 break;
187 } 213 }
188 buf = cx18_queue_get_buf(s, id, mdl_ack->data_used); 214 mdl = cx18_queue_get_mdl(s, id, mdl_ack->data_used);
189 215
190 CX18_DEBUG_HI_DMA("DMA DONE for %s (buffer %d)\n", s->name, id); 216 CX18_DEBUG_HI_DMA("DMA DONE for %s (MDL %d)\n", s->name, id);
191 if (buf == NULL) { 217 if (mdl == NULL) {
192 CX18_WARN("Could not find buf %d for stream %s\n", 218 CX18_WARN("Could not find MDL %d for stream %s\n",
193 id, s->name); 219 id, s->name);
194 continue; 220 continue;
195 } 221 }
196 222
197 CX18_DEBUG_HI_DMA("%s recv bytesused = %d\n", 223 CX18_DEBUG_HI_DMA("%s recv bytesused = %d\n",
198 s->name, buf->bytesused); 224 s->name, mdl->bytesused);
199 225
200 if (s->type != CX18_ENC_STREAM_TYPE_TS) 226 if (s->type != CX18_ENC_STREAM_TYPE_TS)
201 cx18_enqueue(s, buf, &s->q_full); 227 cx18_enqueue(s, mdl, &s->q_full);
202 else { 228 else {
203 if (s->dvb.enabled) 229 cx18_mdl_send_to_dvb(s, mdl);
204 dvb_dmx_swfilter(&s->dvb.demux, buf->buf, 230 cx18_enqueue(s, mdl, &s->q_free);
205 buf->bytesused);
206 cx18_enqueue(s, buf, &s->q_free);
207 } 231 }
208 } 232 }
209 /* Put as many buffers as possible back into fw use */ 233 /* Put as many MDLs as possible back into fw use */
210 cx18_stream_load_fw_queue(s); 234 cx18_stream_load_fw_queue(s);
211 235
212 wake_up(&cx->dma_waitq); 236 wake_up(&cx->dma_waitq);
@@ -616,7 +640,7 @@ static int cx18_api_call(struct cx18 *cx, u32 cmd, int args, u32 data[])
616 640
617 /* 641 /*
618 * Wait for XPU to perform extra actions for the caller in some cases. 642 * Wait for XPU to perform extra actions for the caller in some cases.
619 * e.g. CX18_CPU_DE_RELEASE_MDL will cause the CPU to send all buffers 643 * e.g. CX18_CPU_DE_RELEASE_MDL will cause the CPU to send all MDLs
620 * back in a burst shortly thereafter 644 * back in a burst shortly thereafter
621 */ 645 */
622 if (info->flags & API_SLOW) 646 if (info->flags & API_SLOW)
diff --git a/drivers/media/video/cx18/cx18-mailbox.h b/drivers/media/video/cx18/cx18-mailbox.h
index 522ad534034c..33a3491c4537 100644
--- a/drivers/media/video/cx18/cx18-mailbox.h
+++ b/drivers/media/video/cx18/cx18-mailbox.h
@@ -39,14 +39,14 @@
39struct cx18; 39struct cx18;
40 40
41/* 41/*
42 * This structure is used by CPU to provide completed buffers information 42 * This structure is used by CPU to provide completed MDL & buffers information.
43 * Its structure is dictrated by the layout of the SCB, required by the 43 * Its structure is dictated by the layout of the SCB, required by the
44 * firmware, but its definition needs to be here, instead of in cx18-scb.h, 44 * firmware, but its definition needs to be here, instead of in cx18-scb.h,
45 * for mailbox work order scheduling 45 * for mailbox work order scheduling
46 */ 46 */
47struct cx18_mdl_ack { 47struct cx18_mdl_ack {
48 u32 id; /* ID of a completed MDL */ 48 u32 id; /* ID of a completed MDL */
49 u32 data_used; /* Total data filled in the MDL for buffer 'id' */ 49 u32 data_used; /* Total data filled in the MDL with 'id' */
50}; 50};
51 51
52/* The cx18_mailbox struct is the mailbox structure which is used for passing 52/* The cx18_mailbox struct is the mailbox structure which is used for passing
diff --git a/drivers/media/video/cx18/cx18-queue.c b/drivers/media/video/cx18/cx18-queue.c
index fa1ed7897d97..63304823cef5 100644
--- a/drivers/media/video/cx18/cx18-queue.c
+++ b/drivers/media/video/cx18/cx18-queue.c
@@ -26,6 +26,7 @@
26#include "cx18-queue.h" 26#include "cx18-queue.h"
27#include "cx18-streams.h" 27#include "cx18-streams.h"
28#include "cx18-scb.h" 28#include "cx18-scb.h"
29#include "cx18-io.h"
29 30
30void cx18_buf_swap(struct cx18_buffer *buf) 31void cx18_buf_swap(struct cx18_buffer *buf)
31{ 32{
@@ -35,151 +36,312 @@ void cx18_buf_swap(struct cx18_buffer *buf)
35 swab32s((u32 *)(buf->buf + i)); 36 swab32s((u32 *)(buf->buf + i));
36} 37}
37 38
39void _cx18_mdl_swap(struct cx18_mdl *mdl)
40{
41 struct cx18_buffer *buf;
42
43 list_for_each_entry(buf, &mdl->buf_list, list) {
44 if (buf->bytesused == 0)
45 break;
46 cx18_buf_swap(buf);
47 }
48}
49
38void cx18_queue_init(struct cx18_queue *q) 50void cx18_queue_init(struct cx18_queue *q)
39{ 51{
40 INIT_LIST_HEAD(&q->list); 52 INIT_LIST_HEAD(&q->list);
41 atomic_set(&q->buffers, 0); 53 atomic_set(&q->depth, 0);
42 q->bytesused = 0; 54 q->bytesused = 0;
43} 55}
44 56
45struct cx18_queue *_cx18_enqueue(struct cx18_stream *s, struct cx18_buffer *buf, 57struct cx18_queue *_cx18_enqueue(struct cx18_stream *s, struct cx18_mdl *mdl,
46 struct cx18_queue *q, int to_front) 58 struct cx18_queue *q, int to_front)
47{ 59{
48 /* clear the buffer if it is not to be enqueued to the full queue */ 60 /* clear the mdl if it is not to be enqueued to the full queue */
49 if (q != &s->q_full) { 61 if (q != &s->q_full) {
50 buf->bytesused = 0; 62 mdl->bytesused = 0;
51 buf->readpos = 0; 63 mdl->readpos = 0;
52 buf->b_flags = 0; 64 mdl->m_flags = 0;
53 buf->skipped = 0; 65 mdl->skipped = 0;
66 mdl->curr_buf = NULL;
54 } 67 }
55 68
56 /* q_busy is restricted to a max buffer count imposed by firmware */ 69 /* q_busy is restricted to a max buffer count imposed by firmware */
57 if (q == &s->q_busy && 70 if (q == &s->q_busy &&
58 atomic_read(&q->buffers) >= CX18_MAX_FW_MDLS_PER_STREAM) 71 atomic_read(&q->depth) >= CX18_MAX_FW_MDLS_PER_STREAM)
59 q = &s->q_free; 72 q = &s->q_free;
60 73
61 spin_lock(&q->lock); 74 spin_lock(&q->lock);
62 75
63 if (to_front) 76 if (to_front)
64 list_add(&buf->list, &q->list); /* LIFO */ 77 list_add(&mdl->list, &q->list); /* LIFO */
65 else 78 else
66 list_add_tail(&buf->list, &q->list); /* FIFO */ 79 list_add_tail(&mdl->list, &q->list); /* FIFO */
67 q->bytesused += buf->bytesused - buf->readpos; 80 q->bytesused += mdl->bytesused - mdl->readpos;
68 atomic_inc(&q->buffers); 81 atomic_inc(&q->depth);
69 82
70 spin_unlock(&q->lock); 83 spin_unlock(&q->lock);
71 return q; 84 return q;
72} 85}
73 86
74struct cx18_buffer *cx18_dequeue(struct cx18_stream *s, struct cx18_queue *q) 87struct cx18_mdl *cx18_dequeue(struct cx18_stream *s, struct cx18_queue *q)
75{ 88{
76 struct cx18_buffer *buf = NULL; 89 struct cx18_mdl *mdl = NULL;
77 90
78 spin_lock(&q->lock); 91 spin_lock(&q->lock);
79 if (!list_empty(&q->list)) { 92 if (!list_empty(&q->list)) {
80 buf = list_first_entry(&q->list, struct cx18_buffer, list); 93 mdl = list_first_entry(&q->list, struct cx18_mdl, list);
81 list_del_init(&buf->list); 94 list_del_init(&mdl->list);
82 q->bytesused -= buf->bytesused - buf->readpos; 95 q->bytesused -= mdl->bytesused - mdl->readpos;
83 buf->skipped = 0; 96 mdl->skipped = 0;
84 atomic_dec(&q->buffers); 97 atomic_dec(&q->depth);
85 } 98 }
86 spin_unlock(&q->lock); 99 spin_unlock(&q->lock);
87 return buf; 100 return mdl;
101}
102
103static void _cx18_mdl_update_bufs_for_cpu(struct cx18_stream *s,
104 struct cx18_mdl *mdl)
105{
106 struct cx18_buffer *buf;
107 u32 buf_size = s->buf_size;
108 u32 bytesused = mdl->bytesused;
109
110 list_for_each_entry(buf, &mdl->buf_list, list) {
111 buf->readpos = 0;
112 if (bytesused >= buf_size) {
113 buf->bytesused = buf_size;
114 bytesused -= buf_size;
115 } else {
116 buf->bytesused = bytesused;
117 bytesused = 0;
118 }
119 cx18_buf_sync_for_cpu(s, buf);
120 }
121}
122
123static inline void cx18_mdl_update_bufs_for_cpu(struct cx18_stream *s,
124 struct cx18_mdl *mdl)
125{
126 struct cx18_buffer *buf;
127
128 if (list_is_singular(&mdl->buf_list)) {
129 buf = list_first_entry(&mdl->buf_list, struct cx18_buffer,
130 list);
131 buf->bytesused = mdl->bytesused;
132 buf->readpos = 0;
133 cx18_buf_sync_for_cpu(s, buf);
134 } else {
135 _cx18_mdl_update_bufs_for_cpu(s, mdl);
136 }
88} 137}
89 138
90struct cx18_buffer *cx18_queue_get_buf(struct cx18_stream *s, u32 id, 139struct cx18_mdl *cx18_queue_get_mdl(struct cx18_stream *s, u32 id,
91 u32 bytesused) 140 u32 bytesused)
92{ 141{
93 struct cx18 *cx = s->cx; 142 struct cx18 *cx = s->cx;
94 struct cx18_buffer *buf; 143 struct cx18_mdl *mdl;
95 struct cx18_buffer *tmp; 144 struct cx18_mdl *tmp;
96 struct cx18_buffer *ret = NULL; 145 struct cx18_mdl *ret = NULL;
97 LIST_HEAD(sweep_up); 146 LIST_HEAD(sweep_up);
98 147
99 /* 148 /*
100 * We don't have to acquire multiple q locks here, because we are 149 * We don't have to acquire multiple q locks here, because we are
101 * serialized by the single threaded work handler. 150 * serialized by the single threaded work handler.
102 * Buffers from the firmware will thus remain in order as 151 * MDLs from the firmware will thus remain in order as
103 * they are moved from q_busy to q_full or to the dvb ring buffer. 152 * they are moved from q_busy to q_full or to the dvb ring buffer.
104 */ 153 */
105 spin_lock(&s->q_busy.lock); 154 spin_lock(&s->q_busy.lock);
106 list_for_each_entry_safe(buf, tmp, &s->q_busy.list, list) { 155 list_for_each_entry_safe(mdl, tmp, &s->q_busy.list, list) {
107 /* 156 /*
108 * We should find what the firmware told us is done, 157 * We should find what the firmware told us is done,
109 * right at the front of the queue. If we don't, we likely have 158 * right at the front of the queue. If we don't, we likely have
110 * missed a buffer done message from the firmware. 159 * missed an mdl done message from the firmware.
111 * Once we skip a buffer repeatedly, relative to the size of 160 * Once we skip an mdl repeatedly, relative to the size of
112 * q_busy, we have high confidence we've missed it. 161 * q_busy, we have high confidence we've missed it.
113 */ 162 */
114 if (buf->id != id) { 163 if (mdl->id != id) {
115 buf->skipped++; 164 mdl->skipped++;
116 if (buf->skipped >= atomic_read(&s->q_busy.buffers)-1) { 165 if (mdl->skipped >= atomic_read(&s->q_busy.depth)-1) {
117 /* buffer must have fallen out of rotation */ 166 /* mdl must have fallen out of rotation */
118 CX18_WARN("Skipped %s, buffer %d, %d " 167 CX18_WARN("Skipped %s, MDL %d, %d "
119 "times - it must have dropped out of " 168 "times - it must have dropped out of "
120 "rotation\n", s->name, buf->id, 169 "rotation\n", s->name, mdl->id,
121 buf->skipped); 170 mdl->skipped);
122 /* Sweep it up to put it back into rotation */ 171 /* Sweep it up to put it back into rotation */
123 list_move_tail(&buf->list, &sweep_up); 172 list_move_tail(&mdl->list, &sweep_up);
124 atomic_dec(&s->q_busy.buffers); 173 atomic_dec(&s->q_busy.depth);
125 } 174 }
126 continue; 175 continue;
127 } 176 }
128 /* 177 /*
129 * We pull the desired buffer off of the queue here. Something 178 * We pull the desired mdl off of the queue here. Something
130 * will have to put it back on a queue later. 179 * will have to put it back on a queue later.
131 */ 180 */
132 list_del_init(&buf->list); 181 list_del_init(&mdl->list);
133 atomic_dec(&s->q_busy.buffers); 182 atomic_dec(&s->q_busy.depth);
134 ret = buf; 183 ret = mdl;
135 break; 184 break;
136 } 185 }
137 spin_unlock(&s->q_busy.lock); 186 spin_unlock(&s->q_busy.lock);
138 187
139 /* 188 /*
140 * We found the buffer for which we were looking. Get it ready for 189 * We found the mdl for which we were looking. Get it ready for
141 * the caller to put on q_full or in the dvb ring buffer. 190 * the caller to put on q_full or in the dvb ring buffer.
142 */ 191 */
143 if (ret != NULL) { 192 if (ret != NULL) {
144 ret->bytesused = bytesused; 193 ret->bytesused = bytesused;
145 ret->skipped = 0; 194 ret->skipped = 0;
146 /* readpos and b_flags were 0'ed when the buf went on q_busy */ 195 /* 0'ed readpos, m_flags & curr_buf when mdl went on q_busy */
147 cx18_buf_sync_for_cpu(s, ret); 196 cx18_mdl_update_bufs_for_cpu(s, ret);
148 if (s->type != CX18_ENC_STREAM_TYPE_TS) 197 if (s->type != CX18_ENC_STREAM_TYPE_TS)
149 set_bit(CX18_F_B_NEED_BUF_SWAP, &ret->b_flags); 198 set_bit(CX18_F_M_NEED_SWAP, &ret->m_flags);
150 } 199 }
151 200
152 /* Put any buffers the firmware is ignoring back into normal rotation */ 201 /* Put any mdls the firmware is ignoring back into normal rotation */
153 list_for_each_entry_safe(buf, tmp, &sweep_up, list) { 202 list_for_each_entry_safe(mdl, tmp, &sweep_up, list) {
154 list_del_init(&buf->list); 203 list_del_init(&mdl->list);
155 cx18_enqueue(s, buf, &s->q_free); 204 cx18_enqueue(s, mdl, &s->q_free);
156 } 205 }
157 return ret; 206 return ret;
158} 207}
159 208
160/* Move all buffers of a queue to q_free, while flushing the buffers */ 209/* Move all mdls of a queue, while flushing the mdl */
161static void cx18_queue_flush(struct cx18_stream *s, struct cx18_queue *q) 210static void cx18_queue_flush(struct cx18_stream *s,
211 struct cx18_queue *q_src, struct cx18_queue *q_dst)
162{ 212{
163 struct cx18_buffer *buf; 213 struct cx18_mdl *mdl;
164 214
165 if (q == &s->q_free) 215 /* It only makes sense to flush to q_free or q_idle */
216 if (q_src == q_dst || q_dst == &s->q_full || q_dst == &s->q_busy)
166 return; 217 return;
167 218
168 spin_lock(&q->lock); 219 spin_lock(&q_src->lock);
169 while (!list_empty(&q->list)) { 220 spin_lock(&q_dst->lock);
170 buf = list_first_entry(&q->list, struct cx18_buffer, list); 221 while (!list_empty(&q_src->list)) {
171 list_move_tail(&buf->list, &s->q_free.list); 222 mdl = list_first_entry(&q_src->list, struct cx18_mdl, list);
172 buf->bytesused = buf->readpos = buf->b_flags = buf->skipped = 0; 223 list_move_tail(&mdl->list, &q_dst->list);
173 atomic_inc(&s->q_free.buffers); 224 mdl->bytesused = 0;
225 mdl->readpos = 0;
226 mdl->m_flags = 0;
227 mdl->skipped = 0;
228 mdl->curr_buf = NULL;
229 atomic_inc(&q_dst->depth);
174 } 230 }
175 cx18_queue_init(q); 231 cx18_queue_init(q_src);
176 spin_unlock(&q->lock); 232 spin_unlock(&q_src->lock);
233 spin_unlock(&q_dst->lock);
177} 234}
178 235
179void cx18_flush_queues(struct cx18_stream *s) 236void cx18_flush_queues(struct cx18_stream *s)
180{ 237{
181 cx18_queue_flush(s, &s->q_busy); 238 cx18_queue_flush(s, &s->q_busy, &s->q_free);
182 cx18_queue_flush(s, &s->q_full); 239 cx18_queue_flush(s, &s->q_full, &s->q_free);
240}
241
242/*
243 * Note, s->buf_pool is not protected by a lock,
244 * the stream better not have *anything* going on when calling this
245 */
246void cx18_unload_queues(struct cx18_stream *s)
247{
248 struct cx18_queue *q_idle = &s->q_idle;
249 struct cx18_mdl *mdl;
250 struct cx18_buffer *buf;
251
252 /* Move all MDLS to q_idle */
253 cx18_queue_flush(s, &s->q_busy, q_idle);
254 cx18_queue_flush(s, &s->q_full, q_idle);
255 cx18_queue_flush(s, &s->q_free, q_idle);
256
257 /* Reset MDL id's and move all buffers back to the stream's buf_pool */
258 spin_lock(&q_idle->lock);
259 list_for_each_entry(mdl, &q_idle->list, list) {
260 while (!list_empty(&mdl->buf_list)) {
261 buf = list_first_entry(&mdl->buf_list,
262 struct cx18_buffer, list);
263 list_move_tail(&buf->list, &s->buf_pool);
264 buf->bytesused = 0;
265 buf->readpos = 0;
266 }
267 mdl->id = s->mdl_base_idx; /* reset id to a "safe" value */
268 /* all other mdl fields were cleared by cx18_queue_flush() */
269 }
270 spin_unlock(&q_idle->lock);
271}
272
273/*
274 * Note, s->buf_pool is not protected by a lock,
275 * the stream better not have *anything* going on when calling this
276 */
277void cx18_load_queues(struct cx18_stream *s)
278{
279 struct cx18 *cx = s->cx;
280 struct cx18_mdl *mdl;
281 struct cx18_buffer *buf;
282 int mdl_id;
283 int i;
284 u32 partial_buf_size;
285
286 /*
287 * Attach buffers to MDLs, give the MDLs ids, and add MDLs to q_free
288 * Excess MDLs are left on q_idle
289 * Excess buffers are left in buf_pool and/or on an MDL in q_idle
290 */
291 mdl_id = s->mdl_base_idx;
292 for (mdl = cx18_dequeue(s, &s->q_idle), i = s->bufs_per_mdl;
293 mdl != NULL && i == s->bufs_per_mdl;
294 mdl = cx18_dequeue(s, &s->q_idle)) {
295
296 mdl->id = mdl_id;
297
298 for (i = 0; i < s->bufs_per_mdl; i++) {
299 if (list_empty(&s->buf_pool))
300 break;
301
302 buf = list_first_entry(&s->buf_pool, struct cx18_buffer,
303 list);
304 list_move_tail(&buf->list, &mdl->buf_list);
305
306 /* update the firmware's MDL array with this buffer */
307 cx18_writel(cx, buf->dma_handle,
308 &cx->scb->cpu_mdl[mdl_id + i].paddr);
309 cx18_writel(cx, s->buf_size,
310 &cx->scb->cpu_mdl[mdl_id + i].length);
311 }
312
313 if (i == s->bufs_per_mdl) {
314 /*
315 * The encoder doesn't honor s->mdl_size. So in the
316 * case of a non-integral number of buffers to meet
317 * mdl_size, we lie about the size of the last buffer
318 * in the MDL to get the encoder to really only send
319 * us mdl_size bytes per MDL transfer.
320 */
321 partial_buf_size = s->mdl_size % s->buf_size;
322 if (partial_buf_size) {
323 cx18_writel(cx, partial_buf_size,
324 &cx->scb->cpu_mdl[mdl_id + i - 1].length);
325 }
326 cx18_enqueue(s, mdl, &s->q_free);
327 } else {
328 /* Not enough buffers for this MDL; we won't use it */
329 cx18_push(s, mdl, &s->q_idle);
330 }
331 mdl_id += i;
332 }
333}
334
335void _cx18_mdl_sync_for_device(struct cx18_stream *s, struct cx18_mdl *mdl)
336{
337 int dma = s->dma;
338 u32 buf_size = s->buf_size;
339 struct pci_dev *pci_dev = s->cx->pci_dev;
340 struct cx18_buffer *buf;
341
342 list_for_each_entry(buf, &mdl->buf_list, list)
343 pci_dma_sync_single_for_device(pci_dev, buf->dma_handle,
344 buf_size, dma);
183} 345}
184 346
185int cx18_stream_alloc(struct cx18_stream *s) 347int cx18_stream_alloc(struct cx18_stream *s)
@@ -190,44 +352,62 @@ int cx18_stream_alloc(struct cx18_stream *s)
190 if (s->buffers == 0) 352 if (s->buffers == 0)
191 return 0; 353 return 0;
192 354
193 CX18_DEBUG_INFO("Allocate %s stream: %d x %d buffers (%dkB total)\n", 355 CX18_DEBUG_INFO("Allocate %s stream: %d x %d buffers "
356 "(%d.%02d kB total)\n",
194 s->name, s->buffers, s->buf_size, 357 s->name, s->buffers, s->buf_size,
195 s->buffers * s->buf_size / 1024); 358 s->buffers * s->buf_size / 1024,
359 (s->buffers * s->buf_size * 100 / 1024) % 100);
196 360
197 if (((char __iomem *)&cx->scb->cpu_mdl[cx->mdl_offset + s->buffers] - 361 if (((char __iomem *)&cx->scb->cpu_mdl[cx->free_mdl_idx + s->buffers] -
198 (char __iomem *)cx->scb) > SCB_RESERVED_SIZE) { 362 (char __iomem *)cx->scb) > SCB_RESERVED_SIZE) {
199 unsigned bufsz = (((char __iomem *)cx->scb) + SCB_RESERVED_SIZE - 363 unsigned bufsz = (((char __iomem *)cx->scb) + SCB_RESERVED_SIZE -
200 ((char __iomem *)cx->scb->cpu_mdl)); 364 ((char __iomem *)cx->scb->cpu_mdl));
201 365
202 CX18_ERR("Too many buffers, cannot fit in SCB area\n"); 366 CX18_ERR("Too many buffers, cannot fit in SCB area\n");
203 CX18_ERR("Max buffers = %zd\n", 367 CX18_ERR("Max buffers = %zd\n",
204 bufsz / sizeof(struct cx18_mdl)); 368 bufsz / sizeof(struct cx18_mdl_ent));
205 return -ENOMEM; 369 return -ENOMEM;
206 } 370 }
207 371
208 s->mdl_offset = cx->mdl_offset; 372 s->mdl_base_idx = cx->free_mdl_idx;
209 373
210 /* allocate stream buffers. Initially all buffers are in q_free. */ 374 /* allocate stream buffers and MDLs */
211 for (i = 0; i < s->buffers; i++) { 375 for (i = 0; i < s->buffers; i++) {
212 struct cx18_buffer *buf = kzalloc(sizeof(struct cx18_buffer), 376 struct cx18_mdl *mdl;
213 GFP_KERNEL|__GFP_NOWARN); 377 struct cx18_buffer *buf;
214 378
215 if (buf == NULL) 379 /* 1 MDL per buffer to handle the worst & also default case */
380 mdl = kzalloc(sizeof(struct cx18_mdl), GFP_KERNEL|__GFP_NOWARN);
381 if (mdl == NULL)
216 break; 382 break;
383
384 buf = kzalloc(sizeof(struct cx18_buffer),
385 GFP_KERNEL|__GFP_NOWARN);
386 if (buf == NULL) {
387 kfree(mdl);
388 break;
389 }
390
217 buf->buf = kmalloc(s->buf_size, GFP_KERNEL|__GFP_NOWARN); 391 buf->buf = kmalloc(s->buf_size, GFP_KERNEL|__GFP_NOWARN);
218 if (buf->buf == NULL) { 392 if (buf->buf == NULL) {
393 kfree(mdl);
219 kfree(buf); 394 kfree(buf);
220 break; 395 break;
221 } 396 }
222 buf->id = cx->buffer_id++; 397
398 INIT_LIST_HEAD(&mdl->list);
399 INIT_LIST_HEAD(&mdl->buf_list);
400 mdl->id = s->mdl_base_idx; /* a somewhat safe value */
401 cx18_enqueue(s, mdl, &s->q_idle);
402
223 INIT_LIST_HEAD(&buf->list); 403 INIT_LIST_HEAD(&buf->list);
224 buf->dma_handle = pci_map_single(s->cx->pci_dev, 404 buf->dma_handle = pci_map_single(s->cx->pci_dev,
225 buf->buf, s->buf_size, s->dma); 405 buf->buf, s->buf_size, s->dma);
226 cx18_buf_sync_for_cpu(s, buf); 406 cx18_buf_sync_for_cpu(s, buf);
227 cx18_enqueue(s, buf, &s->q_free); 407 list_add_tail(&buf->list, &s->buf_pool);
228 } 408 }
229 if (i == s->buffers) { 409 if (i == s->buffers) {
230 cx->mdl_offset += s->buffers; 410 cx->free_mdl_idx += s->buffers;
231 return 0; 411 return 0;
232 } 412 }
233 CX18_ERR("Couldn't allocate buffers for %s stream\n", s->name); 413 CX18_ERR("Couldn't allocate buffers for %s stream\n", s->name);
@@ -237,13 +417,21 @@ int cx18_stream_alloc(struct cx18_stream *s)
237 417
238void cx18_stream_free(struct cx18_stream *s) 418void cx18_stream_free(struct cx18_stream *s)
239{ 419{
420 struct cx18_mdl *mdl;
240 struct cx18_buffer *buf; 421 struct cx18_buffer *buf;
241 422
242 /* move all buffers to q_free */ 423 /* move all buffers to buf_pool and all MDLs to q_idle */
243 cx18_flush_queues(s); 424 cx18_unload_queues(s);
425
426 /* empty q_idle */
427 while ((mdl = cx18_dequeue(s, &s->q_idle)))
428 kfree(mdl);
429
430 /* empty buf_pool */
431 while (!list_empty(&s->buf_pool)) {
432 buf = list_first_entry(&s->buf_pool, struct cx18_buffer, list);
433 list_del_init(&buf->list);
244 434
245 /* empty q_free */
246 while ((buf = cx18_dequeue(s, &s->q_free))) {
247 pci_unmap_single(s->cx->pci_dev, buf->dma_handle, 435 pci_unmap_single(s->cx->pci_dev, buf->dma_handle,
248 s->buf_size, s->dma); 436 s->buf_size, s->dma);
249 kfree(buf->buf); 437 kfree(buf->buf);
diff --git a/drivers/media/video/cx18/cx18-queue.h b/drivers/media/video/cx18/cx18-queue.h
index 4de06269d88f..88a6d34ad3bb 100644
--- a/drivers/media/video/cx18/cx18-queue.h
+++ b/drivers/media/video/cx18/cx18-queue.h
@@ -40,32 +40,59 @@ static inline void cx18_buf_sync_for_device(struct cx18_stream *s,
40 s->buf_size, s->dma); 40 s->buf_size, s->dma);
41} 41}
42 42
43void _cx18_mdl_sync_for_device(struct cx18_stream *s, struct cx18_mdl *mdl);
44
45static inline void cx18_mdl_sync_for_device(struct cx18_stream *s,
46 struct cx18_mdl *mdl)
47{
48 if (list_is_singular(&mdl->buf_list))
49 cx18_buf_sync_for_device(s, list_first_entry(&mdl->buf_list,
50 struct cx18_buffer,
51 list));
52 else
53 _cx18_mdl_sync_for_device(s, mdl);
54}
55
43void cx18_buf_swap(struct cx18_buffer *buf); 56void cx18_buf_swap(struct cx18_buffer *buf);
57void _cx18_mdl_swap(struct cx18_mdl *mdl);
58
59static inline void cx18_mdl_swap(struct cx18_mdl *mdl)
60{
61 if (list_is_singular(&mdl->buf_list))
62 cx18_buf_swap(list_first_entry(&mdl->buf_list,
63 struct cx18_buffer, list));
64 else
65 _cx18_mdl_swap(mdl);
66}
44 67
45/* cx18_queue utility functions */ 68/* cx18_queue utility functions */
46struct cx18_queue *_cx18_enqueue(struct cx18_stream *s, struct cx18_buffer *buf, 69struct cx18_queue *_cx18_enqueue(struct cx18_stream *s, struct cx18_mdl *mdl,
47 struct cx18_queue *q, int to_front); 70 struct cx18_queue *q, int to_front);
48 71
49static inline 72static inline
50struct cx18_queue *cx18_enqueue(struct cx18_stream *s, struct cx18_buffer *buf, 73struct cx18_queue *cx18_enqueue(struct cx18_stream *s, struct cx18_mdl *mdl,
51 struct cx18_queue *q) 74 struct cx18_queue *q)
52{ 75{
53 return _cx18_enqueue(s, buf, q, 0); /* FIFO */ 76 return _cx18_enqueue(s, mdl, q, 0); /* FIFO */
54} 77}
55 78
56static inline 79static inline
57struct cx18_queue *cx18_push(struct cx18_stream *s, struct cx18_buffer *buf, 80struct cx18_queue *cx18_push(struct cx18_stream *s, struct cx18_mdl *mdl,
58 struct cx18_queue *q) 81 struct cx18_queue *q)
59{ 82{
60 return _cx18_enqueue(s, buf, q, 1); /* LIFO */ 83 return _cx18_enqueue(s, mdl, q, 1); /* LIFO */
61} 84}
62 85
63void cx18_queue_init(struct cx18_queue *q); 86void cx18_queue_init(struct cx18_queue *q);
64struct cx18_buffer *cx18_dequeue(struct cx18_stream *s, struct cx18_queue *q); 87struct cx18_mdl *cx18_dequeue(struct cx18_stream *s, struct cx18_queue *q);
65struct cx18_buffer *cx18_queue_get_buf(struct cx18_stream *s, u32 id, 88struct cx18_mdl *cx18_queue_get_mdl(struct cx18_stream *s, u32 id,
66 u32 bytesused); 89 u32 bytesused);
67void cx18_flush_queues(struct cx18_stream *s); 90void cx18_flush_queues(struct cx18_stream *s);
68 91
92/* queue MDL reconfiguration helpers */
93void cx18_unload_queues(struct cx18_stream *s);
94void cx18_load_queues(struct cx18_stream *s);
95
69/* cx18_stream utility functions */ 96/* cx18_stream utility functions */
70int cx18_stream_alloc(struct cx18_stream *s); 97int cx18_stream_alloc(struct cx18_stream *s);
71void cx18_stream_free(struct cx18_stream *s); 98void cx18_stream_free(struct cx18_stream *s);
diff --git a/drivers/media/video/cx18/cx18-scb.h b/drivers/media/video/cx18/cx18-scb.h
index 1dc1c431f5a1..368f23d08709 100644
--- a/drivers/media/video/cx18/cx18-scb.h
+++ b/drivers/media/video/cx18/cx18-scb.h
@@ -81,7 +81,7 @@
81 81
82 82
83/* This structure is used by EPU to provide memory descriptors in its memory */ 83/* This structure is used by EPU to provide memory descriptors in its memory */
84struct cx18_mdl { 84struct cx18_mdl_ent {
85 u32 paddr; /* Physical address of a buffer segment */ 85 u32 paddr; /* Physical address of a buffer segment */
86 u32 length; /* Length of the buffer segment */ 86 u32 length; /* Length of the buffer segment */
87}; 87};
@@ -272,7 +272,7 @@ struct cx18_scb {
272 struct cx18_mailbox ppu2epu_mb; 272 struct cx18_mailbox ppu2epu_mb;
273 273
274 struct cx18_mdl_ack cpu_mdl_ack[CX18_MAX_STREAMS][CX18_MAX_MDL_ACKS]; 274 struct cx18_mdl_ack cpu_mdl_ack[CX18_MAX_STREAMS][CX18_MAX_MDL_ACKS];
275 struct cx18_mdl cpu_mdl[1]; 275 struct cx18_mdl_ent cpu_mdl[1];
276}; 276};
277 277
278void cx18_init_scb(struct cx18 *cx); 278void cx18_init_scb(struct cx18 *cx);
diff --git a/drivers/media/video/cx18/cx18-streams.c b/drivers/media/video/cx18/cx18-streams.c
index 7df513a2dba8..c398651dd74c 100644
--- a/drivers/media/video/cx18/cx18-streams.c
+++ b/drivers/media/video/cx18/cx18-streams.c
@@ -115,6 +115,9 @@ static void cx18_stream_init(struct cx18 *cx, int type)
115 s->dma = cx18_stream_info[type].dma; 115 s->dma = cx18_stream_info[type].dma;
116 s->buffers = cx->stream_buffers[type]; 116 s->buffers = cx->stream_buffers[type];
117 s->buf_size = cx->stream_buf_size[type]; 117 s->buf_size = cx->stream_buf_size[type];
118 INIT_LIST_HEAD(&s->buf_pool);
119 s->bufs_per_mdl = 1;
120 s->mdl_size = s->buf_size * s->bufs_per_mdl;
118 121
119 init_waitqueue_head(&s->waitq); 122 init_waitqueue_head(&s->waitq);
120 s->id = -1; 123 s->id = -1;
@@ -124,6 +127,8 @@ static void cx18_stream_init(struct cx18 *cx, int type)
124 cx18_queue_init(&s->q_busy); 127 cx18_queue_init(&s->q_busy);
125 spin_lock_init(&s->q_full.lock); 128 spin_lock_init(&s->q_full.lock);
126 cx18_queue_init(&s->q_full); 129 cx18_queue_init(&s->q_full);
130 spin_lock_init(&s->q_idle.lock);
131 cx18_queue_init(&s->q_idle);
127 132
128 INIT_WORK(&s->out_work_order, cx18_out_work_handler); 133 INIT_WORK(&s->out_work_order, cx18_out_work_handler);
129} 134}
@@ -257,9 +262,11 @@ static int cx18_reg_dev(struct cx18 *cx, int type)
257 262
258 switch (vfl_type) { 263 switch (vfl_type) {
259 case VFL_TYPE_GRABBER: 264 case VFL_TYPE_GRABBER:
260 CX18_INFO("Registered device video%d for %s (%d x %d kB)\n", 265 CX18_INFO("Registered device video%d for %s "
266 "(%d x %d.%02d kB)\n",
261 num, s->name, cx->stream_buffers[type], 267 num, s->name, cx->stream_buffers[type],
262 cx->stream_buf_size[type]/1024); 268 cx->stream_buf_size[type] / 1024,
269 (cx->stream_buf_size[type] * 100 / 1024) % 100);
263 break; 270 break;
264 271
265 case VFL_TYPE_RADIO: 272 case VFL_TYPE_RADIO:
@@ -441,8 +448,8 @@ static void cx18_vbi_setup(struct cx18_stream *s)
441} 448}
442 449
443static 450static
444struct cx18_queue *_cx18_stream_put_buf_fw(struct cx18_stream *s, 451struct cx18_queue *_cx18_stream_put_mdl_fw(struct cx18_stream *s,
445 struct cx18_buffer *buf) 452 struct cx18_mdl *mdl)
446{ 453{
447 struct cx18 *cx = s->cx; 454 struct cx18 *cx = s->cx;
448 struct cx18_queue *q; 455 struct cx18_queue *q;
@@ -451,16 +458,16 @@ struct cx18_queue *_cx18_stream_put_buf_fw(struct cx18_stream *s,
451 if (s->handle == CX18_INVALID_TASK_HANDLE || 458 if (s->handle == CX18_INVALID_TASK_HANDLE ||
452 test_bit(CX18_F_S_STOPPING, &s->s_flags) || 459 test_bit(CX18_F_S_STOPPING, &s->s_flags) ||
453 !test_bit(CX18_F_S_STREAMING, &s->s_flags)) 460 !test_bit(CX18_F_S_STREAMING, &s->s_flags))
454 return cx18_enqueue(s, buf, &s->q_free); 461 return cx18_enqueue(s, mdl, &s->q_free);
455 462
456 q = cx18_enqueue(s, buf, &s->q_busy); 463 q = cx18_enqueue(s, mdl, &s->q_busy);
457 if (q != &s->q_busy) 464 if (q != &s->q_busy)
458 return q; /* The firmware has the max buffers it can handle */ 465 return q; /* The firmware has the max MDLs it can handle */
459 466
460 cx18_buf_sync_for_device(s, buf); 467 cx18_mdl_sync_for_device(s, mdl);
461 cx18_vapi(cx, CX18_CPU_DE_SET_MDL, 5, s->handle, 468 cx18_vapi(cx, CX18_CPU_DE_SET_MDL, 5, s->handle,
462 (void __iomem *) &cx->scb->cpu_mdl[buf->id] - cx->enc_mem, 469 (void __iomem *) &cx->scb->cpu_mdl[mdl->id] - cx->enc_mem,
463 1, buf->id, s->buf_size); 470 s->bufs_per_mdl, mdl->id, s->mdl_size);
464 return q; 471 return q;
465} 472}
466 473
@@ -468,19 +475,19 @@ static
468void _cx18_stream_load_fw_queue(struct cx18_stream *s) 475void _cx18_stream_load_fw_queue(struct cx18_stream *s)
469{ 476{
470 struct cx18_queue *q; 477 struct cx18_queue *q;
471 struct cx18_buffer *buf; 478 struct cx18_mdl *mdl;
472 479
473 if (atomic_read(&s->q_free.buffers) == 0 || 480 if (atomic_read(&s->q_free.depth) == 0 ||
474 atomic_read(&s->q_busy.buffers) >= CX18_MAX_FW_MDLS_PER_STREAM) 481 atomic_read(&s->q_busy.depth) >= CX18_MAX_FW_MDLS_PER_STREAM)
475 return; 482 return;
476 483
477 /* Move from q_free to q_busy notifying the firmware, until the limit */ 484 /* Move from q_free to q_busy notifying the firmware, until the limit */
478 do { 485 do {
479 buf = cx18_dequeue(s, &s->q_free); 486 mdl = cx18_dequeue(s, &s->q_free);
480 if (buf == NULL) 487 if (mdl == NULL)
481 break; 488 break;
482 q = _cx18_stream_put_buf_fw(s, buf); 489 q = _cx18_stream_put_mdl_fw(s, mdl);
483 } while (atomic_read(&s->q_busy.buffers) < CX18_MAX_FW_MDLS_PER_STREAM 490 } while (atomic_read(&s->q_busy.depth) < CX18_MAX_FW_MDLS_PER_STREAM
484 && q == &s->q_busy); 491 && q == &s->q_busy);
485} 492}
486 493
@@ -492,11 +499,51 @@ void cx18_out_work_handler(struct work_struct *work)
492 _cx18_stream_load_fw_queue(s); 499 _cx18_stream_load_fw_queue(s);
493} 500}
494 501
502static void cx18_stream_configure_mdls(struct cx18_stream *s)
503{
504 cx18_unload_queues(s);
505
506 switch (s->type) {
507 case CX18_ENC_STREAM_TYPE_YUV:
508 /*
509 * Height should be a multiple of 32 lines.
510 * Set the MDL size to the exact size needed for one frame.
511 * Use enough buffers per MDL to cover the MDL size
512 */
513 s->mdl_size = 720 * s->cx->params.height * 3 / 2;
514 s->bufs_per_mdl = s->mdl_size / s->buf_size;
515 if (s->mdl_size % s->buf_size)
516 s->bufs_per_mdl++;
517 break;
518 case CX18_ENC_STREAM_TYPE_VBI:
519 s->bufs_per_mdl = 1;
520 if (cx18_raw_vbi(s->cx)) {
521 s->mdl_size = (s->cx->is_60hz ? 12 : 18)
522 * 2 * vbi_active_samples;
523 } else {
524 /*
525 * See comment in cx18_vbi_setup() below about the
526 * extra lines we capture in sliced VBI mode due to
527 * the lines on which EAV RP codes toggle.
528 */
529 s->mdl_size = s->cx->is_60hz
530 ? (21 - 4 + 1) * 2 * vbi_hblank_samples_60Hz
531 : (23 - 2 + 1) * 2 * vbi_hblank_samples_50Hz;
532 }
533 break;
534 default:
535 s->bufs_per_mdl = 1;
536 s->mdl_size = s->buf_size * s->bufs_per_mdl;
537 break;
538 }
539
540 cx18_load_queues(s);
541}
542
495int cx18_start_v4l2_encode_stream(struct cx18_stream *s) 543int cx18_start_v4l2_encode_stream(struct cx18_stream *s)
496{ 544{
497 u32 data[MAX_MB_ARGUMENTS]; 545 u32 data[MAX_MB_ARGUMENTS];
498 struct cx18 *cx = s->cx; 546 struct cx18 *cx = s->cx;
499 struct cx18_buffer *buf;
500 int captype = 0; 547 int captype = 0;
501 struct cx18_api_func_private priv; 548 struct cx18_api_func_private priv;
502 549
@@ -619,14 +666,7 @@ int cx18_start_v4l2_encode_stream(struct cx18_stream *s)
619 (void __iomem *)&cx->scb->cpu_mdl_ack[s->type][1] - cx->enc_mem); 666 (void __iomem *)&cx->scb->cpu_mdl_ack[s->type][1] - cx->enc_mem);
620 667
621 /* Init all the cpu_mdls for this stream */ 668 /* Init all the cpu_mdls for this stream */
622 cx18_flush_queues(s); 669 cx18_stream_configure_mdls(s);
623 spin_lock(&s->q_free.lock);
624 list_for_each_entry(buf, &s->q_free.list, list) {
625 cx18_writel(cx, buf->dma_handle,
626 &cx->scb->cpu_mdl[buf->id].paddr);
627 cx18_writel(cx, s->buf_size, &cx->scb->cpu_mdl[buf->id].length);
628 }
629 spin_unlock(&s->q_free.lock);
630 _cx18_stream_load_fw_queue(s); 670 _cx18_stream_load_fw_queue(s);
631 671
632 /* begin_capture */ 672 /* begin_capture */
diff --git a/drivers/media/video/cx18/cx18-streams.h b/drivers/media/video/cx18/cx18-streams.h
index 1afc3fd9d822..4a01db5e5a35 100644
--- a/drivers/media/video/cx18/cx18-streams.h
+++ b/drivers/media/video/cx18/cx18-streams.h
@@ -28,18 +28,18 @@ 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/* Related to submission of buffers to firmware */ 31/* Related to submission of mdls to firmware */
32static inline void cx18_stream_load_fw_queue(struct cx18_stream *s) 32static inline void cx18_stream_load_fw_queue(struct cx18_stream *s)
33{ 33{
34 struct cx18 *cx = s->cx; 34 struct cx18 *cx = s->cx;
35 queue_work(cx->out_work_queue, &s->out_work_order); 35 queue_work(cx->out_work_queue, &s->out_work_order);
36} 36}
37 37
38static inline void cx18_stream_put_buf_fw(struct cx18_stream *s, 38static inline void cx18_stream_put_mdl_fw(struct cx18_stream *s,
39 struct cx18_buffer *buf) 39 struct cx18_mdl *mdl)
40{ 40{
41 /* Put buf on q_free; the out work handler will move buf(s) to q_busy */ 41 /* Put mdl on q_free; the out work handler will move mdl(s) to q_busy */
42 cx18_enqueue(s, buf, &s->q_free); 42 cx18_enqueue(s, mdl, &s->q_free);
43 cx18_stream_load_fw_queue(s); 43 cx18_stream_load_fw_queue(s);
44} 44}
45 45
diff --git a/drivers/media/video/cx18/cx18-vbi.c b/drivers/media/video/cx18/cx18-vbi.c
index c2aef4add31d..574c1c6974f8 100644
--- a/drivers/media/video/cx18/cx18-vbi.c
+++ b/drivers/media/video/cx18/cx18-vbi.c
@@ -105,6 +105,7 @@ static void copy_vbi_data(struct cx18 *cx, int lines, u32 pts_stamp)
105 105
106/* Compress raw VBI format, removes leading SAV codes and surplus space 106/* Compress raw VBI format, removes leading SAV codes and surplus space
107 after the frame. Returns new compressed size. */ 107 after the frame. Returns new compressed size. */
108/* FIXME - this function ignores the input size. */
108static u32 compress_raw_buf(struct cx18 *cx, u8 *buf, u32 size, u32 hdr_size) 109static u32 compress_raw_buf(struct cx18 *cx, u8 *buf, u32 size, u32 hdr_size)
109{ 110{
110 u32 line_size = vbi_active_samples; 111 u32 line_size = vbi_active_samples;
@@ -185,8 +186,7 @@ static u32 compress_sliced_buf(struct cx18 *cx, u8 *buf, u32 size,
185 return line; 186 return line;
186} 187}
187 188
188void cx18_process_vbi_data(struct cx18 *cx, struct cx18_buffer *buf, 189static void _cx18_process_vbi_data(struct cx18 *cx, struct cx18_buffer *buf)
189 int streamtype)
190{ 190{
191 /* 191 /*
192 * The CX23418 provides a 12 byte header in its raw VBI buffers to us: 192 * The CX23418 provides a 12 byte header in its raw VBI buffers to us:
@@ -203,9 +203,6 @@ void cx18_process_vbi_data(struct cx18 *cx, struct cx18_buffer *buf,
203 u32 pts; 203 u32 pts;
204 int lines; 204 int lines;
205 205
206 if (streamtype != CX18_ENC_STREAM_TYPE_VBI)
207 return;
208
209 /* 206 /*
210 * The CX23418 sends us data that is 32 bit little-endian swapped, 207 * The CX23418 sends us data that is 32 bit little-endian swapped,
211 * but we want the raw VBI bytes in the order they were in the raster 208 * but we want the raw VBI bytes in the order they were in the raster
@@ -250,3 +247,31 @@ void cx18_process_vbi_data(struct cx18 *cx, struct cx18_buffer *buf,
250 copy_vbi_data(cx, lines, pts); 247 copy_vbi_data(cx, lines, pts);
251 cx->vbi.frame++; 248 cx->vbi.frame++;
252} 249}
250
251void cx18_process_vbi_data(struct cx18 *cx, struct cx18_mdl *mdl,
252 int streamtype)
253{
254 struct cx18_buffer *buf;
255 u32 orig_used;
256
257 if (streamtype != CX18_ENC_STREAM_TYPE_VBI)
258 return;
259
260 /*
261 * Big assumption here:
262 * Every buffer hooked to the MDL's buf_list is a complete VBI frame
263 * that ends at the end of the buffer.
264 *
265 * To assume anything else would make the code in this file
266 * more complex, or require extra memcpy()'s to make the
267 * buffers satisfy the above assumption. It's just simpler to set
268 * up the encoder buffer transfers to make the assumption true.
269 */
270 list_for_each_entry(buf, &mdl->buf_list, list) {
271 orig_used = buf->bytesused;
272 if (orig_used == 0)
273 break;
274 _cx18_process_vbi_data(cx, buf);
275 mdl->bytesused -= (orig_used - buf->bytesused);
276 }
277}
diff --git a/drivers/media/video/cx18/cx18-vbi.h b/drivers/media/video/cx18/cx18-vbi.h
index e7e1ae427f34..b365cf4b4668 100644
--- a/drivers/media/video/cx18/cx18-vbi.h
+++ b/drivers/media/video/cx18/cx18-vbi.h
@@ -21,6 +21,6 @@
21 * 02111-1307 USA 21 * 02111-1307 USA
22 */ 22 */
23 23
24void cx18_process_vbi_data(struct cx18 *cx, struct cx18_buffer *buf, 24void cx18_process_vbi_data(struct cx18 *cx, struct cx18_mdl *mdl,
25 int streamtype); 25 int streamtype);
26int cx18_used_line(struct cx18 *cx, int line, int field); 26int cx18_used_line(struct cx18 *cx, int line, int field);
diff --git a/drivers/media/video/cx18/cx18-version.h b/drivers/media/video/cx18/cx18-version.h
index 45494b094e7f..9c0b5bb1b019 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 2 27#define CX18_DRIVER_VERSION_MINOR 3
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 9956abf576c5..868806effdcf 100644
--- a/drivers/media/video/cx18/cx23418.h
+++ b/drivers/media/video/cx18/cx23418.h
@@ -363,7 +363,7 @@
363/* Description: This command provides the offset to a Memory Descriptor List 363/* Description: This command provides the offset to a Memory Descriptor List
364 IN[0] - Task handle. Handle of the task to start 364 IN[0] - Task handle. Handle of the task to start
365 IN[1] - Offset of the MDL from the beginning of the local DDR. 365 IN[1] - Offset of the MDL from the beginning of the local DDR.
366 IN[2] - Number of cx18_mdl structures in the array pointed to by IN[1] 366 IN[2] - Number of cx18_mdl_ent structures in the array pointed to by IN[1]
367 IN[3] - Buffer ID 367 IN[3] - Buffer ID
368 IN[4] - Total buffer length 368 IN[4] - Total buffer length
369 ReturnCode - One of the ERR_DE_... */ 369 ReturnCode - One of the ERR_DE_... */
diff --git a/drivers/media/video/cx231xx/cx231xx-input.c b/drivers/media/video/cx231xx/cx231xx-input.c
index 48f22fa38e6c..cd135f01b9c1 100644
--- a/drivers/media/video/cx231xx/cx231xx-input.c
+++ b/drivers/media/video/cx231xx/cx231xx-input.c
@@ -126,8 +126,7 @@ static void cx231xx_ir_handle_key(struct cx231xx_IR *ir)
126 126
127 if (do_sendkey) { 127 if (do_sendkey) {
128 dprintk("sending keypress\n"); 128 dprintk("sending keypress\n");
129 ir_input_keydown(ir->input, &ir->ir, poll_result.rc_data[0], 129 ir_input_keydown(ir->input, &ir->ir, poll_result.rc_data[0]);
130 poll_result.rc_data[0]);
131 ir_input_nokey(ir->input, &ir->ir); 130 ir_input_nokey(ir->input, &ir->ir);
132 } 131 }
133 132
@@ -198,7 +197,11 @@ int cx231xx_ir_init(struct cx231xx *dev)
198 usb_make_path(dev->udev, ir->phys, sizeof(ir->phys)); 197 usb_make_path(dev->udev, ir->phys, sizeof(ir->phys));
199 strlcat(ir->phys, "/input0", sizeof(ir->phys)); 198 strlcat(ir->phys, "/input0", sizeof(ir->phys));
200 199
201 ir_input_init(input_dev, &ir->ir, IR_TYPE_OTHER, dev->board.ir_codes); 200 err = ir_input_init(input_dev, &ir->ir, IR_TYPE_OTHER,
201 dev->board.ir_codes);
202 if (err < 0)
203 goto err_out_free;
204
202 input_dev->name = ir->name; 205 input_dev->name = ir->name;
203 input_dev->phys = ir->phys; 206 input_dev->phys = ir->phys;
204 input_dev->id.bustype = BUS_USB; 207 input_dev->id.bustype = BUS_USB;
@@ -223,6 +226,7 @@ err_out_stop:
223 cx231xx_ir_stop(ir); 226 cx231xx_ir_stop(ir);
224 dev->ir = NULL; 227 dev->ir = NULL;
225err_out_free: 228err_out_free:
229 ir_input_free(input_dev);
226 input_free_device(input_dev); 230 input_free_device(input_dev);
227 kfree(ir); 231 kfree(ir);
228 return err; 232 return err;
@@ -237,6 +241,7 @@ int cx231xx_ir_fini(struct cx231xx *dev)
237 return 0; 241 return 0;
238 242
239 cx231xx_ir_stop(ir); 243 cx231xx_ir_stop(ir);
244 ir_input_free(ir->input);
240 input_unregister_device(ir->input); 245 input_unregister_device(ir->input);
241 kfree(ir); 246 kfree(ir);
242 247
diff --git a/drivers/media/video/cx231xx/cx231xx-video.c b/drivers/media/video/cx231xx/cx231xx-video.c
index 36503725d973..d095aa0d6d19 100644
--- a/drivers/media/video/cx231xx/cx231xx-video.c
+++ b/drivers/media/video/cx231xx/cx231xx-video.c
@@ -2106,7 +2106,7 @@ static int cx231xx_v4l2_close(struct file *filp)
2106 } 2106 }
2107 2107
2108 /* Save some power by putting tuner to sleep */ 2108 /* Save some power by putting tuner to sleep */
2109 call_all(dev, tuner, s_standby); 2109 call_all(dev, core, s_power, 0);
2110 2110
2111 /* do this before setting alternate! */ 2111 /* do this before setting alternate! */
2112 cx231xx_uninit_isoc(dev); 2112 cx231xx_uninit_isoc(dev);
diff --git a/drivers/media/video/cx23885/Kconfig b/drivers/media/video/cx23885/Kconfig
index fd3fc3e3198a..bcdda9a9aa96 100644
--- a/drivers/media/video/cx23885/Kconfig
+++ b/drivers/media/video/cx23885/Kconfig
@@ -18,7 +18,9 @@ config VIDEO_CX23885
18 select DVB_TDA10048 if !DVB_FE_CUSTOMISE 18 select DVB_TDA10048 if !DVB_FE_CUSTOMISE
19 select DVB_LNBP21 if !DVB_FE_CUSTOMISE 19 select DVB_LNBP21 if !DVB_FE_CUSTOMISE
20 select DVB_STV6110 if !DVB_FE_CUSTOMISE 20 select DVB_STV6110 if !DVB_FE_CUSTOMISE
21 select DVB_CX24116 if !DVB_FE_CUSTOMISE
21 select DVB_STV0900 if !DVB_FE_CUSTOMISE 22 select DVB_STV0900 if !DVB_FE_CUSTOMISE
23 select DVB_DS3000 if !DVB_FE_CUSTOMISE
22 select MEDIA_TUNER_MT2131 if !MEDIA_TUNER_CUSTOMISE 24 select MEDIA_TUNER_MT2131 if !MEDIA_TUNER_CUSTOMISE
23 select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMISE 25 select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMISE
24 select MEDIA_TUNER_TDA8290 if !MEDIA_TUNER_CUSTOMISE 26 select MEDIA_TUNER_TDA8290 if !MEDIA_TUNER_CUSTOMISE
diff --git a/drivers/media/video/cx23885/Makefile b/drivers/media/video/cx23885/Makefile
index ab8ea35c9bfb..5787ae243631 100644
--- a/drivers/media/video/cx23885/Makefile
+++ b/drivers/media/video/cx23885/Makefile
@@ -1,6 +1,7 @@
1cx23885-objs := cx23885-cards.o cx23885-video.o cx23885-vbi.o \ 1cx23885-objs := cx23885-cards.o cx23885-video.o cx23885-vbi.o \
2 cx23885-core.o cx23885-i2c.o cx23885-dvb.o cx23885-417.o \ 2 cx23885-core.o cx23885-i2c.o cx23885-dvb.o cx23885-417.o \
3 netup-init.o cimax2.o netup-eeprom.o 3 cx23885-ioctl.o cx23885-ir.o cx23885-input.o cx23888-ir.o \
4 netup-init.o cimax2.o netup-eeprom.o cx23885-f300.o
4 5
5obj-$(CONFIG_VIDEO_CX23885) += cx23885.o 6obj-$(CONFIG_VIDEO_CX23885) += cx23885.o
6 7
diff --git a/drivers/media/video/cx23885/cx23885-417.c b/drivers/media/video/cx23885/cx23885-417.c
index 6c3b51ce3372..0eed852c61e9 100644
--- a/drivers/media/video/cx23885/cx23885-417.c
+++ b/drivers/media/video/cx23885/cx23885-417.c
@@ -37,6 +37,7 @@
37#include <media/cx2341x.h> 37#include <media/cx2341x.h>
38 38
39#include "cx23885.h" 39#include "cx23885.h"
40#include "cx23885-ioctl.h"
40 41
41#define CX23885_FIRM_IMAGE_SIZE 376836 42#define CX23885_FIRM_IMAGE_SIZE 376836
42#define CX23885_FIRM_IMAGE_NAME "v4l-cx23885-enc.fw" 43#define CX23885_FIRM_IMAGE_NAME "v4l-cx23885-enc.fw"
@@ -318,7 +319,7 @@ static int mc417_wait_ready(struct cx23885_dev *dev)
318 } 319 }
319} 320}
320 321
321static int mc417_register_write(struct cx23885_dev *dev, u16 address, u32 value) 322int mc417_register_write(struct cx23885_dev *dev, u16 address, u32 value)
322{ 323{
323 u32 regval; 324 u32 regval;
324 325
@@ -382,7 +383,7 @@ static int mc417_register_write(struct cx23885_dev *dev, u16 address, u32 value)
382 return mc417_wait_ready(dev); 383 return mc417_wait_ready(dev);
383} 384}
384 385
385static int mc417_register_read(struct cx23885_dev *dev, u16 address, u32 *value) 386int mc417_register_read(struct cx23885_dev *dev, u16 address, u32 *value)
386{ 387{
387 int retval; 388 int retval;
388 u32 regval; 389 u32 regval;
@@ -1724,6 +1725,11 @@ static const struct v4l2_ioctl_ops mpeg_ioctl_ops = {
1724 .vidioc_log_status = vidioc_log_status, 1725 .vidioc_log_status = vidioc_log_status,
1725 .vidioc_querymenu = vidioc_querymenu, 1726 .vidioc_querymenu = vidioc_querymenu,
1726 .vidioc_queryctrl = vidioc_queryctrl, 1727 .vidioc_queryctrl = vidioc_queryctrl,
1728 .vidioc_g_chip_ident = cx23885_g_chip_ident,
1729#ifdef CONFIG_VIDEO_ADV_DEBUG
1730 .vidioc_g_register = cx23885_g_register,
1731 .vidioc_s_register = cx23885_s_register,
1732#endif
1727}; 1733};
1728 1734
1729static struct video_device cx23885_mpeg_template = { 1735static struct video_device cx23885_mpeg_template = {
diff --git a/drivers/media/video/cx23885/cx23885-cards.c b/drivers/media/video/cx23885/cx23885-cards.c
index bfdf79f1033c..1ec48169277d 100644
--- a/drivers/media/video/cx23885/cx23885-cards.c
+++ b/drivers/media/video/cx23885/cx23885-cards.c
@@ -28,6 +28,7 @@
28#include "cx23885.h" 28#include "cx23885.h"
29#include "tuner-xc2028.h" 29#include "tuner-xc2028.h"
30#include "netup-init.h" 30#include "netup-init.h"
31#include "cx23888-ir.h"
31 32
32/* ------------------------------------------------------------------ */ 33/* ------------------------------------------------------------------ */
33/* board config info */ 34/* board config info */
@@ -199,11 +200,61 @@ struct cx23885_board cx23885_boards[] = {
199 }, 200 },
200 [CX23885_BOARD_MYGICA_X8506] = { 201 [CX23885_BOARD_MYGICA_X8506] = {
201 .name = "Mygica X8506 DMB-TH", 202 .name = "Mygica X8506 DMB-TH",
203 .tuner_type = TUNER_XC5000,
204 .tuner_addr = 0x61,
205 .porta = CX23885_ANALOG_VIDEO,
202 .portb = CX23885_MPEG_DVB, 206 .portb = CX23885_MPEG_DVB,
207 .input = {
208 {
209 .type = CX23885_VMUX_TELEVISION,
210 .vmux = CX25840_COMPOSITE2,
211 },
212 {
213 .type = CX23885_VMUX_COMPOSITE1,
214 .vmux = CX25840_COMPOSITE8,
215 },
216 {
217 .type = CX23885_VMUX_SVIDEO,
218 .vmux = CX25840_SVIDEO_LUMA3 |
219 CX25840_SVIDEO_CHROMA4,
220 },
221 {
222 .type = CX23885_VMUX_COMPONENT,
223 .vmux = CX25840_COMPONENT_ON |
224 CX25840_VIN1_CH1 |
225 CX25840_VIN6_CH2 |
226 CX25840_VIN7_CH3,
227 },
228 },
203 }, 229 },
204 [CX23885_BOARD_MAGICPRO_PROHDTVE2] = { 230 [CX23885_BOARD_MAGICPRO_PROHDTVE2] = {
205 .name = "Magic-Pro ProHDTV Extreme 2", 231 .name = "Magic-Pro ProHDTV Extreme 2",
232 .tuner_type = TUNER_XC5000,
233 .tuner_addr = 0x61,
234 .porta = CX23885_ANALOG_VIDEO,
206 .portb = CX23885_MPEG_DVB, 235 .portb = CX23885_MPEG_DVB,
236 .input = {
237 {
238 .type = CX23885_VMUX_TELEVISION,
239 .vmux = CX25840_COMPOSITE2,
240 },
241 {
242 .type = CX23885_VMUX_COMPOSITE1,
243 .vmux = CX25840_COMPOSITE8,
244 },
245 {
246 .type = CX23885_VMUX_SVIDEO,
247 .vmux = CX25840_SVIDEO_LUMA3 |
248 CX25840_SVIDEO_CHROMA4,
249 },
250 {
251 .type = CX23885_VMUX_COMPONENT,
252 .vmux = CX25840_COMPONENT_ON |
253 CX25840_VIN1_CH1 |
254 CX25840_VIN6_CH2 |
255 CX25840_VIN7_CH3,
256 },
257 },
207 }, 258 },
208 [CX23885_BOARD_HAUPPAUGE_HVR1850] = { 259 [CX23885_BOARD_HAUPPAUGE_HVR1850] = {
209 .name = "Hauppauge WinTV-HVR1850", 260 .name = "Hauppauge WinTV-HVR1850",
@@ -214,6 +265,15 @@ struct cx23885_board cx23885_boards[] = {
214 .name = "Compro VideoMate E800", 265 .name = "Compro VideoMate E800",
215 .portc = CX23885_MPEG_DVB, 266 .portc = CX23885_MPEG_DVB,
216 }, 267 },
268 [CX23885_BOARD_HAUPPAUGE_HVR1290] = {
269 .name = "Hauppauge WinTV-HVR1290",
270 .portc = CX23885_MPEG_DVB,
271 },
272 [CX23885_BOARD_MYGICA_X8558PRO] = {
273 .name = "Mygica X8558 PRO DMB-TH",
274 .portb = CX23885_MPEG_DVB,
275 .portc = CX23885_MPEG_DVB,
276 },
217}; 277};
218const unsigned int cx23885_bcount = ARRAY_SIZE(cx23885_boards); 278const unsigned int cx23885_bcount = ARRAY_SIZE(cx23885_boards);
219 279
@@ -349,6 +409,14 @@ struct cx23885_subid cx23885_subids[] = {
349 .subvendor = 0x1858, 409 .subvendor = 0x1858,
350 .subdevice = 0xe800, 410 .subdevice = 0xe800,
351 .card = CX23885_BOARD_COMPRO_VIDEOMATE_E800, 411 .card = CX23885_BOARD_COMPRO_VIDEOMATE_E800,
412 }, {
413 .subvendor = 0x0070,
414 .subdevice = 0x8551,
415 .card = CX23885_BOARD_HAUPPAUGE_HVR1290,
416 }, {
417 .subvendor = 0x14f1,
418 .subdevice = 0x8578,
419 .card = CX23885_BOARD_MYGICA_X8558PRO,
352 }, 420 },
353}; 421};
354const unsigned int cx23885_idcount = ARRAY_SIZE(cx23885_subids); 422const unsigned int cx23885_idcount = ARRAY_SIZE(cx23885_subids);
@@ -509,9 +577,13 @@ static void hauppauge_eeprom(struct cx23885_dev *dev, u8 *eeprom_data)
509 * DVB-T and MPEG2 HW Encoder */ 577 * DVB-T and MPEG2 HW Encoder */
510 break; 578 break;
511 case 85021: 579 case 85021:
512 /* WinTV-HVR1850 (PCIe, OEM, RCA in, IR, FM, 580 /* WinTV-HVR1850 (PCIe, Retail, 3.5mm in, IR, FM,
513 Dual channel ATSC and MPEG2 HW Encoder */ 581 Dual channel ATSC and MPEG2 HW Encoder */
514 break; 582 break;
583 case 85721:
584 /* WinTV-HVR1290 (PCIe, OEM, RCA in, IR,
585 Dual channel ATSC and Basic analog */
586 break;
515 default: 587 default:
516 printk(KERN_WARNING "%s: warning: " 588 printk(KERN_WARNING "%s: warning: "
517 "unknown hauppauge model #%d\n", 589 "unknown hauppauge model #%d\n",
@@ -710,10 +782,14 @@ void cx23885_gpio_setup(struct cx23885_dev *dev)
710 cx_set(GP0_IO, 0x00040004); 782 cx_set(GP0_IO, 0x00040004);
711 break; 783 break;
712 case CX23885_BOARD_TBS_6920: 784 case CX23885_BOARD_TBS_6920:
713 case CX23885_BOARD_TEVII_S470:
714 cx_write(MC417_CTL, 0x00000036); 785 cx_write(MC417_CTL, 0x00000036);
715 cx_write(MC417_OEN, 0x00001000); 786 cx_write(MC417_OEN, 0x00001000);
716 cx_write(MC417_RWD, 0x00001800); 787 cx_set(MC417_RWD, 0x00000002);
788 mdelay(200);
789 cx_clear(MC417_RWD, 0x00000800);
790 mdelay(200);
791 cx_set(MC417_RWD, 0x00000800);
792 mdelay(200);
717 break; 793 break;
718 case CX23885_BOARD_NETUP_DUAL_DVBS2_CI: 794 case CX23885_BOARD_NETUP_DUAL_DVBS2_CI:
719 /* GPIO-0 INTA from CiMax1 795 /* GPIO-0 INTA from CiMax1
@@ -758,15 +834,26 @@ void cx23885_gpio_setup(struct cx23885_dev *dev)
758 break; 834 break;
759 case CX23885_BOARD_MYGICA_X8506: 835 case CX23885_BOARD_MYGICA_X8506:
760 case CX23885_BOARD_MAGICPRO_PROHDTVE2: 836 case CX23885_BOARD_MAGICPRO_PROHDTVE2:
837 /* GPIO-0 (0)Analog / (1)Digital TV */
761 /* GPIO-1 reset XC5000 */ 838 /* GPIO-1 reset XC5000 */
762 /* GPIO-2 reset LGS8GL5 / LGS8G75 */ 839 /* GPIO-2 reset LGS8GL5 / LGS8G75 */
763 cx_set(GP0_IO, 0x00060000); 840 cx23885_gpio_enable(dev, GPIO_0 | GPIO_1 | GPIO_2, 1);
764 cx_clear(GP0_IO, 0x00000006); 841 cx23885_gpio_clear(dev, GPIO_1 | GPIO_2);
765 mdelay(100); 842 mdelay(100);
766 cx_set(GP0_IO, 0x00060006); 843 cx23885_gpio_set(dev, GPIO_0 | GPIO_1 | GPIO_2);
844 mdelay(100);
845 break;
846 case CX23885_BOARD_MYGICA_X8558PRO:
847 /* GPIO-0 reset first ATBM8830 */
848 /* GPIO-1 reset second ATBM8830 */
849 cx23885_gpio_enable(dev, GPIO_0 | GPIO_1, 1);
850 cx23885_gpio_clear(dev, GPIO_0 | GPIO_1);
851 mdelay(100);
852 cx23885_gpio_set(dev, GPIO_0 | GPIO_1);
767 mdelay(100); 853 mdelay(100);
768 break; 854 break;
769 case CX23885_BOARD_HAUPPAUGE_HVR1850: 855 case CX23885_BOARD_HAUPPAUGE_HVR1850:
856 case CX23885_BOARD_HAUPPAUGE_HVR1290:
770 /* GPIO-0 656_CLK */ 857 /* GPIO-0 656_CLK */
771 /* GPIO-1 656_D0 */ 858 /* GPIO-1 656_D0 */
772 /* GPIO-2 Wake# */ 859 /* GPIO-2 Wake# */
@@ -801,6 +888,7 @@ void cx23885_gpio_setup(struct cx23885_dev *dev)
801 888
802int cx23885_ir_init(struct cx23885_dev *dev) 889int cx23885_ir_init(struct cx23885_dev *dev)
803{ 890{
891 int ret = 0;
804 switch (dev->board) { 892 switch (dev->board) {
805 case CX23885_BOARD_HAUPPAUGE_HVR1250: 893 case CX23885_BOARD_HAUPPAUGE_HVR1250:
806 case CX23885_BOARD_HAUPPAUGE_HVR1500: 894 case CX23885_BOARD_HAUPPAUGE_HVR1500:
@@ -812,15 +900,46 @@ int cx23885_ir_init(struct cx23885_dev *dev)
812 case CX23885_BOARD_HAUPPAUGE_HVR1275: 900 case CX23885_BOARD_HAUPPAUGE_HVR1275:
813 case CX23885_BOARD_HAUPPAUGE_HVR1255: 901 case CX23885_BOARD_HAUPPAUGE_HVR1255:
814 case CX23885_BOARD_HAUPPAUGE_HVR1210: 902 case CX23885_BOARD_HAUPPAUGE_HVR1210:
815 case CX23885_BOARD_HAUPPAUGE_HVR1850:
816 /* FIXME: Implement me */ 903 /* FIXME: Implement me */
817 break; 904 break;
905 case CX23885_BOARD_HAUPPAUGE_HVR1850:
906 case CX23885_BOARD_HAUPPAUGE_HVR1290:
907 ret = cx23888_ir_probe(dev);
908 if (ret)
909 break;
910 dev->sd_ir = cx23885_find_hw(dev, CX23885_HW_888_IR);
911 dev->pci_irqmask |= PCI_MSK_IR;
912 break;
818 case CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP: 913 case CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP:
819 request_module("ir-kbd-i2c"); 914 request_module("ir-kbd-i2c");
820 break; 915 break;
821 } 916 }
822 917
823 return 0; 918 return ret;
919}
920
921void cx23885_ir_fini(struct cx23885_dev *dev)
922{
923 switch (dev->board) {
924 case CX23885_BOARD_HAUPPAUGE_HVR1850:
925 case CX23885_BOARD_HAUPPAUGE_HVR1290:
926 dev->pci_irqmask &= ~PCI_MSK_IR;
927 cx_clear(PCI_INT_MSK, PCI_MSK_IR);
928 cx23888_ir_remove(dev);
929 dev->sd_ir = NULL;
930 break;
931 }
932}
933
934void cx23885_ir_pci_int_enable(struct cx23885_dev *dev)
935{
936 switch (dev->board) {
937 case CX23885_BOARD_HAUPPAUGE_HVR1850:
938 case CX23885_BOARD_HAUPPAUGE_HVR1290:
939 if (dev->sd_ir && (dev->pci_irqmask & PCI_MSK_IR))
940 cx_set(PCI_INT_MSK, PCI_MSK_IR);
941 break;
942 }
824} 943}
825 944
826void cx23885_card_setup(struct cx23885_dev *dev) 945void cx23885_card_setup(struct cx23885_dev *dev)
@@ -853,6 +972,7 @@ void cx23885_card_setup(struct cx23885_dev *dev)
853 case CX23885_BOARD_HAUPPAUGE_HVR1255: 972 case CX23885_BOARD_HAUPPAUGE_HVR1255:
854 case CX23885_BOARD_HAUPPAUGE_HVR1210: 973 case CX23885_BOARD_HAUPPAUGE_HVR1210:
855 case CX23885_BOARD_HAUPPAUGE_HVR1850: 974 case CX23885_BOARD_HAUPPAUGE_HVR1850:
975 case CX23885_BOARD_HAUPPAUGE_HVR1290:
856 if (dev->i2c_bus[0].i2c_rc == 0) 976 if (dev->i2c_bus[0].i2c_rc == 0)
857 hauppauge_eeprom(dev, eeprom+0xc0); 977 hauppauge_eeprom(dev, eeprom+0xc0);
858 break; 978 break;
@@ -886,8 +1006,12 @@ void cx23885_card_setup(struct cx23885_dev *dev)
886 ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */ 1006 ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */
887 ts2->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; 1007 ts2->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO;
888 break; 1008 break;
889 case CX23885_BOARD_TEVII_S470:
890 case CX23885_BOARD_TBS_6920: 1009 case CX23885_BOARD_TBS_6920:
1010 ts1->gen_ctrl_val = 0x4; /* Parallel */
1011 ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */
1012 ts1->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO;
1013 break;
1014 case CX23885_BOARD_TEVII_S470:
891 case CX23885_BOARD_DVBWORLD_2005: 1015 case CX23885_BOARD_DVBWORLD_2005:
892 ts1->gen_ctrl_val = 0x5; /* Parallel */ 1016 ts1->gen_ctrl_val = 0x5; /* Parallel */
893 ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */ 1017 ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */
@@ -907,6 +1031,14 @@ void cx23885_card_setup(struct cx23885_dev *dev)
907 ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */ 1031 ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */
908 ts1->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; 1032 ts1->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO;
909 break; 1033 break;
1034 case CX23885_BOARD_MYGICA_X8558PRO:
1035 ts1->gen_ctrl_val = 0x5; /* Parallel */
1036 ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */
1037 ts1->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO;
1038 ts2->gen_ctrl_val = 0xc; /* Serial bus + punctured clock */
1039 ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */
1040 ts2->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO;
1041 break;
910 case CX23885_BOARD_HAUPPAUGE_HVR1250: 1042 case CX23885_BOARD_HAUPPAUGE_HVR1250:
911 case CX23885_BOARD_HAUPPAUGE_HVR1500: 1043 case CX23885_BOARD_HAUPPAUGE_HVR1500:
912 case CX23885_BOARD_HAUPPAUGE_HVR1500Q: 1044 case CX23885_BOARD_HAUPPAUGE_HVR1500Q:
@@ -922,6 +1054,7 @@ void cx23885_card_setup(struct cx23885_dev *dev)
922 case CX23885_BOARD_HAUPPAUGE_HVR1210: 1054 case CX23885_BOARD_HAUPPAUGE_HVR1210:
923 case CX23885_BOARD_HAUPPAUGE_HVR1850: 1055 case CX23885_BOARD_HAUPPAUGE_HVR1850:
924 case CX23885_BOARD_COMPRO_VIDEOMATE_E800: 1056 case CX23885_BOARD_COMPRO_VIDEOMATE_E800:
1057 case CX23885_BOARD_HAUPPAUGE_HVR1290:
925 default: 1058 default:
926 ts2->gen_ctrl_val = 0xc; /* Serial bus + punctured clock */ 1059 ts2->gen_ctrl_val = 0xc; /* Serial bus + punctured clock */
927 ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */ 1060 ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */
@@ -939,6 +1072,10 @@ void cx23885_card_setup(struct cx23885_dev *dev)
939 case CX23885_BOARD_COMPRO_VIDEOMATE_E650F: 1072 case CX23885_BOARD_COMPRO_VIDEOMATE_E650F:
940 case CX23885_BOARD_NETUP_DUAL_DVBS2_CI: 1073 case CX23885_BOARD_NETUP_DUAL_DVBS2_CI:
941 case CX23885_BOARD_COMPRO_VIDEOMATE_E800: 1074 case CX23885_BOARD_COMPRO_VIDEOMATE_E800:
1075 case CX23885_BOARD_HAUPPAUGE_HVR1850:
1076 case CX23885_BOARD_MYGICA_X8506:
1077 case CX23885_BOARD_MAGICPRO_PROHDTVE2:
1078 case CX23885_BOARD_HAUPPAUGE_HVR1290:
942 dev->sd_cx25840 = v4l2_i2c_new_subdev(&dev->v4l2_dev, 1079 dev->sd_cx25840 = v4l2_i2c_new_subdev(&dev->v4l2_dev,
943 &dev->i2c_bus[2].i2c_adap, 1080 &dev->i2c_bus[2].i2c_adap,
944 "cx25840", "cx25840", 0x88 >> 1, NULL); 1081 "cx25840", "cx25840", 0x88 >> 1, NULL);
diff --git a/drivers/media/video/cx23885/cx23885-core.c b/drivers/media/video/cx23885/cx23885-core.c
index fa2d350e20fd..04b12d27bc13 100644
--- a/drivers/media/video/cx23885/cx23885-core.c
+++ b/drivers/media/video/cx23885/cx23885-core.c
@@ -32,6 +32,9 @@
32 32
33#include "cx23885.h" 33#include "cx23885.h"
34#include "cimax2.h" 34#include "cimax2.h"
35#include "cx23888-ir.h"
36#include "cx23885-ir.h"
37#include "cx23885-input.h"
35 38
36MODULE_DESCRIPTION("Driver for cx23885 based TV cards"); 39MODULE_DESCRIPTION("Driver for cx23885 based TV cards");
37MODULE_AUTHOR("Steven Toth <stoth@linuxtv.org>"); 40MODULE_AUTHOR("Steven Toth <stoth@linuxtv.org>");
@@ -753,6 +756,23 @@ static void cx23885_dev_checkrevision(struct cx23885_dev *dev)
753 __func__, dev->hwrevision); 756 __func__, dev->hwrevision);
754} 757}
755 758
759/* Find the first v4l2_subdev member of the group id in hw */
760struct v4l2_subdev *cx23885_find_hw(struct cx23885_dev *dev, u32 hw)
761{
762 struct v4l2_subdev *result = NULL;
763 struct v4l2_subdev *sd;
764
765 spin_lock(&dev->v4l2_dev.lock);
766 v4l2_device_for_each_subdev(sd, &dev->v4l2_dev) {
767 if (sd->grp_id == hw) {
768 result = sd;
769 break;
770 }
771 }
772 spin_unlock(&dev->v4l2_dev.lock);
773 return result;
774}
775
756static int cx23885_dev_setup(struct cx23885_dev *dev) 776static int cx23885_dev_setup(struct cx23885_dev *dev)
757{ 777{
758 int i; 778 int i;
@@ -899,7 +919,7 @@ static int cx23885_dev_setup(struct cx23885_dev *dev)
899 cx23885_i2c_register(&dev->i2c_bus[1]); 919 cx23885_i2c_register(&dev->i2c_bus[1]);
900 cx23885_i2c_register(&dev->i2c_bus[2]); 920 cx23885_i2c_register(&dev->i2c_bus[2]);
901 cx23885_card_setup(dev); 921 cx23885_card_setup(dev);
902 call_all(dev, tuner, s_standby); 922 call_all(dev, core, s_power, 0);
903 cx23885_ir_init(dev); 923 cx23885_ir_init(dev);
904 924
905 if (cx23885_boards[dev->board].porta == CX23885_ANALOG_VIDEO) { 925 if (cx23885_boards[dev->board].porta == CX23885_ANALOG_VIDEO) {
@@ -1637,6 +1657,7 @@ static irqreturn_t cx23885_irq(int irq, void *dev_id)
1637 u32 ts1_status, ts1_mask; 1657 u32 ts1_status, ts1_mask;
1638 u32 ts2_status, ts2_mask; 1658 u32 ts2_status, ts2_mask;
1639 int vida_count = 0, ts1_count = 0, ts2_count = 0, handled = 0; 1659 int vida_count = 0, ts1_count = 0, ts2_count = 0, handled = 0;
1660 bool ir_handled = false;
1640 1661
1641 pci_status = cx_read(PCI_INT_STAT); 1662 pci_status = cx_read(PCI_INT_STAT);
1642 pci_mask = cx_read(PCI_INT_MSK); 1663 pci_mask = cx_read(PCI_INT_MSK);
@@ -1662,18 +1683,12 @@ static irqreturn_t cx23885_irq(int irq, void *dev_id)
1662 dprintk(7, "ts2_status: 0x%08x ts2_mask: 0x%08x count: 0x%x\n", 1683 dprintk(7, "ts2_status: 0x%08x ts2_mask: 0x%08x count: 0x%x\n",
1663 ts2_status, ts2_mask, ts2_count); 1684 ts2_status, ts2_mask, ts2_count);
1664 1685
1665 if ((pci_status & PCI_MSK_RISC_RD) || 1686 if (pci_status & (PCI_MSK_RISC_RD | PCI_MSK_RISC_WR |
1666 (pci_status & PCI_MSK_RISC_WR) || 1687 PCI_MSK_AL_RD | PCI_MSK_AL_WR | PCI_MSK_APB_DMA |
1667 (pci_status & PCI_MSK_AL_RD) || 1688 PCI_MSK_VID_C | PCI_MSK_VID_B | PCI_MSK_VID_A |
1668 (pci_status & PCI_MSK_AL_WR) || 1689 PCI_MSK_AUD_INT | PCI_MSK_AUD_EXT |
1669 (pci_status & PCI_MSK_APB_DMA) || 1690 PCI_MSK_GPIO0 | PCI_MSK_GPIO1 |
1670 (pci_status & PCI_MSK_VID_C) || 1691 PCI_MSK_IR)) {
1671 (pci_status & PCI_MSK_VID_B) ||
1672 (pci_status & PCI_MSK_VID_A) ||
1673 (pci_status & PCI_MSK_AUD_INT) ||
1674 (pci_status & PCI_MSK_AUD_EXT) ||
1675 (pci_status & PCI_MSK_GPIO0) ||
1676 (pci_status & PCI_MSK_GPIO1)) {
1677 1692
1678 if (pci_status & PCI_MSK_RISC_RD) 1693 if (pci_status & PCI_MSK_RISC_RD)
1679 dprintk(7, " (PCI_MSK_RISC_RD 0x%08x)\n", 1694 dprintk(7, " (PCI_MSK_RISC_RD 0x%08x)\n",
@@ -1722,6 +1737,10 @@ static irqreturn_t cx23885_irq(int irq, void *dev_id)
1722 if (pci_status & PCI_MSK_GPIO1) 1737 if (pci_status & PCI_MSK_GPIO1)
1723 dprintk(7, " (PCI_MSK_GPIO1 0x%08x)\n", 1738 dprintk(7, " (PCI_MSK_GPIO1 0x%08x)\n",
1724 PCI_MSK_GPIO1); 1739 PCI_MSK_GPIO1);
1740
1741 if (pci_status & PCI_MSK_IR)
1742 dprintk(7, " (PCI_MSK_IR 0x%08x)\n",
1743 PCI_MSK_IR);
1725 } 1744 }
1726 1745
1727 if (cx23885_boards[dev->board].cimax > 0 && 1746 if (cx23885_boards[dev->board].cimax > 0 &&
@@ -1752,12 +1771,48 @@ static irqreturn_t cx23885_irq(int irq, void *dev_id)
1752 if (vida_status) 1771 if (vida_status)
1753 handled += cx23885_video_irq(dev, vida_status); 1772 handled += cx23885_video_irq(dev, vida_status);
1754 1773
1774 if (pci_status & PCI_MSK_IR) {
1775 v4l2_subdev_call(dev->sd_ir, ir, interrupt_service_routine,
1776 pci_status, &ir_handled);
1777 if (ir_handled)
1778 handled++;
1779 }
1780
1755 if (handled) 1781 if (handled)
1756 cx_write(PCI_INT_STAT, pci_status); 1782 cx_write(PCI_INT_STAT, pci_status);
1757out: 1783out:
1758 return IRQ_RETVAL(handled); 1784 return IRQ_RETVAL(handled);
1759} 1785}
1760 1786
1787static void cx23885_v4l2_dev_notify(struct v4l2_subdev *sd,
1788 unsigned int notification, void *arg)
1789{
1790 struct cx23885_dev *dev;
1791
1792 if (sd == NULL)
1793 return;
1794
1795 dev = to_cx23885(sd->v4l2_dev);
1796
1797 switch (notification) {
1798 case V4L2_SUBDEV_IR_RX_NOTIFY: /* Called in an IRQ context */
1799 if (sd == dev->sd_ir)
1800 cx23885_ir_rx_v4l2_dev_notify(sd, *(u32 *)arg);
1801 break;
1802 case V4L2_SUBDEV_IR_TX_NOTIFY: /* Called in an IRQ context */
1803 if (sd == dev->sd_ir)
1804 cx23885_ir_tx_v4l2_dev_notify(sd, *(u32 *)arg);
1805 break;
1806 }
1807}
1808
1809static void cx23885_v4l2_dev_notify_init(struct cx23885_dev *dev)
1810{
1811 INIT_WORK(&dev->ir_rx_work, cx23885_ir_rx_work_handler);
1812 INIT_WORK(&dev->ir_tx_work, cx23885_ir_tx_work_handler);
1813 dev->v4l2_dev.notify = cx23885_v4l2_dev_notify;
1814}
1815
1761static inline int encoder_on_portb(struct cx23885_dev *dev) 1816static inline int encoder_on_portb(struct cx23885_dev *dev)
1762{ 1817{
1763 return cx23885_boards[dev->board].portb == CX23885_MPEG_ENCODER; 1818 return cx23885_boards[dev->board].portb == CX23885_MPEG_ENCODER;
@@ -1816,6 +1871,26 @@ void cx23885_gpio_clear(struct cx23885_dev *dev, u32 mask)
1816 printk(KERN_INFO "%s: Unsupported\n", dev->name); 1871 printk(KERN_INFO "%s: Unsupported\n", dev->name);
1817} 1872}
1818 1873
1874u32 cx23885_gpio_get(struct cx23885_dev *dev, u32 mask)
1875{
1876 if (mask & 0x00000007)
1877 return (cx_read(GP0_IO) >> 8) & mask & 0x7;
1878
1879 if (mask & 0x0007fff8) {
1880 if (encoder_on_portb(dev) || encoder_on_portc(dev))
1881 printk(KERN_ERR
1882 "%s: Reading GPIO moving on encoder ports\n",
1883 dev->name);
1884 return (cx_read(MC417_RWD) & ((mask & 0x7fff8) >> 3)) << 3;
1885 }
1886
1887 /* TODO: 23-19 */
1888 if (mask & 0x00f80000)
1889 printk(KERN_INFO "%s: Unsupported\n", dev->name);
1890
1891 return 0;
1892}
1893
1819void cx23885_gpio_enable(struct cx23885_dev *dev, u32 mask, int asoutput) 1894void cx23885_gpio_enable(struct cx23885_dev *dev, u32 mask, int asoutput)
1820{ 1895{
1821 if ((mask & 0x00000007) && asoutput) 1896 if ((mask & 0x00000007) && asoutput)
@@ -1854,6 +1929,9 @@ static int __devinit cx23885_initdev(struct pci_dev *pci_dev,
1854 if (err < 0) 1929 if (err < 0)
1855 goto fail_free; 1930 goto fail_free;
1856 1931
1932 /* Prepare to handle notifications from subdevices */
1933 cx23885_v4l2_dev_notify_init(dev);
1934
1857 /* pci init */ 1935 /* pci init */
1858 dev->pci = pci_dev; 1936 dev->pci = pci_dev;
1859 if (pci_enable_device(pci_dev)) { 1937 if (pci_enable_device(pci_dev)) {
@@ -1896,6 +1974,14 @@ static int __devinit cx23885_initdev(struct pci_dev *pci_dev,
1896 break; 1974 break;
1897 } 1975 }
1898 1976
1977 /*
1978 * The CX2388[58] IR controller can start firing interrupts when
1979 * enabled, so these have to take place after the cx23885_irq() handler
1980 * is hooked up by the call to request_irq() above.
1981 */
1982 cx23885_ir_pci_int_enable(dev);
1983 cx23885_input_init(dev);
1984
1899 return 0; 1985 return 0;
1900 1986
1901fail_irq: 1987fail_irq:
@@ -1912,6 +1998,9 @@ static void __devexit cx23885_finidev(struct pci_dev *pci_dev)
1912 struct v4l2_device *v4l2_dev = pci_get_drvdata(pci_dev); 1998 struct v4l2_device *v4l2_dev = pci_get_drvdata(pci_dev);
1913 struct cx23885_dev *dev = to_cx23885(v4l2_dev); 1999 struct cx23885_dev *dev = to_cx23885(v4l2_dev);
1914 2000
2001 cx23885_input_fini(dev);
2002 cx23885_ir_fini(dev);
2003
1915 cx23885_shutdown(dev); 2004 cx23885_shutdown(dev);
1916 2005
1917 pci_disable_device(pci_dev); 2006 pci_disable_device(pci_dev);
diff --git a/drivers/media/video/cx23885/cx23885-dvb.c b/drivers/media/video/cx23885/cx23885-dvb.c
index 16c6a921f40b..e45d2df08138 100644
--- a/drivers/media/video/cx23885/cx23885-dvb.c
+++ b/drivers/media/video/cx23885/cx23885-dvb.c
@@ -38,6 +38,7 @@
38#include "tda18271.h" 38#include "tda18271.h"
39#include "lgdt330x.h" 39#include "lgdt330x.h"
40#include "xc5000.h" 40#include "xc5000.h"
41#include "max2165.h"
41#include "tda10048.h" 42#include "tda10048.h"
42#include "tuner-xc2028.h" 43#include "tuner-xc2028.h"
43#include "tuner-simple.h" 44#include "tuner-simple.h"
@@ -54,6 +55,9 @@
54#include "netup-eeprom.h" 55#include "netup-eeprom.h"
55#include "netup-init.h" 56#include "netup-init.h"
56#include "lgdt3305.h" 57#include "lgdt3305.h"
58#include "atbm8830.h"
59#include "ds3000.h"
60#include "cx23885-f300.h"
57 61
58static unsigned int debug; 62static unsigned int debug;
59 63
@@ -400,6 +404,7 @@ static struct stv0900_reg stv0900_ts_regs[] = {
400 404
401static struct stv0900_config netup_stv0900_config = { 405static struct stv0900_config netup_stv0900_config = {
402 .demod_address = 0x68, 406 .demod_address = 0x68,
407 .demod_mode = 1, /* dual */
403 .xtal = 8000000, 408 .xtal = 8000000,
404 .clkmode = 3,/* 0-CLKI, 2-XTALI, else AUTO */ 409 .clkmode = 3,/* 0-CLKI, 2-XTALI, else AUTO */
405 .diseqc_mode = 2,/* 2/3 PWM */ 410 .diseqc_mode = 2,/* 2/3 PWM */
@@ -414,34 +419,22 @@ static struct stv6110_config netup_stv6110_tunerconfig_a = {
414 .i2c_address = 0x60, 419 .i2c_address = 0x60,
415 .mclk = 16000000, 420 .mclk = 16000000,
416 .clk_div = 1, 421 .clk_div = 1,
422 .gain = 8, /* +16 dB - maximum gain */
417}; 423};
418 424
419static struct stv6110_config netup_stv6110_tunerconfig_b = { 425static struct stv6110_config netup_stv6110_tunerconfig_b = {
420 .i2c_address = 0x63, 426 .i2c_address = 0x63,
421 .mclk = 16000000, 427 .mclk = 16000000,
422 .clk_div = 1, 428 .clk_div = 1,
429 .gain = 8, /* +16 dB - maximum gain */
423}; 430};
424 431
425static int tbs_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
426{
427 struct cx23885_tsport *port = fe->dvb->priv;
428 struct cx23885_dev *dev = port->dev;
429
430 if (voltage == SEC_VOLTAGE_18)
431 cx_write(MC417_RWD, 0x00001e00);/* GPIO-13 high */
432 else if (voltage == SEC_VOLTAGE_13)
433 cx_write(MC417_RWD, 0x00001a00);/* GPIO-13 low */
434 else
435 cx_write(MC417_RWD, 0x00001800);/* GPIO-12 low */
436 return 0;
437}
438
439static struct cx24116_config tbs_cx24116_config = { 432static struct cx24116_config tbs_cx24116_config = {
440 .demod_address = 0x05, 433 .demod_address = 0x55,
441}; 434};
442 435
443static struct cx24116_config tevii_cx24116_config = { 436static struct ds3000_config tevii_ds3000_config = {
444 .demod_address = 0x55, 437 .demod_address = 0x68,
445}; 438};
446 439
447static struct cx24116_config dvbworld_cx24116_config = { 440static struct cx24116_config dvbworld_cx24116_config = {
@@ -486,11 +479,40 @@ static int cx23885_dvb_set_frontend(struct dvb_frontend *fe,
486 break; 479 break;
487 } 480 }
488 break; 481 break;
482 case CX23885_BOARD_MYGICA_X8506:
483 case CX23885_BOARD_MAGICPRO_PROHDTVE2:
484 /* Select Digital TV */
485 cx23885_gpio_set(dev, GPIO_0);
486 break;
489 } 487 }
490 return (port->set_frontend_save) ? 488 return 0;
491 port->set_frontend_save(fe, param) : -ENODEV;
492} 489}
493 490
491static int cx23885_dvb_fe_ioctl_override(struct dvb_frontend *fe,
492 unsigned int cmd, void *parg,
493 unsigned int stage)
494{
495 int err = 0;
496
497 switch (stage) {
498 case DVB_FE_IOCTL_PRE:
499
500 switch (cmd) {
501 case FE_SET_FRONTEND:
502 err = cx23885_dvb_set_frontend(fe,
503 (struct dvb_frontend_parameters *) parg);
504 break;
505 }
506 break;
507
508 case DVB_FE_IOCTL_POST:
509 /* no post-ioctl handling required */
510 break;
511 }
512 return err;
513};
514
515
494static struct lgs8gxx_config magicpro_prohdtve2_lgs8g75_config = { 516static struct lgs8gxx_config magicpro_prohdtve2_lgs8g75_config = {
495 .prod = LGS8GXX_PROD_LGS8G75, 517 .prod = LGS8GXX_PROD_LGS8G75,
496 .demod_address = 0x19, 518 .demod_address = 0x19,
@@ -511,6 +533,38 @@ static struct xc5000_config magicpro_prohdtve2_xc5000_config = {
511 .if_khz = 6500, 533 .if_khz = 6500,
512}; 534};
513 535
536static struct atbm8830_config mygica_x8558pro_atbm8830_cfg1 = {
537 .prod = ATBM8830_PROD_8830,
538 .demod_address = 0x44,
539 .serial_ts = 0,
540 .ts_sampling_edge = 1,
541 .ts_clk_gated = 0,
542 .osc_clk_freq = 30400, /* in kHz */
543 .if_freq = 0, /* zero IF */
544 .zif_swap_iq = 1,
545};
546
547static struct max2165_config mygic_x8558pro_max2165_cfg1 = {
548 .i2c_address = 0x60,
549 .osc_clk = 20
550};
551
552static struct atbm8830_config mygica_x8558pro_atbm8830_cfg2 = {
553 .prod = ATBM8830_PROD_8830,
554 .demod_address = 0x44,
555 .serial_ts = 1,
556 .ts_sampling_edge = 1,
557 .ts_clk_gated = 0,
558 .osc_clk_freq = 30400, /* in kHz */
559 .if_freq = 0, /* zero IF */
560 .zif_swap_iq = 1,
561};
562
563static struct max2165_config mygic_x8558pro_max2165_cfg2 = {
564 .i2c_address = 0x60,
565 .osc_clk = 20
566};
567
514static int dvb_register(struct cx23885_tsport *port) 568static int dvb_register(struct cx23885_tsport *port)
515{ 569{
516 struct cx23885_dev *dev = port->dev; 570 struct cx23885_dev *dev = port->dev;
@@ -550,12 +604,6 @@ static int dvb_register(struct cx23885_tsport *port)
550 0x60, &dev->i2c_bus[1].i2c_adap, 604 0x60, &dev->i2c_bus[1].i2c_adap,
551 &hauppauge_hvr127x_config); 605 &hauppauge_hvr127x_config);
552 } 606 }
553
554 /* FIXME: temporary hack */
555 /* define bridge override to set_frontend */
556 port->set_frontend_save = fe0->dvb.frontend->ops.set_frontend;
557 fe0->dvb.frontend->ops.set_frontend = cx23885_dvb_set_frontend;
558
559 break; 607 break;
560 case CX23885_BOARD_HAUPPAUGE_HVR1255: 608 case CX23885_BOARD_HAUPPAUGE_HVR1255:
561 i2c_bus = &dev->i2c_bus[0]; 609 i2c_bus = &dev->i2c_bus[0];
@@ -772,23 +820,23 @@ static int dvb_register(struct cx23885_tsport *port)
772 } 820 }
773 break; 821 break;
774 case CX23885_BOARD_TBS_6920: 822 case CX23885_BOARD_TBS_6920:
775 i2c_bus = &dev->i2c_bus[0]; 823 i2c_bus = &dev->i2c_bus[1];
776 824
777 fe0->dvb.frontend = dvb_attach(cx24116_attach, 825 fe0->dvb.frontend = dvb_attach(cx24116_attach,
778 &tbs_cx24116_config, 826 &tbs_cx24116_config,
779 &i2c_bus->i2c_adap); 827 &i2c_bus->i2c_adap);
780 if (fe0->dvb.frontend != NULL) 828 if (fe0->dvb.frontend != NULL)
781 fe0->dvb.frontend->ops.set_voltage = tbs_set_voltage; 829 fe0->dvb.frontend->ops.set_voltage = f300_set_voltage;
782 830
783 break; 831 break;
784 case CX23885_BOARD_TEVII_S470: 832 case CX23885_BOARD_TEVII_S470:
785 i2c_bus = &dev->i2c_bus[1]; 833 i2c_bus = &dev->i2c_bus[1];
786 834
787 fe0->dvb.frontend = dvb_attach(cx24116_attach, 835 fe0->dvb.frontend = dvb_attach(ds3000_attach,
788 &tevii_cx24116_config, 836 &tevii_ds3000_config,
789 &i2c_bus->i2c_adap); 837 &i2c_bus->i2c_adap);
790 if (fe0->dvb.frontend != NULL) 838 if (fe0->dvb.frontend != NULL)
791 fe0->dvb.frontend->ops.set_voltage = tbs_set_voltage; 839 fe0->dvb.frontend->ops.set_voltage = f300_set_voltage;
792 840
793 break; 841 break;
794 case CX23885_BOARD_DVBWORLD_2005: 842 case CX23885_BOARD_DVBWORLD_2005:
@@ -814,8 +862,8 @@ static int dvb_register(struct cx23885_tsport *port)
814 if (!dvb_attach(lnbh24_attach, 862 if (!dvb_attach(lnbh24_attach,
815 fe0->dvb.frontend, 863 fe0->dvb.frontend,
816 &i2c_bus->i2c_adap, 864 &i2c_bus->i2c_adap,
817 LNBH24_PCL, 865 LNBH24_PCL | LNBH24_TTX,
818 LNBH24_TTX, 0x09)) 866 LNBH24_TEN, 0x09))
819 printk(KERN_ERR 867 printk(KERN_ERR
820 "No LNBH24 found!\n"); 868 "No LNBH24 found!\n");
821 869
@@ -835,8 +883,8 @@ static int dvb_register(struct cx23885_tsport *port)
835 if (!dvb_attach(lnbh24_attach, 883 if (!dvb_attach(lnbh24_attach,
836 fe0->dvb.frontend, 884 fe0->dvb.frontend,
837 &i2c_bus->i2c_adap, 885 &i2c_bus->i2c_adap,
838 LNBH24_PCL, 886 LNBH24_PCL | LNBH24_TTX,
839 LNBH24_TTX, 0x0a)) 887 LNBH24_TEN, 0x0a))
840 printk(KERN_ERR 888 printk(KERN_ERR
841 "No LNBH24 found!\n"); 889 "No LNBH24 found!\n");
842 890
@@ -872,6 +920,7 @@ static int dvb_register(struct cx23885_tsport *port)
872 } 920 }
873 break; 921 break;
874 case CX23885_BOARD_HAUPPAUGE_HVR1850: 922 case CX23885_BOARD_HAUPPAUGE_HVR1850:
923 case CX23885_BOARD_HAUPPAUGE_HVR1290:
875 i2c_bus = &dev->i2c_bus[0]; 924 i2c_bus = &dev->i2c_bus[0];
876 fe0->dvb.frontend = dvb_attach(s5h1411_attach, 925 fe0->dvb.frontend = dvb_attach(s5h1411_attach,
877 &hcw_s5h1411_config, 926 &hcw_s5h1411_config,
@@ -881,6 +930,36 @@ static int dvb_register(struct cx23885_tsport *port)
881 0x60, &dev->i2c_bus[0].i2c_adap, 930 0x60, &dev->i2c_bus[0].i2c_adap,
882 &hauppauge_tda18271_config); 931 &hauppauge_tda18271_config);
883 break; 932 break;
933 case CX23885_BOARD_MYGICA_X8558PRO:
934 switch (port->nr) {
935 /* port B */
936 case 1:
937 i2c_bus = &dev->i2c_bus[0];
938 fe0->dvb.frontend = dvb_attach(atbm8830_attach,
939 &mygica_x8558pro_atbm8830_cfg1,
940 &i2c_bus->i2c_adap);
941 if (fe0->dvb.frontend != NULL) {
942 dvb_attach(max2165_attach,
943 fe0->dvb.frontend,
944 &i2c_bus->i2c_adap,
945 &mygic_x8558pro_max2165_cfg1);
946 }
947 break;
948 /* port C */
949 case 2:
950 i2c_bus = &dev->i2c_bus[1];
951 fe0->dvb.frontend = dvb_attach(atbm8830_attach,
952 &mygica_x8558pro_atbm8830_cfg2,
953 &i2c_bus->i2c_adap);
954 if (fe0->dvb.frontend != NULL) {
955 dvb_attach(max2165_attach,
956 fe0->dvb.frontend,
957 &i2c_bus->i2c_adap,
958 &mygic_x8558pro_max2165_cfg2);
959 }
960 break;
961 }
962 break;
884 963
885 default: 964 default:
886 printk(KERN_INFO "%s: The frontend of your DVB/ATSC card " 965 printk(KERN_INFO "%s: The frontend of your DVB/ATSC card "
@@ -897,14 +976,15 @@ static int dvb_register(struct cx23885_tsport *port)
897 fe0->dvb.frontend->callback = cx23885_tuner_callback; 976 fe0->dvb.frontend->callback = cx23885_tuner_callback;
898 977
899 /* Put the analog decoder in standby to keep it quiet */ 978 /* Put the analog decoder in standby to keep it quiet */
900 call_all(dev, tuner, s_standby); 979 call_all(dev, core, s_power, 0);
901 980
902 if (fe0->dvb.frontend->ops.analog_ops.standby) 981 if (fe0->dvb.frontend->ops.analog_ops.standby)
903 fe0->dvb.frontend->ops.analog_ops.standby(fe0->dvb.frontend); 982 fe0->dvb.frontend->ops.analog_ops.standby(fe0->dvb.frontend);
904 983
905 /* register everything */ 984 /* register everything */
906 ret = videobuf_dvb_register_bus(&port->frontends, THIS_MODULE, port, 985 ret = videobuf_dvb_register_bus(&port->frontends, THIS_MODULE, port,
907 &dev->pci->dev, adapter_nr, 0); 986 &dev->pci->dev, adapter_nr, 0,
987 cx23885_dvb_fe_ioctl_override);
908 988
909 /* init CI & MAC */ 989 /* init CI & MAC */
910 switch (dev->board) { 990 switch (dev->board) {
diff --git a/drivers/media/video/cx23885/cx23885-f300.c b/drivers/media/video/cx23885/cx23885-f300.c
new file mode 100644
index 000000000000..93998f220986
--- /dev/null
+++ b/drivers/media/video/cx23885/cx23885-f300.c
@@ -0,0 +1,177 @@
1/*
2 * Driver for Silicon Labs C8051F300 microcontroller.
3 *
4 * It is used for LNB power control in TeVii S470,
5 * TBS 6920 PCIe DVB-S2 cards.
6 *
7 * Microcontroller connected to cx23885 GPIO pins:
8 * GPIO0 - data - P0.3 F300
9 * GPIO1 - reset - P0.2 F300
10 * GPIO2 - clk - P0.1 F300
11 * GPIO3 - busy - P0.0 F300
12 *
13 * Copyright (C) 2009 Igor M. Liplianin <liplianin@me.by>
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 *
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, write to the Free Software
28 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29 */
30
31#include "cx23885.h"
32
33#define F300_DATA GPIO_0
34#define F300_RESET GPIO_1
35#define F300_CLK GPIO_2
36#define F300_BUSY GPIO_3
37
38static void f300_set_line(struct cx23885_dev *dev, u32 line, u8 lvl)
39{
40 cx23885_gpio_enable(dev, line, 1);
41 if (lvl == 1)
42 cx23885_gpio_set(dev, line);
43 else
44 cx23885_gpio_clear(dev, line);
45}
46
47static u8 f300_get_line(struct cx23885_dev *dev, u32 line)
48{
49 cx23885_gpio_enable(dev, line, 0);
50
51 return cx23885_gpio_get(dev, line);
52}
53
54static void f300_send_byte(struct cx23885_dev *dev, u8 dta)
55{
56 u8 i;
57
58 for (i = 0; i < 8; i++) {
59 f300_set_line(dev, F300_CLK, 0);
60 udelay(30);
61 f300_set_line(dev, F300_DATA, (dta & 0x80) >> 7);/* msb first */
62 udelay(30);
63 dta <<= 1;
64 f300_set_line(dev, F300_CLK, 1);
65 udelay(30);
66 }
67}
68
69static u8 f300_get_byte(struct cx23885_dev *dev)
70{
71 u8 i, dta = 0;
72
73 for (i = 0; i < 8; i++) {
74 f300_set_line(dev, F300_CLK, 0);
75 udelay(30);
76 dta <<= 1;
77 f300_set_line(dev, F300_CLK, 1);
78 udelay(30);
79 dta |= f300_get_line(dev, F300_DATA);/* msb first */
80
81 }
82
83 return dta;
84}
85
86static u8 f300_xfer(struct dvb_frontend *fe, u8 *buf)
87{
88 struct cx23885_tsport *port = fe->dvb->priv;
89 struct cx23885_dev *dev = port->dev;
90 u8 i, temp, ret = 0;
91
92 temp = buf[0];
93 for (i = 0; i < buf[0]; i++)
94 temp += buf[i + 1];
95 temp = (~temp + 1);/* get check sum */
96 buf[1 + buf[0]] = temp;
97
98 f300_set_line(dev, F300_RESET, 1);
99 f300_set_line(dev, F300_CLK, 1);
100 udelay(30);
101 f300_set_line(dev, F300_DATA, 1);
102 msleep(1);
103
104 /* question: */
105 f300_set_line(dev, F300_RESET, 0);/* begin to send data */
106 msleep(1);
107
108 f300_send_byte(dev, 0xe0);/* the slave address is 0xe0, write */
109 msleep(1);
110
111 temp = buf[0];
112 temp += 2;
113 for (i = 0; i < temp; i++)
114 f300_send_byte(dev, buf[i]);
115
116 f300_set_line(dev, F300_RESET, 1);/* sent data over */
117 f300_set_line(dev, F300_DATA, 1);
118
119 /* answer: */
120 temp = 0;
121 for (i = 0; ((i < 8) & (temp == 0)); i++) {
122 msleep(1);
123 if (f300_get_line(dev, F300_BUSY) == 0)
124 temp = 1;
125 }
126
127 if (i > 7) {
128 printk(KERN_ERR "%s: timeout, the slave no response\n",
129 __func__);
130 ret = 1; /* timeout, the slave no response */
131 } else { /* the slave not busy, prepare for getting data */
132 f300_set_line(dev, F300_RESET, 0);/*ready...*/
133 msleep(1);
134 f300_send_byte(dev, 0xe1);/* 0xe1 is Read */
135 msleep(1);
136 temp = f300_get_byte(dev);/*get the data length */
137 if (temp > 14)
138 temp = 14;
139
140 for (i = 0; i < (temp + 1); i++)
141 f300_get_byte(dev);/* get data to empty buffer */
142
143 f300_set_line(dev, F300_RESET, 1);/* received data over */
144 f300_set_line(dev, F300_DATA, 1);
145 }
146
147 return ret;
148}
149
150int f300_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
151{
152 u8 buf[16];
153
154 buf[0] = 0x05;
155 buf[1] = 0x38;/* write port */
156 buf[2] = 0x01;/* A port, lnb power */
157
158 switch (voltage) {
159 case SEC_VOLTAGE_13:
160 buf[3] = 0x01;/* power on */
161 buf[4] = 0x02;/* B port, H/V */
162 buf[5] = 0x00;/*13V v*/
163 break;
164 case SEC_VOLTAGE_18:
165 buf[3] = 0x01;
166 buf[4] = 0x02;
167 buf[5] = 0x01;/* 18V h*/
168 break;
169 case SEC_VOLTAGE_OFF:
170 buf[3] = 0x00;/* power off */
171 buf[4] = 0x00;
172 buf[5] = 0x00;
173 break;
174 }
175
176 return f300_xfer(fe, buf);
177}
diff --git a/drivers/media/video/cx23885/cx23885-f300.h b/drivers/media/video/cx23885/cx23885-f300.h
new file mode 100644
index 000000000000..e73344c94963
--- /dev/null
+++ b/drivers/media/video/cx23885/cx23885-f300.h
@@ -0,0 +1,2 @@
1extern int f300_set_voltage(struct dvb_frontend *fe,
2 fe_sec_voltage_t voltage);
diff --git a/drivers/media/video/cx23885/cx23885-input.c b/drivers/media/video/cx23885/cx23885-input.c
new file mode 100644
index 000000000000..469e083dd5f8
--- /dev/null
+++ b/drivers/media/video/cx23885/cx23885-input.c
@@ -0,0 +1,427 @@
1/*
2 * Driver for the Conexant CX23885/7/8 PCIe bridge
3 *
4 * Infrared remote control input device
5 *
6 * Most of this file is
7 *
8 * Copyright (C) 2009 Andy Walls <awalls@radix.net>
9 *
10 * However, the cx23885_input_{init,fini} functions contained herein are
11 * derived from Linux kernel files linux/media/video/.../...-input.c marked as:
12 *
13 * Copyright (C) 2008 <srinivasa.deevi at conexant dot com>
14 * Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it>
15 * Markus Rechberger <mrechberger@gmail.com>
16 * Mauro Carvalho Chehab <mchehab@infradead.org>
17 * Sascha Sommer <saschasommer@freenet.de>
18 * Copyright (C) 2004, 2005 Chris Pascoe
19 * Copyright (C) 2003, 2004 Gerd Knorr
20 * Copyright (C) 2003 Pavel Machek
21 *
22 * This program is free software; you can redistribute it and/or
23 * modify it under the terms of the GNU General Public License
24 * as published by the Free Software Foundation; either version 2
25 * of the License, or (at your option) any later version.
26 *
27 * This program is distributed in the hope that it will be useful,
28 * but WITHOUT ANY WARRANTY; without even the implied warranty of
29 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30 * GNU General Public License for more details.
31 *
32 * You should have received a copy of the GNU General Public License
33 * along with this program; if not, write to the Free Software
34 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
35 * 02110-1301, USA.
36 */
37
38#include <linux/input.h>
39#include <media/ir-common.h>
40#include <media/v4l2-subdev.h>
41
42#include "cx23885.h"
43
44#define RC5_BITS 14
45#define RC5_HALF_BITS (2*RC5_BITS)
46#define RC5_HALF_BITS_MASK ((1 << RC5_HALF_BITS) - 1)
47
48#define RC5_START_BITS_NORMAL 0x3 /* Command range 0 - 63 */
49#define RC5_START_BITS_EXTENDED 0x2 /* Command range 64 - 127 */
50
51#define RC5_EXTENDED_COMMAND_OFFSET 64
52
53static inline unsigned int rc5_command(u32 rc5_baseband)
54{
55 return RC5_INSTR(rc5_baseband) +
56 ((RC5_START(rc5_baseband) == RC5_START_BITS_EXTENDED)
57 ? RC5_EXTENDED_COMMAND_OFFSET : 0);
58}
59
60static void cx23885_input_process_raw_rc5(struct cx23885_dev *dev)
61{
62 struct card_ir *ir_input = dev->ir_input;
63 unsigned int code, command;
64 u32 rc5;
65
66 /* Ignore codes that are too short to be valid RC-5 */
67 if (ir_input->last_bit < (RC5_HALF_BITS - 1))
68 return;
69
70 /* The library has the manchester coding backwards; XOR to adapt. */
71 code = (ir_input->code & RC5_HALF_BITS_MASK) ^ RC5_HALF_BITS_MASK;
72 rc5 = ir_rc5_decode(code);
73
74 switch (RC5_START(rc5)) {
75 case RC5_START_BITS_NORMAL:
76 break;
77 case RC5_START_BITS_EXTENDED:
78 /* Don't allow if the remote only emits standard commands */
79 if (ir_input->start == RC5_START_BITS_NORMAL)
80 return;
81 break;
82 default:
83 return;
84 }
85
86 if (ir_input->addr != RC5_ADDR(rc5))
87 return;
88
89 /* Don't generate a keypress for RC-5 auto-repeated keypresses */
90 command = rc5_command(rc5);
91 if (RC5_TOGGLE(rc5) != RC5_TOGGLE(ir_input->last_rc5) ||
92 command != rc5_command(ir_input->last_rc5) ||
93 /* Catch T == 0, CMD == 0 (e.g. '0') as first keypress after init */
94 RC5_START(ir_input->last_rc5) == 0) {
95 /* This keypress is differnet: not an auto repeat */
96 ir_input_nokey(ir_input->dev, &ir_input->ir);
97 ir_input_keydown(ir_input->dev, &ir_input->ir, command);
98 }
99 ir_input->last_rc5 = rc5;
100
101 /* Schedule when we should do the key up event: ir_input_nokey() */
102 mod_timer(&ir_input->timer_keyup,
103 jiffies + msecs_to_jiffies(ir_input->rc5_key_timeout));
104}
105
106static void cx23885_input_next_pulse_width_rc5(struct cx23885_dev *dev,
107 u32 ns_pulse)
108{
109 const int rc5_quarterbit_ns = 444444; /* 32 cycles/36 kHz/2 = 444 us */
110 struct card_ir *ir_input = dev->ir_input;
111 int i, level, quarterbits, halfbits;
112
113 if (!ir_input->active) {
114 ir_input->active = 1;
115 /* assume an initial space that we may not detect or measure */
116 ir_input->code = 0;
117 ir_input->last_bit = 0;
118 }
119
120 if (ns_pulse == V4L2_SUBDEV_IR_PULSE_RX_SEQ_END) {
121 ir_input->last_bit++; /* Account for the final space */
122 ir_input->active = 0;
123 cx23885_input_process_raw_rc5(dev);
124 return;
125 }
126
127 level = (ns_pulse & V4L2_SUBDEV_IR_PULSE_LEVEL_MASK) ? 1 : 0;
128
129 /* Skip any leading space to sync to the start bit */
130 if (ir_input->last_bit == 0 && level == 0)
131 return;
132
133 /*
134 * With valid RC-5 we can get up to two consecutive half-bits in a
135 * single pulse measurment. Experiments have shown that the duration
136 * of a half-bit can vary. Make sure we always end up with an even
137 * number of quarter bits at the same level (mark or space).
138 */
139 ns_pulse &= V4L2_SUBDEV_IR_PULSE_MAX_WIDTH_NS;
140 quarterbits = ns_pulse / rc5_quarterbit_ns;
141 if (quarterbits & 1)
142 quarterbits++;
143 halfbits = quarterbits / 2;
144
145 for (i = 0; i < halfbits; i++) {
146 ir_input->last_bit++;
147 ir_input->code |= (level << ir_input->last_bit);
148
149 if (ir_input->last_bit >= RC5_HALF_BITS-1) {
150 ir_input->active = 0;
151 cx23885_input_process_raw_rc5(dev);
152 /*
153 * If level is 1, a leading mark is invalid for RC5.
154 * If level is 0, we scan past extra intial space.
155 * Either way we don't want to reactivate collecting
156 * marks or spaces here with any left over half-bits.
157 */
158 break;
159 }
160 }
161}
162
163static void cx23885_input_process_pulse_widths_rc5(struct cx23885_dev *dev,
164 bool add_eom)
165{
166 struct card_ir *ir_input = dev->ir_input;
167 struct ir_input_state *ir_input_state = &ir_input->ir;
168
169 u32 ns_pulse[RC5_HALF_BITS+1];
170 ssize_t num = 0;
171 int count, i;
172
173 do {
174 v4l2_subdev_call(dev->sd_ir, ir, rx_read, (u8 *) ns_pulse,
175 sizeof(ns_pulse), &num);
176
177 count = num / sizeof(u32);
178
179 /* Append an end of Rx seq, if the caller requested */
180 if (add_eom && count < ARRAY_SIZE(ns_pulse)) {
181 ns_pulse[count] = V4L2_SUBDEV_IR_PULSE_RX_SEQ_END;
182 count++;
183 }
184
185 /* Just drain the Rx FIFO, if we're called, but not RC-5 */
186 if (ir_input_state->ir_type != IR_TYPE_RC5)
187 continue;
188
189 for (i = 0; i < count; i++)
190 cx23885_input_next_pulse_width_rc5(dev, ns_pulse[i]);
191 } while (num != 0);
192}
193
194void cx23885_input_rx_work_handler(struct cx23885_dev *dev, u32 events)
195{
196 struct v4l2_subdev_ir_parameters params;
197 int overrun, data_available;
198
199 if (dev->sd_ir == NULL || events == 0)
200 return;
201
202 switch (dev->board) {
203 case CX23885_BOARD_HAUPPAUGE_HVR1850:
204 case CX23885_BOARD_HAUPPAUGE_HVR1290:
205 /*
206 * The only board we handle right now. However other boards
207 * using the CX2388x integrated IR controller should be similar
208 */
209 break;
210 default:
211 return;
212 }
213
214 overrun = events & (V4L2_SUBDEV_IR_RX_SW_FIFO_OVERRUN |
215 V4L2_SUBDEV_IR_RX_HW_FIFO_OVERRUN);
216
217 data_available = events & (V4L2_SUBDEV_IR_RX_END_OF_RX_DETECTED |
218 V4L2_SUBDEV_IR_RX_FIFO_SERVICE_REQ);
219
220 if (overrun) {
221 /* If there was a FIFO overrun, stop the device */
222 v4l2_subdev_call(dev->sd_ir, ir, rx_g_parameters, &params);
223 params.enable = false;
224 /* Mitigate race with cx23885_input_ir_stop() */
225 params.shutdown = atomic_read(&dev->ir_input_stopping);
226 v4l2_subdev_call(dev->sd_ir, ir, rx_s_parameters, &params);
227 }
228
229 if (data_available)
230 cx23885_input_process_pulse_widths_rc5(dev, overrun);
231
232 if (overrun) {
233 /* If there was a FIFO overrun, clear & restart the device */
234 params.enable = true;
235 /* Mitigate race with cx23885_input_ir_stop() */
236 params.shutdown = atomic_read(&dev->ir_input_stopping);
237 v4l2_subdev_call(dev->sd_ir, ir, rx_s_parameters, &params);
238 }
239}
240
241static void cx23885_input_ir_start(struct cx23885_dev *dev)
242{
243 struct card_ir *ir_input = dev->ir_input;
244 struct ir_input_state *ir_input_state = &ir_input->ir;
245 struct v4l2_subdev_ir_parameters params;
246
247 if (dev->sd_ir == NULL)
248 return;
249
250 atomic_set(&dev->ir_input_stopping, 0);
251
252 /* keyup timer set up, if needed */
253 switch (dev->board) {
254 case CX23885_BOARD_HAUPPAUGE_HVR1850:
255 case CX23885_BOARD_HAUPPAUGE_HVR1290:
256 setup_timer(&ir_input->timer_keyup,
257 ir_rc5_timer_keyup, /* Not actually RC-5 specific */
258 (unsigned long) ir_input);
259 if (ir_input_state->ir_type == IR_TYPE_RC5) {
260 /*
261 * RC-5 repeats a held key every
262 * 64 bits * (2 * 32/36000) sec/bit = 113.778 ms
263 */
264 ir_input->rc5_key_timeout = 115;
265 }
266 break;
267 }
268
269 v4l2_subdev_call(dev->sd_ir, ir, rx_g_parameters, &params);
270 switch (dev->board) {
271 case CX23885_BOARD_HAUPPAUGE_HVR1850:
272 case CX23885_BOARD_HAUPPAUGE_HVR1290:
273 /*
274 * The IR controller on this board only returns pulse widths.
275 * Any other mode setting will fail to set up the device.
276 */
277 params.mode = V4L2_SUBDEV_IR_MODE_PULSE_WIDTH;
278 params.enable = true;
279 params.interrupt_enable = true;
280 params.shutdown = false;
281
282 /* Setup for baseband compatible with both RC-5 and RC-6A */
283 params.modulation = false;
284 /* RC-5: 2,222,222 ns = 1/36 kHz * 32 cycles * 2 marks * 1.25*/
285 /* RC-6A: 3,333,333 ns = 1/36 kHz * 16 cycles * 6 marks * 1.25*/
286 params.max_pulse_width = 3333333; /* ns */
287 /* RC-5: 666,667 ns = 1/36 kHz * 32 cycles * 1 mark * 0.75 */
288 /* RC-6A: 333,333 ns = 1/36 kHz * 16 cycles * 1 mark * 0.75 */
289 params.noise_filter_min_width = 333333; /* ns */
290 /*
291 * This board has inverted receive sense:
292 * mark is received as low logic level;
293 * falling edges are detected as rising edges; etc.
294 */
295 params.invert = true;
296 break;
297 }
298 v4l2_subdev_call(dev->sd_ir, ir, rx_s_parameters, &params);
299}
300
301static void cx23885_input_ir_stop(struct cx23885_dev *dev)
302{
303 struct card_ir *ir_input = dev->ir_input;
304 struct v4l2_subdev_ir_parameters params;
305
306 if (dev->sd_ir == NULL)
307 return;
308
309 /*
310 * Stop the sd_ir subdevice from generating notifications and
311 * scheduling work.
312 * It is shutdown this way in order to mitigate a race with
313 * cx23885_input_rx_work_handler() in the overrun case, which could
314 * re-enable the subdevice.
315 */
316 atomic_set(&dev->ir_input_stopping, 1);
317 v4l2_subdev_call(dev->sd_ir, ir, rx_g_parameters, &params);
318 while (params.shutdown == false) {
319 params.enable = false;
320 params.interrupt_enable = false;
321 params.shutdown = true;
322 v4l2_subdev_call(dev->sd_ir, ir, rx_s_parameters, &params);
323 v4l2_subdev_call(dev->sd_ir, ir, rx_g_parameters, &params);
324 }
325
326 flush_scheduled_work();
327
328 switch (dev->board) {
329 case CX23885_BOARD_HAUPPAUGE_HVR1850:
330 case CX23885_BOARD_HAUPPAUGE_HVR1290:
331 del_timer_sync(&ir_input->timer_keyup);
332 break;
333 }
334}
335
336int cx23885_input_init(struct cx23885_dev *dev)
337{
338 struct card_ir *ir;
339 struct input_dev *input_dev;
340 struct ir_scancode_table *ir_codes = NULL;
341 int ir_type, ir_addr, ir_start;
342 int ret;
343
344 /*
345 * If the IR device (hardware registers, chip, GPIO lines, etc.) isn't
346 * encapsulated in a v4l2_subdev, then I'm not going to deal with it.
347 */
348 if (dev->sd_ir == NULL)
349 return -ENODEV;
350
351 switch (dev->board) {
352 case CX23885_BOARD_HAUPPAUGE_HVR1850:
353 case CX23885_BOARD_HAUPPAUGE_HVR1290:
354 /* Parameters for the grey Hauppauge remote for the HVR-1850 */
355 ir_codes = &ir_codes_hauppauge_new_table;
356 ir_type = IR_TYPE_RC5;
357 ir_addr = 0x1e; /* RC-5 system bits emitted by the remote */
358 ir_start = RC5_START_BITS_NORMAL; /* A basic RC-5 remote */
359 break;
360 }
361 if (ir_codes == NULL)
362 return -ENODEV;
363
364 ir = kzalloc(sizeof(*ir), GFP_KERNEL);
365 input_dev = input_allocate_device();
366 if (!ir || !input_dev) {
367 ret = -ENOMEM;
368 goto err_out_free;
369 }
370
371 ir->dev = input_dev;
372 ir->addr = ir_addr;
373 ir->start = ir_start;
374
375 /* init input device */
376 snprintf(ir->name, sizeof(ir->name), "cx23885 IR (%s)",
377 cx23885_boards[dev->board].name);
378 snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0", pci_name(dev->pci));
379
380 ret = ir_input_init(input_dev, &ir->ir, ir_type, ir_codes);
381 if (ret < 0)
382 goto err_out_free;
383
384 input_dev->name = ir->name;
385 input_dev->phys = ir->phys;
386 input_dev->id.bustype = BUS_PCI;
387 input_dev->id.version = 1;
388 if (dev->pci->subsystem_vendor) {
389 input_dev->id.vendor = dev->pci->subsystem_vendor;
390 input_dev->id.product = dev->pci->subsystem_device;
391 } else {
392 input_dev->id.vendor = dev->pci->vendor;
393 input_dev->id.product = dev->pci->device;
394 }
395 input_dev->dev.parent = &dev->pci->dev;
396
397 dev->ir_input = ir;
398 cx23885_input_ir_start(dev);
399
400 ret = input_register_device(ir->dev);
401 if (ret)
402 goto err_out_stop;
403
404 return 0;
405
406err_out_stop:
407 cx23885_input_ir_stop(dev);
408 dev->ir_input = NULL;
409err_out_free:
410 ir_input_free(input_dev);
411 input_free_device(input_dev);
412 kfree(ir);
413 return ret;
414}
415
416void cx23885_input_fini(struct cx23885_dev *dev)
417{
418 /* Always stop the IR hardware from generating interrupts */
419 cx23885_input_ir_stop(dev);
420
421 if (dev->ir_input == NULL)
422 return;
423 ir_input_free(dev->ir_input->dev);
424 input_unregister_device(dev->ir_input->dev);
425 kfree(dev->ir_input);
426 dev->ir_input = NULL;
427}
diff --git a/drivers/media/video/cx23885/cx23885-input.h b/drivers/media/video/cx23885/cx23885-input.h
new file mode 100644
index 000000000000..3572cb1ecfc2
--- /dev/null
+++ b/drivers/media/video/cx23885/cx23885-input.h
@@ -0,0 +1,30 @@
1/*
2 * Driver for the Conexant CX23885/7/8 PCIe bridge
3 *
4 * Infrared remote control input device
5 *
6 * Copyright (C) 2009 Andy Walls <awalls@radix.net>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (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., 51 Franklin Street, Fifth Floor, Boston, MA
21 * 02110-1301, USA.
22 */
23
24#ifndef _CX23885_INPUT_H_
25#define _CX23885_INPUT_H_
26int cx23885_input_rx_work_handler(struct cx23885_dev *dev, u32 events);
27
28int cx23885_input_init(struct cx23885_dev *dev);
29void cx23885_input_fini(struct cx23885_dev *dev);
30#endif
diff --git a/drivers/media/video/cx23885/cx23885-ioctl.c b/drivers/media/video/cx23885/cx23885-ioctl.c
new file mode 100644
index 000000000000..dfb4627fb340
--- /dev/null
+++ b/drivers/media/video/cx23885/cx23885-ioctl.c
@@ -0,0 +1,208 @@
1/*
2 * Driver for the Conexant CX23885/7/8 PCIe bridge
3 *
4 * Various common ioctl() support functions
5 *
6 * Copyright (c) 2009 Andy Walls <awalls@radix.net>
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 *
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., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24#include "cx23885.h"
25#include <media/v4l2-chip-ident.h>
26
27int cx23885_g_chip_ident(struct file *file, void *fh,
28 struct v4l2_dbg_chip_ident *chip)
29{
30 struct cx23885_dev *dev = ((struct cx23885_fh *)fh)->dev;
31 int err = 0;
32 u8 rev;
33
34 chip->ident = V4L2_IDENT_NONE;
35 chip->revision = 0;
36 switch (chip->match.type) {
37 case V4L2_CHIP_MATCH_HOST:
38 switch (chip->match.addr) {
39 case 0:
40 rev = cx_read(RDR_CFG2) & 0xff;
41 switch (dev->pci->device) {
42 case 0x8852:
43 /* rev 0x04 could be '885 or '888. Pick '888. */
44 if (rev == 0x04)
45 chip->ident = V4L2_IDENT_CX23888;
46 else
47 chip->ident = V4L2_IDENT_CX23885;
48 break;
49 case 0x8880:
50 if (rev == 0x0e || rev == 0x0f)
51 chip->ident = V4L2_IDENT_CX23887;
52 else
53 chip->ident = V4L2_IDENT_CX23888;
54 break;
55 default:
56 chip->ident = V4L2_IDENT_UNKNOWN;
57 break;
58 }
59 chip->revision = (dev->pci->device << 16) | (rev << 8) |
60 (dev->hwrevision & 0xff);
61 break;
62 case 1:
63 if (dev->v4l_device != NULL) {
64 chip->ident = V4L2_IDENT_CX23417;
65 chip->revision = 0;
66 }
67 break;
68 case 2:
69 /*
70 * The integrated IR controller on the CX23888 is
71 * host chip 2. It may not be used/initialized or sd_ir
72 * may be pointing at the cx25840 subdevice for the
73 * IR controller on the CX23885. Thus we find it
74 * without using the dev->sd_ir pointer.
75 */
76 call_hw(dev, CX23885_HW_888_IR, core, g_chip_ident,
77 chip);
78 break;
79 default:
80 err = -EINVAL; /* per V4L2 spec */
81 break;
82 }
83 break;
84 case V4L2_CHIP_MATCH_I2C_DRIVER:
85 /* If needed, returns V4L2_IDENT_AMBIGUOUS without extra work */
86 call_all(dev, core, g_chip_ident, chip);
87 break;
88 case V4L2_CHIP_MATCH_I2C_ADDR:
89 /*
90 * We could return V4L2_IDENT_UNKNOWN, but we don't do the work
91 * to look if a chip is at the address with no driver. That's a
92 * dangerous thing to do with EEPROMs anyway.
93 */
94 call_all(dev, core, g_chip_ident, chip);
95 break;
96 default:
97 err = -EINVAL;
98 break;
99 }
100 return err;
101}
102
103#ifdef CONFIG_VIDEO_ADV_DEBUG
104static int cx23885_g_host_register(struct cx23885_dev *dev,
105 struct v4l2_dbg_register *reg)
106{
107 if ((reg->reg & 0x3) != 0 || reg->reg >= pci_resource_len(dev->pci, 0))
108 return -EINVAL;
109
110 reg->size = 4;
111 reg->val = cx_read(reg->reg);
112 return 0;
113}
114
115static int cx23417_g_register(struct cx23885_dev *dev,
116 struct v4l2_dbg_register *reg)
117{
118 u32 value;
119
120 if (dev->v4l_device == NULL)
121 return -EINVAL;
122
123 if ((reg->reg & 0x3) != 0 || reg->reg >= 0x10000)
124 return -EINVAL;
125
126 if (mc417_register_read(dev, (u16) reg->reg, &value))
127 return -EINVAL; /* V4L2 spec, but -EREMOTEIO really */
128
129 reg->size = 4;
130 reg->val = value;
131 return 0;
132}
133
134int cx23885_g_register(struct file *file, void *fh,
135 struct v4l2_dbg_register *reg)
136{
137 struct cx23885_dev *dev = ((struct cx23885_fh *)fh)->dev;
138
139 if (!capable(CAP_SYS_ADMIN))
140 return -EPERM;
141
142 if (reg->match.type == V4L2_CHIP_MATCH_HOST) {
143 switch (reg->match.addr) {
144 case 0:
145 return cx23885_g_host_register(dev, reg);
146 case 1:
147 return cx23417_g_register(dev, reg);
148 default:
149 break;
150 }
151 }
152
153 /* FIXME - any error returns should not be ignored */
154 call_all(dev, core, g_register, reg);
155 return 0;
156}
157
158static int cx23885_s_host_register(struct cx23885_dev *dev,
159 struct v4l2_dbg_register *reg)
160{
161 if ((reg->reg & 0x3) != 0 || reg->reg >= pci_resource_len(dev->pci, 0))
162 return -EINVAL;
163
164 reg->size = 4;
165 cx_write(reg->reg, reg->val);
166 return 0;
167}
168
169static int cx23417_s_register(struct cx23885_dev *dev,
170 struct v4l2_dbg_register *reg)
171{
172 if (dev->v4l_device == NULL)
173 return -EINVAL;
174
175 if ((reg->reg & 0x3) != 0 || reg->reg >= 0x10000)
176 return -EINVAL;
177
178 if (mc417_register_write(dev, (u16) reg->reg, (u32) reg->val))
179 return -EINVAL; /* V4L2 spec, but -EREMOTEIO really */
180
181 reg->size = 4;
182 return 0;
183}
184
185int cx23885_s_register(struct file *file, void *fh,
186 struct v4l2_dbg_register *reg)
187{
188 struct cx23885_dev *dev = ((struct cx23885_fh *)fh)->dev;
189
190 if (!capable(CAP_SYS_ADMIN))
191 return -EPERM;
192
193 if (reg->match.type == V4L2_CHIP_MATCH_HOST) {
194 switch (reg->match.addr) {
195 case 0:
196 return cx23885_s_host_register(dev, reg);
197 case 1:
198 return cx23417_s_register(dev, reg);
199 default:
200 break;
201 }
202 }
203
204 /* FIXME - any error returns should not be ignored */
205 call_all(dev, core, s_register, reg);
206 return 0;
207}
208#endif
diff --git a/drivers/media/video/cx23885/cx23885-ioctl.h b/drivers/media/video/cx23885/cx23885-ioctl.h
new file mode 100644
index 000000000000..80b0f4923c6a
--- /dev/null
+++ b/drivers/media/video/cx23885/cx23885-ioctl.h
@@ -0,0 +1,39 @@
1/*
2 * Driver for the Conexant CX23885/7/8 PCIe bridge
3 *
4 * Various common ioctl() support functions
5 *
6 * Copyright (c) 2009 Andy Walls <awalls@radix.net>
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 *
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., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24#ifndef _CX23885_IOCTL_H_
25#define _CX23885_IOCTL_H_
26
27int cx23885_g_chip_ident(struct file *file, void *fh,
28 struct v4l2_dbg_chip_ident *chip);
29
30#ifdef CONFIG_VIDEO_ADV_DEBUG
31int cx23885_g_register(struct file *file, void *fh,
32 struct v4l2_dbg_register *reg);
33
34
35int cx23885_s_register(struct file *file, void *fh,
36 struct v4l2_dbg_register *reg);
37
38#endif
39#endif
diff --git a/drivers/media/video/cx23885/cx23885-ir.c b/drivers/media/video/cx23885/cx23885-ir.c
new file mode 100644
index 000000000000..6ae982cc9856
--- /dev/null
+++ b/drivers/media/video/cx23885/cx23885-ir.c
@@ -0,0 +1,101 @@
1/*
2 * Driver for the Conexant CX23885/7/8 PCIe bridge
3 *
4 * Infrared device support routines - non-input, non-vl42_subdev routines
5 *
6 * Copyright (C) 2009 Andy Walls <awalls@radix.net>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (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., 51 Franklin Street, Fifth Floor, Boston, MA
21 * 02110-1301, USA.
22 */
23
24#include <media/v4l2-device.h>
25
26#include "cx23885.h"
27#include "cx23885-input.h"
28
29#define CX23885_IR_RX_FIFO_SERVICE_REQ 0
30#define CX23885_IR_RX_END_OF_RX_DETECTED 1
31#define CX23885_IR_RX_HW_FIFO_OVERRUN 2
32#define CX23885_IR_RX_SW_FIFO_OVERRUN 3
33
34#define CX23885_IR_TX_FIFO_SERVICE_REQ 0
35
36
37void cx23885_ir_rx_work_handler(struct work_struct *work)
38{
39 struct cx23885_dev *dev =
40 container_of(work, struct cx23885_dev, ir_rx_work);
41 u32 events = 0;
42 unsigned long *notifications = &dev->ir_rx_notifications;
43
44 if (test_and_clear_bit(CX23885_IR_RX_SW_FIFO_OVERRUN, notifications))
45 events |= V4L2_SUBDEV_IR_RX_SW_FIFO_OVERRUN;
46 if (test_and_clear_bit(CX23885_IR_RX_HW_FIFO_OVERRUN, notifications))
47 events |= V4L2_SUBDEV_IR_RX_HW_FIFO_OVERRUN;
48 if (test_and_clear_bit(CX23885_IR_RX_END_OF_RX_DETECTED, notifications))
49 events |= V4L2_SUBDEV_IR_RX_END_OF_RX_DETECTED;
50 if (test_and_clear_bit(CX23885_IR_RX_FIFO_SERVICE_REQ, notifications))
51 events |= V4L2_SUBDEV_IR_RX_FIFO_SERVICE_REQ;
52
53 if (events == 0)
54 return;
55
56 if (dev->ir_input)
57 cx23885_input_rx_work_handler(dev, events);
58}
59
60void cx23885_ir_tx_work_handler(struct work_struct *work)
61{
62 struct cx23885_dev *dev =
63 container_of(work, struct cx23885_dev, ir_tx_work);
64 u32 events = 0;
65 unsigned long *notifications = &dev->ir_tx_notifications;
66
67 if (test_and_clear_bit(CX23885_IR_TX_FIFO_SERVICE_REQ, notifications))
68 events |= V4L2_SUBDEV_IR_TX_FIFO_SERVICE_REQ;
69
70 if (events == 0)
71 return;
72
73}
74
75/* Called in an IRQ context */
76void cx23885_ir_rx_v4l2_dev_notify(struct v4l2_subdev *sd, u32 events)
77{
78 struct cx23885_dev *dev = to_cx23885(sd->v4l2_dev);
79 unsigned long *notifications = &dev->ir_rx_notifications;
80
81 if (events & V4L2_SUBDEV_IR_RX_FIFO_SERVICE_REQ)
82 set_bit(CX23885_IR_RX_FIFO_SERVICE_REQ, notifications);
83 if (events & V4L2_SUBDEV_IR_RX_END_OF_RX_DETECTED)
84 set_bit(CX23885_IR_RX_END_OF_RX_DETECTED, notifications);
85 if (events & V4L2_SUBDEV_IR_RX_HW_FIFO_OVERRUN)
86 set_bit(CX23885_IR_RX_HW_FIFO_OVERRUN, notifications);
87 if (events & V4L2_SUBDEV_IR_RX_SW_FIFO_OVERRUN)
88 set_bit(CX23885_IR_RX_SW_FIFO_OVERRUN, notifications);
89 schedule_work(&dev->ir_rx_work);
90}
91
92/* Called in an IRQ context */
93void cx23885_ir_tx_v4l2_dev_notify(struct v4l2_subdev *sd, u32 events)
94{
95 struct cx23885_dev *dev = to_cx23885(sd->v4l2_dev);
96 unsigned long *notifications = &dev->ir_tx_notifications;
97
98 if (events & V4L2_SUBDEV_IR_TX_FIFO_SERVICE_REQ)
99 set_bit(CX23885_IR_TX_FIFO_SERVICE_REQ, notifications);
100 schedule_work(&dev->ir_tx_work);
101}
diff --git a/drivers/media/video/cx23885/cx23885-ir.h b/drivers/media/video/cx23885/cx23885-ir.h
new file mode 100644
index 000000000000..9b8a6d5d1ef6
--- /dev/null
+++ b/drivers/media/video/cx23885/cx23885-ir.h
@@ -0,0 +1,31 @@
1/*
2 * Driver for the Conexant CX23885/7/8 PCIe bridge
3 *
4 * Infrared device support routines - non-input, non-vl42_subdev routines
5 *
6 * Copyright (C) 2009 Andy Walls <awalls@radix.net>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (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., 51 Franklin Street, Fifth Floor, Boston, MA
21 * 02110-1301, USA.
22 */
23
24#ifndef _CX23885_IR_H_
25#define _CX23885_IR_H_
26void cx23885_ir_rx_v4l2_dev_notify(struct v4l2_subdev *sd, u32 events);
27void cx23885_ir_tx_v4l2_dev_notify(struct v4l2_subdev *sd, u32 events);
28
29void cx23885_ir_rx_work_handler(struct work_struct *work);
30void cx23885_ir_tx_work_handler(struct work_struct *work);
31#endif
diff --git a/drivers/media/video/cx23885/cx23885-reg.h b/drivers/media/video/cx23885/cx23885-reg.h
index eafbe5226bae..c0bc9a068954 100644
--- a/drivers/media/video/cx23885/cx23885-reg.h
+++ b/drivers/media/video/cx23885/cx23885-reg.h
@@ -212,8 +212,9 @@ Channel manager Data Structure entry = 20 DWORD
212 212
213#define DEV_CNTRL2 0x00040000 213#define DEV_CNTRL2 0x00040000
214 214
215#define PCI_MSK_GPIO1 (1 << 24) 215#define PCI_MSK_IR (1 << 28)
216#define PCI_MSK_GPIO0 (1 << 23) 216#define PCI_MSK_GPIO1 (1 << 24)
217#define PCI_MSK_GPIO0 (1 << 23)
217#define PCI_MSK_APB_DMA (1 << 12) 218#define PCI_MSK_APB_DMA (1 << 12)
218#define PCI_MSK_AL_WR (1 << 11) 219#define PCI_MSK_AL_WR (1 << 11)
219#define PCI_MSK_AL_RD (1 << 10) 220#define PCI_MSK_AL_RD (1 << 10)
diff --git a/drivers/media/video/cx23885/cx23885-video.c b/drivers/media/video/cx23885/cx23885-video.c
index 654cc253cd50..8b372b4f0de2 100644
--- a/drivers/media/video/cx23885/cx23885-video.c
+++ b/drivers/media/video/cx23885/cx23885-video.c
@@ -35,6 +35,7 @@
35#include "cx23885.h" 35#include "cx23885.h"
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 39
39MODULE_DESCRIPTION("v4l2 driver module for cx23885 based TV cards"); 40MODULE_DESCRIPTION("v4l2 driver module for cx23885 based TV cards");
40MODULE_AUTHOR("Steven Toth <stoth@linuxtv.org>"); 41MODULE_AUTHOR("Steven Toth <stoth@linuxtv.org>");
@@ -401,6 +402,13 @@ static int cx23885_video_mux(struct cx23885_dev *dev, unsigned int input)
401 INPUT(input)->gpio2, INPUT(input)->gpio3); 402 INPUT(input)->gpio2, INPUT(input)->gpio3);
402 dev->input = input; 403 dev->input = input;
403 404
405 if (dev->board == CX23885_BOARD_MYGICA_X8506 ||
406 dev->board == CX23885_BOARD_MAGICPRO_PROHDTVE2) {
407 /* Select Analog TV */
408 if (INPUT(input)->type == CX23885_VMUX_TELEVISION)
409 cx23885_gpio_clear(dev, GPIO_0);
410 }
411
404 /* Tell the internal A/V decoder */ 412 /* Tell the internal A/V decoder */
405 v4l2_subdev_call(dev->sd_cx25840, video, s_routing, 413 v4l2_subdev_call(dev->sd_cx25840, video, s_routing,
406 INPUT(input)->vmux, 0, 0); 414 INPUT(input)->vmux, 0, 0);
@@ -1144,6 +1152,7 @@ static int cx23885_enum_input(struct cx23885_dev *dev, struct v4l2_input *i)
1144 [CX23885_VMUX_COMPOSITE3] = "Composite3", 1152 [CX23885_VMUX_COMPOSITE3] = "Composite3",
1145 [CX23885_VMUX_COMPOSITE4] = "Composite4", 1153 [CX23885_VMUX_COMPOSITE4] = "Composite4",
1146 [CX23885_VMUX_SVIDEO] = "S-Video", 1154 [CX23885_VMUX_SVIDEO] = "S-Video",
1155 [CX23885_VMUX_COMPONENT] = "Component",
1147 [CX23885_VMUX_TELEVISION] = "Television", 1156 [CX23885_VMUX_TELEVISION] = "Television",
1148 [CX23885_VMUX_CABLE] = "Cable TV", 1157 [CX23885_VMUX_CABLE] = "Cable TV",
1149 [CX23885_VMUX_DVB] = "DVB", 1158 [CX23885_VMUX_DVB] = "DVB",
@@ -1312,34 +1321,6 @@ static int vidioc_s_frequency(struct file *file, void *priv,
1312 cx23885_set_freq(dev, f); 1321 cx23885_set_freq(dev, f);
1313} 1322}
1314 1323
1315#ifdef CONFIG_VIDEO_ADV_DEBUG
1316static int vidioc_g_register(struct file *file, void *fh,
1317 struct v4l2_dbg_register *reg)
1318{
1319 struct cx23885_dev *dev = ((struct cx23885_fh *)fh)->dev;
1320
1321 if (!v4l2_chip_match_host(&reg->match))
1322 return -EINVAL;
1323
1324 call_all(dev, core, g_register, reg);
1325
1326 return 0;
1327}
1328
1329static int vidioc_s_register(struct file *file, void *fh,
1330 struct v4l2_dbg_register *reg)
1331{
1332 struct cx23885_dev *dev = ((struct cx23885_fh *)fh)->dev;
1333
1334 if (!v4l2_chip_match_host(&reg->match))
1335 return -EINVAL;
1336
1337 call_all(dev, core, s_register, reg);
1338
1339 return 0;
1340}
1341#endif
1342
1343/* ----------------------------------------------------------- */ 1324/* ----------------------------------------------------------- */
1344 1325
1345static void cx23885_vid_timeout(unsigned long data) 1326static void cx23885_vid_timeout(unsigned long data)
@@ -1449,9 +1430,10 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = {
1449 .vidioc_s_tuner = vidioc_s_tuner, 1430 .vidioc_s_tuner = vidioc_s_tuner,
1450 .vidioc_g_frequency = vidioc_g_frequency, 1431 .vidioc_g_frequency = vidioc_g_frequency,
1451 .vidioc_s_frequency = vidioc_s_frequency, 1432 .vidioc_s_frequency = vidioc_s_frequency,
1433 .vidioc_g_chip_ident = cx23885_g_chip_ident,
1452#ifdef CONFIG_VIDEO_ADV_DEBUG 1434#ifdef CONFIG_VIDEO_ADV_DEBUG
1453 .vidioc_g_register = vidioc_g_register, 1435 .vidioc_g_register = cx23885_g_register,
1454 .vidioc_s_register = vidioc_s_register, 1436 .vidioc_s_register = cx23885_s_register,
1455#endif 1437#endif
1456}; 1438};
1457 1439
@@ -1529,9 +1511,11 @@ int cx23885_video_register(struct cx23885_dev *dev)
1529 if (sd) { 1511 if (sd) {
1530 struct tuner_setup tun_setup; 1512 struct tuner_setup tun_setup;
1531 1513
1514 memset(&tun_setup, 0, sizeof(tun_setup));
1532 tun_setup.mode_mask = T_ANALOG_TV; 1515 tun_setup.mode_mask = T_ANALOG_TV;
1533 tun_setup.type = dev->tuner_type; 1516 tun_setup.type = dev->tuner_type;
1534 tun_setup.addr = v4l2_i2c_subdev_addr(sd); 1517 tun_setup.addr = v4l2_i2c_subdev_addr(sd);
1518 tun_setup.tuner_callback = cx23885_tuner_callback;
1535 1519
1536 v4l2_subdev_call(sd, tuner, s_type_addr, &tun_setup); 1520 v4l2_subdev_call(sd, tuner, s_type_addr, &tun_setup);
1537 } 1521 }
diff --git a/drivers/media/video/cx23885/cx23885.h b/drivers/media/video/cx23885/cx23885.h
index cc7a165561ff..fa744764dc8b 100644
--- a/drivers/media/video/cx23885/cx23885.h
+++ b/drivers/media/video/cx23885/cx23885.h
@@ -79,6 +79,8 @@
79#define CX23885_BOARD_MAGICPRO_PROHDTVE2 23 79#define CX23885_BOARD_MAGICPRO_PROHDTVE2 23
80#define CX23885_BOARD_HAUPPAUGE_HVR1850 24 80#define CX23885_BOARD_HAUPPAUGE_HVR1850 24
81#define CX23885_BOARD_COMPRO_VIDEOMATE_E800 25 81#define CX23885_BOARD_COMPRO_VIDEOMATE_E800 25
82#define CX23885_BOARD_HAUPPAUGE_HVR1290 26
83#define CX23885_BOARD_MYGICA_X8558PRO 27
82 84
83#define GPIO_0 0x00000001 85#define GPIO_0 0x00000001
84#define GPIO_1 0x00000002 86#define GPIO_1 0x00000002
@@ -157,6 +159,7 @@ enum cx23885_itype {
157 CX23885_VMUX_COMPOSITE3, 159 CX23885_VMUX_COMPOSITE3,
158 CX23885_VMUX_COMPOSITE4, 160 CX23885_VMUX_COMPOSITE4,
159 CX23885_VMUX_SVIDEO, 161 CX23885_VMUX_SVIDEO,
162 CX23885_VMUX_COMPONENT,
160 CX23885_VMUX_TELEVISION, 163 CX23885_VMUX_TELEVISION,
161 CX23885_VMUX_CABLE, 164 CX23885_VMUX_CABLE,
162 CX23885_VMUX_DVB, 165 CX23885_VMUX_DVB,
@@ -297,10 +300,6 @@ struct cx23885_tsport {
297 /* Allow a single tsport to have multiple frontends */ 300 /* Allow a single tsport to have multiple frontends */
298 u32 num_frontends; 301 u32 num_frontends;
299 void *port_priv; 302 void *port_priv;
300
301 /* FIXME: temporary hack */
302 int (*set_frontend_save) (struct dvb_frontend *,
303 struct dvb_frontend_parameters *);
304}; 303};
305 304
306struct cx23885_dev { 305struct cx23885_dev {
@@ -356,6 +355,16 @@ struct cx23885_dev {
356 unsigned int has_radio; 355 unsigned int has_radio;
357 struct v4l2_subdev *sd_cx25840; 356 struct v4l2_subdev *sd_cx25840;
358 357
358 /* Infrared */
359 struct v4l2_subdev *sd_ir;
360 struct work_struct ir_rx_work;
361 unsigned long ir_rx_notifications;
362 struct work_struct ir_tx_work;
363 unsigned long ir_tx_notifications;
364
365 struct card_ir *ir_input;
366 atomic_t ir_input_stopping;
367
359 /* V4l */ 368 /* V4l */
360 u32 freq; 369 u32 freq;
361 struct video_device *video_dev; 370 struct video_device *video_dev;
@@ -383,6 +392,13 @@ static inline struct cx23885_dev *to_cx23885(struct v4l2_device *v4l2_dev)
383#define call_all(dev, o, f, args...) \ 392#define call_all(dev, o, f, args...) \
384 v4l2_device_call_all(&dev->v4l2_dev, 0, o, f, ##args) 393 v4l2_device_call_all(&dev->v4l2_dev, 0, o, f, ##args)
385 394
395#define CX23885_HW_888_IR (1 << 0)
396
397#define call_hw(dev, grpid, o, f, args...) \
398 v4l2_device_call_all(&dev->v4l2_dev, grpid, o, f, ##args)
399
400extern struct v4l2_subdev *cx23885_find_hw(struct cx23885_dev *dev, u32 hw);
401
386extern struct list_head cx23885_devlist; 402extern struct list_head cx23885_devlist;
387 403
388#define SRAM_CH01 0 /* Video A */ 404#define SRAM_CH01 0 /* Video A */
@@ -455,6 +471,7 @@ extern void cx23885_wakeup(struct cx23885_tsport *port,
455 471
456extern void cx23885_gpio_set(struct cx23885_dev *dev, u32 mask); 472extern void cx23885_gpio_set(struct cx23885_dev *dev, u32 mask);
457extern void cx23885_gpio_clear(struct cx23885_dev *dev, u32 mask); 473extern void cx23885_gpio_clear(struct cx23885_dev *dev, u32 mask);
474extern u32 cx23885_gpio_get(struct cx23885_dev *dev, u32 mask);
458extern void cx23885_gpio_enable(struct cx23885_dev *dev, u32 mask, 475extern void cx23885_gpio_enable(struct cx23885_dev *dev, u32 mask,
459 int asoutput); 476 int asoutput);
460 477
@@ -471,6 +488,8 @@ extern int cx23885_tuner_callback(void *priv, int component,
471 int command, int arg); 488 int command, int arg);
472extern void cx23885_card_list(struct cx23885_dev *dev); 489extern void cx23885_card_list(struct cx23885_dev *dev);
473extern int cx23885_ir_init(struct cx23885_dev *dev); 490extern int cx23885_ir_init(struct cx23885_dev *dev);
491extern void cx23885_ir_pci_int_enable(struct cx23885_dev *dev);
492extern void cx23885_ir_fini(struct cx23885_dev *dev);
474extern void cx23885_gpio_setup(struct cx23885_dev *dev); 493extern void cx23885_gpio_setup(struct cx23885_dev *dev);
475extern void cx23885_card_setup(struct cx23885_dev *dev); 494extern void cx23885_card_setup(struct cx23885_dev *dev);
476extern void cx23885_card_setup_pre_i2c(struct cx23885_dev *dev); 495extern void cx23885_card_setup_pre_i2c(struct cx23885_dev *dev);
@@ -515,6 +534,10 @@ extern void cx23885_417_check_encoder(struct cx23885_dev *dev);
515extern void cx23885_mc417_init(struct cx23885_dev *dev); 534extern void cx23885_mc417_init(struct cx23885_dev *dev);
516extern int mc417_memory_read(struct cx23885_dev *dev, u32 address, u32 *value); 535extern int mc417_memory_read(struct cx23885_dev *dev, u32 address, u32 *value);
517extern int mc417_memory_write(struct cx23885_dev *dev, u32 address, u32 value); 536extern int mc417_memory_write(struct cx23885_dev *dev, u32 address, u32 value);
537extern int mc417_register_read(struct cx23885_dev *dev,
538 u16 address, u32 *value);
539extern int mc417_register_write(struct cx23885_dev *dev,
540 u16 address, u32 value);
518extern void mc417_gpio_set(struct cx23885_dev *dev, u32 mask); 541extern void mc417_gpio_set(struct cx23885_dev *dev, u32 mask);
519extern void mc417_gpio_clear(struct cx23885_dev *dev, u32 mask); 542extern void mc417_gpio_clear(struct cx23885_dev *dev, u32 mask);
520extern void mc417_gpio_enable(struct cx23885_dev *dev, u32 mask, int asoutput); 543extern void mc417_gpio_enable(struct cx23885_dev *dev, u32 mask, int asoutput);
diff --git a/drivers/media/video/cx23885/cx23888-ir.c b/drivers/media/video/cx23885/cx23888-ir.c
new file mode 100644
index 000000000000..3ccc8afeccf3
--- /dev/null
+++ b/drivers/media/video/cx23885/cx23888-ir.c
@@ -0,0 +1,1239 @@
1/*
2 * Driver for the Conexant CX23885/7/8 PCIe bridge
3 *
4 * CX23888 Integrated Consumer Infrared Controller
5 *
6 * Copyright (C) 2009 Andy Walls <awalls@radix.net>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (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., 51 Franklin Street, Fifth Floor, Boston, MA
21 * 02110-1301, USA.
22 */
23
24#include <linux/kfifo.h>
25
26#include <media/v4l2-device.h>
27#include <media/v4l2-chip-ident.h>
28
29#include "cx23885.h"
30
31static unsigned int ir_888_debug;
32module_param(ir_888_debug, int, 0644);
33MODULE_PARM_DESC(ir_888_debug, "enable debug messages [CX23888 IR controller]");
34
35#define CX23888_IR_REG_BASE 0x170000
36/*
37 * These CX23888 register offsets have a straightforward one to one mapping
38 * to the CX23885 register offsets of 0x200 through 0x218
39 */
40#define CX23888_IR_CNTRL_REG 0x170000
41#define CNTRL_WIN_3_3 0x00000000
42#define CNTRL_WIN_4_3 0x00000001
43#define CNTRL_WIN_3_4 0x00000002
44#define CNTRL_WIN_4_4 0x00000003
45#define CNTRL_WIN 0x00000003
46#define CNTRL_EDG_NONE 0x00000000
47#define CNTRL_EDG_FALL 0x00000004
48#define CNTRL_EDG_RISE 0x00000008
49#define CNTRL_EDG_BOTH 0x0000000C
50#define CNTRL_EDG 0x0000000C
51#define CNTRL_DMD 0x00000010
52#define CNTRL_MOD 0x00000020
53#define CNTRL_RFE 0x00000040
54#define CNTRL_TFE 0x00000080
55#define CNTRL_RXE 0x00000100
56#define CNTRL_TXE 0x00000200
57#define CNTRL_RIC 0x00000400
58#define CNTRL_TIC 0x00000800
59#define CNTRL_CPL 0x00001000
60#define CNTRL_LBM 0x00002000
61#define CNTRL_R 0x00004000
62
63#define CX23888_IR_TXCLK_REG 0x170004
64#define TXCLK_TCD 0x0000FFFF
65
66#define CX23888_IR_RXCLK_REG 0x170008
67#define RXCLK_RCD 0x0000FFFF
68
69#define CX23888_IR_CDUTY_REG 0x17000C
70#define CDUTY_CDC 0x0000000F
71
72#define CX23888_IR_STATS_REG 0x170010
73#define STATS_RTO 0x00000001
74#define STATS_ROR 0x00000002
75#define STATS_RBY 0x00000004
76#define STATS_TBY 0x00000008
77#define STATS_RSR 0x00000010
78#define STATS_TSR 0x00000020
79
80#define CX23888_IR_IRQEN_REG 0x170014
81#define IRQEN_RTE 0x00000001
82#define IRQEN_ROE 0x00000002
83#define IRQEN_RSE 0x00000010
84#define IRQEN_TSE 0x00000020
85
86#define CX23888_IR_FILTR_REG 0x170018
87#define FILTR_LPF 0x0000FFFF
88
89/* This register doesn't follow the pattern; it's 0x23C on a CX23885 */
90#define CX23888_IR_FIFO_REG 0x170040
91#define FIFO_RXTX 0x0000FFFF
92#define FIFO_RXTX_LVL 0x00010000
93#define FIFO_RXTX_RTO 0x0001FFFF
94#define FIFO_RX_NDV 0x00020000
95#define FIFO_RX_DEPTH 8
96#define FIFO_TX_DEPTH 8
97
98/* CX23888 unique registers */
99#define CX23888_IR_SEEDP_REG 0x17001C
100#define CX23888_IR_TIMOL_REG 0x170020
101#define CX23888_IR_WAKE0_REG 0x170024
102#define CX23888_IR_WAKE1_REG 0x170028
103#define CX23888_IR_WAKE2_REG 0x17002C
104#define CX23888_IR_MASK0_REG 0x170030
105#define CX23888_IR_MASK1_REG 0x170034
106#define CX23888_IR_MAKS2_REG 0x170038
107#define CX23888_IR_DPIPG_REG 0x17003C
108#define CX23888_IR_LEARN_REG 0x170044
109
110#define CX23888_VIDCLK_FREQ 108000000 /* 108 MHz, BT.656 */
111#define CX23888_IR_REFCLK_FREQ (CX23888_VIDCLK_FREQ / 2)
112
113#define CX23888_IR_RX_KFIFO_SIZE (512 * sizeof(u32))
114#define CX23888_IR_TX_KFIFO_SIZE (512 * sizeof(u32))
115
116struct cx23888_ir_state {
117 struct v4l2_subdev sd;
118 struct cx23885_dev *dev;
119 u32 id;
120 u32 rev;
121
122 struct v4l2_subdev_ir_parameters rx_params;
123 struct mutex rx_params_lock;
124 atomic_t rxclk_divider;
125 atomic_t rx_invert;
126
127 struct kfifo *rx_kfifo;
128 spinlock_t rx_kfifo_lock;
129
130 struct v4l2_subdev_ir_parameters tx_params;
131 struct mutex tx_params_lock;
132 atomic_t txclk_divider;
133
134 struct kfifo *tx_kfifo;
135 spinlock_t tx_kfifo_lock;
136};
137
138static inline struct cx23888_ir_state *to_state(struct v4l2_subdev *sd)
139{
140 return v4l2_get_subdevdata(sd);
141}
142
143/*
144 * IR register block read and write functions
145 */
146static
147inline int cx23888_ir_write4(struct cx23885_dev *dev, u32 addr, u32 value)
148{
149 cx_write(addr, value);
150 return 0;
151}
152
153static inline u32 cx23888_ir_read4(struct cx23885_dev *dev, u32 addr)
154{
155 return cx_read(addr);
156}
157
158static inline int cx23888_ir_and_or4(struct cx23885_dev *dev, u32 addr,
159 u32 and_mask, u32 or_value)
160{
161 cx_andor(addr, ~and_mask, or_value);
162 return 0;
163}
164
165/*
166 * Rx and Tx Clock Divider register computations
167 *
168 * Note the largest clock divider value of 0xffff corresponds to:
169 * (0xffff + 1) * 1000 / 108/2 MHz = 1,213,629.629... ns
170 * which fits in 21 bits, so we'll use unsigned int for time arguments.
171 */
172static inline u16 count_to_clock_divider(unsigned int d)
173{
174 if (d > RXCLK_RCD + 1)
175 d = RXCLK_RCD;
176 else if (d < 2)
177 d = 1;
178 else
179 d--;
180 return (u16) d;
181}
182
183static inline u16 ns_to_clock_divider(unsigned int ns)
184{
185 return count_to_clock_divider(
186 DIV_ROUND_CLOSEST(CX23888_IR_REFCLK_FREQ / 1000000 * ns, 1000));
187}
188
189static inline unsigned int clock_divider_to_ns(unsigned int divider)
190{
191 /* Period of the Rx or Tx clock in ns */
192 return DIV_ROUND_CLOSEST((divider + 1) * 1000,
193 CX23888_IR_REFCLK_FREQ / 1000000);
194}
195
196static inline u16 carrier_freq_to_clock_divider(unsigned int freq)
197{
198 return count_to_clock_divider(
199 DIV_ROUND_CLOSEST(CX23888_IR_REFCLK_FREQ, freq * 16));
200}
201
202static inline unsigned int clock_divider_to_carrier_freq(unsigned int divider)
203{
204 return DIV_ROUND_CLOSEST(CX23888_IR_REFCLK_FREQ, (divider + 1) * 16);
205}
206
207static inline u16 freq_to_clock_divider(unsigned int freq,
208 unsigned int rollovers)
209{
210 return count_to_clock_divider(
211 DIV_ROUND_CLOSEST(CX23888_IR_REFCLK_FREQ, freq * rollovers));
212}
213
214static inline unsigned int clock_divider_to_freq(unsigned int divider,
215 unsigned int rollovers)
216{
217 return DIV_ROUND_CLOSEST(CX23888_IR_REFCLK_FREQ,
218 (divider + 1) * rollovers);
219}
220
221/*
222 * Low Pass Filter register calculations
223 *
224 * Note the largest count value of 0xffff corresponds to:
225 * 0xffff * 1000 / 108/2 MHz = 1,213,611.11... ns
226 * which fits in 21 bits, so we'll use unsigned int for time arguments.
227 */
228static inline u16 count_to_lpf_count(unsigned int d)
229{
230 if (d > FILTR_LPF)
231 d = FILTR_LPF;
232 else if (d < 4)
233 d = 0;
234 return (u16) d;
235}
236
237static inline u16 ns_to_lpf_count(unsigned int ns)
238{
239 return count_to_lpf_count(
240 DIV_ROUND_CLOSEST(CX23888_IR_REFCLK_FREQ / 1000000 * ns, 1000));
241}
242
243static inline unsigned int lpf_count_to_ns(unsigned int count)
244{
245 /* Duration of the Low Pass Filter rejection window in ns */
246 return DIV_ROUND_CLOSEST(count * 1000,
247 CX23888_IR_REFCLK_FREQ / 1000000);
248}
249
250static inline unsigned int lpf_count_to_us(unsigned int count)
251{
252 /* Duration of the Low Pass Filter rejection window in us */
253 return DIV_ROUND_CLOSEST(count, CX23888_IR_REFCLK_FREQ / 1000000);
254}
255
256/*
257 * FIFO register pulse width count compuations
258 */
259static u32 clock_divider_to_resolution(u16 divider)
260{
261 /*
262 * Resolution is the duration of 1 tick of the readable portion of
263 * of the pulse width counter as read from the FIFO. The two lsb's are
264 * not readable, hence the << 2. This function returns ns.
265 */
266 return DIV_ROUND_CLOSEST((1 << 2) * ((u32) divider + 1) * 1000,
267 CX23888_IR_REFCLK_FREQ / 1000000);
268}
269
270static u64 pulse_width_count_to_ns(u16 count, u16 divider)
271{
272 u64 n;
273 u32 rem;
274
275 /*
276 * The 2 lsb's of the pulse width timer count are not readable, hence
277 * the (count << 2) | 0x3
278 */
279 n = (((u64) count << 2) | 0x3) * (divider + 1) * 1000; /* millicycles */
280 rem = do_div(n, CX23888_IR_REFCLK_FREQ / 1000000); /* / MHz => ns */
281 if (rem >= CX23888_IR_REFCLK_FREQ / 1000000 / 2)
282 n++;
283 return n;
284}
285
286static unsigned int pulse_width_count_to_us(u16 count, u16 divider)
287{
288 u64 n;
289 u32 rem;
290
291 /*
292 * The 2 lsb's of the pulse width timer count are not readable, hence
293 * the (count << 2) | 0x3
294 */
295 n = (((u64) count << 2) | 0x3) * (divider + 1); /* cycles */
296 rem = do_div(n, CX23888_IR_REFCLK_FREQ / 1000000); /* / MHz => us */
297 if (rem >= CX23888_IR_REFCLK_FREQ / 1000000 / 2)
298 n++;
299 return (unsigned int) n;
300}
301
302/*
303 * Pulse Clocks computations: Combined Pulse Width Count & Rx Clock Counts
304 *
305 * The total pulse clock count is an 18 bit pulse width timer count as the most
306 * significant part and (up to) 16 bit clock divider count as a modulus.
307 * When the Rx clock divider ticks down to 0, it increments the 18 bit pulse
308 * width timer count's least significant bit.
309 */
310static u64 ns_to_pulse_clocks(u32 ns)
311{
312 u64 clocks;
313 u32 rem;
314 clocks = CX23888_IR_REFCLK_FREQ / 1000000 * (u64) ns; /* millicycles */
315 rem = do_div(clocks, 1000); /* /1000 = cycles */
316 if (rem >= 1000 / 2)
317 clocks++;
318 return clocks;
319}
320
321static u16 pulse_clocks_to_clock_divider(u64 count)
322{
323 u32 rem;
324
325 rem = do_div(count, (FIFO_RXTX << 2) | 0x3);
326
327 /* net result needs to be rounded down and decremented by 1 */
328 if (count > RXCLK_RCD + 1)
329 count = RXCLK_RCD;
330 else if (count < 2)
331 count = 1;
332 else
333 count--;
334 return (u16) count;
335}
336
337/*
338 * IR Control Register helpers
339 */
340enum tx_fifo_watermark {
341 TX_FIFO_HALF_EMPTY = 0,
342 TX_FIFO_EMPTY = CNTRL_TIC,
343};
344
345enum rx_fifo_watermark {
346 RX_FIFO_HALF_FULL = 0,
347 RX_FIFO_NOT_EMPTY = CNTRL_RIC,
348};
349
350static inline void control_tx_irq_watermark(struct cx23885_dev *dev,
351 enum tx_fifo_watermark level)
352{
353 cx23888_ir_and_or4(dev, CX23888_IR_CNTRL_REG, ~CNTRL_TIC, level);
354}
355
356static inline void control_rx_irq_watermark(struct cx23885_dev *dev,
357 enum rx_fifo_watermark level)
358{
359 cx23888_ir_and_or4(dev, CX23888_IR_CNTRL_REG, ~CNTRL_RIC, level);
360}
361
362static inline void control_tx_enable(struct cx23885_dev *dev, bool enable)
363{
364 cx23888_ir_and_or4(dev, CX23888_IR_CNTRL_REG, ~(CNTRL_TXE | CNTRL_TFE),
365 enable ? (CNTRL_TXE | CNTRL_TFE) : 0);
366}
367
368static inline void control_rx_enable(struct cx23885_dev *dev, bool enable)
369{
370 cx23888_ir_and_or4(dev, CX23888_IR_CNTRL_REG, ~(CNTRL_RXE | CNTRL_RFE),
371 enable ? (CNTRL_RXE | CNTRL_RFE) : 0);
372}
373
374static inline void control_tx_modulation_enable(struct cx23885_dev *dev,
375 bool enable)
376{
377 cx23888_ir_and_or4(dev, CX23888_IR_CNTRL_REG, ~CNTRL_MOD,
378 enable ? CNTRL_MOD : 0);
379}
380
381static inline void control_rx_demodulation_enable(struct cx23885_dev *dev,
382 bool enable)
383{
384 cx23888_ir_and_or4(dev, CX23888_IR_CNTRL_REG, ~CNTRL_DMD,
385 enable ? CNTRL_DMD : 0);
386}
387
388static inline void control_rx_s_edge_detection(struct cx23885_dev *dev,
389 u32 edge_types)
390{
391 cx23888_ir_and_or4(dev, CX23888_IR_CNTRL_REG, ~CNTRL_EDG_BOTH,
392 edge_types & CNTRL_EDG_BOTH);
393}
394
395static void control_rx_s_carrier_window(struct cx23885_dev *dev,
396 unsigned int carrier,
397 unsigned int *carrier_range_low,
398 unsigned int *carrier_range_high)
399{
400 u32 v;
401 unsigned int c16 = carrier * 16;
402
403 if (*carrier_range_low < DIV_ROUND_CLOSEST(c16, 16 + 3)) {
404 v = CNTRL_WIN_3_4;
405 *carrier_range_low = DIV_ROUND_CLOSEST(c16, 16 + 4);
406 } else {
407 v = CNTRL_WIN_3_3;
408 *carrier_range_low = DIV_ROUND_CLOSEST(c16, 16 + 3);
409 }
410
411 if (*carrier_range_high > DIV_ROUND_CLOSEST(c16, 16 - 3)) {
412 v |= CNTRL_WIN_4_3;
413 *carrier_range_high = DIV_ROUND_CLOSEST(c16, 16 - 4);
414 } else {
415 v |= CNTRL_WIN_3_3;
416 *carrier_range_high = DIV_ROUND_CLOSEST(c16, 16 - 3);
417 }
418 cx23888_ir_and_or4(dev, CX23888_IR_CNTRL_REG, ~CNTRL_WIN, v);
419}
420
421static inline void control_tx_polarity_invert(struct cx23885_dev *dev,
422 bool invert)
423{
424 cx23888_ir_and_or4(dev, CX23888_IR_CNTRL_REG, ~CNTRL_CPL,
425 invert ? CNTRL_CPL : 0);
426}
427
428/*
429 * IR Rx & Tx Clock Register helpers
430 */
431static unsigned int txclk_tx_s_carrier(struct cx23885_dev *dev,
432 unsigned int freq,
433 u16 *divider)
434{
435 *divider = carrier_freq_to_clock_divider(freq);
436 cx23888_ir_write4(dev, CX23888_IR_TXCLK_REG, *divider);
437 return clock_divider_to_carrier_freq(*divider);
438}
439
440static unsigned int rxclk_rx_s_carrier(struct cx23885_dev *dev,
441 unsigned int freq,
442 u16 *divider)
443{
444 *divider = carrier_freq_to_clock_divider(freq);
445 cx23888_ir_write4(dev, CX23888_IR_RXCLK_REG, *divider);
446 return clock_divider_to_carrier_freq(*divider);
447}
448
449static u32 txclk_tx_s_max_pulse_width(struct cx23885_dev *dev, u32 ns,
450 u16 *divider)
451{
452 u64 pulse_clocks;
453
454 if (ns > V4L2_SUBDEV_IR_PULSE_MAX_WIDTH_NS)
455 ns = V4L2_SUBDEV_IR_PULSE_MAX_WIDTH_NS;
456 pulse_clocks = ns_to_pulse_clocks(ns);
457 *divider = pulse_clocks_to_clock_divider(pulse_clocks);
458 cx23888_ir_write4(dev, CX23888_IR_TXCLK_REG, *divider);
459 return (u32) pulse_width_count_to_ns(FIFO_RXTX, *divider);
460}
461
462static u32 rxclk_rx_s_max_pulse_width(struct cx23885_dev *dev, u32 ns,
463 u16 *divider)
464{
465 u64 pulse_clocks;
466
467 if (ns > V4L2_SUBDEV_IR_PULSE_MAX_WIDTH_NS)
468 ns = V4L2_SUBDEV_IR_PULSE_MAX_WIDTH_NS;
469 pulse_clocks = ns_to_pulse_clocks(ns);
470 *divider = pulse_clocks_to_clock_divider(pulse_clocks);
471 cx23888_ir_write4(dev, CX23888_IR_RXCLK_REG, *divider);
472 return (u32) pulse_width_count_to_ns(FIFO_RXTX, *divider);
473}
474
475/*
476 * IR Tx Carrier Duty Cycle register helpers
477 */
478static unsigned int cduty_tx_s_duty_cycle(struct cx23885_dev *dev,
479 unsigned int duty_cycle)
480{
481 u32 n;
482 n = DIV_ROUND_CLOSEST(duty_cycle * 100, 625); /* 16ths of 100% */
483 if (n != 0)
484 n--;
485 if (n > 15)
486 n = 15;
487 cx23888_ir_write4(dev, CX23888_IR_CDUTY_REG, n);
488 return DIV_ROUND_CLOSEST((n + 1) * 100, 16);
489}
490
491/*
492 * IR Filter Register helpers
493 */
494static u32 filter_rx_s_min_width(struct cx23885_dev *dev, u32 min_width_ns)
495{
496 u32 count = ns_to_lpf_count(min_width_ns);
497 cx23888_ir_write4(dev, CX23888_IR_FILTR_REG, count);
498 return lpf_count_to_ns(count);
499}
500
501/*
502 * IR IRQ Enable Register helpers
503 */
504static inline void irqenable_rx(struct cx23885_dev *dev, u32 mask)
505{
506 mask &= (IRQEN_RTE | IRQEN_ROE | IRQEN_RSE);
507 cx23888_ir_and_or4(dev, CX23888_IR_IRQEN_REG,
508 ~(IRQEN_RTE | IRQEN_ROE | IRQEN_RSE), mask);
509}
510
511static inline void irqenable_tx(struct cx23885_dev *dev, u32 mask)
512{
513 mask &= IRQEN_TSE;
514 cx23888_ir_and_or4(dev, CX23888_IR_IRQEN_REG, ~IRQEN_TSE, mask);
515}
516
517/*
518 * V4L2 Subdevice IR Ops
519 */
520static int cx23888_ir_irq_handler(struct v4l2_subdev *sd, u32 status,
521 bool *handled)
522{
523 struct cx23888_ir_state *state = to_state(sd);
524 struct cx23885_dev *dev = state->dev;
525
526 u32 cntrl = cx23888_ir_read4(dev, CX23888_IR_CNTRL_REG);
527 u32 irqen = cx23888_ir_read4(dev, CX23888_IR_IRQEN_REG);
528 u32 stats = cx23888_ir_read4(dev, CX23888_IR_STATS_REG);
529
530 u32 rx_data[FIFO_RX_DEPTH];
531 int i, j, k;
532 u32 events, v;
533 int tsr, rsr, rto, ror, tse, rse, rte, roe, kror;
534
535 tsr = stats & STATS_TSR; /* Tx FIFO Service Request */
536 rsr = stats & STATS_RSR; /* Rx FIFO Service Request */
537 rto = stats & STATS_RTO; /* Rx Pulse Width Timer Time Out */
538 ror = stats & STATS_ROR; /* Rx FIFO Over Run */
539
540 tse = irqen & IRQEN_TSE; /* Tx FIFO Service Request IRQ Enable */
541 rse = irqen & IRQEN_RSE; /* Rx FIFO Service Reuqest IRQ Enable */
542 rte = irqen & IRQEN_RTE; /* Rx Pulse Width Timer Time Out IRQ Enable */
543 roe = irqen & IRQEN_ROE; /* Rx FIFO Over Run IRQ Enable */
544
545 *handled = false;
546 v4l2_dbg(2, ir_888_debug, sd, "IRQ Status: %s %s %s %s %s %s\n",
547 tsr ? "tsr" : " ", rsr ? "rsr" : " ",
548 rto ? "rto" : " ", ror ? "ror" : " ",
549 stats & STATS_TBY ? "tby" : " ",
550 stats & STATS_RBY ? "rby" : " ");
551
552 v4l2_dbg(2, ir_888_debug, sd, "IRQ Enables: %s %s %s %s\n",
553 tse ? "tse" : " ", rse ? "rse" : " ",
554 rte ? "rte" : " ", roe ? "roe" : " ");
555
556 /*
557 * Transmitter interrupt service
558 */
559 if (tse && tsr) {
560 /*
561 * TODO:
562 * Check the watermark threshold setting
563 * Pull FIFO_TX_DEPTH or FIFO_TX_DEPTH/2 entries from tx_kfifo
564 * Push the data to the hardware FIFO.
565 * If there was nothing more to send in the tx_kfifo, disable
566 * the TSR IRQ and notify the v4l2_device.
567 * If there was something in the tx_kfifo, check the tx_kfifo
568 * level and notify the v4l2_device, if it is low.
569 */
570 /* For now, inhibit TSR interrupt until Tx is implemented */
571 irqenable_tx(dev, 0);
572 events = V4L2_SUBDEV_IR_TX_FIFO_SERVICE_REQ;
573 v4l2_subdev_notify(sd, V4L2_SUBDEV_IR_TX_NOTIFY, &events);
574 *handled = true;
575 }
576
577 /*
578 * Receiver interrupt service
579 */
580 kror = 0;
581 if ((rse && rsr) || (rte && rto)) {
582 /*
583 * Receive data on RSR to clear the STATS_RSR.
584 * Receive data on RTO, since we may not have yet hit the RSR
585 * watermark when we receive the RTO.
586 */
587 for (i = 0, v = FIFO_RX_NDV;
588 (v & FIFO_RX_NDV) && !kror; i = 0) {
589 for (j = 0;
590 (v & FIFO_RX_NDV) && j < FIFO_RX_DEPTH; j++) {
591 v = cx23888_ir_read4(dev, CX23888_IR_FIFO_REG);
592 rx_data[i++] = v & ~FIFO_RX_NDV;
593 }
594 if (i == 0)
595 break;
596 j = i * sizeof(u32);
597 k = kfifo_put(state->rx_kfifo,
598 (unsigned char *) rx_data, j);
599 if (k != j)
600 kror++; /* rx_kfifo over run */
601 }
602 *handled = true;
603 }
604
605 events = 0;
606 v = 0;
607 if (kror) {
608 events |= V4L2_SUBDEV_IR_RX_SW_FIFO_OVERRUN;
609 v4l2_err(sd, "IR receiver software FIFO overrun\n");
610 }
611 if (roe && ror) {
612 /*
613 * The RX FIFO Enable (CNTRL_RFE) must be toggled to clear
614 * the Rx FIFO Over Run status (STATS_ROR)
615 */
616 v |= CNTRL_RFE;
617 events |= V4L2_SUBDEV_IR_RX_HW_FIFO_OVERRUN;
618 v4l2_err(sd, "IR receiver hardware FIFO overrun\n");
619 }
620 if (rte && rto) {
621 /*
622 * The IR Receiver Enable (CNTRL_RXE) must be toggled to clear
623 * the Rx Pulse Width Timer Time Out (STATS_RTO)
624 */
625 v |= CNTRL_RXE;
626 events |= V4L2_SUBDEV_IR_RX_END_OF_RX_DETECTED;
627 }
628 if (v) {
629 /* Clear STATS_ROR & STATS_RTO as needed by reseting hardware */
630 cx23888_ir_write4(dev, CX23888_IR_CNTRL_REG, cntrl & ~v);
631 cx23888_ir_write4(dev, CX23888_IR_CNTRL_REG, cntrl);
632 *handled = true;
633 }
634 if (kfifo_len(state->rx_kfifo) >= CX23888_IR_RX_KFIFO_SIZE / 2)
635 events |= V4L2_SUBDEV_IR_RX_FIFO_SERVICE_REQ;
636
637 if (events)
638 v4l2_subdev_notify(sd, V4L2_SUBDEV_IR_RX_NOTIFY, &events);
639 return 0;
640}
641
642/* Receiver */
643static int cx23888_ir_rx_read(struct v4l2_subdev *sd, u8 *buf, size_t count,
644 ssize_t *num)
645{
646 struct cx23888_ir_state *state = to_state(sd);
647 bool invert = (bool) atomic_read(&state->rx_invert);
648 u16 divider = (u16) atomic_read(&state->rxclk_divider);
649
650 unsigned int i, n;
651 u32 *p;
652 u32 u, v;
653
654 n = count / sizeof(u32) * sizeof(u32);
655 if (n == 0) {
656 *num = 0;
657 return 0;
658 }
659
660 n = kfifo_get(state->rx_kfifo, buf, n);
661
662 n /= sizeof(u32);
663 *num = n * sizeof(u32);
664
665 for (p = (u32 *) buf, i = 0; i < n; p++, i++) {
666 if ((*p & FIFO_RXTX_RTO) == FIFO_RXTX_RTO) {
667 *p = V4L2_SUBDEV_IR_PULSE_RX_SEQ_END;
668 v4l2_dbg(2, ir_888_debug, sd, "rx read: end of rx\n");
669 continue;
670 }
671
672 u = (*p & FIFO_RXTX_LVL) ? V4L2_SUBDEV_IR_PULSE_LEVEL_MASK : 0;
673 if (invert)
674 u = u ? 0 : V4L2_SUBDEV_IR_PULSE_LEVEL_MASK;
675
676 v = (u32) pulse_width_count_to_ns((u16) (*p & FIFO_RXTX),
677 divider);
678 if (v >= V4L2_SUBDEV_IR_PULSE_MAX_WIDTH_NS)
679 v = V4L2_SUBDEV_IR_PULSE_MAX_WIDTH_NS - 1;
680
681 *p = u | v;
682
683 v4l2_dbg(2, ir_888_debug, sd, "rx read: %10u ns %s\n",
684 v, u ? "mark" : "space");
685 }
686 return 0;
687}
688
689static int cx23888_ir_rx_g_parameters(struct v4l2_subdev *sd,
690 struct v4l2_subdev_ir_parameters *p)
691{
692 struct cx23888_ir_state *state = to_state(sd);
693 mutex_lock(&state->rx_params_lock);
694 memcpy(p, &state->rx_params, sizeof(struct v4l2_subdev_ir_parameters));
695 mutex_unlock(&state->rx_params_lock);
696 return 0;
697}
698
699static int cx23888_ir_rx_shutdown(struct v4l2_subdev *sd)
700{
701 struct cx23888_ir_state *state = to_state(sd);
702 struct cx23885_dev *dev = state->dev;
703
704 mutex_lock(&state->rx_params_lock);
705
706 /* Disable or slow down all IR Rx circuits and counters */
707 irqenable_rx(dev, 0);
708 control_rx_enable(dev, false);
709 control_rx_demodulation_enable(dev, false);
710 control_rx_s_edge_detection(dev, CNTRL_EDG_NONE);
711 filter_rx_s_min_width(dev, 0);
712 cx23888_ir_write4(dev, CX23888_IR_RXCLK_REG, RXCLK_RCD);
713
714 state->rx_params.shutdown = true;
715
716 mutex_unlock(&state->rx_params_lock);
717 return 0;
718}
719
720static int cx23888_ir_rx_s_parameters(struct v4l2_subdev *sd,
721 struct v4l2_subdev_ir_parameters *p)
722{
723 struct cx23888_ir_state *state = to_state(sd);
724 struct cx23885_dev *dev = state->dev;
725 struct v4l2_subdev_ir_parameters *o = &state->rx_params;
726 u16 rxclk_divider;
727
728 if (p->shutdown)
729 return cx23888_ir_rx_shutdown(sd);
730
731 if (p->mode != V4L2_SUBDEV_IR_MODE_PULSE_WIDTH)
732 return -ENOSYS;
733
734 mutex_lock(&state->rx_params_lock);
735
736 o->shutdown = p->shutdown;
737
738 o->mode = p->mode = V4L2_SUBDEV_IR_MODE_PULSE_WIDTH;
739
740 o->bytes_per_data_element = p->bytes_per_data_element = sizeof(u32);
741
742 /* Before we tweak the hardware, we have to disable the receiver */
743 irqenable_rx(dev, 0);
744 control_rx_enable(dev, false);
745
746 control_rx_demodulation_enable(dev, p->modulation);
747 o->modulation = p->modulation;
748
749 if (p->modulation) {
750 p->carrier_freq = rxclk_rx_s_carrier(dev, p->carrier_freq,
751 &rxclk_divider);
752
753 o->carrier_freq = p->carrier_freq;
754
755 o->duty_cycle = p->duty_cycle = 50;
756
757 control_rx_s_carrier_window(dev, p->carrier_freq,
758 &p->carrier_range_lower,
759 &p->carrier_range_upper);
760 o->carrier_range_lower = p->carrier_range_lower;
761 o->carrier_range_upper = p->carrier_range_upper;
762 } else {
763 p->max_pulse_width =
764 rxclk_rx_s_max_pulse_width(dev, p->max_pulse_width,
765 &rxclk_divider);
766 o->max_pulse_width = p->max_pulse_width;
767 }
768 atomic_set(&state->rxclk_divider, rxclk_divider);
769
770 p->noise_filter_min_width =
771 filter_rx_s_min_width(dev, p->noise_filter_min_width);
772 o->noise_filter_min_width = p->noise_filter_min_width;
773
774 p->resolution = clock_divider_to_resolution(rxclk_divider);
775 o->resolution = p->resolution;
776
777 /* FIXME - make this dependent on resolution for better performance */
778 control_rx_irq_watermark(dev, RX_FIFO_HALF_FULL);
779
780 control_rx_s_edge_detection(dev, CNTRL_EDG_BOTH);
781
782 o->invert = p->invert;
783 atomic_set(&state->rx_invert, p->invert);
784
785 o->interrupt_enable = p->interrupt_enable;
786 o->enable = p->enable;
787 if (p->enable) {
788 kfifo_reset(state->rx_kfifo);
789 if (p->interrupt_enable)
790 irqenable_rx(dev, IRQEN_RSE | IRQEN_RTE | IRQEN_ROE);
791 control_rx_enable(dev, p->enable);
792 }
793
794 mutex_unlock(&state->rx_params_lock);
795 return 0;
796}
797
798/* Transmitter */
799static int cx23888_ir_tx_write(struct v4l2_subdev *sd, u8 *buf, size_t count,
800 ssize_t *num)
801{
802 struct cx23888_ir_state *state = to_state(sd);
803 struct cx23885_dev *dev = state->dev;
804 /* For now enable the Tx FIFO Service interrupt & pretend we did work */
805 irqenable_tx(dev, IRQEN_TSE);
806 *num = count;
807 return 0;
808}
809
810static int cx23888_ir_tx_g_parameters(struct v4l2_subdev *sd,
811 struct v4l2_subdev_ir_parameters *p)
812{
813 struct cx23888_ir_state *state = to_state(sd);
814 mutex_lock(&state->tx_params_lock);
815 memcpy(p, &state->tx_params, sizeof(struct v4l2_subdev_ir_parameters));
816 mutex_unlock(&state->tx_params_lock);
817 return 0;
818}
819
820static int cx23888_ir_tx_shutdown(struct v4l2_subdev *sd)
821{
822 struct cx23888_ir_state *state = to_state(sd);
823 struct cx23885_dev *dev = state->dev;
824
825 mutex_lock(&state->tx_params_lock);
826
827 /* Disable or slow down all IR Tx circuits and counters */
828 irqenable_tx(dev, 0);
829 control_tx_enable(dev, false);
830 control_tx_modulation_enable(dev, false);
831 cx23888_ir_write4(dev, CX23888_IR_TXCLK_REG, TXCLK_TCD);
832
833 state->tx_params.shutdown = true;
834
835 mutex_unlock(&state->tx_params_lock);
836 return 0;
837}
838
839static int cx23888_ir_tx_s_parameters(struct v4l2_subdev *sd,
840 struct v4l2_subdev_ir_parameters *p)
841{
842 struct cx23888_ir_state *state = to_state(sd);
843 struct cx23885_dev *dev = state->dev;
844 struct v4l2_subdev_ir_parameters *o = &state->tx_params;
845 u16 txclk_divider;
846
847 if (p->shutdown)
848 return cx23888_ir_tx_shutdown(sd);
849
850 if (p->mode != V4L2_SUBDEV_IR_MODE_PULSE_WIDTH)
851 return -ENOSYS;
852
853 mutex_lock(&state->tx_params_lock);
854
855 o->shutdown = p->shutdown;
856
857 o->mode = p->mode = V4L2_SUBDEV_IR_MODE_PULSE_WIDTH;
858
859 o->bytes_per_data_element = p->bytes_per_data_element = sizeof(u32);
860
861 /* Before we tweak the hardware, we have to disable the transmitter */
862 irqenable_tx(dev, 0);
863 control_tx_enable(dev, false);
864
865 control_tx_modulation_enable(dev, p->modulation);
866 o->modulation = p->modulation;
867
868 if (p->modulation) {
869 p->carrier_freq = txclk_tx_s_carrier(dev, p->carrier_freq,
870 &txclk_divider);
871 o->carrier_freq = p->carrier_freq;
872
873 p->duty_cycle = cduty_tx_s_duty_cycle(dev, p->duty_cycle);
874 o->duty_cycle = p->duty_cycle;
875 } else {
876 p->max_pulse_width =
877 txclk_tx_s_max_pulse_width(dev, p->max_pulse_width,
878 &txclk_divider);
879 o->max_pulse_width = p->max_pulse_width;
880 }
881 atomic_set(&state->txclk_divider, txclk_divider);
882
883 p->resolution = clock_divider_to_resolution(txclk_divider);
884 o->resolution = p->resolution;
885
886 /* FIXME - make this dependent on resolution for better performance */
887 control_tx_irq_watermark(dev, TX_FIFO_HALF_EMPTY);
888
889 control_tx_polarity_invert(dev, p->invert);
890 o->invert = p->invert;
891
892 o->interrupt_enable = p->interrupt_enable;
893 o->enable = p->enable;
894 if (p->enable) {
895 kfifo_reset(state->tx_kfifo);
896 if (p->interrupt_enable)
897 irqenable_tx(dev, IRQEN_TSE);
898 control_tx_enable(dev, p->enable);
899 }
900
901 mutex_unlock(&state->tx_params_lock);
902 return 0;
903}
904
905
906/*
907 * V4L2 Subdevice Core Ops
908 */
909static int cx23888_ir_log_status(struct v4l2_subdev *sd)
910{
911 struct cx23888_ir_state *state = to_state(sd);
912 struct cx23885_dev *dev = state->dev;
913 char *s;
914 int i, j;
915
916 u32 cntrl = cx23888_ir_read4(dev, CX23888_IR_CNTRL_REG);
917 u32 txclk = cx23888_ir_read4(dev, CX23888_IR_TXCLK_REG) & TXCLK_TCD;
918 u32 rxclk = cx23888_ir_read4(dev, CX23888_IR_RXCLK_REG) & RXCLK_RCD;
919 u32 cduty = cx23888_ir_read4(dev, CX23888_IR_CDUTY_REG) & CDUTY_CDC;
920 u32 stats = cx23888_ir_read4(dev, CX23888_IR_STATS_REG);
921 u32 irqen = cx23888_ir_read4(dev, CX23888_IR_IRQEN_REG);
922 u32 filtr = cx23888_ir_read4(dev, CX23888_IR_FILTR_REG) & FILTR_LPF;
923
924 v4l2_info(sd, "IR Receiver:\n");
925 v4l2_info(sd, "\tEnabled: %s\n",
926 cntrl & CNTRL_RXE ? "yes" : "no");
927 v4l2_info(sd, "\tDemodulation from a carrier: %s\n",
928 cntrl & CNTRL_DMD ? "enabled" : "disabled");
929 v4l2_info(sd, "\tFIFO: %s\n",
930 cntrl & CNTRL_RFE ? "enabled" : "disabled");
931 switch (cntrl & CNTRL_EDG) {
932 case CNTRL_EDG_NONE:
933 s = "disabled";
934 break;
935 case CNTRL_EDG_FALL:
936 s = "falling edge";
937 break;
938 case CNTRL_EDG_RISE:
939 s = "rising edge";
940 break;
941 case CNTRL_EDG_BOTH:
942 s = "rising & falling edges";
943 break;
944 default:
945 s = "??? edge";
946 break;
947 }
948 v4l2_info(sd, "\tPulse timers' start/stop trigger: %s\n", s);
949 v4l2_info(sd, "\tFIFO data on pulse timer overflow: %s\n",
950 cntrl & CNTRL_R ? "not loaded" : "overflow marker");
951 v4l2_info(sd, "\tFIFO interrupt watermark: %s\n",
952 cntrl & CNTRL_RIC ? "not empty" : "half full or greater");
953 v4l2_info(sd, "\tLoopback mode: %s\n",
954 cntrl & CNTRL_LBM ? "loopback active" : "normal receive");
955 if (cntrl & CNTRL_DMD) {
956 v4l2_info(sd, "\tExpected carrier (16 clocks): %u Hz\n",
957 clock_divider_to_carrier_freq(rxclk));
958 switch (cntrl & CNTRL_WIN) {
959 case CNTRL_WIN_3_3:
960 i = 3;
961 j = 3;
962 break;
963 case CNTRL_WIN_4_3:
964 i = 4;
965 j = 3;
966 break;
967 case CNTRL_WIN_3_4:
968 i = 3;
969 j = 4;
970 break;
971 case CNTRL_WIN_4_4:
972 i = 4;
973 j = 4;
974 break;
975 default:
976 i = 0;
977 j = 0;
978 break;
979 }
980 v4l2_info(sd, "\tNext carrier edge window: 16 clocks "
981 "-%1d/+%1d, %u to %u Hz\n", i, j,
982 clock_divider_to_freq(rxclk, 16 + j),
983 clock_divider_to_freq(rxclk, 16 - i));
984 } else {
985 v4l2_info(sd, "\tMax measurable pulse width: %u us, "
986 "%llu ns\n",
987 pulse_width_count_to_us(FIFO_RXTX, rxclk),
988 pulse_width_count_to_ns(FIFO_RXTX, rxclk));
989 }
990 v4l2_info(sd, "\tLow pass filter: %s\n",
991 filtr ? "enabled" : "disabled");
992 if (filtr)
993 v4l2_info(sd, "\tMin acceptable pulse width (LPF): %u us, "
994 "%u ns\n",
995 lpf_count_to_us(filtr),
996 lpf_count_to_ns(filtr));
997 v4l2_info(sd, "\tPulse width timer timed-out: %s\n",
998 stats & STATS_RTO ? "yes" : "no");
999 v4l2_info(sd, "\tPulse width timer time-out intr: %s\n",
1000 irqen & IRQEN_RTE ? "enabled" : "disabled");
1001 v4l2_info(sd, "\tFIFO overrun: %s\n",
1002 stats & STATS_ROR ? "yes" : "no");
1003 v4l2_info(sd, "\tFIFO overrun interrupt: %s\n",
1004 irqen & IRQEN_ROE ? "enabled" : "disabled");
1005 v4l2_info(sd, "\tBusy: %s\n",
1006 stats & STATS_RBY ? "yes" : "no");
1007 v4l2_info(sd, "\tFIFO service requested: %s\n",
1008 stats & STATS_RSR ? "yes" : "no");
1009 v4l2_info(sd, "\tFIFO service request interrupt: %s\n",
1010 irqen & IRQEN_RSE ? "enabled" : "disabled");
1011
1012 v4l2_info(sd, "IR Transmitter:\n");
1013 v4l2_info(sd, "\tEnabled: %s\n",
1014 cntrl & CNTRL_TXE ? "yes" : "no");
1015 v4l2_info(sd, "\tModulation onto a carrier: %s\n",
1016 cntrl & CNTRL_MOD ? "enabled" : "disabled");
1017 v4l2_info(sd, "\tFIFO: %s\n",
1018 cntrl & CNTRL_TFE ? "enabled" : "disabled");
1019 v4l2_info(sd, "\tFIFO interrupt watermark: %s\n",
1020 cntrl & CNTRL_TIC ? "not empty" : "half full or less");
1021 v4l2_info(sd, "\tSignal polarity: %s\n",
1022 cntrl & CNTRL_CPL ? "0:mark 1:space" : "0:space 1:mark");
1023 if (cntrl & CNTRL_MOD) {
1024 v4l2_info(sd, "\tCarrier (16 clocks): %u Hz\n",
1025 clock_divider_to_carrier_freq(txclk));
1026 v4l2_info(sd, "\tCarrier duty cycle: %2u/16\n",
1027 cduty + 1);
1028 } else {
1029 v4l2_info(sd, "\tMax pulse width: %u us, "
1030 "%llu ns\n",
1031 pulse_width_count_to_us(FIFO_RXTX, txclk),
1032 pulse_width_count_to_ns(FIFO_RXTX, txclk));
1033 }
1034 v4l2_info(sd, "\tBusy: %s\n",
1035 stats & STATS_TBY ? "yes" : "no");
1036 v4l2_info(sd, "\tFIFO service requested: %s\n",
1037 stats & STATS_TSR ? "yes" : "no");
1038 v4l2_info(sd, "\tFIFO service request interrupt: %s\n",
1039 irqen & IRQEN_TSE ? "enabled" : "disabled");
1040
1041 return 0;
1042}
1043
1044static inline int cx23888_ir_dbg_match(const struct v4l2_dbg_match *match)
1045{
1046 return match->type == V4L2_CHIP_MATCH_HOST && match->addr == 2;
1047}
1048
1049static int cx23888_ir_g_chip_ident(struct v4l2_subdev *sd,
1050 struct v4l2_dbg_chip_ident *chip)
1051{
1052 struct cx23888_ir_state *state = to_state(sd);
1053
1054 if (cx23888_ir_dbg_match(&chip->match)) {
1055 chip->ident = state->id;
1056 chip->revision = state->rev;
1057 }
1058 return 0;
1059}
1060
1061#ifdef CONFIG_VIDEO_ADV_DEBUG
1062static int cx23888_ir_g_register(struct v4l2_subdev *sd,
1063 struct v4l2_dbg_register *reg)
1064{
1065 struct cx23888_ir_state *state = to_state(sd);
1066 u32 addr = CX23888_IR_REG_BASE + (u32) reg->reg;
1067
1068 if (!cx23888_ir_dbg_match(&reg->match))
1069 return -EINVAL;
1070 if ((addr & 0x3) != 0)
1071 return -EINVAL;
1072 if (addr < CX23888_IR_CNTRL_REG || addr > CX23888_IR_LEARN_REG)
1073 return -EINVAL;
1074 if (!capable(CAP_SYS_ADMIN))
1075 return -EPERM;
1076 reg->size = 4;
1077 reg->val = cx23888_ir_read4(state->dev, addr);
1078 return 0;
1079}
1080
1081static int cx23888_ir_s_register(struct v4l2_subdev *sd,
1082 struct v4l2_dbg_register *reg)
1083{
1084 struct cx23888_ir_state *state = to_state(sd);
1085 u32 addr = CX23888_IR_REG_BASE + (u32) reg->reg;
1086
1087 if (!cx23888_ir_dbg_match(&reg->match))
1088 return -EINVAL;
1089 if ((addr & 0x3) != 0)
1090 return -EINVAL;
1091 if (addr < CX23888_IR_CNTRL_REG || addr > CX23888_IR_LEARN_REG)
1092 return -EINVAL;
1093 if (!capable(CAP_SYS_ADMIN))
1094 return -EPERM;
1095 cx23888_ir_write4(state->dev, addr, reg->val);
1096 return 0;
1097}
1098#endif
1099
1100static const struct v4l2_subdev_core_ops cx23888_ir_core_ops = {
1101 .g_chip_ident = cx23888_ir_g_chip_ident,
1102 .log_status = cx23888_ir_log_status,
1103#ifdef CONFIG_VIDEO_ADV_DEBUG
1104 .g_register = cx23888_ir_g_register,
1105 .s_register = cx23888_ir_s_register,
1106#endif
1107};
1108
1109static const struct v4l2_subdev_ir_ops cx23888_ir_ir_ops = {
1110 .interrupt_service_routine = cx23888_ir_irq_handler,
1111
1112 .rx_read = cx23888_ir_rx_read,
1113 .rx_g_parameters = cx23888_ir_rx_g_parameters,
1114 .rx_s_parameters = cx23888_ir_rx_s_parameters,
1115
1116 .tx_write = cx23888_ir_tx_write,
1117 .tx_g_parameters = cx23888_ir_tx_g_parameters,
1118 .tx_s_parameters = cx23888_ir_tx_s_parameters,
1119};
1120
1121static const struct v4l2_subdev_ops cx23888_ir_controller_ops = {
1122 .core = &cx23888_ir_core_ops,
1123 .ir = &cx23888_ir_ir_ops,
1124};
1125
1126static const struct v4l2_subdev_ir_parameters default_rx_params = {
1127 .bytes_per_data_element = sizeof(u32),
1128 .mode = V4L2_SUBDEV_IR_MODE_PULSE_WIDTH,
1129
1130 .enable = false,
1131 .interrupt_enable = false,
1132 .shutdown = true,
1133
1134 .modulation = true,
1135 .carrier_freq = 36000, /* 36 kHz - RC-5, RC-6, and RC-6A carrier */
1136
1137 /* RC-5: 666,667 ns = 1/36 kHz * 32 cycles * 1 mark * 0.75 */
1138 /* RC-6A: 333,333 ns = 1/36 kHz * 16 cycles * 1 mark * 0.75 */
1139 .noise_filter_min_width = 333333, /* ns */
1140 .carrier_range_lower = 35000,
1141 .carrier_range_upper = 37000,
1142 .invert = false,
1143};
1144
1145static const struct v4l2_subdev_ir_parameters default_tx_params = {
1146 .bytes_per_data_element = sizeof(u32),
1147 .mode = V4L2_SUBDEV_IR_MODE_PULSE_WIDTH,
1148
1149 .enable = false,
1150 .interrupt_enable = false,
1151 .shutdown = true,
1152
1153 .modulation = true,
1154 .carrier_freq = 36000, /* 36 kHz - RC-5 carrier */
1155 .duty_cycle = 25, /* 25 % - RC-5 carrier */
1156 .invert = false,
1157};
1158
1159int cx23888_ir_probe(struct cx23885_dev *dev)
1160{
1161 struct cx23888_ir_state *state;
1162 struct v4l2_subdev *sd;
1163 struct v4l2_subdev_ir_parameters default_params;
1164 int ret;
1165
1166 state = kzalloc(sizeof(struct cx23888_ir_state), GFP_KERNEL);
1167 if (state == NULL)
1168 return -ENOMEM;
1169
1170 spin_lock_init(&state->rx_kfifo_lock);
1171 state->rx_kfifo = kfifo_alloc(CX23888_IR_RX_KFIFO_SIZE, GFP_KERNEL,
1172 &state->rx_kfifo_lock);
1173 if (state->rx_kfifo == NULL)
1174 return -ENOMEM;
1175
1176 spin_lock_init(&state->tx_kfifo_lock);
1177 state->tx_kfifo = kfifo_alloc(CX23888_IR_TX_KFIFO_SIZE, GFP_KERNEL,
1178 &state->tx_kfifo_lock);
1179 if (state->tx_kfifo == NULL) {
1180 kfifo_free(state->rx_kfifo);
1181 return -ENOMEM;
1182 }
1183
1184 state->dev = dev;
1185 state->id = V4L2_IDENT_CX23888_IR;
1186 state->rev = 0;
1187 sd = &state->sd;
1188
1189 v4l2_subdev_init(sd, &cx23888_ir_controller_ops);
1190 v4l2_set_subdevdata(sd, state);
1191 /* FIXME - fix the formatting of dev->v4l2_dev.name and use it */
1192 snprintf(sd->name, sizeof(sd->name), "%s/888-ir", dev->name);
1193 sd->grp_id = CX23885_HW_888_IR;
1194
1195 ret = v4l2_device_register_subdev(&dev->v4l2_dev, sd);
1196 if (ret == 0) {
1197 /*
1198 * Ensure no interrupts arrive from '888 specific conditions,
1199 * since we ignore them in this driver to have commonality with
1200 * similar IR controller cores.
1201 */
1202 cx23888_ir_write4(dev, CX23888_IR_IRQEN_REG, 0);
1203
1204 mutex_init(&state->rx_params_lock);
1205 memcpy(&default_params, &default_rx_params,
1206 sizeof(struct v4l2_subdev_ir_parameters));
1207 v4l2_subdev_call(sd, ir, rx_s_parameters, &default_params);
1208
1209 mutex_init(&state->tx_params_lock);
1210 memcpy(&default_params, &default_tx_params,
1211 sizeof(struct v4l2_subdev_ir_parameters));
1212 v4l2_subdev_call(sd, ir, tx_s_parameters, &default_params);
1213 } else {
1214 kfifo_free(state->rx_kfifo);
1215 kfifo_free(state->tx_kfifo);
1216 }
1217 return ret;
1218}
1219
1220int cx23888_ir_remove(struct cx23885_dev *dev)
1221{
1222 struct v4l2_subdev *sd;
1223 struct cx23888_ir_state *state;
1224
1225 sd = cx23885_find_hw(dev, CX23885_HW_888_IR);
1226 if (sd == NULL)
1227 return -ENODEV;
1228
1229 cx23888_ir_rx_shutdown(sd);
1230 cx23888_ir_tx_shutdown(sd);
1231
1232 state = to_state(sd);
1233 v4l2_device_unregister_subdev(sd);
1234 kfifo_free(state->rx_kfifo);
1235 kfifo_free(state->tx_kfifo);
1236 kfree(state);
1237 /* Nothing more to free() as state held the actual v4l2_subdev object */
1238 return 0;
1239}
diff --git a/drivers/media/video/cx23885/cx23888-ir.h b/drivers/media/video/cx23885/cx23888-ir.h
new file mode 100644
index 000000000000..3d446f9eb94b
--- /dev/null
+++ b/drivers/media/video/cx23885/cx23888-ir.h
@@ -0,0 +1,28 @@
1/*
2 * Driver for the Conexant CX23885/7/8 PCIe bridge
3 *
4 * CX23888 Integrated Consumer Infrared Controller
5 *
6 * Copyright (C) 2009 Andy Walls <awalls@radix.net>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (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., 51 Franklin Street, Fifth Floor, Boston, MA
21 * 02110-1301, USA.
22 */
23
24#ifndef _CX23888_IR_H_
25#define _CX23888_IR_H_
26int cx23888_ir_probe(struct cx23885_dev *dev);
27int cx23888_ir_remove(struct cx23885_dev *dev);
28#endif
diff --git a/drivers/media/video/cx25840/cx25840-audio.c b/drivers/media/video/cx25840/cx25840-audio.c
index 2f846f5e0f9f..45608d50529c 100644
--- a/drivers/media/video/cx25840/cx25840-audio.c
+++ b/drivers/media/video/cx25840/cx25840-audio.c
@@ -23,87 +23,137 @@
23 23
24#include "cx25840-core.h" 24#include "cx25840-core.h"
25 25
26static int set_audclk_freq(struct i2c_client *client, u32 freq) 26/*
27 * Note: The PLL and SRC parameters are based on a reference frequency that
28 * would ideally be:
29 *
30 * NTSC Color subcarrier freq * 8 = 4.5 MHz/286 * 455/2 * 8 = 28.63636363... MHz
31 *
32 * However, it's not the exact reference frequency that matters, only that the
33 * firmware and modules that comprise the driver for a particular board all
34 * use the same value (close to the ideal value).
35 *
36 * Comments below will note which reference frequency is assumed for various
37 * parameters. They will usually be one of
38 *
39 * ref_freq = 28.636360 MHz
40 * or
41 * ref_freq = 28.636363 MHz
42 */
43
44static int cx25840_set_audclk_freq(struct i2c_client *client, u32 freq)
27{ 45{
28 struct cx25840_state *state = to_state(i2c_get_clientdata(client)); 46 struct cx25840_state *state = to_state(i2c_get_clientdata(client));
29 47
30 if (freq != 32000 && freq != 44100 && freq != 48000)
31 return -EINVAL;
32
33 /* common for all inputs and rates */
34 /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x10 */
35 if (!state->is_cx23885 && !state->is_cx231xx)
36 cx25840_write(client, 0x127, 0x50);
37
38 if (state->aud_input != CX25840_AUDIO_SERIAL) { 48 if (state->aud_input != CX25840_AUDIO_SERIAL) {
39 switch (freq) { 49 switch (freq) {
40 case 32000: 50 case 32000:
41 if (state->is_cx23885) { 51 /*
42 /* We don't have register values 52 * VID_PLL Integer = 0x0f, VID_PLL Post Divider = 0x04
43 * so avoid destroying registers. */ 53 * AUX_PLL Integer = 0x06, AUX PLL Post Divider = 0x10
44 break; 54 */
45 } 55 cx25840_write4(client, 0x108, 0x1006040f);
46 56
47 if (!state->is_cx231xx) { 57 /*
48 /* VID_PLL and AUX_PLL */ 58 * VID_PLL Fraction (register 0x10c) = 0x2be2fe
49 cx25840_write4(client, 0x108, 0x1006040f); 59 * 28636360 * 0xf.15f17f0/4 = 108 MHz
50 60 * 432 MHz pre-postdivide
51 /* AUX_PLL_FRAC */ 61 */
52 cx25840_write4(client, 0x110, 0x01bb39ee); 62
53 } 63 /*
54 64 * AUX_PLL Fraction = 0x1bb39ee
55 if (state->is_cx25836) 65 * 28636363 * 0x6.dd9cf70/0x10 = 32000 * 384
66 * 196.6 MHz pre-postdivide
67 * FIXME < 200 MHz is out of specified valid range
68 * FIXME 28636363 ref_freq doesn't match VID PLL ref
69 */
70 cx25840_write4(client, 0x110, 0x01bb39ee);
71
72 /*
73 * SA_MCLK_SEL = 1
74 * SA_MCLK_DIV = 0x10 = 384/384 * AUX_PLL post dvivider
75 */
76 cx25840_write(client, 0x127, 0x50);
77
78 if (is_cx2583x(state))
56 break; 79 break;
57 80
58 /* src3/4/6_ctl = 0x0801f77f */ 81 /* src3/4/6_ctl */
82 /* 0x1.f77f = (4 * 28636360/8 * 2/455) / 32000 */
59 cx25840_write4(client, 0x900, 0x0801f77f); 83 cx25840_write4(client, 0x900, 0x0801f77f);
60 cx25840_write4(client, 0x904, 0x0801f77f); 84 cx25840_write4(client, 0x904, 0x0801f77f);
61 cx25840_write4(client, 0x90c, 0x0801f77f); 85 cx25840_write4(client, 0x90c, 0x0801f77f);
62 break; 86 break;
63 87
64 case 44100: 88 case 44100:
65 if (state->is_cx23885) { 89 /*
66 /* We don't have register values 90 * VID_PLL Integer = 0x0f, VID_PLL Post Divider = 0x04
67 * so avoid destroying registers. */ 91 * AUX_PLL Integer = 0x09, AUX PLL Post Divider = 0x10
92 */
93 cx25840_write4(client, 0x108, 0x1009040f);
94
95 /*
96 * VID_PLL Fraction (register 0x10c) = 0x2be2fe
97 * 28636360 * 0xf.15f17f0/4 = 108 MHz
98 * 432 MHz pre-postdivide
99 */
100
101 /*
102 * AUX_PLL Fraction = 0x0ec6bd6
103 * 28636363 * 0x9.7635eb0/0x10 = 44100 * 384
104 * 271 MHz pre-postdivide
105 * FIXME 28636363 ref_freq doesn't match VID PLL ref
106 */
107 cx25840_write4(client, 0x110, 0x00ec6bd6);
108
109 /*
110 * SA_MCLK_SEL = 1
111 * SA_MCLK_DIV = 0x10 = 384/384 * AUX_PLL post dvivider
112 */
113 cx25840_write(client, 0x127, 0x50);
114
115 if (is_cx2583x(state))
68 break; 116 break;
69 }
70
71 if (!state->is_cx231xx) {
72 /* VID_PLL and AUX_PLL */
73 cx25840_write4(client, 0x108, 0x1009040f);
74
75 /* AUX_PLL_FRAC */
76 cx25840_write4(client, 0x110, 0x00ec6bd6);
77 }
78 117
79 if (state->is_cx25836) 118 /* src3/4/6_ctl */
80 break; 119 /* 0x1.6d59 = (4 * 28636360/8 * 2/455) / 44100 */
81
82 /* src3/4/6_ctl = 0x08016d59 */
83 cx25840_write4(client, 0x900, 0x08016d59); 120 cx25840_write4(client, 0x900, 0x08016d59);
84 cx25840_write4(client, 0x904, 0x08016d59); 121 cx25840_write4(client, 0x904, 0x08016d59);
85 cx25840_write4(client, 0x90c, 0x08016d59); 122 cx25840_write4(client, 0x90c, 0x08016d59);
86 break; 123 break;
87 124
88 case 48000: 125 case 48000:
89 if (state->is_cx23885) { 126 /*
90 /* We don't have register values 127 * VID_PLL Integer = 0x0f, VID_PLL Post Divider = 0x04
91 * so avoid destroying registers. */ 128 * AUX_PLL Integer = 0x0a, AUX PLL Post Divider = 0x10
92 break; 129 */
93 } 130 cx25840_write4(client, 0x108, 0x100a040f);
94 131
95 if (!state->is_cx231xx) { 132 /*
96 /* VID_PLL and AUX_PLL */ 133 * VID_PLL Fraction (register 0x10c) = 0x2be2fe
97 cx25840_write4(client, 0x108, 0x100a040f); 134 * 28636360 * 0xf.15f17f0/4 = 108 MHz
98 135 * 432 MHz pre-postdivide
99 /* AUX_PLL_FRAC */ 136 */
100 cx25840_write4(client, 0x110, 0x0098d6e5); 137
101 } 138 /*
102 139 * AUX_PLL Fraction = 0x098d6e5
103 if (state->is_cx25836) 140 * 28636363 * 0xa.4c6b728/0x10 = 48000 * 384
141 * 295 MHz pre-postdivide
142 * FIXME 28636363 ref_freq doesn't match VID PLL ref
143 */
144 cx25840_write4(client, 0x110, 0x0098d6e5);
145
146 /*
147 * SA_MCLK_SEL = 1
148 * SA_MCLK_DIV = 0x10 = 384/384 * AUX_PLL post dvivider
149 */
150 cx25840_write(client, 0x127, 0x50);
151
152 if (is_cx2583x(state))
104 break; 153 break;
105 154
106 /* src3/4/6_ctl = 0x08014faa */ 155 /* src3/4/6_ctl */
156 /* 0x1.4faa = (4 * 28636360/8 * 2/455) / 48000 */
107 cx25840_write4(client, 0x900, 0x08014faa); 157 cx25840_write4(client, 0x900, 0x08014faa);
108 cx25840_write4(client, 0x904, 0x08014faa); 158 cx25840_write4(client, 0x904, 0x08014faa);
109 cx25840_write4(client, 0x90c, 0x08014faa); 159 cx25840_write4(client, 0x90c, 0x08014faa);
@@ -112,91 +162,249 @@ static int set_audclk_freq(struct i2c_client *client, u32 freq)
112 } else { 162 } else {
113 switch (freq) { 163 switch (freq) {
114 case 32000: 164 case 32000:
115 if (state->is_cx23885) { 165 /*
116 /* We don't have register values 166 * VID_PLL Integer = 0x0f, VID_PLL Post Divider = 0x04
117 * so avoid destroying registers. */ 167 * AUX_PLL Integer = 0x08, AUX PLL Post Divider = 0x1e
118 break; 168 */
119 } 169 cx25840_write4(client, 0x108, 0x1e08040f);
120 170
121 if (!state->is_cx231xx) { 171 /*
122 /* VID_PLL and AUX_PLL */ 172 * VID_PLL Fraction (register 0x10c) = 0x2be2fe
123 cx25840_write4(client, 0x108, 0x1e08040f); 173 * 28636360 * 0xf.15f17f0/4 = 108 MHz
124 174 * 432 MHz pre-postdivide
125 /* AUX_PLL_FRAC */ 175 */
126 cx25840_write4(client, 0x110, 0x012a0869); 176
127 } 177 /*
178 * AUX_PLL Fraction = 0x12a0869
179 * 28636363 * 0x8.9504348/0x1e = 32000 * 256
180 * 246 MHz pre-postdivide
181 * FIXME 28636363 ref_freq doesn't match VID PLL ref
182 */
183 cx25840_write4(client, 0x110, 0x012a0869);
184
185 /*
186 * SA_MCLK_SEL = 1
187 * SA_MCLK_DIV = 0x14 = 256/384 * AUX_PLL post dvivider
188 */
189 cx25840_write(client, 0x127, 0x54);
128 190
129 if (state->is_cx25836) 191 if (is_cx2583x(state))
130 break; 192 break;
131 193
132 /* src1_ctl = 0x08010000 */ 194 /* src1_ctl */
195 /* 0x1.0000 = 32000/32000 */
133 cx25840_write4(client, 0x8f8, 0x08010000); 196 cx25840_write4(client, 0x8f8, 0x08010000);
134 197
135 /* src3/4/6_ctl = 0x08020000 */ 198 /* src3/4/6_ctl */
199 /* 0x2.0000 = 2 * (32000/32000) */
136 cx25840_write4(client, 0x900, 0x08020000); 200 cx25840_write4(client, 0x900, 0x08020000);
137 cx25840_write4(client, 0x904, 0x08020000); 201 cx25840_write4(client, 0x904, 0x08020000);
138 cx25840_write4(client, 0x90c, 0x08020000); 202 cx25840_write4(client, 0x90c, 0x08020000);
139
140 /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x14 */
141 cx25840_write(client, 0x127, 0x54);
142 break; 203 break;
143 204
144 case 44100: 205 case 44100:
145 if (state->is_cx23885) { 206 /*
146 /* We don't have register values 207 * VID_PLL Integer = 0x0f, VID_PLL Post Divider = 0x04
147 * so avoid destroying registers. */ 208 * AUX_PLL Integer = 0x09, AUX PLL Post Divider = 0x18
148 break; 209 */
149 } 210 cx25840_write4(client, 0x108, 0x1809040f);
150 211
151 212 /*
152 if (!state->is_cx231xx) { 213 * VID_PLL Fraction (register 0x10c) = 0x2be2fe
153 /* VID_PLL and AUX_PLL */ 214 * 28636360 * 0xf.15f17f0/4 = 108 MHz
154 cx25840_write4(client, 0x108, 0x1809040f); 215 * 432 MHz pre-postdivide
155 216 */
156 /* AUX_PLL_FRAC */ 217
157 cx25840_write4(client, 0x110, 0x00ec6bd6); 218 /*
158 } 219 * AUX_PLL Fraction = 0x0ec6bd6
159 220 * 28636363 * 0x9.7635eb0/0x18 = 44100 * 256
160 if (state->is_cx25836) 221 * 271 MHz pre-postdivide
222 * FIXME 28636363 ref_freq doesn't match VID PLL ref
223 */
224 cx25840_write4(client, 0x110, 0x00ec6bd6);
225
226 /*
227 * SA_MCLK_SEL = 1
228 * SA_MCLK_DIV = 0x10 = 256/384 * AUX_PLL post dvivider
229 */
230 cx25840_write(client, 0x127, 0x50);
231
232 if (is_cx2583x(state))
161 break; 233 break;
162 234
163 /* src1_ctl = 0x08010000 */ 235 /* src1_ctl */
236 /* 0x1.60cd = 44100/32000 */
164 cx25840_write4(client, 0x8f8, 0x080160cd); 237 cx25840_write4(client, 0x8f8, 0x080160cd);
165 238
166 /* src3/4/6_ctl = 0x08020000 */ 239 /* src3/4/6_ctl */
240 /* 0x1.7385 = 2 * (32000/44100) */
167 cx25840_write4(client, 0x900, 0x08017385); 241 cx25840_write4(client, 0x900, 0x08017385);
168 cx25840_write4(client, 0x904, 0x08017385); 242 cx25840_write4(client, 0x904, 0x08017385);
169 cx25840_write4(client, 0x90c, 0x08017385); 243 cx25840_write4(client, 0x90c, 0x08017385);
170 break; 244 break;
171 245
172 case 48000: 246 case 48000:
173 if (!state->is_cx23885 && !state->is_cx231xx) { 247 /*
174 /* VID_PLL and AUX_PLL */ 248 * VID_PLL Integer = 0x0f, VID_PLL Post Divider = 0x04
175 cx25840_write4(client, 0x108, 0x180a040f); 249 * AUX_PLL Integer = 0x0a, AUX PLL Post Divider = 0x18
250 */
251 cx25840_write4(client, 0x108, 0x180a040f);
252
253 /*
254 * VID_PLL Fraction (register 0x10c) = 0x2be2fe
255 * 28636360 * 0xf.15f17f0/4 = 108 MHz
256 * 432 MHz pre-postdivide
257 */
258
259 /*
260 * AUX_PLL Fraction = 0x098d6e5
261 * 28636363 * 0xa.4c6b728/0x18 = 48000 * 256
262 * 295 MHz pre-postdivide
263 * FIXME 28636363 ref_freq doesn't match VID PLL ref
264 */
265 cx25840_write4(client, 0x110, 0x0098d6e5);
266
267 /*
268 * SA_MCLK_SEL = 1
269 * SA_MCLK_DIV = 0x10 = 256/384 * AUX_PLL post dvivider
270 */
271 cx25840_write(client, 0x127, 0x50);
272
273 if (is_cx2583x(state))
274 break;
176 275
177 /* AUX_PLL_FRAC */ 276 /* src1_ctl */
178 cx25840_write4(client, 0x110, 0x0098d6e5); 277 /* 0x1.8000 = 48000/32000 */
179 } 278 cx25840_write4(client, 0x8f8, 0x08018000);
180 279
181 if (state->is_cx25836) 280 /* src3/4/6_ctl */
182 break; 281 /* 0x1.5555 = 2 * (32000/48000) */
282 cx25840_write4(client, 0x900, 0x08015555);
283 cx25840_write4(client, 0x904, 0x08015555);
284 cx25840_write4(client, 0x90c, 0x08015555);
285 break;
286 }
287 }
288
289 state->audclk_freq = freq;
290
291 return 0;
292}
293
294static inline int cx25836_set_audclk_freq(struct i2c_client *client, u32 freq)
295{
296 return cx25840_set_audclk_freq(client, freq);
297}
298
299static int cx23885_set_audclk_freq(struct i2c_client *client, u32 freq)
300{
301 struct cx25840_state *state = to_state(i2c_get_clientdata(client));
302
303 if (state->aud_input != CX25840_AUDIO_SERIAL) {
304 switch (freq) {
305 case 32000:
306 case 44100:
307 case 48000:
308 /* We don't have register values
309 * so avoid destroying registers. */
310 /* FIXME return -EINVAL; */
311 break;
312 }
313 } else {
314 switch (freq) {
315 case 32000:
316 case 44100:
317 /* We don't have register values
318 * so avoid destroying registers. */
319 /* FIXME return -EINVAL; */
320 break;
321
322 case 48000:
323 /* src1_ctl */
324 /* 0x1.867c = 48000 / (2 * 28636360/8 * 2/455) */
325 cx25840_write4(client, 0x8f8, 0x0801867c);
326
327 /* src3/4/6_ctl */
328 /* 0x1.4faa = (4 * 28636360/8 * 2/455) / 48000 */
329 cx25840_write4(client, 0x900, 0x08014faa);
330 cx25840_write4(client, 0x904, 0x08014faa);
331 cx25840_write4(client, 0x90c, 0x08014faa);
332 break;
333 }
334 }
335
336 state->audclk_freq = freq;
337
338 return 0;
339}
340
341static int cx231xx_set_audclk_freq(struct i2c_client *client, u32 freq)
342{
343 struct cx25840_state *state = to_state(i2c_get_clientdata(client));
344
345 if (state->aud_input != CX25840_AUDIO_SERIAL) {
346 switch (freq) {
347 case 32000:
348 /* src3/4/6_ctl */
349 /* 0x1.f77f = (4 * 28636360/8 * 2/455) / 32000 */
350 cx25840_write4(client, 0x900, 0x0801f77f);
351 cx25840_write4(client, 0x904, 0x0801f77f);
352 cx25840_write4(client, 0x90c, 0x0801f77f);
353 break;
354
355 case 44100:
356 /* src3/4/6_ctl */
357 /* 0x1.6d59 = (4 * 28636360/8 * 2/455) / 44100 */
358 cx25840_write4(client, 0x900, 0x08016d59);
359 cx25840_write4(client, 0x904, 0x08016d59);
360 cx25840_write4(client, 0x90c, 0x08016d59);
361 break;
362
363 case 48000:
364 /* src3/4/6_ctl */
365 /* 0x1.4faa = (4 * 28636360/8 * 2/455) / 48000 */
366 cx25840_write4(client, 0x900, 0x08014faa);
367 cx25840_write4(client, 0x904, 0x08014faa);
368 cx25840_write4(client, 0x90c, 0x08014faa);
369 break;
370 }
371 } else {
372 switch (freq) {
373 /* FIXME These cases make different assumptions about audclk */
374 case 32000:
375 /* src1_ctl */
376 /* 0x1.0000 = 32000/32000 */
377 cx25840_write4(client, 0x8f8, 0x08010000);
183 378
184 if (!state->is_cx23885 && !state->is_cx231xx) { 379 /* src3/4/6_ctl */
185 /* src1_ctl */ 380 /* 0x2.0000 = 2 * (32000/32000) */
186 cx25840_write4(client, 0x8f8, 0x08018000); 381 cx25840_write4(client, 0x900, 0x08020000);
382 cx25840_write4(client, 0x904, 0x08020000);
383 cx25840_write4(client, 0x90c, 0x08020000);
384 break;
187 385
188 /* src3/4/6_ctl */ 386 case 44100:
189 cx25840_write4(client, 0x900, 0x08015555); 387 /* src1_ctl */
190 cx25840_write4(client, 0x904, 0x08015555); 388 /* 0x1.60cd = 44100/32000 */
191 cx25840_write4(client, 0x90c, 0x08015555); 389 cx25840_write4(client, 0x8f8, 0x080160cd);
192 } else {
193 390
194 cx25840_write4(client, 0x8f8, 0x0801867c); 391 /* src3/4/6_ctl */
392 /* 0x1.7385 = 2 * (32000/44100) */
393 cx25840_write4(client, 0x900, 0x08017385);
394 cx25840_write4(client, 0x904, 0x08017385);
395 cx25840_write4(client, 0x90c, 0x08017385);
396 break;
195 397
196 cx25840_write4(client, 0x900, 0x08014faa); 398 case 48000:
197 cx25840_write4(client, 0x904, 0x08014faa); 399 /* src1_ctl */
198 cx25840_write4(client, 0x90c, 0x08014faa); 400 /* 0x1.867c = 48000 / (2 * 28636360/8 * 2/455) */
199 } 401 cx25840_write4(client, 0x8f8, 0x0801867c);
402
403 /* src3/4/6_ctl */
404 /* 0x1.4faa = (4 * 28636360/8 * 2/455) / 48000 */
405 cx25840_write4(client, 0x900, 0x08014faa);
406 cx25840_write4(client, 0x904, 0x08014faa);
407 cx25840_write4(client, 0x90c, 0x08014faa);
200 break; 408 break;
201 } 409 }
202 } 410 }
@@ -206,6 +414,25 @@ static int set_audclk_freq(struct i2c_client *client, u32 freq)
206 return 0; 414 return 0;
207} 415}
208 416
417static int set_audclk_freq(struct i2c_client *client, u32 freq)
418{
419 struct cx25840_state *state = to_state(i2c_get_clientdata(client));
420
421 if (freq != 32000 && freq != 44100 && freq != 48000)
422 return -EINVAL;
423
424 if (is_cx231xx(state))
425 return cx231xx_set_audclk_freq(client, freq);
426
427 if (is_cx2388x(state))
428 return cx23885_set_audclk_freq(client, freq);
429
430 if (is_cx2583x(state))
431 return cx25836_set_audclk_freq(client, freq);
432
433 return cx25840_set_audclk_freq(client, freq);
434}
435
209void cx25840_audio_set_path(struct i2c_client *client) 436void cx25840_audio_set_path(struct i2c_client *client)
210{ 437{
211 struct cx25840_state *state = to_state(i2c_get_clientdata(client)); 438 struct cx25840_state *state = to_state(i2c_get_clientdata(client));
@@ -243,7 +470,7 @@ void cx25840_audio_set_path(struct i2c_client *client)
243 cx25840_and_or(client, 0x810, ~0x1, 0x00); 470 cx25840_and_or(client, 0x810, ~0x1, 0x00);
244 471
245 /* Ensure the controller is running when we exit */ 472 /* Ensure the controller is running when we exit */
246 if (state->is_cx23885 || state->is_cx231xx) 473 if (is_cx2388x(state) || is_cx231xx(state))
247 cx25840_and_or(client, 0x803, ~0x10, 0x10); 474 cx25840_and_or(client, 0x803, ~0x10, 0x10);
248} 475}
249 476
@@ -383,7 +610,7 @@ int cx25840_s_clock_freq(struct v4l2_subdev *sd, u32 freq)
383 struct cx25840_state *state = to_state(sd); 610 struct cx25840_state *state = to_state(sd);
384 int retval; 611 int retval;
385 612
386 if (!state->is_cx25836) 613 if (!is_cx2583x(state))
387 cx25840_and_or(client, 0x810, ~0x1, 1); 614 cx25840_and_or(client, 0x810, ~0x1, 1);
388 if (state->aud_input != CX25840_AUDIO_SERIAL) { 615 if (state->aud_input != CX25840_AUDIO_SERIAL) {
389 cx25840_and_or(client, 0x803, ~0x10, 0); 616 cx25840_and_or(client, 0x803, ~0x10, 0);
@@ -392,7 +619,7 @@ int cx25840_s_clock_freq(struct v4l2_subdev *sd, u32 freq)
392 retval = set_audclk_freq(client, freq); 619 retval = set_audclk_freq(client, freq);
393 if (state->aud_input != CX25840_AUDIO_SERIAL) 620 if (state->aud_input != CX25840_AUDIO_SERIAL)
394 cx25840_and_or(client, 0x803, ~0x10, 0x10); 621 cx25840_and_or(client, 0x803, ~0x10, 0x10);
395 if (!state->is_cx25836) 622 if (!is_cx2583x(state))
396 cx25840_and_or(client, 0x810, ~0x1, 0); 623 cx25840_and_or(client, 0x810, ~0x1, 0);
397 return retval; 624 return retval;
398} 625}
diff --git a/drivers/media/video/cx25840/cx25840-core.c b/drivers/media/video/cx25840/cx25840-core.c
index 1aeaf18a9bea..385ecd58f1c0 100644
--- a/drivers/media/video/cx25840/cx25840-core.c
+++ b/drivers/media/video/cx25840/cx25840-core.c
@@ -259,6 +259,13 @@ static void cx23885_initialize(struct i2c_client *client)
259 struct cx25840_state *state = to_state(i2c_get_clientdata(client)); 259 struct cx25840_state *state = to_state(i2c_get_clientdata(client));
260 struct workqueue_struct *q; 260 struct workqueue_struct *q;
261 261
262 /*
263 * Come out of digital power down
264 * The CX23888, at least, needs this, otherwise registers aside from
265 * 0x0-0x2 can't be read or written.
266 */
267 cx25840_write(client, 0x000, 0);
268
262 /* Internal Reset */ 269 /* Internal Reset */
263 cx25840_and_or(client, 0x102, ~0x01, 0x01); 270 cx25840_and_or(client, 0x102, ~0x01, 0x01);
264 cx25840_and_or(client, 0x102, ~0x01, 0x00); 271 cx25840_and_or(client, 0x102, ~0x01, 0x00);
@@ -269,18 +276,45 @@ static void cx23885_initialize(struct i2c_client *client)
269 /* DIF in reset? */ 276 /* DIF in reset? */
270 cx25840_write(client, 0x398, 0); 277 cx25840_write(client, 0x398, 0);
271 278
272 /* Trust the default xtal, no division */ 279 /*
273 /* This changes for the cx23888 products */ 280 * Trust the default xtal, no division
281 * '885: 28.636363... MHz
282 * '887: 25.000000 MHz
283 * '888: 50.000000 MHz
284 */
274 cx25840_write(client, 0x2, 0x76); 285 cx25840_write(client, 0x2, 0x76);
275 286
276 /* Bring down the regulator for AUX clk */ 287 /* Power up all the PLL's and DLL */
277 cx25840_write(client, 0x1, 0x40); 288 cx25840_write(client, 0x1, 0x40);
278 289
279 /* Sys PLL frac */ 290 /* Sys PLL */
280 cx25840_write4(client, 0x11c, 0x01d1744c); 291 switch (state->id) {
281 292 case V4L2_IDENT_CX23888_AV:
282 /* Sys PLL int */ 293 /*
283 cx25840_write4(client, 0x118, 0x00000416); 294 * 50.0 MHz * (0xb + 0xe8ba26/0x2000000)/4 = 5 * 28.636363 MHz
295 * 572.73 MHz before post divide
296 */
297 cx25840_write4(client, 0x11c, 0x00e8ba26);
298 cx25840_write4(client, 0x118, 0x0000040b);
299 break;
300 case V4L2_IDENT_CX23887_AV:
301 /*
302 * 25.0 MHz * (0x16 + 0x1d1744c/0x2000000)/4 = 5 * 28.636363 MHz
303 * 572.73 MHz before post divide
304 */
305 cx25840_write4(client, 0x11c, 0x01d1744c);
306 cx25840_write4(client, 0x118, 0x00000416);
307 break;
308 case V4L2_IDENT_CX23885_AV:
309 default:
310 /*
311 * 28.636363 MHz * (0x14 + 0x0/0x2000000)/4 = 5 * 28.636363 MHz
312 * 572.73 MHz before post divide
313 */
314 cx25840_write4(client, 0x11c, 0x00000000);
315 cx25840_write4(client, 0x118, 0x00000414);
316 break;
317 }
284 318
285 /* Disable DIF bypass */ 319 /* Disable DIF bypass */
286 cx25840_write4(client, 0x33c, 0x00000001); 320 cx25840_write4(client, 0x33c, 0x00000001);
@@ -288,11 +322,15 @@ static void cx23885_initialize(struct i2c_client *client)
288 /* DIF Src phase inc */ 322 /* DIF Src phase inc */
289 cx25840_write4(client, 0x340, 0x0df7df83); 323 cx25840_write4(client, 0x340, 0x0df7df83);
290 324
291 /* Vid PLL frac */ 325 /*
292 cx25840_write4(client, 0x10c, 0x01b6db7b); 326 * Vid PLL
293 327 * Setup for a BT.656 pixel clock of 13.5 Mpixels/second
294 /* Vid PLL int */ 328 *
295 cx25840_write4(client, 0x108, 0x00000512); 329 * 28.636363 MHz * (0xf + 0x02be2c9/0x2000000)/4 = 8 * 13.5 MHz
330 * 432.0 MHz before post divide
331 */
332 cx25840_write4(client, 0x10c, 0x002be2c9);
333 cx25840_write4(client, 0x108, 0x0000040f);
296 334
297 /* Luma */ 335 /* Luma */
298 cx25840_write4(client, 0x414, 0x00107d12); 336 cx25840_write4(client, 0x414, 0x00107d12);
@@ -300,11 +338,43 @@ static void cx23885_initialize(struct i2c_client *client)
300 /* Chroma */ 338 /* Chroma */
301 cx25840_write4(client, 0x420, 0x3d008282); 339 cx25840_write4(client, 0x420, 0x3d008282);
302 340
303 /* Aux PLL frac */ 341 /*
304 cx25840_write4(client, 0x114, 0x017dbf48); 342 * Aux PLL
305 343 * Initial setup for audio sample clock:
306 /* Aux PLL int */ 344 * 48 ksps, 16 bits/sample, x160 multiplier = 122.88 MHz
307 cx25840_write4(client, 0x110, 0x000a030e); 345 * Intial I2S output/master clock(?):
346 * 48 ksps, 16 bits/sample, x16 multiplier = 12.288 MHz
347 */
348 switch (state->id) {
349 case V4L2_IDENT_CX23888_AV:
350 /*
351 * 50.0 MHz * (0x7 + 0x0bedfa4/0x2000000)/3 = 122.88 MHz
352 * 368.64 MHz before post divide
353 * 122.88 MHz / 0xa = 12.288 MHz
354 */
355 cx25840_write4(client, 0x114, 0x00bedfa4);
356 cx25840_write4(client, 0x110, 0x000a0307);
357 break;
358 case V4L2_IDENT_CX23887_AV:
359 /*
360 * 25.0 MHz * (0xe + 0x17dbf48/0x2000000)/3 = 122.88 MHz
361 * 368.64 MHz before post divide
362 * 122.88 MHz / 0xa = 12.288 MHz
363 */
364 cx25840_write4(client, 0x114, 0x017dbf48);
365 cx25840_write4(client, 0x110, 0x000a030e);
366 break;
367 case V4L2_IDENT_CX23885_AV:
368 default:
369 /*
370 * 28.636363 MHz * (0xc + 0x1bf0c9e/0x2000000)/3 = 122.88 MHz
371 * 368.64 MHz before post divide
372 * 122.88 MHz / 0xa = 12.288 MHz
373 */
374 cx25840_write4(client, 0x114, 0x01bf0c9e);
375 cx25840_write4(client, 0x110, 0x000a030c);
376 break;
377 };
308 378
309 /* ADC2 input select */ 379 /* ADC2 input select */
310 cx25840_write(client, 0x102, 0x10); 380 cx25840_write(client, 0x102, 0x10);
@@ -494,7 +564,7 @@ void cx25840_std_setup(struct i2c_client *client)
494 } 564 }
495 565
496 /* DEBUG: Displays configured PLL frequency */ 566 /* DEBUG: Displays configured PLL frequency */
497 if (!state->is_cx231xx) { 567 if (!is_cx231xx(state)) {
498 pll_int = cx25840_read(client, 0x108); 568 pll_int = cx25840_read(client, 0x108);
499 pll_frac = cx25840_read4(client, 0x10c) & 0x1ffffff; 569 pll_frac = cx25840_read4(client, 0x10c) & 0x1ffffff;
500 pll_post = cx25840_read(client, 0x109); 570 pll_post = cx25840_read(client, 0x109);
@@ -615,13 +685,30 @@ static void input_change(struct i2c_client *client)
615 } 685 }
616 cx25840_write(client, 0x80b, 0x00); 686 cx25840_write(client, 0x80b, 0x00);
617 } else if (std & V4L2_STD_PAL) { 687 } else if (std & V4L2_STD_PAL) {
618 /* Follow tuner change procedure for PAL */ 688 /* Autodetect audio standard and audio system */
619 cx25840_write(client, 0x808, 0xff); 689 cx25840_write(client, 0x808, 0xff);
620 cx25840_write(client, 0x80b, 0x10); 690 /* Since system PAL-L is pretty much non-existant and
691 not used by any public broadcast network, force
692 6.5 MHz carrier to be interpreted as System DK,
693 this avoids DK audio detection instability */
694 cx25840_write(client, 0x80b, 0x00);
621 } else if (std & V4L2_STD_SECAM) { 695 } else if (std & V4L2_STD_SECAM) {
622 /* Select autodetect for SECAM */ 696 /* Autodetect audio standard and audio system */
623 cx25840_write(client, 0x808, 0xff); 697 cx25840_write(client, 0x808, 0xff);
624 cx25840_write(client, 0x80b, 0x10); 698 /* If only one of SECAM-DK / SECAM-L is required, then force
699 6.5MHz carrier, else autodetect it */
700 if ((std & V4L2_STD_SECAM_DK) &&
701 !(std & (V4L2_STD_SECAM_L | V4L2_STD_SECAM_LC))) {
702 /* 6.5 MHz carrier to be interpreted as System DK */
703 cx25840_write(client, 0x80b, 0x00);
704 } else if (!(std & V4L2_STD_SECAM_DK) &&
705 (std & (V4L2_STD_SECAM_L | V4L2_STD_SECAM_LC))) {
706 /* 6.5 MHz carrier to be interpreted as System L */
707 cx25840_write(client, 0x80b, 0x08);
708 } else {
709 /* 6.5 MHz carrier to be autodetected */
710 cx25840_write(client, 0x80b, 0x10);
711 }
625 } 712 }
626 713
627 cx25840_and_or(client, 0x810, ~0x01, 0); 714 cx25840_and_or(client, 0x810, ~0x01, 0);
@@ -633,6 +720,10 @@ static int set_input(struct i2c_client *client, enum cx25840_video_input vid_inp
633 struct cx25840_state *state = to_state(i2c_get_clientdata(client)); 720 struct cx25840_state *state = to_state(i2c_get_clientdata(client));
634 u8 is_composite = (vid_input >= CX25840_COMPOSITE1 && 721 u8 is_composite = (vid_input >= CX25840_COMPOSITE1 &&
635 vid_input <= CX25840_COMPOSITE8); 722 vid_input <= CX25840_COMPOSITE8);
723 u8 is_component = (vid_input & CX25840_COMPONENT_ON) ==
724 CX25840_COMPONENT_ON;
725 int luma = vid_input & 0xf0;
726 int chroma = vid_input & 0xf00;
636 u8 reg; 727 u8 reg;
637 728
638 v4l_dbg(1, cx25840_debug, client, 729 v4l_dbg(1, cx25840_debug, client,
@@ -645,18 +736,14 @@ static int set_input(struct i2c_client *client, enum cx25840_video_input vid_inp
645 reg = vid_input & 0xff; 736 reg = vid_input & 0xff;
646 if ((vid_input & CX25840_SVIDEO_ON) == CX25840_SVIDEO_ON) 737 if ((vid_input & CX25840_SVIDEO_ON) == CX25840_SVIDEO_ON)
647 is_composite = 0; 738 is_composite = 0;
648 else 739 else if ((vid_input & CX25840_COMPONENT_ON) == 0)
649 is_composite = 1; 740 is_composite = 1;
650 741
651 v4l_dbg(1, cx25840_debug, client, "mux cfg 0x%x comp=%d\n", 742 v4l_dbg(1, cx25840_debug, client, "mux cfg 0x%x comp=%d\n",
652 reg, is_composite); 743 reg, is_composite);
653 } else 744 } else if (is_composite) {
654 if (is_composite) {
655 reg = 0xf0 + (vid_input - CX25840_COMPOSITE1); 745 reg = 0xf0 + (vid_input - CX25840_COMPOSITE1);
656 } else { 746 } else {
657 int luma = vid_input & 0xf0;
658 int chroma = vid_input & 0xf00;
659
660 if ((vid_input & ~0xff0) || 747 if ((vid_input & ~0xff0) ||
661 luma < CX25840_SVIDEO_LUMA1 || luma > CX25840_SVIDEO_LUMA8 || 748 luma < CX25840_SVIDEO_LUMA1 || luma > CX25840_SVIDEO_LUMA8 ||
662 chroma < CX25840_SVIDEO_CHROMA4 || chroma > CX25840_SVIDEO_CHROMA8) { 749 chroma < CX25840_SVIDEO_CHROMA4 || chroma > CX25840_SVIDEO_CHROMA8) {
@@ -678,7 +765,7 @@ static int set_input(struct i2c_client *client, enum cx25840_video_input vid_inp
678 * configuration in reg (for the cx23885) so we have no 765 * configuration in reg (for the cx23885) so we have no
679 * need to attempt to flip bits for earlier av decoders. 766 * need to attempt to flip bits for earlier av decoders.
680 */ 767 */
681 if (!state->is_cx23885 && !state->is_cx231xx) { 768 if (!is_cx2388x(state) && !is_cx231xx(state)) {
682 switch (aud_input) { 769 switch (aud_input) {
683 case CX25840_AUDIO_SERIAL: 770 case CX25840_AUDIO_SERIAL:
684 /* do nothing, use serial audio input */ 771 /* do nothing, use serial audio input */
@@ -698,10 +785,13 @@ static int set_input(struct i2c_client *client, enum cx25840_video_input vid_inp
698 785
699 cx25840_write(client, 0x103, reg); 786 cx25840_write(client, 0x103, reg);
700 787
701 /* Set INPUT_MODE to Composite (0) or S-Video (1) */ 788 /* Set INPUT_MODE to Composite, S-Video or Component */
702 cx25840_and_or(client, 0x401, ~0x6, is_composite ? 0 : 0x02); 789 if (is_component)
790 cx25840_and_or(client, 0x401, ~0x6, 0x6);
791 else
792 cx25840_and_or(client, 0x401, ~0x6, is_composite ? 0 : 0x02);
703 793
704 if (!state->is_cx23885 && !state->is_cx231xx) { 794 if (!is_cx2388x(state) && !is_cx231xx(state)) {
705 /* Set CH_SEL_ADC2 to 1 if input comes from CH3 */ 795 /* Set CH_SEL_ADC2 to 1 if input comes from CH3 */
706 cx25840_and_or(client, 0x102, ~0x2, (reg & 0x80) == 0 ? 2 : 0); 796 cx25840_and_or(client, 0x102, ~0x2, (reg & 0x80) == 0 ? 2 : 0);
707 /* Set DUAL_MODE_ADC2 to 1 if input comes from both CH2&CH3 */ 797 /* Set DUAL_MODE_ADC2 to 1 if input comes from both CH2&CH3 */
@@ -710,22 +800,31 @@ static int set_input(struct i2c_client *client, enum cx25840_video_input vid_inp
710 else 800 else
711 cx25840_and_or(client, 0x102, ~0x4, 0); 801 cx25840_and_or(client, 0x102, ~0x4, 0);
712 } else { 802 } else {
713 if (is_composite) 803 /* Set DUAL_MODE_ADC2 to 1 if component*/
804 cx25840_and_or(client, 0x102, ~0x4, is_component ? 0x4 : 0x0);
805 if (is_composite) {
714 /* ADC2 input select channel 2 */ 806 /* ADC2 input select channel 2 */
715 cx25840_and_or(client, 0x102, ~0x2, 0); 807 cx25840_and_or(client, 0x102, ~0x2, 0);
716 else 808 } else if (!is_component) {
717 /* ADC2 input select channel 3 */ 809 /* S-Video */
718 cx25840_and_or(client, 0x102, ~0x2, 2); 810 if (chroma >= CX25840_SVIDEO_CHROMA7) {
811 /* ADC2 input select channel 3 */
812 cx25840_and_or(client, 0x102, ~0x2, 2);
813 } else {
814 /* ADC2 input select channel 2 */
815 cx25840_and_or(client, 0x102, ~0x2, 0);
816 }
817 }
719 } 818 }
720 819
721 state->vid_input = vid_input; 820 state->vid_input = vid_input;
722 state->aud_input = aud_input; 821 state->aud_input = aud_input;
723 if (!state->is_cx25836) { 822 if (!is_cx2583x(state)) {
724 cx25840_audio_set_path(client); 823 cx25840_audio_set_path(client);
725 input_change(client); 824 input_change(client);
726 } 825 }
727 826
728 if (state->is_cx23885) { 827 if (is_cx2388x(state)) {
729 /* Audio channel 1 src : Parallel 1 */ 828 /* Audio channel 1 src : Parallel 1 */
730 cx25840_write(client, 0x124, 0x03); 829 cx25840_write(client, 0x124, 0x03);
731 830
@@ -741,7 +840,7 @@ static int set_input(struct i2c_client *client, enum cx25840_video_input vid_inp
741 */ 840 */
742 cx25840_write(client, 0x918, 0xa0); 841 cx25840_write(client, 0x918, 0xa0);
743 cx25840_write(client, 0x919, 0x01); 842 cx25840_write(client, 0x919, 0x01);
744 } else if (state->is_cx231xx) { 843 } else if (is_cx231xx(state)) {
745 /* Audio channel 1 src : Parallel 1 */ 844 /* Audio channel 1 src : Parallel 1 */
746 cx25840_write(client, 0x124, 0x03); 845 cx25840_write(client, 0x124, 0x03);
747 846
@@ -805,7 +904,7 @@ static int set_v4lstd(struct i2c_client *client)
805 cx25840_and_or(client, 0x400, ~0xf, fmt); 904 cx25840_and_or(client, 0x400, ~0xf, fmt);
806 cx25840_and_or(client, 0x403, ~0x3, pal_m); 905 cx25840_and_or(client, 0x403, ~0x3, pal_m);
807 cx25840_std_setup(client); 906 cx25840_std_setup(client);
808 if (!state->is_cx25836) 907 if (!is_cx2583x(state))
809 input_change(client); 908 input_change(client);
810 return 0; 909 return 0;
811} 910}
@@ -868,7 +967,7 @@ static int cx25840_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
868 case V4L2_CID_AUDIO_TREBLE: 967 case V4L2_CID_AUDIO_TREBLE:
869 case V4L2_CID_AUDIO_BALANCE: 968 case V4L2_CID_AUDIO_BALANCE:
870 case V4L2_CID_AUDIO_MUTE: 969 case V4L2_CID_AUDIO_MUTE:
871 if (state->is_cx25836) 970 if (is_cx2583x(state))
872 return -EINVAL; 971 return -EINVAL;
873 return cx25840_audio_s_ctrl(sd, ctrl); 972 return cx25840_audio_s_ctrl(sd, ctrl);
874 973
@@ -905,7 +1004,7 @@ static int cx25840_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
905 case V4L2_CID_AUDIO_TREBLE: 1004 case V4L2_CID_AUDIO_TREBLE:
906 case V4L2_CID_AUDIO_BALANCE: 1005 case V4L2_CID_AUDIO_BALANCE:
907 case V4L2_CID_AUDIO_MUTE: 1006 case V4L2_CID_AUDIO_MUTE:
908 if (state->is_cx25836) 1007 if (is_cx2583x(state))
909 return -EINVAL; 1008 return -EINVAL;
910 return cx25840_audio_g_ctrl(sd, ctrl); 1009 return cx25840_audio_g_ctrl(sd, ctrl);
911 default: 1010 default:
@@ -1209,11 +1308,11 @@ static int cx25840_load_fw(struct v4l2_subdev *sd)
1209 if (!state->is_initialized) { 1308 if (!state->is_initialized) {
1210 /* initialize and load firmware */ 1309 /* initialize and load firmware */
1211 state->is_initialized = 1; 1310 state->is_initialized = 1;
1212 if (state->is_cx25836) 1311 if (is_cx2583x(state))
1213 cx25836_initialize(client); 1312 cx25836_initialize(client);
1214 else if (state->is_cx23885) 1313 else if (is_cx2388x(state))
1215 cx23885_initialize(client); 1314 cx23885_initialize(client);
1216 else if (state->is_cx231xx) 1315 else if (is_cx231xx(state))
1217 cx231xx_initialize(client); 1316 cx231xx_initialize(client);
1218 else 1317 else
1219 cx25840_initialize(client); 1318 cx25840_initialize(client);
@@ -1256,17 +1355,17 @@ static int cx25840_s_stream(struct v4l2_subdev *sd, int enable)
1256 v4l_dbg(1, cx25840_debug, client, "%s output\n", 1355 v4l_dbg(1, cx25840_debug, client, "%s output\n",
1257 enable ? "enable" : "disable"); 1356 enable ? "enable" : "disable");
1258 if (enable) { 1357 if (enable) {
1259 if (state->is_cx23885 || state->is_cx231xx) { 1358 if (is_cx2388x(state) || is_cx231xx(state)) {
1260 u8 v = (cx25840_read(client, 0x421) | 0x0b); 1359 u8 v = (cx25840_read(client, 0x421) | 0x0b);
1261 cx25840_write(client, 0x421, v); 1360 cx25840_write(client, 0x421, v);
1262 } else { 1361 } else {
1263 cx25840_write(client, 0x115, 1362 cx25840_write(client, 0x115,
1264 state->is_cx25836 ? 0x0c : 0x8c); 1363 is_cx2583x(state) ? 0x0c : 0x8c);
1265 cx25840_write(client, 0x116, 1364 cx25840_write(client, 0x116,
1266 state->is_cx25836 ? 0x04 : 0x07); 1365 is_cx2583x(state) ? 0x04 : 0x07);
1267 } 1366 }
1268 } else { 1367 } else {
1269 if (state->is_cx23885 || state->is_cx231xx) { 1368 if (is_cx2388x(state) || is_cx231xx(state)) {
1270 u8 v = cx25840_read(client, 0x421) & ~(0x0b); 1369 u8 v = cx25840_read(client, 0x421) & ~(0x0b);
1271 cx25840_write(client, 0x421, v); 1370 cx25840_write(client, 0x421, v);
1272 } else { 1371 } else {
@@ -1292,7 +1391,7 @@ static int cx25840_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
1292 default: 1391 default:
1293 break; 1392 break;
1294 } 1393 }
1295 if (state->is_cx25836) 1394 if (is_cx2583x(state))
1296 return -EINVAL; 1395 return -EINVAL;
1297 1396
1298 switch (qc->id) { 1397 switch (qc->id) {
@@ -1346,7 +1445,7 @@ static int cx25840_s_audio_routing(struct v4l2_subdev *sd,
1346 struct cx25840_state *state = to_state(sd); 1445 struct cx25840_state *state = to_state(sd);
1347 struct i2c_client *client = v4l2_get_subdevdata(sd); 1446 struct i2c_client *client = v4l2_get_subdevdata(sd);
1348 1447
1349 if (state->is_cx25836) 1448 if (is_cx2583x(state))
1350 return -EINVAL; 1449 return -EINVAL;
1351 return set_input(client, state->vid_input, input); 1450 return set_input(client, state->vid_input, input);
1352} 1451}
@@ -1356,7 +1455,7 @@ static int cx25840_s_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *fr
1356 struct cx25840_state *state = to_state(sd); 1455 struct cx25840_state *state = to_state(sd);
1357 struct i2c_client *client = v4l2_get_subdevdata(sd); 1456 struct i2c_client *client = v4l2_get_subdevdata(sd);
1358 1457
1359 if (!state->is_cx25836) 1458 if (!is_cx2583x(state))
1360 input_change(client); 1459 input_change(client);
1361 return 0; 1460 return 0;
1362} 1461}
@@ -1373,7 +1472,7 @@ static int cx25840_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
1373 return 0; 1472 return 0;
1374 1473
1375 vt->signal = vpres ? 0xffff : 0x0; 1474 vt->signal = vpres ? 0xffff : 0x0;
1376 if (state->is_cx25836) 1475 if (is_cx2583x(state))
1377 return 0; 1476 return 0;
1378 1477
1379 vt->capability |= 1478 vt->capability |=
@@ -1404,7 +1503,7 @@ static int cx25840_s_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
1404 struct cx25840_state *state = to_state(sd); 1503 struct cx25840_state *state = to_state(sd);
1405 struct i2c_client *client = v4l2_get_subdevdata(sd); 1504 struct i2c_client *client = v4l2_get_subdevdata(sd);
1406 1505
1407 if (state->radio || state->is_cx25836) 1506 if (state->radio || is_cx2583x(state))
1408 return 0; 1507 return 0;
1409 1508
1410 switch (vt->audmode) { 1509 switch (vt->audmode) {
@@ -1445,11 +1544,11 @@ static int cx25840_reset(struct v4l2_subdev *sd, u32 val)
1445 struct cx25840_state *state = to_state(sd); 1544 struct cx25840_state *state = to_state(sd);
1446 struct i2c_client *client = v4l2_get_subdevdata(sd); 1545 struct i2c_client *client = v4l2_get_subdevdata(sd);
1447 1546
1448 if (state->is_cx25836) 1547 if (is_cx2583x(state))
1449 cx25836_initialize(client); 1548 cx25836_initialize(client);
1450 else if (state->is_cx23885) 1549 else if (is_cx2388x(state))
1451 cx23885_initialize(client); 1550 cx23885_initialize(client);
1452 else if (state->is_cx231xx) 1551 else if (is_cx231xx(state))
1453 cx231xx_initialize(client); 1552 cx231xx_initialize(client);
1454 else 1553 else
1455 cx25840_initialize(client); 1554 cx25840_initialize(client);
@@ -1470,7 +1569,7 @@ static int cx25840_log_status(struct v4l2_subdev *sd)
1470 struct i2c_client *client = v4l2_get_subdevdata(sd); 1569 struct i2c_client *client = v4l2_get_subdevdata(sd);
1471 1570
1472 log_video_status(client); 1571 log_video_status(client);
1473 if (!state->is_cx25836) 1572 if (!is_cx2583x(state))
1474 log_audio_status(client); 1573 log_audio_status(client);
1475 return 0; 1574 return 0;
1476} 1575}
@@ -1521,12 +1620,50 @@ static const struct v4l2_subdev_ops cx25840_ops = {
1521 1620
1522/* ----------------------------------------------------------------------- */ 1621/* ----------------------------------------------------------------------- */
1523 1622
1623static u32 get_cx2388x_ident(struct i2c_client *client)
1624{
1625 u32 ret;
1626
1627 /* Come out of digital power down */
1628 cx25840_write(client, 0x000, 0);
1629
1630 /* Detecting whether the part is cx23885/7/8 is more
1631 * difficult than it needs to be. No ID register. Instead we
1632 * probe certain registers indicated in the datasheets to look
1633 * for specific defaults that differ between the silicon designs. */
1634
1635 /* It's either 885/7 if the IR Tx Clk Divider register exists */
1636 if (cx25840_read4(client, 0x204) & 0xffff) {
1637 /* CX23885 returns bogus repetitive byte values for the DIF,
1638 * which doesn't exist for it. (Ex. 8a8a8a8a or 31313131) */
1639 ret = cx25840_read4(client, 0x300);
1640 if (((ret & 0xffff0000) >> 16) == (ret & 0xffff)) {
1641 /* No DIF */
1642 ret = V4L2_IDENT_CX23885_AV;
1643 } else {
1644 /* CX23887 has a broken DIF, but the registers
1645 * appear valid (but unsed), good enough to detect. */
1646 ret = V4L2_IDENT_CX23887_AV;
1647 }
1648 } else if (cx25840_read4(client, 0x300) & 0x0fffffff) {
1649 /* DIF PLL Freq Word reg exists; chip must be a CX23888 */
1650 ret = V4L2_IDENT_CX23888_AV;
1651 } else {
1652 v4l_err(client, "Unable to detect h/w, assuming cx23887\n");
1653 ret = V4L2_IDENT_CX23887_AV;
1654 }
1655
1656 /* Back into digital power down */
1657 cx25840_write(client, 0x000, 2);
1658 return ret;
1659}
1660
1524static int cx25840_probe(struct i2c_client *client, 1661static int cx25840_probe(struct i2c_client *client,
1525 const struct i2c_device_id *did) 1662 const struct i2c_device_id *did)
1526{ 1663{
1527 struct cx25840_state *state; 1664 struct cx25840_state *state;
1528 struct v4l2_subdev *sd; 1665 struct v4l2_subdev *sd;
1529 u32 id; 1666 u32 id = V4L2_IDENT_NONE;
1530 u16 device_id; 1667 u16 device_id;
1531 1668
1532 /* Check if the adapter supports the needed features */ 1669 /* Check if the adapter supports the needed features */
@@ -1543,17 +1680,22 @@ static int cx25840_probe(struct i2c_client *client,
1543 * 0x83 for the cx2583x and 0x84 for the cx2584x */ 1680 * 0x83 for the cx2583x and 0x84 for the cx2584x */
1544 if ((device_id & 0xff00) == 0x8300) { 1681 if ((device_id & 0xff00) == 0x8300) {
1545 id = V4L2_IDENT_CX25836 + ((device_id >> 4) & 0xf) - 6; 1682 id = V4L2_IDENT_CX25836 + ((device_id >> 4) & 0xf) - 6;
1546 } 1683 } else if ((device_id & 0xff00) == 0x8400) {
1547 else if ((device_id & 0xff00) == 0x8400) {
1548 id = V4L2_IDENT_CX25840 + ((device_id >> 4) & 0xf); 1684 id = V4L2_IDENT_CX25840 + ((device_id >> 4) & 0xf);
1549 } else if (device_id == 0x0000) { 1685 } else if (device_id == 0x0000) {
1550 id = V4L2_IDENT_CX25836 + ((device_id >> 4) & 0xf) - 6; 1686 id = get_cx2388x_ident(client);
1551 } else if (device_id == 0x1313) {
1552 id = V4L2_IDENT_CX25836 + ((device_id >> 4) & 0xf) - 6;
1553 } else if ((device_id & 0xfff0) == 0x5A30) { 1687 } else if ((device_id & 0xfff0) == 0x5A30) {
1554 id = V4L2_IDENT_CX25840 + ((device_id >> 4) & 0xf); 1688 /* The CX23100 (0x5A3C = 23100) doesn't have an A/V decoder */
1555 } 1689 id = V4L2_IDENT_CX2310X_AV;
1556 else { 1690 } else if ((device_id & 0xff) == (device_id >> 8)) {
1691 v4l_err(client,
1692 "likely a confused/unresponsive cx2388[578] A/V decoder"
1693 " found @ 0x%x (%s)\n",
1694 client->addr << 1, client->adapter->name);
1695 v4l_err(client, "A method to reset it from the cx25840 driver"
1696 " software is not known at this time\n");
1697 return -ENODEV;
1698 } else {
1557 v4l_dbg(1, cx25840_debug, client, "cx25840 not found\n"); 1699 v4l_dbg(1, cx25840_debug, client, "cx25840 not found\n");
1558 return -ENODEV; 1700 return -ENODEV;
1559 } 1701 }
@@ -1564,17 +1706,45 @@ static int cx25840_probe(struct i2c_client *client,
1564 1706
1565 sd = &state->sd; 1707 sd = &state->sd;
1566 v4l2_i2c_subdev_init(sd, client, &cx25840_ops); 1708 v4l2_i2c_subdev_init(sd, client, &cx25840_ops);
1567 /* Note: revision '(device_id & 0x0f) == 2' was never built. The 1709 switch (id) {
1568 marking skips from 0x1 == 22 to 0x3 == 23. */ 1710 case V4L2_IDENT_CX23885_AV:
1569 v4l_info(client, "cx25%3x-2%x found @ 0x%x (%s)\n", 1711 v4l_info(client, "cx23885 A/V decoder found @ 0x%x (%s)\n",
1570 (device_id & 0xfff0) >> 4, 1712 client->addr << 1, client->adapter->name);
1571 (device_id & 0x0f) < 3 ? (device_id & 0x0f) + 1 : (device_id & 0x0f), 1713 break;
1572 client->addr << 1, client->adapter->name); 1714 case V4L2_IDENT_CX23887_AV:
1715 v4l_info(client, "cx23887 A/V decoder found @ 0x%x (%s)\n",
1716 client->addr << 1, client->adapter->name);
1717 break;
1718 case V4L2_IDENT_CX23888_AV:
1719 v4l_info(client, "cx23888 A/V decoder found @ 0x%x (%s)\n",
1720 client->addr << 1, client->adapter->name);
1721 break;
1722 case V4L2_IDENT_CX2310X_AV:
1723 v4l_info(client, "cx%d A/V decoder found @ 0x%x (%s)\n",
1724 device_id, client->addr << 1, client->adapter->name);
1725 break;
1726 case V4L2_IDENT_CX25840:
1727 case V4L2_IDENT_CX25841:
1728 case V4L2_IDENT_CX25842:
1729 case V4L2_IDENT_CX25843:
1730 /* Note: revision '(device_id & 0x0f) == 2' was never built. The
1731 marking skips from 0x1 == 22 to 0x3 == 23. */
1732 v4l_info(client, "cx25%3x-2%x found @ 0x%x (%s)\n",
1733 (device_id & 0xfff0) >> 4,
1734 (device_id & 0x0f) < 3 ? (device_id & 0x0f) + 1
1735 : (device_id & 0x0f),
1736 client->addr << 1, client->adapter->name);
1737 break;
1738 case V4L2_IDENT_CX25836:
1739 case V4L2_IDENT_CX25837:
1740 default:
1741 v4l_info(client, "cx25%3x-%x found @ 0x%x (%s)\n",
1742 (device_id & 0xfff0) >> 4, device_id & 0x0f,
1743 client->addr << 1, client->adapter->name);
1744 break;
1745 }
1573 1746
1574 state->c = client; 1747 state->c = client;
1575 state->is_cx25836 = ((device_id & 0xff00) == 0x8300);
1576 state->is_cx23885 = (device_id == 0x0000) || (device_id == 0x1313);
1577 state->is_cx231xx = (device_id == 0x5a3e);
1578 state->vid_input = CX25840_COMPOSITE7; 1748 state->vid_input = CX25840_COMPOSITE7;
1579 state->aud_input = CX25840_AUDIO8; 1749 state->aud_input = CX25840_AUDIO8;
1580 state->audclk_freq = 48000; 1750 state->audclk_freq = 48000;
diff --git a/drivers/media/video/cx25840/cx25840-core.h b/drivers/media/video/cx25840/cx25840-core.h
index 814b56536994..55345444417f 100644
--- a/drivers/media/video/cx25840/cx25840-core.h
+++ b/drivers/media/video/cx25840/cx25840-core.h
@@ -23,6 +23,7 @@
23 23
24#include <linux/videodev2.h> 24#include <linux/videodev2.h>
25#include <media/v4l2-device.h> 25#include <media/v4l2-device.h>
26#include <media/v4l2-chip-ident.h>
26#include <linux/i2c.h> 27#include <linux/i2c.h>
27 28
28/* ENABLE_PVR150_WORKAROUND activates a workaround for a hardware bug that is 29/* ENABLE_PVR150_WORKAROUND activates a workaround for a hardware bug that is
@@ -48,9 +49,6 @@ struct cx25840_state {
48 int vbi_line_offset; 49 int vbi_line_offset;
49 u32 id; 50 u32 id;
50 u32 rev; 51 u32 rev;
51 int is_cx25836;
52 int is_cx23885;
53 int is_cx231xx;
54 int is_initialized; 52 int is_initialized;
55 wait_queue_head_t fw_wait; /* wake up when the fw load is finished */ 53 wait_queue_head_t fw_wait; /* wake up when the fw load is finished */
56 struct work_struct fw_work; /* work entry for fw load */ 54 struct work_struct fw_work; /* work entry for fw load */
@@ -61,6 +59,24 @@ static inline struct cx25840_state *to_state(struct v4l2_subdev *sd)
61 return container_of(sd, struct cx25840_state, sd); 59 return container_of(sd, struct cx25840_state, sd);
62} 60}
63 61
62static inline bool is_cx2583x(struct cx25840_state *state)
63{
64 return state->id == V4L2_IDENT_CX25836 ||
65 state->id == V4L2_IDENT_CX25837;
66}
67
68static inline bool is_cx231xx(struct cx25840_state *state)
69{
70 return state->id == V4L2_IDENT_CX2310X_AV;
71}
72
73static inline bool is_cx2388x(struct cx25840_state *state)
74{
75 return state->id == V4L2_IDENT_CX23885_AV ||
76 state->id == V4L2_IDENT_CX23887_AV ||
77 state->id == V4L2_IDENT_CX23888_AV;
78}
79
64/* ----------------------------------------------------------------------- */ 80/* ----------------------------------------------------------------------- */
65/* cx25850-core.c */ 81/* cx25850-core.c */
66int cx25840_write(struct i2c_client *client, u16 addr, u8 value); 82int cx25840_write(struct i2c_client *client, u16 addr, u8 value);
diff --git a/drivers/media/video/cx25840/cx25840-firmware.c b/drivers/media/video/cx25840/cx25840-firmware.c
index 1f483c1d0dbe..8150200511da 100644
--- a/drivers/media/video/cx25840/cx25840-firmware.c
+++ b/drivers/media/video/cx25840/cx25840-firmware.c
@@ -67,9 +67,9 @@ static const char *get_fw_name(struct i2c_client *client)
67 67
68 if (firmware[0]) 68 if (firmware[0])
69 return firmware; 69 return firmware;
70 if (state->is_cx23885) 70 if (is_cx2388x(state))
71 return "v4l-cx23885-avcore-01.fw"; 71 return "v4l-cx23885-avcore-01.fw";
72 if (state->is_cx231xx) 72 if (is_cx231xx(state))
73 return "v4l-cx231xx-avcore-01.fw"; 73 return "v4l-cx231xx-avcore-01.fw";
74 return "v4l-cx25840.fw"; 74 return "v4l-cx25840.fw";
75} 75}
@@ -112,13 +112,13 @@ int cx25840_loadfw(struct i2c_client *client)
112 int MAX_BUF_SIZE = FWSEND; 112 int MAX_BUF_SIZE = FWSEND;
113 u32 gpio_oe = 0, gpio_da = 0; 113 u32 gpio_oe = 0, gpio_da = 0;
114 114
115 if (state->is_cx23885) { 115 if (is_cx2388x(state)) {
116 /* Preserve the GPIO OE and output bits */ 116 /* Preserve the GPIO OE and output bits */
117 gpio_oe = cx25840_read(client, 0x160); 117 gpio_oe = cx25840_read(client, 0x160);
118 gpio_da = cx25840_read(client, 0x164); 118 gpio_da = cx25840_read(client, 0x164);
119 } 119 }
120 120
121 if ((state->is_cx231xx) && MAX_BUF_SIZE > 16) { 121 if (is_cx231xx(state) && MAX_BUF_SIZE > 16) {
122 v4l_err(client, " Firmware download size changed to 16 bytes max length\n"); 122 v4l_err(client, " Firmware download size changed to 16 bytes max length\n");
123 MAX_BUF_SIZE = 16; /* cx231xx cannot accept more than 16 bytes at a time */ 123 MAX_BUF_SIZE = 16; /* cx231xx cannot accept more than 16 bytes at a time */
124 } 124 }
@@ -156,7 +156,7 @@ int cx25840_loadfw(struct i2c_client *client)
156 size = fw->size; 156 size = fw->size;
157 release_firmware(fw); 157 release_firmware(fw);
158 158
159 if (state->is_cx23885) { 159 if (is_cx2388x(state)) {
160 /* Restore GPIO configuration after f/w load */ 160 /* Restore GPIO configuration after f/w load */
161 cx25840_write(client, 0x160, gpio_oe); 161 cx25840_write(client, 0x160, gpio_oe);
162 cx25840_write(client, 0x164, gpio_da); 162 cx25840_write(client, 0x164, gpio_da);
diff --git a/drivers/media/video/cx88/Kconfig b/drivers/media/video/cx88/Kconfig
index 49952980dab3..c7e5851d3486 100644
--- a/drivers/media/video/cx88/Kconfig
+++ b/drivers/media/video/cx88/Kconfig
@@ -61,6 +61,8 @@ config VIDEO_CX88_DVB
61 select DVB_STV0299 if !DVB_FE_CUSTOMISE 61 select DVB_STV0299 if !DVB_FE_CUSTOMISE
62 select DVB_STV0288 if !DVB_FE_CUSTOMISE 62 select DVB_STV0288 if !DVB_FE_CUSTOMISE
63 select DVB_STB6000 if !DVB_FE_CUSTOMISE 63 select DVB_STB6000 if !DVB_FE_CUSTOMISE
64 select DVB_STV0900 if !DVB_FE_CUSTOMISE
65 select DVB_STB6100 if !DVB_FE_CUSTOMISE
64 select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMISE 66 select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMISE
65 ---help--- 67 ---help---
66 This adds support for DVB/ATSC cards based on the 68 This adds support for DVB/ATSC cards based on the
diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c
index 33be6369871a..d844f2aaa01d 100644
--- a/drivers/media/video/cx88/cx88-cards.c
+++ b/drivers/media/video/cx88/cx88-cards.c
@@ -2075,6 +2075,18 @@ static const struct cx88_board cx88_boards[] = {
2075 }, 2075 },
2076 .mpeg = CX88_MPEG_DVB, 2076 .mpeg = CX88_MPEG_DVB,
2077 }, 2077 },
2078 [CX88_BOARD_PROF_7301] = {
2079 .name = "Prof 7301 DVB-S/S2",
2080 .tuner_type = UNSET,
2081 .radio_type = UNSET,
2082 .tuner_addr = ADDR_UNSET,
2083 .radio_addr = ADDR_UNSET,
2084 .input = { {
2085 .type = CX88_VMUX_DVB,
2086 .vmux = 0,
2087 } },
2088 .mpeg = CX88_MPEG_DVB,
2089 },
2078}; 2090};
2079 2091
2080/* ------------------------------------------------------------------ */ 2092/* ------------------------------------------------------------------ */
@@ -2535,6 +2547,10 @@ static const struct cx88_subid cx88_subids[] = {
2535 .subvendor = 0x107d, 2547 .subvendor = 0x107d,
2536 .subdevice = 0x6618, 2548 .subdevice = 0x6618,
2537 .card = CX88_BOARD_WINFAST_TV2000_XP_GLOBAL, 2549 .card = CX88_BOARD_WINFAST_TV2000_XP_GLOBAL,
2550 }, {
2551 .subvendor = 0xb034,
2552 .subdevice = 0x3034,
2553 .card = CX88_BOARD_PROF_7301,
2538 }, 2554 },
2539}; 2555};
2540 2556
@@ -3211,6 +3227,7 @@ static void cx88_card_setup(struct cx88_core *core)
3211 case CX88_BOARD_TBS_8920: 3227 case CX88_BOARD_TBS_8920:
3212 case CX88_BOARD_PROF_6200: 3228 case CX88_BOARD_PROF_6200:
3213 case CX88_BOARD_PROF_7300: 3229 case CX88_BOARD_PROF_7300:
3230 case CX88_BOARD_PROF_7301:
3214 case CX88_BOARD_SATTRADE_ST4200: 3231 case CX88_BOARD_SATTRADE_ST4200:
3215 cx_write(MO_GP0_IO, 0x8000); 3232 cx_write(MO_GP0_IO, 0x8000);
3216 msleep(100); 3233 msleep(100);
@@ -3267,7 +3284,7 @@ static void cx88_card_setup(struct cx88_core *core)
3267 ctl.fname); 3284 ctl.fname);
3268 call_all(core, tuner, s_config, &xc2028_cfg); 3285 call_all(core, tuner, s_config, &xc2028_cfg);
3269 } 3286 }
3270 call_all(core, tuner, s_standby); 3287 call_all(core, core, s_power, 0);
3271} 3288}
3272 3289
3273/* ------------------------------------------------------------------ */ 3290/* ------------------------------------------------------------------ */
diff --git a/drivers/media/video/cx88/cx88-dvb.c b/drivers/media/video/cx88/cx88-dvb.c
index 518bcfe18bcb..b14296923250 100644
--- a/drivers/media/video/cx88/cx88-dvb.c
+++ b/drivers/media/video/cx88/cx88-dvb.c
@@ -53,6 +53,9 @@
53#include "stv0288.h" 53#include "stv0288.h"
54#include "stb6000.h" 54#include "stb6000.h"
55#include "cx24116.h" 55#include "cx24116.h"
56#include "stv0900.h"
57#include "stb6100.h"
58#include "stb6100_proc.h"
56 59
57MODULE_DESCRIPTION("driver for cx2388x based DVB cards"); 60MODULE_DESCRIPTION("driver for cx2388x based DVB cards");
58MODULE_AUTHOR("Chris Pascoe <c.pascoe@itee.uq.edu.au>"); 61MODULE_AUTHOR("Chris Pascoe <c.pascoe@itee.uq.edu.au>");
@@ -573,6 +576,15 @@ static int cx24116_set_ts_param(struct dvb_frontend *fe,
573 return 0; 576 return 0;
574} 577}
575 578
579static int stv0900_set_ts_param(struct dvb_frontend *fe,
580 int is_punctured)
581{
582 struct cx8802_dev *dev = fe->dvb->priv;
583 dev->ts_gen_cntrl = 0;
584
585 return 0;
586}
587
576static int cx24116_reset_device(struct dvb_frontend *fe) 588static int cx24116_reset_device(struct dvb_frontend *fe)
577{ 589{
578 struct cx8802_dev *dev = fe->dvb->priv; 590 struct cx8802_dev *dev = fe->dvb->priv;
@@ -601,6 +613,23 @@ static struct cx24116_config tevii_s460_config = {
601 .reset_device = cx24116_reset_device, 613 .reset_device = cx24116_reset_device,
602}; 614};
603 615
616static struct stv0900_config prof_7301_stv0900_config = {
617 .demod_address = 0x6a,
618/* demod_mode = 0,*/
619 .xtal = 27000000,
620 .clkmode = 3,/* 0-CLKI, 2-XTALI, else AUTO */
621 .diseqc_mode = 2,/* 2/3 PWM */
622 .tun1_maddress = 0,/* 0x60 */
623 .tun1_adc = 0,/* 2 Vpp */
624 .path1_mode = 3,
625 .set_ts_params = stv0900_set_ts_param,
626};
627
628static struct stb6100_config prof_7301_stb6100_config = {
629 .tuner_address = 0x60,
630 .refclock = 27000000,
631};
632
604static struct stv0299_config tevii_tuner_sharp_config = { 633static struct stv0299_config tevii_tuner_sharp_config = {
605 .demod_address = 0x68, 634 .demod_address = 0x68,
606 .inittab = sharp_z0194a_inittab, 635 .inittab = sharp_z0194a_inittab,
@@ -1149,6 +1178,31 @@ static int dvb_register(struct cx8802_dev *dev)
1149 goto frontend_detach; 1178 goto frontend_detach;
1150 } 1179 }
1151 break; 1180 break;
1181 case CX88_BOARD_PROF_7301:{
1182 struct dvb_tuner_ops *tuner_ops = NULL;
1183
1184 fe0->dvb.frontend = dvb_attach(stv0900_attach,
1185 &prof_7301_stv0900_config,
1186 &core->i2c_adap, 0);
1187 if (fe0->dvb.frontend != NULL) {
1188 if (!dvb_attach(stb6100_attach, fe0->dvb.frontend,
1189 &prof_7301_stb6100_config,
1190 &core->i2c_adap))
1191 goto frontend_detach;
1192
1193 tuner_ops = &fe0->dvb.frontend->ops.tuner_ops;
1194 tuner_ops->set_frequency = stb6100_set_freq;
1195 tuner_ops->get_frequency = stb6100_get_freq;
1196 tuner_ops->set_bandwidth = stb6100_set_bandw;
1197 tuner_ops->get_bandwidth = stb6100_get_bandw;
1198
1199 core->prev_set_voltage =
1200 fe0->dvb.frontend->ops.set_voltage;
1201 fe0->dvb.frontend->ops.set_voltage =
1202 tevii_dvbs_set_voltage;
1203 }
1204 break;
1205 }
1152 default: 1206 default:
1153 printk(KERN_ERR "%s/2: The frontend of your DVB/ATSC card isn't supported yet\n", 1207 printk(KERN_ERR "%s/2: The frontend of your DVB/ATSC card isn't supported yet\n",
1154 core->name); 1208 core->name);
@@ -1170,11 +1224,11 @@ static int dvb_register(struct cx8802_dev *dev)
1170 fe1->dvb.frontend->ops.ts_bus_ctrl = cx88_dvb_bus_ctrl; 1224 fe1->dvb.frontend->ops.ts_bus_ctrl = cx88_dvb_bus_ctrl;
1171 1225
1172 /* Put the analog decoder in standby to keep it quiet */ 1226 /* Put the analog decoder in standby to keep it quiet */
1173 call_all(core, tuner, s_standby); 1227 call_all(core, core, s_power, 0);
1174 1228
1175 /* register everything */ 1229 /* register everything */
1176 return videobuf_dvb_register_bus(&dev->frontends, THIS_MODULE, dev, 1230 return videobuf_dvb_register_bus(&dev->frontends, THIS_MODULE, dev,
1177 &dev->pci->dev, adapter_nr, mfe_shared); 1231 &dev->pci->dev, adapter_nr, mfe_shared, NULL);
1178 1232
1179frontend_detach: 1233frontend_detach:
1180 core->gate_ctrl = NULL; 1234 core->gate_ctrl = NULL;
diff --git a/drivers/media/video/cx88/cx88-input.c b/drivers/media/video/cx88/cx88-input.c
index 78b3635178af..92b8cdf9fb81 100644
--- a/drivers/media/video/cx88/cx88-input.c
+++ b/drivers/media/video/cx88/cx88-input.c
@@ -118,13 +118,13 @@ static void cx88_ir_handle_key(struct cx88_IR *ir)
118 118
119 data = (data << 4) | ((gpio_key & 0xf0) >> 4); 119 data = (data << 4) | ((gpio_key & 0xf0) >> 4);
120 120
121 ir_input_keydown(ir->input, &ir->ir, data, data); 121 ir_input_keydown(ir->input, &ir->ir, data);
122 ir_input_nokey(ir->input, &ir->ir); 122 ir_input_nokey(ir->input, &ir->ir);
123 123
124 } else if (ir->mask_keydown) { 124 } else if (ir->mask_keydown) {
125 /* bit set on keydown */ 125 /* bit set on keydown */
126 if (gpio & ir->mask_keydown) { 126 if (gpio & ir->mask_keydown) {
127 ir_input_keydown(ir->input, &ir->ir, data, data); 127 ir_input_keydown(ir->input, &ir->ir, data);
128 } else { 128 } else {
129 ir_input_nokey(ir->input, &ir->ir); 129 ir_input_nokey(ir->input, &ir->ir);
130 } 130 }
@@ -132,14 +132,14 @@ static void cx88_ir_handle_key(struct cx88_IR *ir)
132 } else if (ir->mask_keyup) { 132 } else if (ir->mask_keyup) {
133 /* bit cleared on keydown */ 133 /* bit cleared on keydown */
134 if (0 == (gpio & ir->mask_keyup)) { 134 if (0 == (gpio & ir->mask_keyup)) {
135 ir_input_keydown(ir->input, &ir->ir, data, data); 135 ir_input_keydown(ir->input, &ir->ir, data);
136 } else { 136 } else {
137 ir_input_nokey(ir->input, &ir->ir); 137 ir_input_nokey(ir->input, &ir->ir);
138 } 138 }
139 139
140 } else { 140 } else {
141 /* can't distinguish keydown/up :-/ */ 141 /* can't distinguish keydown/up :-/ */
142 ir_input_keydown(ir->input, &ir->ir, data, data); 142 ir_input_keydown(ir->input, &ir->ir, data);
143 ir_input_nokey(ir->input, &ir->ir); 143 ir_input_nokey(ir->input, &ir->ir);
144 } 144 }
145} 145}
@@ -303,6 +303,23 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
303 ir->mask_keydown = 0x02; 303 ir->mask_keydown = 0x02;
304 ir->polling = 50; /* ms */ 304 ir->polling = 50; /* ms */
305 break; 305 break;
306 case CX88_BOARD_OMICOM_SS4_PCI:
307 case CX88_BOARD_SATTRADE_ST4200:
308 case CX88_BOARD_TBS_8920:
309 case CX88_BOARD_TBS_8910:
310 case CX88_BOARD_PROF_7300:
311 case CX88_BOARD_PROF_7301:
312 case CX88_BOARD_PROF_6200:
313 ir_codes = &ir_codes_tbs_nec_table;
314 ir_type = IR_TYPE_PD;
315 ir->sampling = 0xff00; /* address */
316 break;
317 case CX88_BOARD_TEVII_S460:
318 case CX88_BOARD_TEVII_S420:
319 ir_codes = &ir_codes_tevii_nec_table;
320 ir_type = IR_TYPE_PD;
321 ir->sampling = 0xff00; /* address */
322 break;
306 case CX88_BOARD_DNTV_LIVE_DVB_T_PRO: 323 case CX88_BOARD_DNTV_LIVE_DVB_T_PRO:
307 ir_codes = &ir_codes_dntv_live_dvbt_pro_table; 324 ir_codes = &ir_codes_dntv_live_dvbt_pro_table;
308 ir_type = IR_TYPE_PD; 325 ir_type = IR_TYPE_PD;
@@ -343,7 +360,10 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
343 snprintf(ir->name, sizeof(ir->name), "cx88 IR (%s)", core->board.name); 360 snprintf(ir->name, sizeof(ir->name), "cx88 IR (%s)", core->board.name);
344 snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0", pci_name(pci)); 361 snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0", pci_name(pci));
345 362
346 ir_input_init(input_dev, &ir->ir, ir_type, ir_codes); 363 err = ir_input_init(input_dev, &ir->ir, ir_type, ir_codes);
364 if (err < 0)
365 goto err_out_free;
366
347 input_dev->name = ir->name; 367 input_dev->name = ir->name;
348 input_dev->phys = ir->phys; 368 input_dev->phys = ir->phys;
349 input_dev->id.bustype = BUS_PCI; 369 input_dev->id.bustype = BUS_PCI;
@@ -373,6 +393,7 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
373 cx88_ir_stop(core, ir); 393 cx88_ir_stop(core, ir);
374 core->ir = NULL; 394 core->ir = NULL;
375 err_out_free: 395 err_out_free:
396 ir_input_free(input_dev);
376 input_free_device(input_dev); 397 input_free_device(input_dev);
377 kfree(ir); 398 kfree(ir);
378 return err; 399 return err;
@@ -387,6 +408,7 @@ int cx88_ir_fini(struct cx88_core *core)
387 return 0; 408 return 0;
388 409
389 cx88_ir_stop(core, ir); 410 cx88_ir_stop(core, ir);
411 ir_input_free(ir->input);
390 input_unregister_device(ir->input); 412 input_unregister_device(ir->input);
391 kfree(ir); 413 kfree(ir);
392 414
@@ -432,8 +454,17 @@ void cx88_ir_irq(struct cx88_core *core)
432 454
433 /* decode it */ 455 /* decode it */
434 switch (core->boardnr) { 456 switch (core->boardnr) {
457 case CX88_BOARD_TEVII_S460:
458 case CX88_BOARD_TEVII_S420:
435 case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1: 459 case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1:
436 case CX88_BOARD_DNTV_LIVE_DVB_T_PRO: 460 case CX88_BOARD_DNTV_LIVE_DVB_T_PRO:
461 case CX88_BOARD_OMICOM_SS4_PCI:
462 case CX88_BOARD_SATTRADE_ST4200:
463 case CX88_BOARD_TBS_8920:
464 case CX88_BOARD_TBS_8910:
465 case CX88_BOARD_PROF_7300:
466 case CX88_BOARD_PROF_7301:
467 case CX88_BOARD_PROF_6200:
437 ircode = ir_decode_pulsedistance(ir->samples, ir->scount, 1, 4); 468 ircode = ir_decode_pulsedistance(ir->samples, ir->scount, 1, 4);
438 469
439 if (ircode == 0xffffffff) { /* decoding error */ 470 if (ircode == 0xffffffff) { /* decoding error */
@@ -461,7 +492,7 @@ void cx88_ir_irq(struct cx88_core *core)
461 492
462 ir_dprintk("Key Code: %x\n", (ircode >> 16) & 0x7f); 493 ir_dprintk("Key Code: %x\n", (ircode >> 16) & 0x7f);
463 494
464 ir_input_keydown(ir->input, &ir->ir, (ircode >> 16) & 0x7f, (ircode >> 16) & 0xff); 495 ir_input_keydown(ir->input, &ir->ir, (ircode >> 16) & 0x7f);
465 ir->release = jiffies + msecs_to_jiffies(120); 496 ir->release = jiffies + msecs_to_jiffies(120);
466 break; 497 break;
467 case CX88_BOARD_HAUPPAUGE: 498 case CX88_BOARD_HAUPPAUGE:
@@ -498,7 +529,7 @@ void cx88_ir_irq(struct cx88_core *core)
498 if ( dev != 0x1e && dev != 0x1f ) 529 if ( dev != 0x1e && dev != 0x1f )
499 /* not a hauppauge remote */ 530 /* not a hauppauge remote */
500 break; 531 break;
501 ir_input_keydown(ir->input, &ir->ir, code, ircode); 532 ir_input_keydown(ir->input, &ir->ir, code);
502 ir->release = jiffies + msecs_to_jiffies(120); 533 ir->release = jiffies + msecs_to_jiffies(120);
503 break; 534 break;
504 case CX88_BOARD_PINNACLE_PCTV_HD_800i: 535 case CX88_BOARD_PINNACLE_PCTV_HD_800i:
@@ -506,7 +537,7 @@ void cx88_ir_irq(struct cx88_core *core)
506 ir_dprintk("biphase decoded: %x\n", ircode); 537 ir_dprintk("biphase decoded: %x\n", ircode);
507 if ((ircode & 0xfffff000) != 0x3000) 538 if ((ircode & 0xfffff000) != 0x3000)
508 break; 539 break;
509 ir_input_keydown(ir->input, &ir->ir, ircode & 0x3f, ircode); 540 ir_input_keydown(ir->input, &ir->ir, ircode & 0x3f);
510 ir->release = jiffies + msecs_to_jiffies(120); 541 ir->release = jiffies + msecs_to_jiffies(120);
511 break; 542 break;
512 } 543 }
diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c
index 57e6b1241090..d7e8fcee559c 100644
--- a/drivers/media/video/cx88/cx88-video.c
+++ b/drivers/media/video/cx88/cx88-video.c
@@ -935,7 +935,7 @@ static int video_release(struct file *file)
935 935
936 mutex_lock(&dev->core->lock); 936 mutex_lock(&dev->core->lock);
937 if(atomic_dec_and_test(&dev->core->users)) 937 if(atomic_dec_and_test(&dev->core->users))
938 call_all(dev->core, tuner, s_standby); 938 call_all(dev->core, core, s_power, 0);
939 mutex_unlock(&dev->core->lock); 939 mutex_unlock(&dev->core->lock);
940 940
941 return 0; 941 return 0;
diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h
index d5cea41f4207..e1c521710103 100644
--- a/drivers/media/video/cx88/cx88.h
+++ b/drivers/media/video/cx88/cx88.h
@@ -238,6 +238,7 @@ extern struct sram_channel cx88_sram_channels[];
238#define CX88_BOARD_HAUPPAUGE_IRONLY 80 238#define CX88_BOARD_HAUPPAUGE_IRONLY 80
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 242
242enum cx88_itype { 243enum cx88_itype {
243 CX88_VMUX_COMPOSITE1 = 1, 244 CX88_VMUX_COMPOSITE1 = 1,
diff --git a/drivers/media/video/davinci/vpfe_capture.c b/drivers/media/video/davinci/vpfe_capture.c
index 402ce43ef38e..12a1b3d7132d 100644
--- a/drivers/media/video/davinci/vpfe_capture.c
+++ b/drivers/media/video/davinci/vpfe_capture.c
@@ -660,7 +660,7 @@ static void vpfe_detach_irq(struct vpfe_device *vpfe_dev)
660 660
661 frame_format = ccdc_dev->hw_ops.get_frame_format(); 661 frame_format = ccdc_dev->hw_ops.get_frame_format();
662 if (frame_format == CCDC_FRMFMT_PROGRESSIVE) 662 if (frame_format == CCDC_FRMFMT_PROGRESSIVE)
663 free_irq(IRQ_VDINT1, vpfe_dev); 663 free_irq(vpfe_dev->ccdc_irq1, vpfe_dev);
664} 664}
665 665
666static int vpfe_attach_irq(struct vpfe_device *vpfe_dev) 666static int vpfe_attach_irq(struct vpfe_device *vpfe_dev)
@@ -1338,7 +1338,7 @@ static int vpfe_reqbufs(struct file *file, void *priv,
1338 vpfe_dev->memory = req_buf->memory; 1338 vpfe_dev->memory = req_buf->memory;
1339 videobuf_queue_dma_contig_init(&vpfe_dev->buffer_queue, 1339 videobuf_queue_dma_contig_init(&vpfe_dev->buffer_queue,
1340 &vpfe_videobuf_qops, 1340 &vpfe_videobuf_qops,
1341 NULL, 1341 vpfe_dev->pdev,
1342 &vpfe_dev->irqlock, 1342 &vpfe_dev->irqlock,
1343 req_buf->type, 1343 req_buf->type,
1344 vpfe_dev->fmt.fmt.pix.field, 1344 vpfe_dev->fmt.fmt.pix.field,
@@ -1413,6 +1413,41 @@ static int vpfe_dqbuf(struct file *file, void *priv,
1413 buf, file->f_flags & O_NONBLOCK); 1413 buf, file->f_flags & O_NONBLOCK);
1414} 1414}
1415 1415
1416static int vpfe_queryctrl(struct file *file, void *priv,
1417 struct v4l2_queryctrl *qctrl)
1418{
1419 struct vpfe_device *vpfe_dev = video_drvdata(file);
1420 struct vpfe_subdev_info *sdinfo;
1421
1422 sdinfo = vpfe_dev->current_subdev;
1423
1424 return v4l2_device_call_until_err(&vpfe_dev->v4l2_dev, sdinfo->grp_id,
1425 core, queryctrl, qctrl);
1426
1427}
1428
1429static int vpfe_g_ctrl(struct file *file, void *priv, struct v4l2_control *ctrl)
1430{
1431 struct vpfe_device *vpfe_dev = video_drvdata(file);
1432 struct vpfe_subdev_info *sdinfo;
1433
1434 sdinfo = vpfe_dev->current_subdev;
1435
1436 return v4l2_device_call_until_err(&vpfe_dev->v4l2_dev, sdinfo->grp_id,
1437 core, g_ctrl, ctrl);
1438}
1439
1440static int vpfe_s_ctrl(struct file *file, void *priv, struct v4l2_control *ctrl)
1441{
1442 struct vpfe_device *vpfe_dev = video_drvdata(file);
1443 struct vpfe_subdev_info *sdinfo;
1444
1445 sdinfo = vpfe_dev->current_subdev;
1446
1447 return v4l2_device_call_until_err(&vpfe_dev->v4l2_dev, sdinfo->grp_id,
1448 core, s_ctrl, ctrl);
1449}
1450
1416/* 1451/*
1417 * vpfe_calculate_offsets : This function calculates buffers offset 1452 * vpfe_calculate_offsets : This function calculates buffers offset
1418 * for top and bottom field 1453 * for top and bottom field
@@ -1577,7 +1612,7 @@ static int vpfe_cropcap(struct file *file, void *priv,
1577 1612
1578 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_cropcap\n"); 1613 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_cropcap\n");
1579 1614
1580 if (vpfe_dev->std_index > ARRAY_SIZE(vpfe_standards)) 1615 if (vpfe_dev->std_index >= ARRAY_SIZE(vpfe_standards))
1581 return -EINVAL; 1616 return -EINVAL;
1582 1617
1583 memset(crop, 0, sizeof(struct v4l2_cropcap)); 1618 memset(crop, 0, sizeof(struct v4l2_cropcap));
@@ -1710,6 +1745,9 @@ static const struct v4l2_ioctl_ops vpfe_ioctl_ops = {
1710 .vidioc_querystd = vpfe_querystd, 1745 .vidioc_querystd = vpfe_querystd,
1711 .vidioc_s_std = vpfe_s_std, 1746 .vidioc_s_std = vpfe_s_std,
1712 .vidioc_g_std = vpfe_g_std, 1747 .vidioc_g_std = vpfe_g_std,
1748 .vidioc_queryctrl = vpfe_queryctrl,
1749 .vidioc_g_ctrl = vpfe_g_ctrl,
1750 .vidioc_s_ctrl = vpfe_s_ctrl,
1713 .vidioc_reqbufs = vpfe_reqbufs, 1751 .vidioc_reqbufs = vpfe_reqbufs,
1714 .vidioc_querybuf = vpfe_querybuf, 1752 .vidioc_querybuf = vpfe_querybuf,
1715 .vidioc_qbuf = vpfe_qbuf, 1753 .vidioc_qbuf = vpfe_qbuf,
@@ -1978,8 +2016,7 @@ static __init int vpfe_probe(struct platform_device *pdev)
1978 platform_set_drvdata(pdev, vpfe_dev); 2016 platform_set_drvdata(pdev, vpfe_dev);
1979 /* set driver private data */ 2017 /* set driver private data */
1980 video_set_drvdata(vpfe_dev->video_dev, vpfe_dev); 2018 video_set_drvdata(vpfe_dev->video_dev, vpfe_dev);
1981 i2c_adap = i2c_get_adapter(1); 2019 i2c_adap = i2c_get_adapter(vpfe_cfg->i2c_adapter_id);
1982 vpfe_cfg = pdev->dev.platform_data;
1983 num_subdevs = vpfe_cfg->num_subdevs; 2020 num_subdevs = vpfe_cfg->num_subdevs;
1984 vpfe_dev->sd = kmalloc(sizeof(struct v4l2_subdev *) * num_subdevs, 2021 vpfe_dev->sd = kmalloc(sizeof(struct v4l2_subdev *) * num_subdevs,
1985 GFP_KERNEL); 2022 GFP_KERNEL);
diff --git a/drivers/media/video/em28xx/em28xx-audio.c b/drivers/media/video/em28xx/em28xx-audio.c
index ac947aecb9c3..bd783387b37d 100644
--- a/drivers/media/video/em28xx/em28xx-audio.c
+++ b/drivers/media/video/em28xx/em28xx-audio.c
@@ -293,7 +293,7 @@ static int snd_em28xx_capture_open(struct snd_pcm_substream *substream)
293 dprintk("opening device and trying to acquire exclusive lock\n"); 293 dprintk("opening device and trying to acquire exclusive lock\n");
294 294
295 if (!dev) { 295 if (!dev) {
296 printk(KERN_ERR "BUG: em28xx can't find device struct." 296 em28xx_err("BUG: em28xx can't find device struct."
297 " Can't proceed with open\n"); 297 " Can't proceed with open\n");
298 return -ENODEV; 298 return -ENODEV;
299 } 299 }
@@ -325,7 +325,7 @@ static int snd_em28xx_capture_open(struct snd_pcm_substream *substream)
325 325
326 return 0; 326 return 0;
327err: 327err:
328 printk(KERN_ERR "Error while configuring em28xx mixer\n"); 328 em28xx_err("Error while configuring em28xx mixer\n");
329 return ret; 329 return ret;
330} 330}
331 331
diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c
index c0fd5c6feeac..82da205047be 100644
--- a/drivers/media/video/em28xx/em28xx-cards.c
+++ b/drivers/media/video/em28xx/em28xx-cards.c
@@ -225,6 +225,14 @@ static struct em28xx_reg_seq silvercrest_reg_seq[] = {
225 { -1, -1, -1, -1}, 225 { -1, -1, -1, -1},
226}; 226};
227 227
228static struct em28xx_reg_seq vc211a_enable[] = {
229 {EM28XX_R08_GPIO, 0xff, 0x07, 10},
230 {EM28XX_R08_GPIO, 0xff, 0x0f, 10},
231 {EM28XX_R08_GPIO, 0xff, 0x0b, 10},
232 { -1, -1, -1, -1},
233};
234
235
228/* 236/*
229 * Board definitions 237 * Board definitions
230 */ 238 */
@@ -829,7 +837,7 @@ struct em28xx_board em28xx_boards[] = {
829 .mts_firmware = 1, 837 .mts_firmware = 1,
830 .has_dvb = 1, 838 .has_dvb = 1,
831 .dvb_gpio = hauppauge_wintv_hvr_900_digital, 839 .dvb_gpio = hauppauge_wintv_hvr_900_digital,
832 .ir_codes = &ir_codes_hauppauge_new_table, 840 .ir_codes = &ir_codes_rc5_hauppauge_new_table,
833 .decoder = EM28XX_TVP5150, 841 .decoder = EM28XX_TVP5150,
834 .input = { { 842 .input = { {
835 .type = EM28XX_VMUX_TELEVISION, 843 .type = EM28XX_VMUX_TELEVISION,
@@ -1009,6 +1017,23 @@ struct em28xx_board em28xx_boards[] = {
1009 .amux = EM28XX_AMUX_LINE_IN, 1017 .amux = EM28XX_AMUX_LINE_IN,
1010 } }, 1018 } },
1011 }, 1019 },
1020 [EM2800_BOARD_VC211A] = {
1021 .name = "Actionmaster/LinXcel/Digitus VC211A",
1022 .is_em2800 = 1,
1023 .tuner_type = TUNER_ABSENT, /* Capture-only board */
1024 .decoder = EM28XX_SAA711X,
1025 .input = { {
1026 .type = EM28XX_VMUX_COMPOSITE1,
1027 .vmux = SAA7115_COMPOSITE0,
1028 .amux = EM28XX_AMUX_LINE_IN,
1029 .gpio = vc211a_enable,
1030 }, {
1031 .type = EM28XX_VMUX_SVIDEO,
1032 .vmux = SAA7115_SVIDEO3,
1033 .amux = EM28XX_AMUX_LINE_IN,
1034 .gpio = vc211a_enable,
1035 } },
1036 },
1012 [EM2800_BOARD_LEADTEK_WINFAST_USBII] = { 1037 [EM2800_BOARD_LEADTEK_WINFAST_USBII] = {
1013 .name = "Leadtek Winfast USB II", 1038 .name = "Leadtek Winfast USB II",
1014 .is_em2800 = 1, 1039 .is_em2800 = 1,
@@ -1381,10 +1406,14 @@ struct em28xx_board em28xx_boards[] = {
1381 }, 1406 },
1382 [EM2882_BOARD_TERRATEC_HYBRID_XS] = { 1407 [EM2882_BOARD_TERRATEC_HYBRID_XS] = {
1383 .name = "Terratec Hybrid XS (em2882)", 1408 .name = "Terratec Hybrid XS (em2882)",
1384 .valid = EM28XX_BOARD_NOT_VALIDATED,
1385 .tuner_type = TUNER_XC2028, 1409 .tuner_type = TUNER_XC2028,
1386 .tuner_gpio = default_tuner_gpio, 1410 .tuner_gpio = default_tuner_gpio,
1411 .mts_firmware = 1,
1387 .decoder = EM28XX_TVP5150, 1412 .decoder = EM28XX_TVP5150,
1413 .has_dvb = 1,
1414 .dvb_gpio = hauppauge_wintv_hvr_900_digital,
1415 .ir_codes = &ir_codes_terratec_cinergy_xs_table,
1416 .xclk = EM28XX_XCLK_FREQUENCY_12MHZ,
1388 .input = { { 1417 .input = { {
1389 .type = EM28XX_VMUX_TELEVISION, 1418 .type = EM28XX_VMUX_TELEVISION,
1390 .vmux = TVP5150_COMPOSITE0, 1419 .vmux = TVP5150_COMPOSITE0,
@@ -1608,6 +1637,8 @@ struct usb_device_id em28xx_id_table[] = {
1608 .driver_info = EM2820_BOARD_UNKNOWN }, 1637 .driver_info = EM2820_BOARD_UNKNOWN },
1609 { USB_DEVICE(0xeb1a, 0x2861), 1638 { USB_DEVICE(0xeb1a, 0x2861),
1610 .driver_info = EM2820_BOARD_UNKNOWN }, 1639 .driver_info = EM2820_BOARD_UNKNOWN },
1640 { USB_DEVICE(0xeb1a, 0x2862),
1641 .driver_info = EM2820_BOARD_UNKNOWN },
1611 { USB_DEVICE(0xeb1a, 0x2870), 1642 { USB_DEVICE(0xeb1a, 0x2870),
1612 .driver_info = EM2820_BOARD_UNKNOWN }, 1643 .driver_info = EM2820_BOARD_UNKNOWN },
1613 { USB_DEVICE(0xeb1a, 0x2881), 1644 { USB_DEVICE(0xeb1a, 0x2881),
@@ -2050,6 +2081,7 @@ static void em28xx_setup_xc3028(struct em28xx *dev, struct xc2028_ctrl *ctl)
2050 switch (dev->model) { 2081 switch (dev->model) {
2051 case EM2880_BOARD_EMPIRE_DUAL_TV: 2082 case EM2880_BOARD_EMPIRE_DUAL_TV:
2052 case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900: 2083 case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900:
2084 case EM2882_BOARD_TERRATEC_HYBRID_XS:
2053 ctl->demod = XC3028_FE_ZARLINK456; 2085 ctl->demod = XC3028_FE_ZARLINK456;
2054 break; 2086 break;
2055 case EM2880_BOARD_TERRATEC_HYBRID_XS: 2087 case EM2880_BOARD_TERRATEC_HYBRID_XS:
@@ -2227,6 +2259,7 @@ static int em28xx_hint_board(struct em28xx *dev)
2227/* ----------------------------------------------------------------------- */ 2259/* ----------------------------------------------------------------------- */
2228void em28xx_register_i2c_ir(struct em28xx *dev) 2260void em28xx_register_i2c_ir(struct em28xx *dev)
2229{ 2261{
2262 struct i2c_board_info info;
2230 const unsigned short addr_list[] = { 2263 const unsigned short addr_list[] = {
2231 0x30, 0x47, I2C_CLIENT_END 2264 0x30, 0x47, I2C_CLIENT_END
2232 }; 2265 };
@@ -2234,9 +2267,9 @@ void em28xx_register_i2c_ir(struct em28xx *dev)
2234 if (disable_ir) 2267 if (disable_ir)
2235 return; 2268 return;
2236 2269
2237 memset(&dev->info, 0, sizeof(&dev->info)); 2270 memset(&info, 0, sizeof(struct i2c_board_info));
2238 memset(&dev->init_data, 0, sizeof(dev->init_data)); 2271 memset(&dev->init_data, 0, sizeof(dev->init_data));
2239 strlcpy(dev->info.type, "ir_video", I2C_NAME_SIZE); 2272 strlcpy(info.type, "ir_video", I2C_NAME_SIZE);
2240 2273
2241 /* detect & configure */ 2274 /* detect & configure */
2242 switch (dev->model) { 2275 switch (dev->model) {
@@ -2259,8 +2292,8 @@ void em28xx_register_i2c_ir(struct em28xx *dev)
2259 } 2292 }
2260 2293
2261 if (dev->init_data.name) 2294 if (dev->init_data.name)
2262 dev->info.platform_data = &dev->init_data; 2295 info.platform_data = &dev->init_data;
2263 i2c_new_probed_device(&dev->i2c_adap, &dev->info, addr_list); 2296 i2c_new_probed_device(&dev->i2c_adap, &info, addr_list);
2264} 2297}
2265 2298
2266void em28xx_card_setup(struct em28xx *dev) 2299void em28xx_card_setup(struct em28xx *dev)
@@ -2524,6 +2557,9 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
2524 dev->chip_id = retval; 2557 dev->chip_id = retval;
2525 2558
2526 switch (dev->chip_id) { 2559 switch (dev->chip_id) {
2560 case CHIP_ID_EM2800:
2561 em28xx_info("chip ID is em2800\n");
2562 break;
2527 case CHIP_ID_EM2710: 2563 case CHIP_ID_EM2710:
2528 em28xx_info("chip ID is em2710\n"); 2564 em28xx_info("chip ID is em2710\n");
2529 break; 2565 break;
@@ -2650,7 +2686,7 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
2650 em28xx_init_extension(dev); 2686 em28xx_init_extension(dev);
2651 2687
2652 /* Save some power by putting tuner to sleep */ 2688 /* Save some power by putting tuner to sleep */
2653 v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_standby); 2689 v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_power, 0);
2654 2690
2655 return 0; 2691 return 0;
2656 2692
diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c
index a88257a7d94f..3f86d36dff2b 100644
--- a/drivers/media/video/em28xx/em28xx-core.c
+++ b/drivers/media/video/em28xx/em28xx-core.c
@@ -50,7 +50,7 @@ MODULE_PARM_DESC(reg_debug, "enable debug messages [URB reg]");
50 printk(KERN_INFO "%s %s :"fmt, \ 50 printk(KERN_INFO "%s %s :"fmt, \
51 dev->name, __func__ , ##arg); } while (0) 51 dev->name, __func__ , ##arg); } while (0)
52 52
53static int alt = EM28XX_PINOUT; 53static int alt;
54module_param(alt, int, 0644); 54module_param(alt, int, 0644);
55MODULE_PARM_DESC(alt, "alternate setting to use for video endpoint"); 55MODULE_PARM_DESC(alt, "alternate setting to use for video endpoint");
56 56
@@ -533,8 +533,15 @@ int em28xx_audio_setup(struct em28xx *dev)
533 533
534 vid1 = em28xx_read_ac97(dev, AC97_VENDOR_ID1); 534 vid1 = em28xx_read_ac97(dev, AC97_VENDOR_ID1);
535 if (vid1 < 0) { 535 if (vid1 < 0) {
536 /* Device likely doesn't support AC97 */ 536 /*
537 * Device likely doesn't support AC97
538 * Note: (some) em2800 devices without eeprom reports 0x91 on
539 * CHIPCFG register, even not having an AC97 chip
540 */
537 em28xx_warn("AC97 chip type couldn't be determined\n"); 541 em28xx_warn("AC97 chip type couldn't be determined\n");
542 dev->audio_mode.ac97 = EM28XX_NO_AC97;
543 dev->has_alsa_audio = 0;
544 dev->audio_mode.has_audio = 0;
538 goto init_audio; 545 goto init_audio;
539 } 546 }
540 547
@@ -778,6 +785,16 @@ int em28xx_set_alternate(struct em28xx *dev)
778 int i; 785 int i;
779 unsigned int min_pkt_size = dev->width * 2 + 4; 786 unsigned int min_pkt_size = dev->width * 2 + 4;
780 787
788 /*
789 * alt = 0 is used only for control messages, so, only values
790 * greater than 0 can be used for streaming.
791 */
792 if (alt && alt < dev->num_alt) {
793 em28xx_coredbg("alternate forced to %d\n", dev->alt);
794 dev->alt = alt;
795 goto set_alt;
796 }
797
781 /* When image size is bigger than a certain value, 798 /* When image size is bigger than a certain value,
782 the frame size should be increased, otherwise, only 799 the frame size should be increased, otherwise, only
783 green screen will be received. 800 green screen will be received.
@@ -798,6 +815,7 @@ int em28xx_set_alternate(struct em28xx *dev)
798 dev->alt = i; 815 dev->alt = i;
799 } 816 }
800 817
818set_alt:
801 if (dev->alt != prev_alt) { 819 if (dev->alt != prev_alt) {
802 em28xx_coredbg("minimum isoc packet size: %u (alt=%d)\n", 820 em28xx_coredbg("minimum isoc packet size: %u (alt=%d)\n",
803 min_pkt_size, dev->alt); 821 min_pkt_size, dev->alt);
diff --git a/drivers/media/video/em28xx/em28xx-dvb.c b/drivers/media/video/em28xx/em28xx-dvb.c
index db749461e5c6..cc0505eb900f 100644
--- a/drivers/media/video/em28xx/em28xx-dvb.c
+++ b/drivers/media/video/em28xx/em28xx-dvb.c
@@ -313,22 +313,20 @@ static int attach_xc3028(u8 addr, struct em28xx *dev)
313 cfg.i2c_addr = addr; 313 cfg.i2c_addr = addr;
314 314
315 if (!dev->dvb->frontend) { 315 if (!dev->dvb->frontend) {
316 printk(KERN_ERR "%s/2: dvb frontend not attached. " 316 em28xx_errdev("/2: dvb frontend not attached. "
317 "Can't attach xc3028\n", 317 "Can't attach xc3028\n");
318 dev->name);
319 return -EINVAL; 318 return -EINVAL;
320 } 319 }
321 320
322 fe = dvb_attach(xc2028_attach, dev->dvb->frontend, &cfg); 321 fe = dvb_attach(xc2028_attach, dev->dvb->frontend, &cfg);
323 if (!fe) { 322 if (!fe) {
324 printk(KERN_ERR "%s/2: xc3028 attach failed\n", 323 em28xx_errdev("/2: xc3028 attach failed\n");
325 dev->name);
326 dvb_frontend_detach(dev->dvb->frontend); 324 dvb_frontend_detach(dev->dvb->frontend);
327 dev->dvb->frontend = NULL; 325 dev->dvb->frontend = NULL;
328 return -EINVAL; 326 return -EINVAL;
329 } 327 }
330 328
331 printk(KERN_INFO "%s/2: xc3028 attached\n", dev->name); 329 em28xx_info("%s/2: xc3028 attached\n", dev->name);
332 330
333 return 0; 331 return 0;
334} 332}
@@ -463,7 +461,7 @@ static int dvb_init(struct em28xx *dev)
463 dvb = kzalloc(sizeof(struct em28xx_dvb), GFP_KERNEL); 461 dvb = kzalloc(sizeof(struct em28xx_dvb), GFP_KERNEL);
464 462
465 if (dvb == NULL) { 463 if (dvb == NULL) {
466 printk(KERN_INFO "em28xx_dvb: memory allocation failed\n"); 464 em28xx_info("em28xx_dvb: memory allocation failed\n");
467 return -ENOMEM; 465 return -ENOMEM;
468 } 466 }
469 dev->dvb = dvb; 467 dev->dvb = dvb;
@@ -493,6 +491,7 @@ static int dvb_init(struct em28xx *dev)
493 } 491 }
494 break; 492 break;
495 case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900: 493 case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900:
494 case EM2882_BOARD_TERRATEC_HYBRID_XS:
496 case EM2880_BOARD_EMPIRE_DUAL_TV: 495 case EM2880_BOARD_EMPIRE_DUAL_TV:
497 dvb->frontend = dvb_attach(zl10353_attach, 496 dvb->frontend = dvb_attach(zl10353_attach,
498 &em28xx_zl10353_xc3028_no_i2c_gate, 497 &em28xx_zl10353_xc3028_no_i2c_gate,
@@ -569,15 +568,12 @@ static int dvb_init(struct em28xx *dev)
569 } 568 }
570 break; 569 break;
571 default: 570 default:
572 printk(KERN_ERR "%s/2: The frontend of your DVB/ATSC card" 571 em28xx_errdev("/2: The frontend of your DVB/ATSC card"
573 " isn't supported yet\n", 572 " isn't supported yet\n");
574 dev->name);
575 break; 573 break;
576 } 574 }
577 if (NULL == dvb->frontend) { 575 if (NULL == dvb->frontend) {
578 printk(KERN_ERR 576 em28xx_errdev("/2: frontend initialization failed\n");
579 "%s/2: frontend initialization failed\n",
580 dev->name);
581 result = -EINVAL; 577 result = -EINVAL;
582 goto out_free; 578 goto out_free;
583 } 579 }
@@ -591,7 +587,7 @@ static int dvb_init(struct em28xx *dev)
591 goto out_free; 587 goto out_free;
592 588
593 em28xx_set_mode(dev, EM28XX_SUSPEND); 589 em28xx_set_mode(dev, EM28XX_SUSPEND);
594 printk(KERN_INFO "Successfully loaded em28xx-dvb\n"); 590 em28xx_info("Successfully loaded em28xx-dvb\n");
595 return 0; 591 return 0;
596 592
597out_free: 593out_free:
diff --git a/drivers/media/video/em28xx/em28xx-input.c b/drivers/media/video/em28xx/em28xx-input.c
index 7a0fe3816e3d..d96ec7c09dca 100644
--- a/drivers/media/video/em28xx/em28xx-input.c
+++ b/drivers/media/video/em28xx/em28xx-input.c
@@ -70,6 +70,7 @@ struct em28xx_IR {
70 int polling; 70 int polling;
71 struct delayed_work work; 71 struct delayed_work work;
72 unsigned int last_toggle:1; 72 unsigned int last_toggle:1;
73 unsigned int full_code:1;
73 unsigned int last_readcount; 74 unsigned int last_readcount;
74 unsigned int repeat_interval; 75 unsigned int repeat_interval;
75 76
@@ -246,9 +247,10 @@ static void em28xx_ir_handle_key(struct em28xx_IR *ir)
246 return; 247 return;
247 } 248 }
248 249
249 dprintk("ir->get_key result tb=%02x rc=%02x lr=%02x data=%02x\n", 250 dprintk("ir->get_key result tb=%02x rc=%02x lr=%02x data=%02x%02x\n",
250 poll_result.toggle_bit, poll_result.read_count, 251 poll_result.toggle_bit, poll_result.read_count,
251 ir->last_readcount, poll_result.rc_data[0]); 252 ir->last_readcount, poll_result.rc_address,
253 poll_result.rc_data[0]);
252 254
253 if (ir->dev->chip_id == CHIP_ID_EM2874) { 255 if (ir->dev->chip_id == CHIP_ID_EM2874) {
254 /* The em2874 clears the readcount field every time the 256 /* The em2874 clears the readcount field every time the
@@ -282,8 +284,15 @@ static void em28xx_ir_handle_key(struct em28xx_IR *ir)
282 284
283 if (do_sendkey) { 285 if (do_sendkey) {
284 dprintk("sending keypress\n"); 286 dprintk("sending keypress\n");
285 ir_input_keydown(ir->input, &ir->ir, poll_result.rc_data[0], 287
286 poll_result.rc_data[0]); 288 if (ir->full_code)
289 ir_input_keydown(ir->input, &ir->ir,
290 poll_result.rc_address << 8 |
291 poll_result.rc_data[0]);
292 else
293 ir_input_keydown(ir->input, &ir->ir,
294 poll_result.rc_data[0]);
295
287 ir_input_nokey(ir->input, &ir->ir); 296 ir_input_nokey(ir->input, &ir->ir);
288 } 297 }
289 298
@@ -333,6 +342,8 @@ int em28xx_ir_init(struct em28xx *dev)
333 switch (dev->chip_id) { 342 switch (dev->chip_id) {
334 case CHIP_ID_EM2860: 343 case CHIP_ID_EM2860:
335 case CHIP_ID_EM2883: 344 case CHIP_ID_EM2883:
345 if (dev->model == EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950)
346 ir->full_code = 1;
336 ir->get_key = default_polling_getkey; 347 ir->get_key = default_polling_getkey;
337 break; 348 break;
338 case CHIP_ID_EM2874: 349 case CHIP_ID_EM2874:
@@ -356,7 +367,11 @@ int em28xx_ir_init(struct em28xx *dev)
356 usb_make_path(dev->udev, ir->phys, sizeof(ir->phys)); 367 usb_make_path(dev->udev, ir->phys, sizeof(ir->phys));
357 strlcat(ir->phys, "/input0", sizeof(ir->phys)); 368 strlcat(ir->phys, "/input0", sizeof(ir->phys));
358 369
359 ir_input_init(input_dev, &ir->ir, IR_TYPE_OTHER, dev->board.ir_codes); 370 err = ir_input_init(input_dev, &ir->ir, IR_TYPE_OTHER,
371 dev->board.ir_codes);
372 if (err < 0)
373 goto err_out_free;
374
360 input_dev->name = ir->name; 375 input_dev->name = ir->name;
361 input_dev->phys = ir->phys; 376 input_dev->phys = ir->phys;
362 input_dev->id.bustype = BUS_USB; 377 input_dev->id.bustype = BUS_USB;
@@ -381,6 +396,7 @@ int em28xx_ir_init(struct em28xx *dev)
381 em28xx_ir_stop(ir); 396 em28xx_ir_stop(ir);
382 dev->ir = NULL; 397 dev->ir = NULL;
383 err_out_free: 398 err_out_free:
399 ir_input_free(input_dev);
384 input_free_device(input_dev); 400 input_free_device(input_dev);
385 kfree(ir); 401 kfree(ir);
386 return err; 402 return err;
@@ -395,6 +411,7 @@ int em28xx_ir_fini(struct em28xx *dev)
395 return 0; 411 return 0;
396 412
397 em28xx_ir_stop(ir); 413 em28xx_ir_stop(ir);
414 ir_input_free(ir->input);
398 input_unregister_device(ir->input); 415 input_unregister_device(ir->input);
399 kfree(ir); 416 kfree(ir);
400 417
diff --git a/drivers/media/video/em28xx/em28xx-reg.h b/drivers/media/video/em28xx/em28xx-reg.h
index ed12e7ffcbd0..058ac87639ce 100644
--- a/drivers/media/video/em28xx/em28xx-reg.h
+++ b/drivers/media/video/em28xx/em28xx-reg.h
@@ -192,6 +192,7 @@
192 192
193/* FIXME: Need to be populated with the other chip ID's */ 193/* FIXME: Need to be populated with the other chip ID's */
194enum em28xx_chip_id { 194enum em28xx_chip_id {
195 CHIP_ID_EM2800 = 7,
195 CHIP_ID_EM2710 = 17, 196 CHIP_ID_EM2710 = 17,
196 CHIP_ID_EM2820 = 18, /* Also used by some em2710 */ 197 CHIP_ID_EM2820 = 18, /* Also used by some em2710 */
197 CHIP_ID_EM2840 = 20, 198 CHIP_ID_EM2840 = 20,
diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c
index 3a1dfb7726f8..7ad65370f274 100644
--- a/drivers/media/video/em28xx/em28xx-video.c
+++ b/drivers/media/video/em28xx/em28xx-video.c
@@ -1060,12 +1060,6 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
1060 /* the em2800 can only scale down to 50% */ 1060 /* the em2800 can only scale down to 50% */
1061 height = height > (3 * maxh / 4) ? maxh : maxh / 2; 1061 height = height > (3 * maxh / 4) ? maxh : maxh / 2;
1062 width = width > (3 * maxw / 4) ? maxw : maxw / 2; 1062 width = width > (3 * maxw / 4) ? maxw : maxw / 2;
1063 /* According to empiatech support the MaxPacketSize is too small
1064 * to support framesizes larger than 640x480 @ 30 fps or 640x576
1065 * @ 25 fps. As this would cut of a part of the image we prefer
1066 * 360x576 or 360x480 for now */
1067 if (width == maxw && height == maxh)
1068 width /= 2;
1069 } else { 1063 } else {
1070 /* width must even because of the YUYV format 1064 /* width must even because of the YUYV format
1071 height must be even because of interlacing */ 1065 height must be even because of interlacing */
@@ -2225,7 +2219,7 @@ static int em28xx_v4l2_close(struct file *filp)
2225 } 2219 }
2226 2220
2227 /* Save some power by putting tuner to sleep */ 2221 /* Save some power by putting tuner to sleep */
2228 v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_standby); 2222 v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_power, 0);
2229 2223
2230 /* do this before setting alternate! */ 2224 /* do this before setting alternate! */
2231 em28xx_uninit_isoc(dev); 2225 em28xx_uninit_isoc(dev);
diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h
index 0a73e8bf0d6e..441df644ddbe 100644
--- a/drivers/media/video/em28xx/em28xx.h
+++ b/drivers/media/video/em28xx/em28xx.h
@@ -110,6 +110,7 @@
110#define EM2820_BOARD_SILVERCREST_WEBCAM 71 110#define EM2820_BOARD_SILVERCREST_WEBCAM 71
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 114
114/* Limits minimum and default number of buffers */ 115/* Limits minimum and default number of buffers */
115#define EM28XX_MIN_BUF 4 116#define EM28XX_MIN_BUF 4
@@ -143,9 +144,6 @@
143 */ 144 */
144#define EM28XX_NUM_PACKETS 40 145#define EM28XX_NUM_PACKETS 40
145 146
146/* default alternate; 0 means choose the best */
147#define EM28XX_PINOUT 0
148
149#define EM28XX_INTERLACED_DEFAULT 1 147#define EM28XX_INTERLACED_DEFAULT 1
150 148
151/* 149/*
@@ -615,7 +613,6 @@ struct em28xx {
615 struct em28xx_dvb *dvb; 613 struct em28xx_dvb *dvb;
616 614
617 /* I2C keyboard data */ 615 /* I2C keyboard data */
618 struct i2c_board_info info;
619 struct IR_i2c_init_data init_data; 616 struct IR_i2c_init_data init_data;
620}; 617};
621 618
@@ -800,7 +797,7 @@ static inline unsigned int norm_maxw(struct em28xx *dev)
800 if (dev->board.is_webcam) 797 if (dev->board.is_webcam)
801 return dev->sensor_xres; 798 return dev->sensor_xres;
802 799
803 if (dev->board.max_range_640_480) 800 if (dev->board.max_range_640_480 || dev->board.is_em2800)
804 return 640; 801 return 640;
805 802
806 return 720; 803 return 720;
diff --git a/drivers/media/video/gspca/Kconfig b/drivers/media/video/gspca/Kconfig
index fe2e490ebc52..609d65b0b10d 100644
--- a/drivers/media/video/gspca/Kconfig
+++ b/drivers/media/video/gspca/Kconfig
@@ -76,10 +76,11 @@ config USB_GSPCA_MR97310A
76 module will be called gspca_mr97310a. 76 module will be called gspca_mr97310a.
77 77
78config USB_GSPCA_OV519 78config USB_GSPCA_OV519
79 tristate "OV519 USB Camera Driver" 79 tristate "OV51x / OVFX2 / W996xCF USB Camera Driver"
80 depends on VIDEO_V4L2 && USB_GSPCA 80 depends on VIDEO_V4L2 && USB_GSPCA
81 help 81 help
82 Say Y here if you want support for cameras based on the OV519 chip. 82 Say Y here if you want support for cameras based on one of these:
83 OV511(+), OV518(+), OV519, OVFX2, W9967CF, W9968CF
83 84
84 To compile this driver as a module, choose M here: the 85 To compile this driver as a module, choose M here: the
85 module will be called gspca_ov519. 86 module will be called gspca_ov519.
@@ -103,6 +104,15 @@ config USB_GSPCA_PAC207
103 To compile this driver as a module, choose M here: the 104 To compile this driver as a module, choose M here: the
104 module will be called gspca_pac207. 105 module will be called gspca_pac207.
105 106
107config USB_GSPCA_PAC7302
108 tristate "Pixart PAC7302 USB Camera Driver"
109 depends on VIDEO_V4L2 && USB_GSPCA
110 help
111 Say Y here if you want support for cameras based on the PAC7302 chip.
112
113 To compile this driver as a module, choose M here: the
114 module will be called gspca_pac7302.
115
106config USB_GSPCA_PAC7311 116config USB_GSPCA_PAC7311
107 tristate "Pixart PAC7311 USB Camera Driver" 117 tristate "Pixart PAC7311 USB Camera Driver"
108 depends on VIDEO_V4L2 && USB_GSPCA 118 depends on VIDEO_V4L2 && USB_GSPCA
@@ -229,6 +239,15 @@ config USB_GSPCA_STK014
229 To compile this driver as a module, choose M here: the 239 To compile this driver as a module, choose M here: the
230 module will be called gspca_stk014. 240 module will be called gspca_stk014.
231 241
242config USB_GSPCA_STV0680
243 tristate "STV0680 USB Camera Driver"
244 depends on VIDEO_V4L2 && USB_GSPCA
245 help
246 Say Y here if you want support for cameras based on the STV0680 chip.
247
248 To compile this driver as a module, choose M here: the
249 module will be called gspca_stv0680.
250
232config USB_GSPCA_SUNPLUS 251config USB_GSPCA_SUNPLUS
233 tristate "SUNPLUS USB Camera Driver" 252 tristate "SUNPLUS USB Camera Driver"
234 depends on VIDEO_V4L2 && USB_GSPCA 253 depends on VIDEO_V4L2 && USB_GSPCA
diff --git a/drivers/media/video/gspca/Makefile b/drivers/media/video/gspca/Makefile
index b7420818037e..ff2c7279d82e 100644
--- a/drivers/media/video/gspca/Makefile
+++ b/drivers/media/video/gspca/Makefile
@@ -8,6 +8,7 @@ obj-$(CONFIG_USB_GSPCA_MR97310A) += gspca_mr97310a.o
8obj-$(CONFIG_USB_GSPCA_OV519) += gspca_ov519.o 8obj-$(CONFIG_USB_GSPCA_OV519) += gspca_ov519.o
9obj-$(CONFIG_USB_GSPCA_OV534) += gspca_ov534.o 9obj-$(CONFIG_USB_GSPCA_OV534) += gspca_ov534.o
10obj-$(CONFIG_USB_GSPCA_PAC207) += gspca_pac207.o 10obj-$(CONFIG_USB_GSPCA_PAC207) += gspca_pac207.o
11obj-$(CONFIG_USB_GSPCA_PAC7302) += gspca_pac7302.o
11obj-$(CONFIG_USB_GSPCA_PAC7311) += gspca_pac7311.o 12obj-$(CONFIG_USB_GSPCA_PAC7311) += gspca_pac7311.o
12obj-$(CONFIG_USB_GSPCA_SN9C20X) += gspca_sn9c20x.o 13obj-$(CONFIG_USB_GSPCA_SN9C20X) += gspca_sn9c20x.o
13obj-$(CONFIG_USB_GSPCA_SONIXB) += gspca_sonixb.o 14obj-$(CONFIG_USB_GSPCA_SONIXB) += gspca_sonixb.o
@@ -22,6 +23,7 @@ obj-$(CONFIG_USB_GSPCA_SQ905) += gspca_sq905.o
22obj-$(CONFIG_USB_GSPCA_SQ905C) += gspca_sq905c.o 23obj-$(CONFIG_USB_GSPCA_SQ905C) += gspca_sq905c.o
23obj-$(CONFIG_USB_GSPCA_SUNPLUS) += gspca_sunplus.o 24obj-$(CONFIG_USB_GSPCA_SUNPLUS) += gspca_sunplus.o
24obj-$(CONFIG_USB_GSPCA_STK014) += gspca_stk014.o 25obj-$(CONFIG_USB_GSPCA_STK014) += gspca_stk014.o
26obj-$(CONFIG_USB_GSPCA_STV0680) += gspca_stv0680.o
25obj-$(CONFIG_USB_GSPCA_T613) += gspca_t613.o 27obj-$(CONFIG_USB_GSPCA_T613) += gspca_t613.o
26obj-$(CONFIG_USB_GSPCA_TV8532) += gspca_tv8532.o 28obj-$(CONFIG_USB_GSPCA_TV8532) += gspca_tv8532.o
27obj-$(CONFIG_USB_GSPCA_VC032X) += gspca_vc032x.o 29obj-$(CONFIG_USB_GSPCA_VC032X) += gspca_vc032x.o
@@ -37,6 +39,7 @@ gspca_mr97310a-objs := mr97310a.o
37gspca_ov519-objs := ov519.o 39gspca_ov519-objs := ov519.o
38gspca_ov534-objs := ov534.o 40gspca_ov534-objs := ov534.o
39gspca_pac207-objs := pac207.o 41gspca_pac207-objs := pac207.o
42gspca_pac7302-objs := pac7302.o
40gspca_pac7311-objs := pac7311.o 43gspca_pac7311-objs := pac7311.o
41gspca_sn9c20x-objs := sn9c20x.o 44gspca_sn9c20x-objs := sn9c20x.o
42gspca_sonixb-objs := sonixb.o 45gspca_sonixb-objs := sonixb.o
@@ -50,6 +53,7 @@ gspca_spca561-objs := spca561.o
50gspca_sq905-objs := sq905.o 53gspca_sq905-objs := sq905.o
51gspca_sq905c-objs := sq905c.o 54gspca_sq905c-objs := sq905c.o
52gspca_stk014-objs := stk014.o 55gspca_stk014-objs := stk014.o
56gspca_stv0680-objs := stv0680.o
53gspca_sunplus-objs := sunplus.o 57gspca_sunplus-objs := sunplus.o
54gspca_t613-objs := t613.o 58gspca_t613-objs := t613.o
55gspca_tv8532-objs := tv8532.o 59gspca_tv8532-objs := tv8532.o
diff --git a/drivers/media/video/gspca/conex.c b/drivers/media/video/gspca/conex.c
index eca003566ae3..2f0b8d621e00 100644
--- a/drivers/media/video/gspca/conex.c
+++ b/drivers/media/video/gspca/conex.c
@@ -888,8 +888,7 @@ static void sd_stop0(struct gspca_dev *gspca_dev)
888} 888}
889 889
890static void sd_pkt_scan(struct gspca_dev *gspca_dev, 890static void sd_pkt_scan(struct gspca_dev *gspca_dev,
891 struct gspca_frame *frame, /* target */ 891 u8 *data, /* isoc packet */
892 __u8 *data, /* isoc packet */
893 int len) /* iso packet length */ 892 int len) /* iso packet length */
894{ 893{
895 struct sd *sd = (struct sd *) gspca_dev; 894 struct sd *sd = (struct sd *) gspca_dev;
@@ -897,16 +896,15 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
897 if (data[0] == 0xff && data[1] == 0xd8) { 896 if (data[0] == 0xff && data[1] == 0xd8) {
898 897
899 /* start of frame */ 898 /* start of frame */
900 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, 899 gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
901 data, 0);
902 900
903 /* put the JPEG header in the new frame */ 901 /* put the JPEG header in the new frame */
904 gspca_frame_add(gspca_dev, FIRST_PACKET, frame, 902 gspca_frame_add(gspca_dev, FIRST_PACKET,
905 sd->jpeg_hdr, JPEG_HDR_SZ); 903 sd->jpeg_hdr, JPEG_HDR_SZ);
906 data += 2; 904 data += 2;
907 len -= 2; 905 len -= 2;
908 } 906 }
909 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); 907 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
910} 908}
911 909
912static void setbrightness(struct gspca_dev*gspca_dev) 910static void setbrightness(struct gspca_dev*gspca_dev)
diff --git a/drivers/media/video/gspca/etoms.c b/drivers/media/video/gspca/etoms.c
index c1461e63647f..9de86419ae1e 100644
--- a/drivers/media/video/gspca/etoms.c
+++ b/drivers/media/video/gspca/etoms.c
@@ -752,8 +752,7 @@ static void do_autogain(struct gspca_dev *gspca_dev)
752#undef LIMIT 752#undef LIMIT
753 753
754static void sd_pkt_scan(struct gspca_dev *gspca_dev, 754static void sd_pkt_scan(struct gspca_dev *gspca_dev,
755 struct gspca_frame *frame, /* target */ 755 u8 *data, /* isoc packet */
756 __u8 *data, /* isoc packet */
757 int len) /* iso packet length */ 756 int len) /* iso packet length */
758{ 757{
759 int seqframe; 758 int seqframe;
@@ -767,14 +766,13 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
767 data[2], data[3], data[4], data[5]); 766 data[2], data[3], data[4], data[5]);
768 data += 30; 767 data += 30;
769 /* don't change datalength as the chips provided it */ 768 /* don't change datalength as the chips provided it */
770 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, 769 gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
771 data, 0); 770 gspca_frame_add(gspca_dev, FIRST_PACKET, data, len);
772 gspca_frame_add(gspca_dev, FIRST_PACKET, frame, data, len);
773 return; 771 return;
774 } 772 }
775 if (len) { 773 if (len) {
776 data += 8; 774 data += 8;
777 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); 775 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
778 } else { /* Drop Packet */ 776 } else { /* Drop Packet */
779 gspca_dev->last_packet_type = DISCARD_PACKET; 777 gspca_dev->last_packet_type = DISCARD_PACKET;
780 } 778 }
diff --git a/drivers/media/video/gspca/finepix.c b/drivers/media/video/gspca/finepix.c
index 480ec5c87d0e..5d90e7448579 100644
--- a/drivers/media/video/gspca/finepix.c
+++ b/drivers/media/video/gspca/finepix.c
@@ -82,7 +82,6 @@ static void dostream(struct work_struct *work)
82 struct gspca_dev *gspca_dev = &dev->gspca_dev; 82 struct gspca_dev *gspca_dev = &dev->gspca_dev;
83 struct urb *urb = gspca_dev->urb[0]; 83 struct urb *urb = gspca_dev->urb[0];
84 u8 *data = urb->transfer_buffer; 84 u8 *data = urb->transfer_buffer;
85 struct gspca_frame *frame;
86 int ret = 0; 85 int ret = 0;
87 int len; 86 int len;
88 87
@@ -118,10 +117,6 @@ again:
118 } 117 }
119 if (!gspca_dev->present || !gspca_dev->streaming) 118 if (!gspca_dev->present || !gspca_dev->streaming)
120 goto out; 119 goto out;
121 frame = gspca_get_i_frame(&dev->gspca_dev);
122 if (frame == NULL)
123 gspca_dev->last_packet_type = DISCARD_PACKET;
124
125 if (len < FPIX_MAX_TRANSFER || 120 if (len < FPIX_MAX_TRANSFER ||
126 (data[len - 2] == 0xff && 121 (data[len - 2] == 0xff &&
127 data[len - 1] == 0xd9)) { 122 data[len - 1] == 0xd9)) {
@@ -132,21 +127,17 @@ again:
132 * but there's nothing we can do. We also end 127 * but there's nothing we can do. We also end
133 * here if the the jpeg ends right at the end 128 * here if the the jpeg ends right at the end
134 * of the frame. */ 129 * of the frame. */
135 if (frame) 130 gspca_frame_add(gspca_dev, LAST_PACKET,
136 frame = gspca_frame_add(gspca_dev, 131 data, len);
137 LAST_PACKET,
138 frame,
139 data, len);
140 break; 132 break;
141 } 133 }
142 134
143 /* got a partial image */ 135 /* got a partial image */
144 if (frame) 136 gspca_frame_add(gspca_dev,
145 gspca_frame_add(gspca_dev, 137 gspca_dev->last_packet_type
146 gspca_dev->last_packet_type 138 == LAST_PACKET
147 == LAST_PACKET 139 ? FIRST_PACKET : INTER_PACKET,
148 ? FIRST_PACKET : INTER_PACKET, 140 data, len);
149 frame, data, len);
150 } 141 }
151 142
152 /* We must wait before trying reading the next 143 /* We must wait before trying reading the next
diff --git a/drivers/media/video/gspca/gl860/gl860-mi1320.c b/drivers/media/video/gspca/gl860/gl860-mi1320.c
index 39f6261c1a0c..1355e526ee84 100644
--- a/drivers/media/video/gspca/gl860/gl860-mi1320.c
+++ b/drivers/media/video/gspca/gl860/gl860-mi1320.c
@@ -1,6 +1,5 @@
1/* @file gl860-mi1320.c 1/* Subdriver for the GL860 chip with the MI1320 sensor
2 * @author Olivier LORIN from my logs 2 * Author Olivier LORIN from own logs
3 * @date 2009-08-27
4 * 3 *
5 * This program is free software; you can redistribute it and/or modify 4 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by 5 * it under the terms of the GNU General Public License as published by
@@ -127,49 +126,49 @@ static u8 dat_wbalBL[] =
127 126
128static u8 dat_hvflip1[] = {0xf0, 0x00, 0xf1, 0x00}; 127static u8 dat_hvflip1[] = {0xf0, 0x00, 0xf1, 0x00};
129 128
130static u8 s000[] = 129static u8 dat_common00[] =
131 "\x00\x01\x07\x6a\x06\x63\x0d\x6a" "\xc0\x00\x10\x10\xc1\x03\xc2\x42" 130 "\x00\x01\x07\x6a\x06\x63\x0d\x6a" "\xc0\x00\x10\x10\xc1\x03\xc2\x42"
132 "\xd8\x04\x58\x00\x04\x02"; 131 "\xd8\x04\x58\x00\x04\x02";
133static u8 s001[] = 132static u8 dat_common01[] =
134 "\x0d\x00\xf1\x0b\x0d\x00\xf1\x08" "\x35\x00\xf1\x22\x68\x00\xf1\x5d" 133 "\x0d\x00\xf1\x0b\x0d\x00\xf1\x08" "\x35\x00\xf1\x22\x68\x00\xf1\x5d"
135 "\xf0\x00\xf1\x01\x06\x70\xf1\x0e" "\xf0\x00\xf1\x02\xdd\x18\xf1\xe0"; 134 "\xf0\x00\xf1\x01\x06\x70\xf1\x0e" "\xf0\x00\xf1\x02\xdd\x18\xf1\xe0";
136static u8 s002[] = 135static u8 dat_common02[] =
137 "\x05\x01\xf1\x84\x06\x00\xf1\x44" "\x07\x00\xf1\xbe\x08\x00\xf1\x1e" 136 "\x05\x01\xf1\x84\x06\x00\xf1\x44" "\x07\x00\xf1\xbe\x08\x00\xf1\x1e"
138 "\x20\x01\xf1\x03\x21\x84\xf1\x00" "\x22\x0d\xf1\x0f\x24\x80\xf1\x00" 137 "\x20\x01\xf1\x03\x21\x84\xf1\x00" "\x22\x0d\xf1\x0f\x24\x80\xf1\x00"
139 "\x34\x18\xf1\x2d\x35\x00\xf1\x22" "\x43\x83\xf1\x83\x59\x00\xf1\xff"; 138 "\x34\x18\xf1\x2d\x35\x00\xf1\x22" "\x43\x83\xf1\x83\x59\x00\xf1\xff";
140static u8 s003[] = 139static u8 dat_common03[] =
141 "\xf0\x00\xf1\x02\x39\x06\xf1\x8c" "\x3a\x06\xf1\x8c\x3b\x03\xf1\xda" 140 "\xf0\x00\xf1\x02\x39\x06\xf1\x8c" "\x3a\x06\xf1\x8c\x3b\x03\xf1\xda"
142 "\x3c\x05\xf1\x30\x57\x01\xf1\x0c" "\x58\x01\xf1\x42\x59\x01\xf1\x0c" 141 "\x3c\x05\xf1\x30\x57\x01\xf1\x0c" "\x58\x01\xf1\x42\x59\x01\xf1\x0c"
143 "\x5a\x01\xf1\x42\x5c\x13\xf1\x0e" "\x5d\x17\xf1\x12\x64\x1e\xf1\x1c"; 142 "\x5a\x01\xf1\x42\x5c\x13\xf1\x0e" "\x5d\x17\xf1\x12\x64\x1e\xf1\x1c";
144static u8 s004[] = 143static u8 dat_common04[] =
145 "\xf0\x00\xf1\x02\x24\x5f\xf1\x20" "\x28\xea\xf1\x02\x5f\x41\xf1\x43"; 144 "\xf0\x00\xf1\x02\x24\x5f\xf1\x20" "\x28\xea\xf1\x02\x5f\x41\xf1\x43";
146static u8 s005[] = 145static u8 dat_common05[] =
147 "\x02\x00\xf1\xee\x03\x29\xf1\x1a" "\x04\x02\xf1\xa4\x09\x00\xf1\x68" 146 "\x02\x00\xf1\xee\x03\x29\xf1\x1a" "\x04\x02\xf1\xa4\x09\x00\xf1\x68"
148 "\x0a\x00\xf1\x2a\x0b\x00\xf1\x04" "\x0c\x00\xf1\x93\x0d\x00\xf1\x82" 147 "\x0a\x00\xf1\x2a\x0b\x00\xf1\x04" "\x0c\x00\xf1\x93\x0d\x00\xf1\x82"
149 "\x0e\x00\xf1\x40\x0f\x00\xf1\x5f" "\x10\x00\xf1\x4e\x11\x00\xf1\x5b"; 148 "\x0e\x00\xf1\x40\x0f\x00\xf1\x5f" "\x10\x00\xf1\x4e\x11\x00\xf1\x5b";
150static u8 s006[] = 149static u8 dat_common06[] =
151 "\x15\x00\xf1\xc9\x16\x00\xf1\x5e" "\x17\x00\xf1\x9d\x18\x00\xf1\x06" 150 "\x15\x00\xf1\xc9\x16\x00\xf1\x5e" "\x17\x00\xf1\x9d\x18\x00\xf1\x06"
152 "\x19\x00\xf1\x89\x1a\x00\xf1\x12" "\x1b\x00\xf1\xa1\x1c\x00\xf1\xe4" 151 "\x19\x00\xf1\x89\x1a\x00\xf1\x12" "\x1b\x00\xf1\xa1\x1c\x00\xf1\xe4"
153 "\x1d\x00\xf1\x7a\x1e\x00\xf1\x64" "\xf6\x00\xf1\x5f"; 152 "\x1d\x00\xf1\x7a\x1e\x00\xf1\x64" "\xf6\x00\xf1\x5f";
154static u8 s007[] = 153static u8 dat_common07[] =
155 "\xf0\x00\xf1\x01\x53\x09\xf1\x03" "\x54\x3d\xf1\x1c\x55\x99\xf1\x72" 154 "\xf0\x00\xf1\x01\x53\x09\xf1\x03" "\x54\x3d\xf1\x1c\x55\x99\xf1\x72"
156 "\x56\xc1\xf1\xb1\x57\xd8\xf1\xce" "\x58\xe0\xf1\x00\xdc\x0a\xf1\x03" 155 "\x56\xc1\xf1\xb1\x57\xd8\xf1\xce" "\x58\xe0\xf1\x00\xdc\x0a\xf1\x03"
157 "\xdd\x45\xf1\x20\xde\xae\xf1\x82" "\xdf\xdc\xf1\xc9\xe0\xf6\xf1\xea" 156 "\xdd\x45\xf1\x20\xde\xae\xf1\x82" "\xdf\xdc\xf1\xc9\xe0\xf6\xf1\xea"
158 "\xe1\xff\xf1\x00"; 157 "\xe1\xff\xf1\x00";
159static u8 s008[] = 158static u8 dat_common08[] =
160 "\xf0\x00\xf1\x01\x80\x00\xf1\x06" "\x81\xf6\xf1\x08\x82\xfb\xf1\xf7" 159 "\xf0\x00\xf1\x01\x80\x00\xf1\x06" "\x81\xf6\xf1\x08\x82\xfb\xf1\xf7"
161 "\x83\x00\xf1\xfe\xb6\x07\xf1\x03" "\xb7\x18\xf1\x0c\x84\xfb\xf1\x06" 160 "\x83\x00\xf1\xfe\xb6\x07\xf1\x03" "\xb7\x18\xf1\x0c\x84\xfb\xf1\x06"
162 "\x85\xfb\xf1\xf9\x86\x00\xf1\xff" "\xb8\x07\xf1\x04\xb9\x16\xf1\x0a"; 161 "\x85\xfb\xf1\xf9\x86\x00\xf1\xff" "\xb8\x07\xf1\x04\xb9\x16\xf1\x0a";
163static u8 s009[] = 162static u8 dat_common09[] =
164 "\x87\xfa\xf1\x05\x88\xfc\xf1\xf9" "\x89\x00\xf1\xff\xba\x06\xf1\x03" 163 "\x87\xfa\xf1\x05\x88\xfc\xf1\xf9" "\x89\x00\xf1\xff\xba\x06\xf1\x03"
165 "\xbb\x17\xf1\x09\x8a\xe8\xf1\x14" "\x8b\xf7\xf1\xf0\x8c\xfd\xf1\xfa" 164 "\xbb\x17\xf1\x09\x8a\xe8\xf1\x14" "\x8b\xf7\xf1\xf0\x8c\xfd\xf1\xfa"
166 "\x8d\x00\xf1\x00\xbc\x05\xf1\x01" "\xbd\x0c\xf1\x08\xbe\x00\xf1\x14"; 165 "\x8d\x00\xf1\x00\xbc\x05\xf1\x01" "\xbd\x0c\xf1\x08\xbe\x00\xf1\x14";
167static u8 s010[] = 166static u8 dat_common10[] =
168 "\x8e\xea\xf1\x13\x8f\xf7\xf1\xf2" "\x90\xfd\xf1\xfa\x91\x00\xf1\x00" 167 "\x8e\xea\xf1\x13\x8f\xf7\xf1\xf2" "\x90\xfd\xf1\xfa\x91\x00\xf1\x00"
169 "\xbf\x05\xf1\x01\xc0\x0a\xf1\x08" "\xc1\x00\xf1\x0c\x92\xed\xf1\x0f" 168 "\xbf\x05\xf1\x01\xc0\x0a\xf1\x08" "\xc1\x00\xf1\x0c\x92\xed\xf1\x0f"
170 "\x93\xf9\xf1\xf4\x94\xfe\xf1\xfb" "\x95\x00\xf1\x00\xc2\x04\xf1\x01" 169 "\x93\xf9\xf1\xf4\x94\xfe\xf1\xfb" "\x95\x00\xf1\x00\xc2\x04\xf1\x01"
171 "\xc3\x0a\xf1\x07\xc4\x00\xf1\x10"; 170 "\xc3\x0a\xf1\x07\xc4\x00\xf1\x10";
172static u8 s011[] = 171static u8 dat_common11[] =
173 "\xf0\x00\xf1\x01\x05\x00\xf1\x06" "\x25\x00\xf1\x55\x34\x10\xf1\x10" 172 "\xf0\x00\xf1\x01\x05\x00\xf1\x06" "\x25\x00\xf1\x55\x34\x10\xf1\x10"
174 "\x35\xf0\xf1\x10\x3a\x02\xf1\x03" "\x3b\x04\xf1\x2a\x9b\x43\xf1\x00" 173 "\x35\xf0\xf1\x10\x3a\x02\xf1\x03" "\x3b\x04\xf1\x2a\x9b\x43\xf1\x00"
175 "\xa4\x03\xf1\xc0\xa7\x02\xf1\x81"; 174 "\xa4\x03\xf1\xc0\xa7\x02\xf1\x81";
@@ -222,26 +221,26 @@ void mi1320_init_settings(struct gspca_dev *gspca_dev)
222 221
223static void common(struct gspca_dev *gspca_dev) 222static void common(struct gspca_dev *gspca_dev)
224{ 223{
225 s32 n; /* reserved for FETCH macros */ 224 s32 n; /* reserved for FETCH functions */
226 225
227 ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 22, s000); 226 ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 22, dat_common00);
228 ctrl_out(gspca_dev, 0x40, 1, 0x0041, 0x0000, 0, NULL); 227 ctrl_out(gspca_dev, 0x40, 1, 0x0041, 0x0000, 0, NULL);
229 ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 32, s001); 228 ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 32, dat_common01);
230 n = fetch_validx(gspca_dev, tbl_common, ARRAY_SIZE(tbl_common)); 229 n = fetch_validx(gspca_dev, tbl_common, ARRAY_SIZE(tbl_common));
231 ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 48, s002); 230 ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 48, dat_common02);
232 ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 48, s003); 231 ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 48, dat_common03);
233 ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 16, s004); 232 ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 16, dat_common04);
234 ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 48, s005); 233 ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 48, dat_common05);
235 ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 44, s006); 234 ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 44, dat_common06);
236 keep_on_fetching_validx(gspca_dev, tbl_common, 235 keep_on_fetching_validx(gspca_dev, tbl_common,
237 ARRAY_SIZE(tbl_common), n); 236 ARRAY_SIZE(tbl_common), n);
238 ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 52, s007); 237 ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 52, dat_common07);
239 ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 48, s008); 238 ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 48, dat_common08);
240 ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 48, s009); 239 ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 48, dat_common09);
241 ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 56, s010); 240 ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 56, dat_common10);
242 keep_on_fetching_validx(gspca_dev, tbl_common, 241 keep_on_fetching_validx(gspca_dev, tbl_common,
243 ARRAY_SIZE(tbl_common), n); 242 ARRAY_SIZE(tbl_common), n);
244 ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 40, s011); 243 ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 40, dat_common11);
245 keep_on_fetching_validx(gspca_dev, tbl_common, 244 keep_on_fetching_validx(gspca_dev, tbl_common,
246 ARRAY_SIZE(tbl_common), n); 245 ARRAY_SIZE(tbl_common), n);
247} 246}
diff --git a/drivers/media/video/gspca/gl860/gl860-mi2020.c b/drivers/media/video/gspca/gl860/gl860-mi2020.c
index ffb09fed3e8c..80cb3f1b36f7 100644
--- a/drivers/media/video/gspca/gl860/gl860-mi2020.c
+++ b/drivers/media/video/gspca/gl860/gl860-mi2020.c
@@ -1,7 +1,6 @@
1/* @file gl860-mi2020.c 1/* Subdriver for the GL860 chip with the MI2020 sensor
2 * @author Olivier LORIN, from Ice/Soro2005's logs(A), Fret_saw/Hulkie's 2 * Author Olivier LORIN, from Ice/Soro2005's logs(A), Fret_saw/Hulkie's
3 * logs(B) and Tricid"s logs(C). With the help of Kytrix/BUGabundo/Blazercist. 3 * logs(B) and Tricid"s logs(C). With the help of Kytrix/BUGabundo/Blazercist.
4 * @date 2009-08-27
5 * 4 *
6 * This program is free software; you can redistribute it and/or modify 5 * 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 6 * it under the terms of the GNU General Public License as published by
@@ -41,7 +40,7 @@ static u8 dat_freq1[] = { 0x8c, 0xa4, 0x04 };
41static u8 dat_multi5[] = { 0x8c, 0xa1, 0x03 }; 40static u8 dat_multi5[] = { 0x8c, 0xa1, 0x03 };
42static u8 dat_multi6[] = { 0x90, 0x00, 0x05 }; 41static u8 dat_multi6[] = { 0x90, 0x00, 0x05 };
43 42
44static struct validx tbl_common_a[] = { 43static struct validx tbl_common1[] = {
45 {0x0000, 0x0000}, 44 {0x0000, 0x0000},
46 {1, 0xffff}, /* msleep(35); */ 45 {1, 0xffff}, /* msleep(35); */
47 {0x006a, 0x0007}, {0x0063, 0x0006}, {0x006a, 0x000d}, {0x0000, 0x00c0}, 46 {0x006a, 0x0007}, {0x0063, 0x0006}, {0x006a, 0x000d}, {0x0000, 0x00c0},
@@ -49,7 +48,7 @@ static struct validx tbl_common_a[] = {
49 {0x0000, 0x0058}, {0x0002, 0x0004}, {0x0041, 0x0000}, 48 {0x0000, 0x0058}, {0x0002, 0x0004}, {0x0041, 0x0000},
50}; 49};
51 50
52static struct validx tbl_common_b[] = { 51static struct validx tbl_common2[] = {
53 {0x006a, 0x0007}, 52 {0x006a, 0x0007},
54 {35, 0xffff}, 53 {35, 0xffff},
55 {0x00ef, 0x0006}, 54 {0x00ef, 0x0006},
@@ -60,7 +59,7 @@ static struct validx tbl_common_b[] = {
60 {0x0004, 0x00d8}, {0x0000, 0x0058}, {0x0041, 0x0000}, 59 {0x0004, 0x00d8}, {0x0000, 0x0058}, {0x0041, 0x0000},
61}; 60};
62 61
63static struct idxdata tbl_common_c[] = { 62static struct idxdata tbl_common3[] = {
64 {0x32, "\x02\x00\x08"}, {0x33, "\xf4\x03\x1d"}, 63 {0x32, "\x02\x00\x08"}, {0x33, "\xf4\x03\x1d"},
65 {6, "\xff\xff\xff"}, /* 12 */ 64 {6, "\xff\xff\xff"}, /* 12 */
66 {0x34, "\x1e\x8f\x09"}, {0x34, "\x1c\x01\x28"}, {0x34, "\x1e\x8f\x09"}, 65 {0x34, "\x1e\x8f\x09"}, {0x34, "\x1c\x01\x28"}, {0x34, "\x1e\x8f\x09"},
@@ -109,7 +108,7 @@ static struct idxdata tbl_common_c[] = {
109 {0x33, "\x8c\xa2\x03"}, {0x33, "\x90\x00\xbb"}, 108 {0x33, "\x8c\xa2\x03"}, {0x33, "\x90\x00\xbb"},
110}; 109};
111 110
112static struct idxdata tbl_common_d[] = { 111static struct idxdata tbl_common4[] = {
113 {0x33, "\x8c\x22\x2e"}, {0x33, "\x90\x00\xa0"}, {0x33, "\x8c\xa4\x08"}, 112 {0x33, "\x8c\x22\x2e"}, {0x33, "\x90\x00\xa0"}, {0x33, "\x8c\xa4\x08"},
114 {0x33, "\x90\x00\x1f"}, {0x33, "\x8c\xa4\x09"}, {0x33, "\x90\x00\x21"}, 113 {0x33, "\x90\x00\x1f"}, {0x33, "\x8c\xa4\x09"}, {0x33, "\x90\x00\x21"},
115 {0x33, "\x8c\xa4\x0a"}, {0x33, "\x90\x00\x25"}, {0x33, "\x8c\xa4\x0b"}, 114 {0x33, "\x8c\xa4\x0a"}, {0x33, "\x90\x00\x25"}, {0x33, "\x8c\xa4\x0b"},
@@ -118,7 +117,7 @@ static struct idxdata tbl_common_d[] = {
118 {0x33, "\x90\x00\xa0"}, {0x33, "\x8c\x24\x17"}, {0x33, "\x90\x00\xc0"}, 117 {0x33, "\x90\x00\xa0"}, {0x33, "\x8c\x24\x17"}, {0x33, "\x90\x00\xc0"},
119}; 118};
120 119
121static struct idxdata tbl_common_e[] = { 120static struct idxdata tbl_common5[] = {
122 {0x33, "\x8c\xa4\x04"}, {0x33, "\x90\x00\x80"}, {0x33, "\x8c\xa7\x9d"}, 121 {0x33, "\x8c\xa4\x04"}, {0x33, "\x90\x00\x80"}, {0x33, "\x8c\xa7\x9d"},
123 {0x33, "\x90\x00\x00"}, {0x33, "\x8c\xa7\x9e"}, {0x33, "\x90\x00\x00"}, 122 {0x33, "\x90\x00\x00"}, {0x33, "\x8c\xa7\x9e"}, {0x33, "\x90\x00\x00"},
124 {0x33, "\x8c\xa2\x0c"}, {0x33, "\x90\x00\x17"}, {0x33, "\x8c\xa2\x15"}, 123 {0x33, "\x8c\xa2\x0c"}, {0x33, "\x90\x00\x17"}, {0x33, "\x8c\xa2\x15"},
@@ -180,7 +179,7 @@ static struct validx tbl_init_at_startup[] = {
180 {53, 0xffff}, 179 {53, 0xffff},
181}; 180};
182 181
183static struct idxdata tbl_init_post_alt_low_a[] = { 182static struct idxdata tbl_init_post_alt_low1[] = {
184 {0x33, "\x8c\x27\x15"}, {0x33, "\x90\x00\x25"}, {0x33, "\x8c\x22\x2e"}, 183 {0x33, "\x8c\x27\x15"}, {0x33, "\x90\x00\x25"}, {0x33, "\x8c\x22\x2e"},
185 {0x33, "\x90\x00\x81"}, {0x33, "\x8c\xa4\x08"}, {0x33, "\x90\x00\x17"}, 184 {0x33, "\x90\x00\x81"}, {0x33, "\x8c\xa4\x08"}, {0x33, "\x90\x00\x17"},
186 {0x33, "\x8c\xa4\x09"}, {0x33, "\x90\x00\x1a"}, {0x33, "\x8c\xa4\x0a"}, 185 {0x33, "\x8c\xa4\x09"}, {0x33, "\x90\x00\x1a"}, {0x33, "\x8c\xa4\x0a"},
@@ -189,7 +188,7 @@ static struct idxdata tbl_init_post_alt_low_a[] = {
189 {0x33, "\x90\x00\x9b"}, 188 {0x33, "\x90\x00\x9b"},
190}; 189};
191 190
192static struct idxdata tbl_init_post_alt_low_b[] = { 191static struct idxdata tbl_init_post_alt_low2[] = {
193 {0x33, "\x8c\x27\x03"}, {0x33, "\x90\x03\x24"}, {0x33, "\x8c\x27\x05"}, 192 {0x33, "\x8c\x27\x03"}, {0x33, "\x90\x03\x24"}, {0x33, "\x8c\x27\x05"},
194 {0x33, "\x90\x02\x58"}, {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x05"}, 193 {0x33, "\x90\x02\x58"}, {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x05"},
195 {2, "\xff\xff\xff"}, 194 {2, "\xff\xff\xff"},
@@ -197,7 +196,7 @@ static struct idxdata tbl_init_post_alt_low_b[] = {
197 {2, "\xff\xff\xff"}, 196 {2, "\xff\xff\xff"},
198}; 197};
199 198
200static struct idxdata tbl_init_post_alt_low_c[] = { 199static struct idxdata tbl_init_post_alt_low3[] = {
201 {0x34, "\x1e\x8f\x09"}, {0x34, "\x1c\x01\x28"}, {0x34, "\x1e\x8f\x09"}, 200 {0x34, "\x1e\x8f\x09"}, {0x34, "\x1c\x01\x28"}, {0x34, "\x1e\x8f\x09"},
202 {2, "\xff\xff\xff"}, 201 {2, "\xff\xff\xff"},
203 {0x34, "\x1e\x8f\x09"}, {0x32, "\x14\x06\xe6"}, {0x33, "\x8c\xa1\x20"}, 202 {0x34, "\x1e\x8f\x09"}, {0x32, "\x14\x06\xe6"}, {0x33, "\x8c\xa1\x20"},
@@ -221,7 +220,7 @@ static struct idxdata tbl_init_post_alt_low_c[] = {
221 {1, "\xff\xff\xff"}, 220 {1, "\xff\xff\xff"},
222}; 221};
223 222
224static struct idxdata tbl_init_post_alt_low_d[] = { 223static struct idxdata tbl_init_post_alt_low4[] = {
225 {0x32, "\x10\x01\xf8"}, {0x34, "\xce\x01\xa8"}, {0x34, "\xd0\x66\x33"}, 224 {0x32, "\x10\x01\xf8"}, {0x34, "\xce\x01\xa8"}, {0x34, "\xd0\x66\x33"},
226 {0x34, "\xd2\x31\x9a"}, {0x34, "\xd4\x94\x63"}, {0x34, "\xd6\x4b\x25"}, 225 {0x34, "\xd2\x31\x9a"}, {0x34, "\xd4\x94\x63"}, {0x34, "\xd6\x4b\x25"},
227 {0x34, "\xd8\x26\x70"}, {0x34, "\xda\x72\x4c"}, {0x34, "\xdc\xff\x04"}, 226 {0x34, "\xd8\x26\x70"}, {0x34, "\xda\x72\x4c"}, {0x34, "\xdc\xff\x04"},
@@ -267,7 +266,7 @@ static struct idxdata tbl_init_post_alt_low_d[] = {
267 {0x32, "\x6c\x14\x08"}, 266 {0x32, "\x6c\x14\x08"},
268}; 267};
269 268
270static struct idxdata tbl_init_post_alt_big_a[] = { 269static struct idxdata tbl_init_post_alt_big1[] = {
271 {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x05"}, 270 {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x05"},
272 {2, "\xff\xff\xff"}, 271 {2, "\xff\xff\xff"},
273 {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x06"}, 272 {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x06"},
@@ -288,7 +287,7 @@ static struct idxdata tbl_init_post_alt_big_a[] = {
288 {0x34, "\x04\x00\x2a"}, {0x33, "\x8c\xa7\x02"}, {0x33, "\x90\x00\x01"}, 287 {0x34, "\x04\x00\x2a"}, {0x33, "\x8c\xa7\x02"}, {0x33, "\x90\x00\x01"},
289}; 288};
290 289
291static struct idxdata tbl_init_post_alt_big_b[] = { 290static struct idxdata tbl_init_post_alt_big2[] = {
292 {0x32, "\x10\x01\xf8"}, {0x34, "\xce\x01\xa8"}, {0x34, "\xd0\x66\x33"}, 291 {0x32, "\x10\x01\xf8"}, {0x34, "\xce\x01\xa8"}, {0x34, "\xd0\x66\x33"},
293 {0x34, "\xd2\x31\x9a"}, {0x34, "\xd4\x94\x63"}, {0x34, "\xd6\x4b\x25"}, 292 {0x34, "\xd2\x31\x9a"}, {0x34, "\xd4\x94\x63"}, {0x34, "\xd6\x4b\x25"},
294 {0x34, "\xd8\x26\x70"}, {0x34, "\xda\x72\x4c"}, {0x34, "\xdc\xff\x04"}, 293 {0x34, "\xd8\x26\x70"}, {0x34, "\xda\x72\x4c"}, {0x34, "\xdc\xff\x04"},
@@ -317,7 +316,7 @@ static struct idxdata tbl_init_post_alt_big_b[] = {
317 {0x32, "\x10\x01\xfc"}, {0x33, "\x8c\xa1\x18"}, {0x33, "\x90\x00\x3c"}, 316 {0x32, "\x10\x01\xfc"}, {0x33, "\x8c\xa1\x18"}, {0x33, "\x90\x00\x3c"},
318}; 317};
319 318
320static struct idxdata tbl_init_post_alt_big_c[] = { 319static struct idxdata tbl_init_post_alt_big3[] = {
321 {0x33, "\x8c\xa1\x02"}, 320 {0x33, "\x8c\xa1\x02"},
322 {0x33, "\x90\x00\x1f"}, 321 {0x33, "\x90\x00\x1f"},
323 {0x33, "\x8c\xa1\x02"}, 322 {0x33, "\x8c\xa1\x02"},
@@ -388,14 +387,14 @@ static void common(struct gspca_dev *gspca_dev)
388 s32 reso = gspca_dev->cam.cam_mode[(s32) gspca_dev->curr_mode].priv; 387 s32 reso = gspca_dev->cam.cam_mode[(s32) gspca_dev->curr_mode].priv;
389 388
390 if (_MI2020b_) { 389 if (_MI2020b_) {
391 fetch_validx(gspca_dev, tbl_common_a, ARRAY_SIZE(tbl_common_a)); 390 fetch_validx(gspca_dev, tbl_common1, ARRAY_SIZE(tbl_common1));
392 } else { 391 } else {
393 if (_MI2020_) 392 if (_MI2020_)
394 ctrl_out(gspca_dev, 0x40, 1, 0x0008, 0x0004, 0, NULL); 393 ctrl_out(gspca_dev, 0x40, 1, 0x0008, 0x0004, 0, NULL);
395 else 394 else
396 ctrl_out(gspca_dev, 0x40, 1, 0x0002, 0x0004, 0, NULL); 395 ctrl_out(gspca_dev, 0x40, 1, 0x0002, 0x0004, 0, NULL);
397 msleep(35); 396 msleep(35);
398 fetch_validx(gspca_dev, tbl_common_b, ARRAY_SIZE(tbl_common_b)); 397 fetch_validx(gspca_dev, tbl_common2, ARRAY_SIZE(tbl_common2));
399 } 398 }
400 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x86\x25\x01"); 399 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x86\x25\x01");
401 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x86\x25\x00"); 400 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x86\x25\x00");
@@ -403,13 +402,13 @@ static void common(struct gspca_dev *gspca_dev)
403 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0030, 3, "\x1a\x0a\xcc"); 402 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0030, 3, "\x1a\x0a\xcc");
404 if (reso == IMAGE_1600) 403 if (reso == IMAGE_1600)
405 msleep(2); /* 1600 */ 404 msleep(2); /* 1600 */
406 fetch_idxdata(gspca_dev, tbl_common_c, ARRAY_SIZE(tbl_common_c)); 405 fetch_idxdata(gspca_dev, tbl_common3, ARRAY_SIZE(tbl_common3));
407 406
408 if (_MI2020b_ || _MI2020_) 407 if (_MI2020b_ || _MI2020_)
409 fetch_idxdata(gspca_dev, tbl_common_d, 408 fetch_idxdata(gspca_dev, tbl_common4,
410 ARRAY_SIZE(tbl_common_d)); 409 ARRAY_SIZE(tbl_common4));
411 410
412 fetch_idxdata(gspca_dev, tbl_common_e, ARRAY_SIZE(tbl_common_e)); 411 fetch_idxdata(gspca_dev, tbl_common5, ARRAY_SIZE(tbl_common5));
413 if (_MI2020b_ || _MI2020_) { 412 if (_MI2020b_ || _MI2020_) {
414 /* Different from fret */ 413 /* Different from fret */
415 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x90\x00\x78"); 414 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x90\x00\x78");
@@ -525,15 +524,15 @@ static int mi2020_init_post_alt(struct gspca_dev *gspca_dev)
525 12, dat_800); 524 12, dat_800);
526 525
527 if (_MI2020c_) 526 if (_MI2020c_)
528 fetch_idxdata(gspca_dev, tbl_init_post_alt_low_a, 527 fetch_idxdata(gspca_dev, tbl_init_post_alt_low1,
529 ARRAY_SIZE(tbl_init_post_alt_low_a)); 528 ARRAY_SIZE(tbl_init_post_alt_low1));
530 529
531 if (reso == IMAGE_800) 530 if (reso == IMAGE_800)
532 fetch_idxdata(gspca_dev, tbl_init_post_alt_low_b, 531 fetch_idxdata(gspca_dev, tbl_init_post_alt_low2,
533 ARRAY_SIZE(tbl_init_post_alt_low_b)); 532 ARRAY_SIZE(tbl_init_post_alt_low2));
534 533
535 fetch_idxdata(gspca_dev, tbl_init_post_alt_low_c, 534 fetch_idxdata(gspca_dev, tbl_init_post_alt_low3,
536 ARRAY_SIZE(tbl_init_post_alt_low_c)); 535 ARRAY_SIZE(tbl_init_post_alt_low3));
537 536
538 if (_MI2020b_) { 537 if (_MI2020b_) {
539 ctrl_out(gspca_dev, 0x40, 1, 0x0001, 0x0010, 0, NULL); 538 ctrl_out(gspca_dev, 0x40, 1, 0x0001, 0x0010, 0, NULL);
@@ -574,8 +573,8 @@ static int mi2020_init_post_alt(struct gspca_dev *gspca_dev)
574 msleep(5);/* " */ 573 msleep(5);/* " */
575 574
576 if (_MI2020c_) { 575 if (_MI2020c_) {
577 fetch_idxdata(gspca_dev, tbl_init_post_alt_low_d, 576 fetch_idxdata(gspca_dev, tbl_init_post_alt_low4,
578 ARRAY_SIZE(tbl_init_post_alt_low_d)); 577 ARRAY_SIZE(tbl_init_post_alt_low4));
579 } else { 578 } else {
580 ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0000, 1, &c); 579 ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0000, 1, &c);
581 msleep(14); /* 0xd8 */ 580 msleep(14); /* 0xd8 */
@@ -644,8 +643,8 @@ static int mi2020_init_post_alt(struct gspca_dev *gspca_dev)
644 3, "\x90\x04\xb0"); 643 3, "\x90\x04\xb0");
645 } 644 }
646 645
647 fetch_idxdata(gspca_dev, tbl_init_post_alt_big_a, 646 fetch_idxdata(gspca_dev, tbl_init_post_alt_big1,
648 ARRAY_SIZE(tbl_init_post_alt_big_a)); 647 ARRAY_SIZE(tbl_init_post_alt_big1));
649 648
650 if (reso == IMAGE_1600) 649 if (reso == IMAGE_1600)
651 msleep(13); /* 1600 */ 650 msleep(13); /* 1600 */
@@ -708,8 +707,8 @@ static int mi2020_init_post_alt(struct gspca_dev *gspca_dev)
708 msleep(14); 707 msleep(14);
709 708
710 if (_MI2020c_) 709 if (_MI2020c_)
711 fetch_idxdata(gspca_dev, tbl_init_post_alt_big_b, 710 fetch_idxdata(gspca_dev, tbl_init_post_alt_big2,
712 ARRAY_SIZE(tbl_init_post_alt_big_b)); 711 ARRAY_SIZE(tbl_init_post_alt_big2));
713 712
714 /* flip/mirror */ 713 /* flip/mirror */
715 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_hvflip1); 714 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_hvflip1);
@@ -738,8 +737,8 @@ static int mi2020_init_post_alt(struct gspca_dev *gspca_dev)
738 sd->nbIm = 0; 737 sd->nbIm = 0;
739 738
740 if (_MI2020c_) 739 if (_MI2020c_)
741 fetch_idxdata(gspca_dev, tbl_init_post_alt_big_c, 740 fetch_idxdata(gspca_dev, tbl_init_post_alt_big3,
742 ARRAY_SIZE(tbl_init_post_alt_big_c)); 741 ARRAY_SIZE(tbl_init_post_alt_big3));
743 } 742 }
744 743
745 sd->vold.mirror = mirror; 744 sd->vold.mirror = mirror;
diff --git a/drivers/media/video/gspca/gl860/gl860-ov2640.c b/drivers/media/video/gspca/gl860/gl860-ov2640.c
index 14b9c373f9f7..768cac5cd72b 100644
--- a/drivers/media/video/gspca/gl860/gl860-ov2640.c
+++ b/drivers/media/video/gspca/gl860/gl860-ov2640.c
@@ -1,6 +1,5 @@
1/* @file gl860-ov2640.c 1/* Subdriver for the GL860 chip with the OV2640 sensor
2 * @author Olivier LORIN, from Malmostoso's logs 2 * Author Olivier LORIN, from Malmostoso's logs
3 * @date 2009-08-27
4 * 3 *
5 * This program is free software; you can redistribute it and/or modify 4 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by 5 * it under the terms of the GNU General Public License as published by
@@ -21,8 +20,12 @@
21#include "gl860.h" 20#include "gl860.h"
22 21
23static u8 dat_init1[] = "\x00\x41\x07\x6a\x06\x61\x0d\x6a" "\x10\x10\xc1\x01"; 22static u8 dat_init1[] = "\x00\x41\x07\x6a\x06\x61\x0d\x6a" "\x10\x10\xc1\x01";
24static u8 dat_init2[] = {0x61}; /* expected */ 23
25static u8 dat_init3[] = {0x51}; /* expected */ 24static u8 c61[] = {0x61}; /* expected */
25static u8 c51[] = {0x51}; /* expected */
26static u8 c50[] = {0x50}; /* expected */
27static u8 c28[] = {0x28}; /* expected */
28static u8 ca8[] = {0xa8}; /* expected */
26 29
27static u8 dat_post[] = 30static u8 dat_post[] =
28 "\x00\x41\x07\x6a\x06\xef\x0d\x6a" "\x10\x10\xc1\x01"; 31 "\x00\x41\x07\x6a\x06\xef\x0d\x6a" "\x10\x10\xc1\x01";
@@ -32,10 +35,6 @@ static u8 dat_800[] = "\xd0\x01\xd1\x10\xd2\x58\xd3\x02\xd4\x18\xd5\x21";
32static u8 dat_1280[] = "\xd0\x01\xd1\x18\xd2\xc0\xd3\x02\xd4\x28\xd5\x01"; 35static u8 dat_1280[] = "\xd0\x01\xd1\x18\xd2\xc0\xd3\x02\xd4\x28\xd5\x01";
33static u8 dat_1600[] = "\xd0\x01\xd1\x20\xd2\xb0\xd3\x02\xd4\x30\xd5\x41"; 36static u8 dat_1600[] = "\xd0\x01\xd1\x20\xd2\xb0\xd3\x02\xd4\x30\xd5\x41";
34 37
35static u8 c50[] = {0x50}; /* expected */
36static u8 c28[] = {0x28}; /* expected */
37static u8 ca8[] = {0xa8}; /* expected */
38
39static struct validx tbl_init_at_startup[] = { 38static struct validx tbl_init_at_startup[] = {
40 {0x0000, 0x0000}, {0x0010, 0x0010}, {0x0008, 0x00c0}, {0x0001, 0x00c1}, 39 {0x0000, 0x0000}, {0x0010, 0x0010}, {0x0008, 0x00c0}, {0x0001, 0x00c1},
41 {0x0001, 0x00c2}, {0x0020, 0x0006}, {0x006a, 0x000d}, 40 {0x0001, 0x00c2}, {0x0020, 0x0006}, {0x006a, 0x000d},
@@ -92,7 +91,7 @@ static struct validx tbl_common[] = {
92 {0x6000, 0x0010}, 91 {0x6000, 0x0010},
93}; 92};
94 93
95static struct validx tbl_sensor_settings_common_a[] = { 94static struct validx tbl_sensor_settings_common1[] = {
96 {0x0041, 0x0000}, {0x006a, 0x0007}, {0x00ef, 0x0006}, {0x006a, 0x000d}, 95 {0x0041, 0x0000}, {0x006a, 0x0007}, {0x00ef, 0x0006}, {0x006a, 0x000d},
97 {0x0000, 0x00c0}, {0x0010, 0x0010}, {0x0001, 0x00c1}, {0x0041, 0x00c2}, 96 {0x0000, 0x00c0}, {0x0010, 0x0010}, {0x0001, 0x00c1}, {0x0041, 0x00c2},
98 {0x0004, 0x00d8}, {0x0012, 0x0004}, {0x0000, 0x0058}, {0x0041, 0x0000}, 97 {0x0004, 0x00d8}, {0x0012, 0x0004}, {0x0000, 0x0058}, {0x0041, 0x0000},
@@ -104,40 +103,10 @@ static struct validx tbl_sensor_settings_common_a[] = {
104 {0x0040, 0x0000}, 103 {0x0040, 0x0000},
105}; 104};
106 105
107static struct validx tbl_sensor_settings_common_b[] = { 106static struct validx tbl_sensor_settings_common2[] = {
108 {0x6001, 0x00ff}, {0x6038, 0x000c}, 107 {0x6001, 0x00ff}, {0x6038, 0x000c},
109 {10, 0xffff}, 108 {10, 0xffff},
110 {0x6000, 0x0011}, 109 {0x6000, 0x0011},
111 /* backlight=31/64 */
112 {0x6001, 0x00ff}, {0x603e, 0x0024}, {0x6034, 0x0025},
113 /* bright=0/256 */
114 {0x6000, 0x00ff}, {0x6009, 0x007c}, {0x6000, 0x007d},
115 /* wbal=64/128 */
116 {0x6000, 0x00ff}, {0x6003, 0x007c}, {0x6040, 0x007d},
117 /* cntr=0/256 */
118 {0x6000, 0x00ff}, {0x6007, 0x007c}, {0x6000, 0x007d},
119 /* sat=128/256 */
120 {0x6000, 0x00ff}, {0x6001, 0x007c}, {0x6080, 0x007d},
121 /* sharpness=0/32 */
122 {0x6000, 0x00ff}, {0x6001, 0x0092}, {0x60c0, 0x0093},
123 /* hue=0/256 */
124 {0x6000, 0x00ff}, {0x6002, 0x007c}, {0x6000, 0x007d},
125 /* gam=32/64 */
126 {0x6000, 0x00ff}, {0x6008, 0x007c}, {0x6020, 0x007d},
127 /* image right up */
128 {0xffff, 0xffff},
129 {15, 0xffff},
130 {0x6001, 0x00ff}, {0x6000, 0x8004},
131 {0xffff, 0xffff},
132 {0x60a8, 0x0004},
133 {15, 0xffff},
134 {0x6001, 0x00ff}, {0x6000, 0x8004},
135 {0xffff, 0xffff},
136 {0x60f8, 0x0004},
137 /* image right up */
138 {0xffff, 0xffff},
139 /* backlight=31/64 */
140 {0x6001, 0x00ff}, {0x603e, 0x0024}, {0x6034, 0x0025},
141}; 110};
142 111
143static struct validx tbl_640[] = { 112static struct validx tbl_640[] = {
@@ -166,7 +135,7 @@ static struct validx tbl_800[] = {
166 {0x60ff, 0x00dd}, {0x6020, 0x008c}, {0x6001, 0x00ff}, {0x6044, 0x0018}, 135 {0x60ff, 0x00dd}, {0x6020, 0x008c}, {0x6001, 0x00ff}, {0x6044, 0x0018},
167}; 136};
168 137
169static struct validx tbl_big_a[] = { 138static struct validx tbl_big1[] = {
170 {0x0002, 0x00c1}, {0x6000, 0x00ff}, {0x60f1, 0x00dd}, {0x6004, 0x00e0}, 139 {0x0002, 0x00c1}, {0x6000, 0x00ff}, {0x60f1, 0x00dd}, {0x6004, 0x00e0},
171 {0x6001, 0x00ff}, {0x6000, 0x0012}, {0x6000, 0x0000}, {0x6000, 0x0045}, 140 {0x6001, 0x00ff}, {0x6000, 0x0012}, {0x6000, 0x0000}, {0x6000, 0x0045},
172 {0x6000, 0x0010}, {0x6000, 0x0011}, {0x6011, 0x0017}, {0x6075, 0x0018}, 141 {0x6000, 0x0010}, {0x6000, 0x0011}, {0x6011, 0x0017}, {0x6075, 0x0018},
@@ -176,14 +145,14 @@ static struct validx tbl_big_a[] = {
176 {0x60c8, 0x00c0}, {0x6096, 0x00c1}, {0x6000, 0x008c}, 145 {0x60c8, 0x00c0}, {0x6096, 0x00c1}, {0x6000, 0x008c},
177}; 146};
178 147
179static struct validx tbl_big_b[] = { 148static struct validx tbl_big2[] = {
180 {0x603d, 0x0086}, {0x6000, 0x0050}, {0x6090, 0x0051}, {0x602c, 0x0052}, 149 {0x603d, 0x0086}, {0x6000, 0x0050}, {0x6090, 0x0051}, {0x602c, 0x0052},
181 {0x6000, 0x0053}, {0x6000, 0x0054}, {0x6088, 0x0055}, {0x6000, 0x0057}, 150 {0x6000, 0x0053}, {0x6000, 0x0054}, {0x6088, 0x0055}, {0x6000, 0x0057},
182 {0x6040, 0x005a}, {0x60f0, 0x005b}, {0x6001, 0x005c}, {0x6082, 0x00d3}, 151 {0x6040, 0x005a}, {0x60f0, 0x005b}, {0x6001, 0x005c}, {0x6082, 0x00d3},
183 {0x6000, 0x008e}, 152 {0x6000, 0x008e},
184}; 153};
185 154
186static struct validx tbl_big_c[] = { 155static struct validx tbl_big3[] = {
187 {0x6004, 0x00da}, {0x6000, 0x00e0}, {0x6067, 0x00e1}, {0x60ff, 0x00dd}, 156 {0x6004, 0x00da}, {0x6000, 0x00e0}, {0x6067, 0x00e1}, {0x60ff, 0x00dd},
188 {0x6001, 0x00ff}, {0x6000, 0x00ff}, {0x60f1, 0x00dd}, {0x6004, 0x00e0}, 157 {0x6001, 0x00ff}, {0x6000, 0x00ff}, {0x60f1, 0x00dd}, {0x6004, 0x00e0},
189 {0x6001, 0x00ff}, {0x6000, 0x0011}, {0x6000, 0x00ff}, {0x6010, 0x00c7}, 158 {0x6001, 0x00ff}, {0x6000, 0x0011}, {0x6000, 0x00ff}, {0x6010, 0x00c7},
@@ -223,17 +192,19 @@ void ov2640_init_settings(struct gspca_dev *gspca_dev)
223 sd->vcur.hue = 0; 192 sd->vcur.hue = 0;
224 sd->vcur.saturation = 128; 193 sd->vcur.saturation = 128;
225 sd->vcur.whitebal = 64; 194 sd->vcur.whitebal = 64;
195 sd->vcur.mirror = 0;
196 sd->vcur.flip = 0;
226 197
227 sd->vmax.backlight = 64; 198 sd->vmax.backlight = 64;
228 sd->vmax.brightness = 255; 199 sd->vmax.brightness = 255;
229 sd->vmax.sharpness = 31; 200 sd->vmax.sharpness = 31;
230 sd->vmax.contrast = 255; 201 sd->vmax.contrast = 255;
231 sd->vmax.gamma = 64; 202 sd->vmax.gamma = 64;
232 sd->vmax.hue = 255 + 1; 203 sd->vmax.hue = 254 + 2;
233 sd->vmax.saturation = 255; 204 sd->vmax.saturation = 255;
234 sd->vmax.whitebal = 128; 205 sd->vmax.whitebal = 128;
235 sd->vmax.mirror = 0; 206 sd->vmax.mirror = 1;
236 sd->vmax.flip = 0; 207 sd->vmax.flip = 1;
237 sd->vmax.AC50Hz = 0; 208 sd->vmax.AC50Hz = 0;
238 209
239 sd->dev_camera_settings = ov2640_camera_settings; 210 sd->dev_camera_settings = ov2640_camera_settings;
@@ -259,11 +230,11 @@ static int ov2640_init_at_startup(struct gspca_dev *gspca_dev)
259 230
260 common(gspca_dev); 231 common(gspca_dev);
261 232
262 ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0006, 1, dat_init2); 233 ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0006, 1, c61);
263 234
264 ctrl_out(gspca_dev, 0x40, 1, 0x00ef, 0x0006, 0, NULL); 235 ctrl_out(gspca_dev, 0x40, 1, 0x00ef, 0x0006, 0, NULL);
265 236
266 ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0000, 1, dat_init3); 237 ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0000, 1, c51);
267 238
268 ctrl_out(gspca_dev, 0x40, 1, 0x0051, 0x0000, 0, NULL); 239 ctrl_out(gspca_dev, 0x40, 1, 0x0051, 0x0000, 0, NULL);
269/* ctrl_out(gspca_dev, 0x40, 11, 0x0000, 0x0000, 0, NULL); */ 240/* ctrl_out(gspca_dev, 0x40, 11, 0x0000, 0x0000, 0, NULL); */
@@ -275,6 +246,8 @@ static int ov2640_init_pre_alt(struct gspca_dev *gspca_dev)
275{ 246{
276 struct sd *sd = (struct sd *) gspca_dev; 247 struct sd *sd = (struct sd *) gspca_dev;
277 248
249 sd->mirrorMask = 0;
250
278 sd->vold.backlight = -1; 251 sd->vold.backlight = -1;
279 sd->vold.brightness = -1; 252 sd->vold.brightness = -1;
280 sd->vold.sharpness = -1; 253 sd->vold.sharpness = -1;
@@ -283,6 +256,8 @@ static int ov2640_init_pre_alt(struct gspca_dev *gspca_dev)
283 sd->vold.gamma = -1; 256 sd->vold.gamma = -1;
284 sd->vold.hue = -1; 257 sd->vold.hue = -1;
285 sd->vold.whitebal = -1; 258 sd->vold.whitebal = -1;
259 sd->vold.mirror = -1;
260 sd->vold.flip = -1;
286 261
287 ov2640_init_post_alt(gspca_dev); 262 ov2640_init_post_alt(gspca_dev);
288 263
@@ -292,16 +267,16 @@ static int ov2640_init_pre_alt(struct gspca_dev *gspca_dev)
292static int ov2640_init_post_alt(struct gspca_dev *gspca_dev) 267static int ov2640_init_post_alt(struct gspca_dev *gspca_dev)
293{ 268{
294 s32 reso = gspca_dev->cam.cam_mode[(s32) gspca_dev->curr_mode].priv; 269 s32 reso = gspca_dev->cam.cam_mode[(s32) gspca_dev->curr_mode].priv;
295 s32 n; /* reserved for FETCH macros */ 270 s32 n; /* reserved for FETCH functions */
296 271
297 ctrl_out(gspca_dev, 0x40, 5, 0x0001, 0x0000, 0, NULL); 272 ctrl_out(gspca_dev, 0x40, 5, 0x0001, 0x0000, 0, NULL);
298 273
299 n = fetch_validx(gspca_dev, tbl_sensor_settings_common_a, 274 n = fetch_validx(gspca_dev, tbl_sensor_settings_common1,
300 ARRAY_SIZE(tbl_sensor_settings_common_a)); 275 ARRAY_SIZE(tbl_sensor_settings_common1));
301 ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 12, dat_post); 276 ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 12, dat_post);
302 common(gspca_dev); 277 common(gspca_dev);
303 keep_on_fetching_validx(gspca_dev, tbl_sensor_settings_common_a, 278 keep_on_fetching_validx(gspca_dev, tbl_sensor_settings_common1,
304 ARRAY_SIZE(tbl_sensor_settings_common_a), n); 279 ARRAY_SIZE(tbl_sensor_settings_common1), n);
305 280
306 switch (reso) { 281 switch (reso) {
307 case IMAGE_640: 282 case IMAGE_640:
@@ -316,18 +291,18 @@ static int ov2640_init_post_alt(struct gspca_dev *gspca_dev)
316 291
317 case IMAGE_1600: 292 case IMAGE_1600:
318 case IMAGE_1280: 293 case IMAGE_1280:
319 n = fetch_validx(gspca_dev, tbl_big_a, ARRAY_SIZE(tbl_big_a)); 294 n = fetch_validx(gspca_dev, tbl_big1, ARRAY_SIZE(tbl_big1));
320 295
321 if (reso == IMAGE_1280) { 296 if (reso == IMAGE_1280) {
322 n = fetch_validx(gspca_dev, tbl_big_b, 297 n = fetch_validx(gspca_dev, tbl_big2,
323 ARRAY_SIZE(tbl_big_b)); 298 ARRAY_SIZE(tbl_big2));
324 } else { 299 } else {
325 ctrl_out(gspca_dev, 0x40, 1, 0x601d, 0x0086, 0, NULL); 300 ctrl_out(gspca_dev, 0x40, 1, 0x601d, 0x0086, 0, NULL);
326 ctrl_out(gspca_dev, 0x40, 1, 0x6001, 0x00d7, 0, NULL); 301 ctrl_out(gspca_dev, 0x40, 1, 0x6001, 0x00d7, 0, NULL);
327 ctrl_out(gspca_dev, 0x40, 1, 0x6082, 0x00d3, 0, NULL); 302 ctrl_out(gspca_dev, 0x40, 1, 0x6082, 0x00d3, 0, NULL);
328 } 303 }
329 304
330 n = fetch_validx(gspca_dev, tbl_big_c, ARRAY_SIZE(tbl_big_c)); 305 n = fetch_validx(gspca_dev, tbl_big3, ARRAY_SIZE(tbl_big3));
331 306
332 if (reso == IMAGE_1280) { 307 if (reso == IMAGE_1280) {
333 ctrl_out(gspca_dev, 0x40, 1, 0x6001, 0x00ff, 0, NULL); 308 ctrl_out(gspca_dev, 0x40, 1, 0x6001, 0x00ff, 0, NULL);
@@ -343,20 +318,8 @@ static int ov2640_init_post_alt(struct gspca_dev *gspca_dev)
343 break; 318 break;
344 } 319 }
345 320
346 n = fetch_validx(gspca_dev, tbl_sensor_settings_common_b, 321 n = fetch_validx(gspca_dev, tbl_sensor_settings_common2,
347 ARRAY_SIZE(tbl_sensor_settings_common_b)); 322 ARRAY_SIZE(tbl_sensor_settings_common2));
348 ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0000, 1, c50);
349 keep_on_fetching_validx(gspca_dev, tbl_sensor_settings_common_b,
350 ARRAY_SIZE(tbl_sensor_settings_common_b), n);
351 ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x8004, 1, c28);
352 keep_on_fetching_validx(gspca_dev, tbl_sensor_settings_common_b,
353 ARRAY_SIZE(tbl_sensor_settings_common_b), n);
354 ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x8004, 1, ca8);
355 keep_on_fetching_validx(gspca_dev, tbl_sensor_settings_common_b,
356 ARRAY_SIZE(tbl_sensor_settings_common_b), n);
357 ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0000, 1, c50);
358 keep_on_fetching_validx(gspca_dev, tbl_sensor_settings_common_b,
359 ARRAY_SIZE(tbl_sensor_settings_common_b), n);
360 323
361 ov2640_camera_settings(gspca_dev); 324 ov2640_camera_settings(gspca_dev);
362 325
@@ -393,18 +356,20 @@ static int ov2640_camera_settings(struct gspca_dev *gspca_dev)
393 s32 sat = sd->vcur.saturation; 356 s32 sat = sd->vcur.saturation;
394 s32 hue = sd->vcur.hue; 357 s32 hue = sd->vcur.hue;
395 s32 wbal = sd->vcur.whitebal; 358 s32 wbal = sd->vcur.whitebal;
359 s32 mirror = (((sd->vcur.mirror > 0) ^ sd->mirrorMask) == 0);
360 s32 flip = (((sd->vcur.flip > 0) ^ sd->mirrorMask) == 0);
396 361
397 if (backlight != sd->vold.backlight) { 362 if (backlight != sd->vold.backlight) {
363 /* No sd->vold.backlight=backlight; (to be done again later) */
398 if (backlight < 0 || backlight > sd->vmax.backlight) 364 if (backlight < 0 || backlight > sd->vmax.backlight)
399 backlight = 0; 365 backlight = 0;
400 366
401 ctrl_out(gspca_dev, 0x40, 1, 0x6001 , 0x00ff, 367 ctrl_out(gspca_dev, 0x40, 1, 0x6001 , 0x00ff,
402 0, NULL); 368 0, NULL);
403 ctrl_out(gspca_dev, 0x40, 1, 0x601f + backlight , 0x0024, 369 ctrl_out(gspca_dev, 0x40, 1, 0x601e + backlight , 0x0024,
404 0, NULL); 370 0, NULL);
405 ctrl_out(gspca_dev, 0x40, 1, 0x601f + backlight - 10, 0x0025, 371 ctrl_out(gspca_dev, 0x40, 1, 0x601e + backlight - 10, 0x0025,
406 0, NULL); 372 0, NULL);
407 /* No sd->vold.backlight=backlight; (to be done again later) */
408 } 373 }
409 374
410 if (bright != sd->vold.brightness) { 375 if (bright != sd->vold.brightness) {
@@ -466,7 +431,7 @@ static int ov2640_camera_settings(struct gspca_dev *gspca_dev)
466 ctrl_out(gspca_dev, 0x40, 1, 0x6002 , 0x007c, 0, NULL); 431 ctrl_out(gspca_dev, 0x40, 1, 0x6002 , 0x007c, 0, NULL);
467 ctrl_out(gspca_dev, 0x40, 1, 0x6000 + hue * (hue < 255), 0x007d, 432 ctrl_out(gspca_dev, 0x40, 1, 0x6000 + hue * (hue < 255), 0x007d,
468 0, NULL); 433 0, NULL);
469 if (hue >= sd->vmax.hue) 434 if (hue >= 255)
470 sd->swapRB = 1; 435 sd->swapRB = 1;
471 else 436 else
472 sd->swapRB = 0; 437 sd->swapRB = 0;
@@ -482,14 +447,33 @@ static int ov2640_camera_settings(struct gspca_dev *gspca_dev)
482 ctrl_out(gspca_dev, 0x40, 1, 0x6000 + gam, 0x007d, 0, NULL); 447 ctrl_out(gspca_dev, 0x40, 1, 0x6000 + gam, 0x007d, 0, NULL);
483 } 448 }
484 449
450 if (mirror != sd->vold.mirror || flip != sd->vold.flip) {
451 sd->vold.mirror = mirror;
452 sd->vold.flip = flip;
453
454 mirror = 0x80 * mirror;
455 ctrl_out(gspca_dev, 0x40, 1, 0x6001, 0x00ff, 0, NULL);
456 ctrl_out(gspca_dev, 0x40, 1, 0x6000, 0x8004, 0, NULL);
457 ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x8004, 1, c28);
458 ctrl_out(gspca_dev, 0x40, 1, 0x6028 + mirror, 0x0004, 0, NULL);
459
460 flip = 0x50 * flip + mirror;
461 ctrl_out(gspca_dev, 0x40, 1, 0x6001, 0x00ff, 0, NULL);
462 ctrl_out(gspca_dev, 0x40, 1, 0x6000, 0x8004, 0, NULL);
463 ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x8004, 1, ca8);
464 ctrl_out(gspca_dev, 0x40, 1, 0x6028 + flip, 0x0004, 0, NULL);
465
466 ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0000, 1, c50);
467 }
468
485 if (backlight != sd->vold.backlight) { 469 if (backlight != sd->vold.backlight) {
486 sd->vold.backlight = backlight; 470 sd->vold.backlight = backlight;
487 471
488 ctrl_out(gspca_dev, 0x40, 1, 0x6001 , 0x00ff, 472 ctrl_out(gspca_dev, 0x40, 1, 0x6001 , 0x00ff,
489 0, NULL); 473 0, NULL);
490 ctrl_out(gspca_dev, 0x40, 1, 0x601f + backlight , 0x0024, 474 ctrl_out(gspca_dev, 0x40, 1, 0x601e + backlight , 0x0024,
491 0, NULL); 475 0, NULL);
492 ctrl_out(gspca_dev, 0x40, 1, 0x601f + backlight - 10, 0x0025, 476 ctrl_out(gspca_dev, 0x40, 1, 0x601e + backlight - 10, 0x0025,
493 0, NULL); 477 0, NULL);
494 } 478 }
495 479
diff --git a/drivers/media/video/gspca/gl860/gl860-ov9655.c b/drivers/media/video/gspca/gl860/gl860-ov9655.c
index eda3346f939c..d412694c50af 100644
--- a/drivers/media/video/gspca/gl860/gl860-ov9655.c
+++ b/drivers/media/video/gspca/gl860/gl860-ov9655.c
@@ -1,7 +1,6 @@
1/* @file gl860-ov9655.c 1/* Subdriver for the GL860 chip with the OV9655 sensor
2 * @author Olivier LORIN, from logs done by Simon (Sur3) and Almighurt 2 * Author Olivier LORIN, from logs done by Simon (Sur3) and Almighurt
3 * on dsd's weblog 3 * on dsd's weblog
4 * @date 2009-08-27
5 * 4 *
6 * This program is free software; you can redistribute it and/or modify 5 * 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 6 * it under the terms of the GNU General Public License as published by
@@ -104,14 +103,14 @@ static u8 *tbl_800[] = {
104}; 103};
105 104
106static u8 c04[] = {0x04}; 105static u8 c04[] = {0x04};
107static u8 dat_post_1[] = "\x04\x00\x10\x20\xa1\x00\x00\x02"; 106static u8 dat_post1[] = "\x04\x00\x10\x20\xa1\x00\x00\x02";
108static u8 dat_post_2[] = "\x10\x10\xc1\x02"; 107static u8 dat_post2[] = "\x10\x10\xc1\x02";
109static u8 dat_post_3[] = "\x04\x00\x10\x7c\xa1\x00\x00\x04"; 108static u8 dat_post3[] = "\x04\x00\x10\x7c\xa1\x00\x00\x04";
110static u8 dat_post_4[] = "\x10\x02\xc1\x06"; 109static u8 dat_post4[] = "\x10\x02\xc1\x06";
111static u8 dat_post_5[] = "\x04\x00\x10\x7b\xa1\x00\x00\x08"; 110static u8 dat_post5[] = "\x04\x00\x10\x7b\xa1\x00\x00\x08";
112static u8 dat_post_6[] = "\x10\x10\xc1\x05"; 111static u8 dat_post6[] = "\x10\x10\xc1\x05";
113static u8 dat_post_7[] = "\x04\x00\x10\x7c\xa1\x00\x00\x08"; 112static u8 dat_post7[] = "\x04\x00\x10\x7c\xa1\x00\x00\x08";
114static u8 dat_post_8[] = "\x04\x00\x10\x7c\xa1\x00\x00\x09"; 113static u8 dat_post8[] = "\x04\x00\x10\x7c\xa1\x00\x00\x09";
115 114
116static struct validx tbl_init_post_alt[] = { 115static struct validx tbl_init_post_alt[] = {
117 {0x6032, 0x00ff}, {0x6032, 0x00ff}, {0x6032, 0x00ff}, {0x603c, 0x00ff}, 116 {0x6032, 0x00ff}, {0x6032, 0x00ff}, {0x6032, 0x00ff}, {0x603c, 0x00ff},
@@ -212,7 +211,7 @@ static int ov9655_init_pre_alt(struct gspca_dev *gspca_dev)
212static int ov9655_init_post_alt(struct gspca_dev *gspca_dev) 211static int ov9655_init_post_alt(struct gspca_dev *gspca_dev)
213{ 212{
214 s32 reso = gspca_dev->cam.cam_mode[(s32) gspca_dev->curr_mode].priv; 213 s32 reso = gspca_dev->cam.cam_mode[(s32) gspca_dev->curr_mode].priv;
215 s32 n; /* reserved for FETCH macros */ 214 s32 n; /* reserved for FETCH functions */
216 s32 i; 215 s32 i;
217 u8 **tbl; 216 u8 **tbl;
218 217
@@ -243,7 +242,7 @@ static int ov9655_init_post_alt(struct gspca_dev *gspca_dev)
243 ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x801e, 1, c04); 242 ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x801e, 1, c04);
244 keep_on_fetching_validx(gspca_dev, tbl_init_post_alt, 243 keep_on_fetching_validx(gspca_dev, tbl_init_post_alt,
245 ARRAY_SIZE(tbl_init_post_alt), n); 244 ARRAY_SIZE(tbl_init_post_alt), n);
246 ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_post_1); 245 ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_post1);
247 keep_on_fetching_validx(gspca_dev, tbl_init_post_alt, 246 keep_on_fetching_validx(gspca_dev, tbl_init_post_alt,
248 ARRAY_SIZE(tbl_init_post_alt), n); 247 ARRAY_SIZE(tbl_init_post_alt), n);
249 248
@@ -259,7 +258,7 @@ static int ov9655_init_post_alt(struct gspca_dev *gspca_dev)
259 ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x801e, 1, c04); 258 ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x801e, 1, c04);
260 keep_on_fetching_validx(gspca_dev, tbl_init_post_alt, 259 keep_on_fetching_validx(gspca_dev, tbl_init_post_alt,
261 ARRAY_SIZE(tbl_init_post_alt), n); 260 ARRAY_SIZE(tbl_init_post_alt), n);
262 ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_post_1); 261 ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_post1);
263 keep_on_fetching_validx(gspca_dev, tbl_init_post_alt, 262 keep_on_fetching_validx(gspca_dev, tbl_init_post_alt,
264 ARRAY_SIZE(tbl_init_post_alt), n); 263 ARRAY_SIZE(tbl_init_post_alt), n);
265 264
@@ -270,18 +269,18 @@ static int ov9655_init_post_alt(struct gspca_dev *gspca_dev)
270 keep_on_fetching_validx(gspca_dev, tbl_init_post_alt, 269 keep_on_fetching_validx(gspca_dev, tbl_init_post_alt,
271 ARRAY_SIZE(tbl_init_post_alt), n); 270 ARRAY_SIZE(tbl_init_post_alt), n);
272 271
273 ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_post_1); 272 ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_post1);
274 273
275 ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 4, dat_post_2); 274 ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 4, dat_post2);
276 ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_post_3); 275 ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_post3);
277 276
278 ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 4, dat_post_4); 277 ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 4, dat_post4);
279 ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_post_5); 278 ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_post5);
280 279
281 ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 4, dat_post_6); 280 ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 4, dat_post6);
282 ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_post_7); 281 ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_post7);
283 282
284 ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_post_8); 283 ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_post8);
285 284
286 ov9655_camera_settings(gspca_dev); 285 ov9655_camera_settings(gspca_dev);
287 286
diff --git a/drivers/media/video/gspca/gl860/gl860.c b/drivers/media/video/gspca/gl860/gl860.c
index 6ef59ac7f502..a695e0ae13c2 100644
--- a/drivers/media/video/gspca/gl860/gl860.c
+++ b/drivers/media/video/gspca/gl860/gl860.c
@@ -1,9 +1,7 @@
1/* @file gl860.c 1/* GSPCA subdrivers for Genesys Logic webcams with the GL860 chip
2 * @date 2009-08-27 2 * Subdriver core
3 * 3 *
4 * Genesys Logic webcam with gl860 subdrivers 4 * 2009/09/24 Olivier Lorin <o.lorin@laposte.net>
5 *
6 * Driver by Olivier Lorin <o.lorin@laposte.net>
7 * GSPCA by Jean-Francois Moine <http://moinejf.free.fr> 5 * GSPCA by Jean-Francois Moine <http://moinejf.free.fr>
8 * Thanks BUGabundo and Malmostoso for your amazing help! 6 * Thanks BUGabundo and Malmostoso for your amazing help!
9 * 7 *
@@ -23,8 +21,8 @@
23#include "gspca.h" 21#include "gspca.h"
24#include "gl860.h" 22#include "gl860.h"
25 23
26MODULE_AUTHOR("Olivier Lorin <lorin@laposte.net>"); 24MODULE_AUTHOR("Olivier Lorin <o.lorin@laposte.net>");
27MODULE_DESCRIPTION("GSPCA/Genesys Logic GL860 USB Camera Driver"); 25MODULE_DESCRIPTION("Genesys Logic USB PC Camera Driver");
28MODULE_LICENSE("GPL"); 26MODULE_LICENSE("GPL");
29 27
30/*======================== static function declarations ====================*/ 28/*======================== static function declarations ====================*/
@@ -38,7 +36,7 @@ static int sd_isoc_init(struct gspca_dev *gspca_dev);
38static int sd_start(struct gspca_dev *gspca_dev); 36static int sd_start(struct gspca_dev *gspca_dev);
39static void sd_stop0(struct gspca_dev *gspca_dev); 37static void sd_stop0(struct gspca_dev *gspca_dev);
40static void sd_pkt_scan(struct gspca_dev *gspca_dev, 38static void sd_pkt_scan(struct gspca_dev *gspca_dev,
41 struct gspca_frame *frame, u8 *data, s32 len); 39 u8 *data, int len);
42static void sd_callback(struct gspca_dev *gspca_dev); 40static void sd_callback(struct gspca_dev *gspca_dev);
43 41
44static int gl860_guess_sensor(struct gspca_dev *gspca_dev, 42static int gl860_guess_sensor(struct gspca_dev *gspca_dev,
@@ -53,7 +51,7 @@ MODULE_PARM_DESC(AC50Hz, " Does AC power frequency is 50Hz? (0/1)");
53static char sensor[7]; 51static char sensor[7];
54module_param_string(sensor, sensor, sizeof(sensor), 0644); 52module_param_string(sensor, sensor, sizeof(sensor), 0644);
55MODULE_PARM_DESC(sensor, 53MODULE_PARM_DESC(sensor,
56 " Driver sensor ('MI1320'/'MI2020'/'OV9655'/'OV2640'/'')"); 54 " Driver sensor ('MI1320'/'MI2020'/'OV9655'/'OV2640')");
57 55
58/*============================ webcam controls =============================*/ 56/*============================ webcam controls =============================*/
59 57
@@ -156,7 +154,7 @@ static int gl860_build_control_table(struct gspca_dev *gspca_dev)
156 SET_MY_CTRL(V4L2_CID_VFLIP, 154 SET_MY_CTRL(V4L2_CID_VFLIP,
157 V4L2_CTRL_TYPE_BOOLEAN, "Flip", flip) 155 V4L2_CTRL_TYPE_BOOLEAN, "Flip", flip)
158 SET_MY_CTRL(V4L2_CID_POWER_LINE_FREQUENCY, 156 SET_MY_CTRL(V4L2_CID_POWER_LINE_FREQUENCY,
159 V4L2_CTRL_TYPE_BOOLEAN, "50Hz", AC50Hz) 157 V4L2_CTRL_TYPE_BOOLEAN, "AC power 50Hz", AC50Hz)
160 158
161 return nCtrls; 159 return nCtrls;
162} 160}
@@ -435,7 +433,7 @@ static void sd_stop0(struct gspca_dev *gspca_dev)
435 433
436/* This function is called when an image is being received */ 434/* This function is called when an image is being received */
437static void sd_pkt_scan(struct gspca_dev *gspca_dev, 435static void sd_pkt_scan(struct gspca_dev *gspca_dev,
438 struct gspca_frame *frame, u8 *data, s32 len) 436 u8 *data, int len)
439{ 437{
440 struct sd *sd = (struct sd *) gspca_dev; 438 struct sd *sd = (struct sd *) gspca_dev;
441 static s32 nSkipped; 439 static s32 nSkipped;
@@ -447,11 +445,11 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
447 /* Test only against 0202h, so endianess does not matter */ 445 /* Test only against 0202h, so endianess does not matter */
448 switch (*(s16 *) data) { 446 switch (*(s16 *) data) {
449 case 0x0202: /* End of frame, start a new one */ 447 case 0x0202: /* End of frame, start a new one */
450 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, data, 0); 448 gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
451 nSkipped = 0; 449 nSkipped = 0;
452 if (sd->nbIm >= 0 && sd->nbIm < 10) 450 if (sd->nbIm >= 0 && sd->nbIm < 10)
453 sd->nbIm++; 451 sd->nbIm++;
454 gspca_frame_add(gspca_dev, FIRST_PACKET, frame, data, 0); 452 gspca_frame_add(gspca_dev, FIRST_PACKET, NULL, 0);
455 break; 453 break;
456 454
457 default: 455 default:
@@ -466,7 +464,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
466 nSkipped = nToSkip + 1; 464 nSkipped = nToSkip + 1;
467 } 465 }
468 gspca_frame_add(gspca_dev, 466 gspca_frame_add(gspca_dev,
469 INTER_PACKET, frame, data, len); 467 INTER_PACKET, data, len);
470 } 468 }
471 break; 469 break;
472 } 470 }
@@ -702,6 +700,7 @@ static int gl860_guess_sensor(struct gspca_dev *gspca_dev,
702 ctrl_out(gspca_dev, 0x40, 1, 0x006a, 0x000d, 0, NULL); 700 ctrl_out(gspca_dev, 0x40, 1, 0x006a, 0x000d, 0, NULL);
703 msleep(56); 701 msleep(56);
704 702
703 PDEBUG(D_PROBE, "probing for sensor MI2020 or OVXXXX");
705 nOV = 0; 704 nOV = 0;
706 for (ntry = 0; ntry < 4; ntry++) { 705 for (ntry = 0; ntry < 4; ntry++) {
707 ctrl_out(gspca_dev, 0x40, 1, 0x0040, 0x0000, 0, NULL); 706 ctrl_out(gspca_dev, 0x40, 1, 0x0040, 0x0000, 0, NULL);
@@ -711,14 +710,14 @@ static int gl860_guess_sensor(struct gspca_dev *gspca_dev,
711 ctrl_out(gspca_dev, 0x40, 1, 0x7a00, 0x8030, 0, NULL); 710 ctrl_out(gspca_dev, 0x40, 1, 0x7a00, 0x8030, 0, NULL);
712 msleep(10); 711 msleep(10);
713 ctrl_in(gspca_dev, 0xc0, 2, 0x7a00, 0x8030, 1, &probe); 712 ctrl_in(gspca_dev, 0xc0, 2, 0x7a00, 0x8030, 1, &probe);
714 PDEBUG(D_PROBE, "1st probe=%02x", probe); 713 PDEBUG(D_PROBE, "probe=0x%02x", probe);
715 if (probe == 0xff) 714 if (probe == 0xff)
716 nOV++; 715 nOV++;
717 } 716 }
718 717
719 if (nOV) { 718 if (nOV) {
720 PDEBUG(D_PROBE, "0xff -> sensor OVXXXX"); 719 PDEBUG(D_PROBE, "0xff -> OVXXXX");
721 PDEBUG(D_PROBE, "Probing for sensor OV2640 or OV9655"); 720 PDEBUG(D_PROBE, "probing for sensor OV2640 or OV9655");
722 721
723 nb26 = nb96 = 0; 722 nb26 = nb96 = 0;
724 for (ntry = 0; ntry < 4; ntry++) { 723 for (ntry = 0; ntry < 4; ntry++) {
@@ -728,40 +727,38 @@ static int gl860_guess_sensor(struct gspca_dev *gspca_dev,
728 ctrl_out(gspca_dev, 0x40, 1, 0x6000, 0x800a, 727 ctrl_out(gspca_dev, 0x40, 1, 0x6000, 0x800a,
729 0, NULL); 728 0, NULL);
730 msleep(10); 729 msleep(10);
730
731 /* Wait for 26(OV2640) or 96(OV9655) */ 731 /* Wait for 26(OV2640) or 96(OV9655) */
732 ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x800a, 732 ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x800a,
733 1, &probe); 733 1, &probe);
734 734
735 PDEBUG(D_PROBE, "2nd probe=%02x", probe);
736 if (probe == 0x00)
737 nb26++;
738 if (probe == 0x26 || probe == 0x40) { 735 if (probe == 0x26 || probe == 0x40) {
736 PDEBUG(D_PROBE,
737 "probe=0x%02x -> OV2640",
738 probe);
739 sd->sensor = ID_OV2640; 739 sd->sensor = ID_OV2640;
740 nb26 += 4; 740 nb26 += 4;
741 break; 741 break;
742 } 742 }
743 if (probe == 0x96 || probe == 0x55) { 743 if (probe == 0x96 || probe == 0x55) {
744 PDEBUG(D_PROBE,
745 "probe=0x%02x -> OV9655",
746 probe);
744 sd->sensor = ID_OV9655; 747 sd->sensor = ID_OV9655;
745 nb96 += 4; 748 nb96 += 4;
746 break; 749 break;
747 } 750 }
751 PDEBUG(D_PROBE, "probe=0x%02x", probe);
752 if (probe == 0x00)
753 nb26++;
748 if (probe == 0xff) 754 if (probe == 0xff)
749 nb96++; 755 nb96++;
750 msleep(3); 756 msleep(3);
751 } 757 }
752 if (nb26 < 4 && nb96 < 4) { 758 if (nb26 < 4 && nb96 < 4)
753 PDEBUG(D_PROBE, "No relevant answer ");
754 PDEBUG(D_PROBE, "* 1.3Mpixels -> use OV9655");
755 PDEBUG(D_PROBE, "* 2.0Mpixels -> use OV2640");
756 PDEBUG(D_PROBE,
757 "To force a sensor, add that line to "
758 "/etc/modprobe.d/options.conf:");
759 PDEBUG(D_PROBE, "options gspca_gl860 "
760 "sensor=\"OV2640\" or \"OV9655\"");
761 return -1; 759 return -1;
762 } 760 } else {
763 } else { /* probe = 0 */ 761 PDEBUG(D_PROBE, "Not any 0xff -> MI2020");
764 PDEBUG(D_PROBE, "No 0xff -> sensor MI2020");
765 sd->sensor = ID_MI2020; 762 sd->sensor = ID_MI2020;
766 } 763 }
767 } 764 }
diff --git a/drivers/media/video/gspca/gl860/gl860.h b/drivers/media/video/gspca/gl860/gl860.h
index cef4e24c1e61..305061ff8387 100644
--- a/drivers/media/video/gspca/gl860/gl860.h
+++ b/drivers/media/video/gspca/gl860/gl860.h
@@ -1,6 +1,7 @@
1/* @file gl860.h 1/* GSPCA subdrivers for Genesys Logic webcams with the GL860 chip
2 * @author Olivier LORIN, tiré du pilote Syntek par Nicolas VIVIEN 2 * Subdriver declarations
3 * @date 2009-08-27 3 *
4 * 2009/10/14 Olivier LORIN <o.lorin@laposte.net>
4 * 5 *
5 * This program is free software; you can redistribute it and/or modify 6 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by 7 * it under the terms of the GNU General Public License as published by
diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c
index 23d3fb776918..4076f8e5a6fc 100644
--- a/drivers/media/video/gspca/gspca.c
+++ b/drivers/media/video/gspca/gspca.c
@@ -47,7 +47,7 @@ MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>");
47MODULE_DESCRIPTION("GSPCA USB Camera Driver"); 47MODULE_DESCRIPTION("GSPCA USB Camera Driver");
48MODULE_LICENSE("GPL"); 48MODULE_LICENSE("GPL");
49 49
50#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 7, 0) 50#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 8, 0)
51 51
52#ifdef GSPCA_DEBUG 52#ifdef GSPCA_DEBUG
53int gspca_debug = D_ERR | D_PROBE; 53int gspca_debug = D_ERR | D_PROBE;
@@ -74,7 +74,7 @@ static void PDEBUG_MODE(char *txt, __u32 pixfmt, int w, int h)
74#define PDEBUG_MODE(txt, pixfmt, w, h) 74#define PDEBUG_MODE(txt, pixfmt, w, h)
75#endif 75#endif
76 76
77/* specific memory types - !! should different from V4L2_MEMORY_xxx */ 77/* specific memory types - !! should be different from V4L2_MEMORY_xxx */
78#define GSPCA_MEMORY_NO 0 /* V4L2_MEMORY_xxx starts from 1 */ 78#define GSPCA_MEMORY_NO 0 /* V4L2_MEMORY_xxx starts from 1 */
79#define GSPCA_MEMORY_READ 7 79#define GSPCA_MEMORY_READ 7
80 80
@@ -126,7 +126,6 @@ EXPORT_SYMBOL(gspca_get_i_frame);
126static void fill_frame(struct gspca_dev *gspca_dev, 126static void fill_frame(struct gspca_dev *gspca_dev,
127 struct urb *urb) 127 struct urb *urb)
128{ 128{
129 struct gspca_frame *frame;
130 u8 *data; /* address of data in the iso message */ 129 u8 *data; /* address of data in the iso message */
131 int i, len, st; 130 int i, len, st;
132 cam_pkt_op pkt_scan; 131 cam_pkt_op pkt_scan;
@@ -135,21 +134,16 @@ static void fill_frame(struct gspca_dev *gspca_dev,
135 if (urb->status == -ESHUTDOWN) 134 if (urb->status == -ESHUTDOWN)
136 return; /* disconnection */ 135 return; /* disconnection */
137#ifdef CONFIG_PM 136#ifdef CONFIG_PM
138 if (!gspca_dev->frozen) 137 if (gspca_dev->frozen)
138 return;
139#endif 139#endif
140 PDEBUG(D_ERR|D_PACK, "urb status: %d", urb->status); 140 PDEBUG(D_ERR|D_PACK, "urb status: %d", urb->status);
141 return; 141 urb->status = 0;
142 goto resubmit;
142 } 143 }
143 pkt_scan = gspca_dev->sd_desc->pkt_scan; 144 pkt_scan = gspca_dev->sd_desc->pkt_scan;
144 for (i = 0; i < urb->number_of_packets; i++) { 145 for (i = 0; i < urb->number_of_packets; i++) {
145 146
146 /* check the availability of the frame buffer */
147 frame = gspca_get_i_frame(gspca_dev);
148 if (!frame) {
149 gspca_dev->last_packet_type = DISCARD_PACKET;
150 break;
151 }
152
153 /* check the packet status and length */ 147 /* check the packet status and length */
154 len = urb->iso_frame_desc[i].actual_length; 148 len = urb->iso_frame_desc[i].actual_length;
155 if (len == 0) { 149 if (len == 0) {
@@ -171,9 +165,10 @@ static void fill_frame(struct gspca_dev *gspca_dev,
171 i, urb->iso_frame_desc[i].offset, len); 165 i, urb->iso_frame_desc[i].offset, len);
172 data = (u8 *) urb->transfer_buffer 166 data = (u8 *) urb->transfer_buffer
173 + urb->iso_frame_desc[i].offset; 167 + urb->iso_frame_desc[i].offset;
174 pkt_scan(gspca_dev, frame, data, len); 168 pkt_scan(gspca_dev, data, len);
175 } 169 }
176 170
171resubmit:
177 /* resubmit the URB */ 172 /* resubmit the URB */
178 st = usb_submit_urb(urb, GFP_ATOMIC); 173 st = usb_submit_urb(urb, GFP_ATOMIC);
179 if (st < 0) 174 if (st < 0)
@@ -201,7 +196,6 @@ static void isoc_irq(struct urb *urb)
201static void bulk_irq(struct urb *urb) 196static void bulk_irq(struct urb *urb)
202{ 197{
203 struct gspca_dev *gspca_dev = (struct gspca_dev *) urb->context; 198 struct gspca_dev *gspca_dev = (struct gspca_dev *) urb->context;
204 struct gspca_frame *frame;
205 int st; 199 int st;
206 200
207 PDEBUG(D_PACK, "bulk irq"); 201 PDEBUG(D_PACK, "bulk irq");
@@ -212,29 +206,22 @@ static void bulk_irq(struct urb *urb)
212 break; 206 break;
213 case -ESHUTDOWN: 207 case -ESHUTDOWN:
214 return; /* disconnection */ 208 return; /* disconnection */
215 case -ECONNRESET:
216 urb->status = 0;
217 break;
218 default: 209 default:
219#ifdef CONFIG_PM 210#ifdef CONFIG_PM
220 if (!gspca_dev->frozen) 211 if (gspca_dev->frozen)
212 return;
221#endif 213#endif
222 PDEBUG(D_ERR|D_PACK, "urb status: %d", urb->status); 214 PDEBUG(D_ERR|D_PACK, "urb status: %d", urb->status);
223 return; 215 urb->status = 0;
216 goto resubmit;
224 } 217 }
225 218
226 /* check the availability of the frame buffer */ 219 PDEBUG(D_PACK, "packet l:%d", urb->actual_length);
227 frame = gspca_get_i_frame(gspca_dev); 220 gspca_dev->sd_desc->pkt_scan(gspca_dev,
228 if (!frame) { 221 urb->transfer_buffer,
229 gspca_dev->last_packet_type = DISCARD_PACKET; 222 urb->actual_length);
230 } else {
231 PDEBUG(D_PACK, "packet l:%d", urb->actual_length);
232 gspca_dev->sd_desc->pkt_scan(gspca_dev,
233 frame,
234 urb->transfer_buffer,
235 urb->actual_length);
236 }
237 223
224resubmit:
238 /* resubmit the URB */ 225 /* resubmit the URB */
239 if (gspca_dev->cam.bulk_nurbs != 0) { 226 if (gspca_dev->cam.bulk_nurbs != 0) {
240 st = usb_submit_urb(urb, GFP_ATOMIC); 227 st = usb_submit_urb(urb, GFP_ATOMIC);
@@ -255,24 +242,27 @@ static void bulk_irq(struct urb *urb)
255 * DISCARD_PACKET invalidates the whole frame. 242 * DISCARD_PACKET invalidates the whole frame.
256 * On LAST_PACKET, a new frame is returned. 243 * On LAST_PACKET, a new frame is returned.
257 */ 244 */
258struct gspca_frame *gspca_frame_add(struct gspca_dev *gspca_dev, 245void gspca_frame_add(struct gspca_dev *gspca_dev,
259 enum gspca_packet_type packet_type, 246 enum gspca_packet_type packet_type,
260 struct gspca_frame *frame, 247 const u8 *data,
261 const __u8 *data, 248 int len)
262 int len)
263{ 249{
250 struct gspca_frame *frame;
264 int i, j; 251 int i, j;
265 252
266 PDEBUG(D_PACK, "add t:%d l:%d", packet_type, len); 253 PDEBUG(D_PACK, "add t:%d l:%d", packet_type, len);
267 254
255 /* check the availability of the frame buffer */
256 frame = gspca_dev->cur_frame;
257 if ((frame->v4l2_buf.flags & BUF_ALL_FLAGS)
258 != V4L2_BUF_FLAG_QUEUED) {
259 gspca_dev->last_packet_type = DISCARD_PACKET;
260 return;
261 }
262
268 /* when start of a new frame, if the current frame buffer 263 /* when start of a new frame, if the current frame buffer
269 * is not queued, discard the whole frame */ 264 * is not queued, discard the whole frame */
270 if (packet_type == FIRST_PACKET) { 265 if (packet_type == FIRST_PACKET) {
271 if ((frame->v4l2_buf.flags & BUF_ALL_FLAGS)
272 != V4L2_BUF_FLAG_QUEUED) {
273 gspca_dev->last_packet_type = DISCARD_PACKET;
274 return frame;
275 }
276 frame->data_end = frame->data; 266 frame->data_end = frame->data;
277 jiffies_to_timeval(get_jiffies_64(), 267 jiffies_to_timeval(get_jiffies_64(),
278 &frame->v4l2_buf.timestamp); 268 &frame->v4l2_buf.timestamp);
@@ -280,7 +270,7 @@ struct gspca_frame *gspca_frame_add(struct gspca_dev *gspca_dev,
280 } else if (gspca_dev->last_packet_type == DISCARD_PACKET) { 270 } else if (gspca_dev->last_packet_type == DISCARD_PACKET) {
281 if (packet_type == LAST_PACKET) 271 if (packet_type == LAST_PACKET)
282 gspca_dev->last_packet_type = packet_type; 272 gspca_dev->last_packet_type = packet_type;
283 return frame; 273 return;
284 } 274 }
285 275
286 /* append the packet to the frame buffer */ 276 /* append the packet to the frame buffer */
@@ -312,9 +302,9 @@ struct gspca_frame *gspca_frame_add(struct gspca_dev *gspca_dev,
312 i, 302 i,
313 gspca_dev->fr_o); 303 gspca_dev->fr_o);
314 j = gspca_dev->fr_queue[i]; 304 j = gspca_dev->fr_queue[i];
315 frame = &gspca_dev->frame[j]; 305 gspca_dev->cur_frame = &gspca_dev->frame[j];
316 } 306 }
317 return frame; 307 return;
318} 308}
319EXPORT_SYMBOL(gspca_frame_add); 309EXPORT_SYMBOL(gspca_frame_add);
320 310
@@ -395,6 +385,7 @@ static int frame_alloc(struct gspca_dev *gspca_dev,
395 frame->v4l2_buf.m.offset = i * frsz; 385 frame->v4l2_buf.m.offset = i * frsz;
396 } 386 }
397 gspca_dev->fr_i = gspca_dev->fr_o = gspca_dev->fr_q = 0; 387 gspca_dev->fr_i = gspca_dev->fr_o = gspca_dev->fr_q = 0;
388 gspca_dev->cur_frame = &gspca_dev->frame[0];
398 gspca_dev->last_packet_type = DISCARD_PACKET; 389 gspca_dev->last_packet_type = DISCARD_PACKET;
399 gspca_dev->sequence = 0; 390 gspca_dev->sequence = 0;
400 return 0; 391 return 0;
@@ -475,10 +466,18 @@ static struct usb_host_endpoint *get_ep(struct gspca_dev *gspca_dev)
475 xfer = gspca_dev->cam.bulk ? USB_ENDPOINT_XFER_BULK 466 xfer = gspca_dev->cam.bulk ? USB_ENDPOINT_XFER_BULK
476 : USB_ENDPOINT_XFER_ISOC; 467 : USB_ENDPOINT_XFER_ISOC;
477 i = gspca_dev->alt; /* previous alt setting */ 468 i = gspca_dev->alt; /* previous alt setting */
478 while (--i >= 0) { 469 if (gspca_dev->cam.reverse_alts) {
479 ep = alt_xfer(&intf->altsetting[i], xfer); 470 while (++i < gspca_dev->nbalt) {
480 if (ep) 471 ep = alt_xfer(&intf->altsetting[i], xfer);
481 break; 472 if (ep)
473 break;
474 }
475 } else {
476 while (--i >= 0) {
477 ep = alt_xfer(&intf->altsetting[i], xfer);
478 if (ep)
479 break;
480 }
482 } 481 }
483 if (ep == NULL) { 482 if (ep == NULL) {
484 err("no transfer endpoint found"); 483 err("no transfer endpoint found");
@@ -599,7 +598,11 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev)
599 598
600 /* set the higher alternate setting and 599 /* set the higher alternate setting and
601 * loop until urb submit succeeds */ 600 * loop until urb submit succeeds */
602 gspca_dev->alt = gspca_dev->nbalt; 601 if (gspca_dev->cam.reverse_alts)
602 gspca_dev->alt = 0;
603 else
604 gspca_dev->alt = gspca_dev->nbalt;
605
603 if (gspca_dev->sd_desc->isoc_init) { 606 if (gspca_dev->sd_desc->isoc_init) {
604 ret = gspca_dev->sd_desc->isoc_init(gspca_dev); 607 ret = gspca_dev->sd_desc->isoc_init(gspca_dev);
605 if (ret < 0) 608 if (ret < 0)
@@ -641,15 +644,19 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev)
641 } 644 }
642 if (ret >= 0) 645 if (ret >= 0)
643 break; 646 break;
644 PDEBUG(D_ERR|D_STREAM,
645 "usb_submit_urb alt %d err %d", gspca_dev->alt, ret);
646 gspca_dev->streaming = 0; 647 gspca_dev->streaming = 0;
647 destroy_urbs(gspca_dev); 648 destroy_urbs(gspca_dev);
648 if (ret != -ENOSPC) 649 if (ret != -ENOSPC) {
650 PDEBUG(D_ERR|D_STREAM,
651 "usb_submit_urb alt %d err %d",
652 gspca_dev->alt, ret);
649 goto out; 653 goto out;
654 }
650 655
651 /* the bandwidth is not wide enough 656 /* the bandwidth is not wide enough
652 * negociate or try a lower alternate setting */ 657 * negociate or try a lower alternate setting */
658 PDEBUG(D_ERR|D_STREAM,
659 "bandwidth not wide enough - trying again");
653 msleep(20); /* wait for kill complete */ 660 msleep(20); /* wait for kill complete */
654 if (gspca_dev->sd_desc->isoc_nego) { 661 if (gspca_dev->sd_desc->isoc_nego) {
655 ret = gspca_dev->sd_desc->isoc_nego(gspca_dev); 662 ret = gspca_dev->sd_desc->isoc_nego(gspca_dev);
@@ -980,7 +987,7 @@ static void gspca_release(struct video_device *vfd)
980{ 987{
981 struct gspca_dev *gspca_dev = container_of(vfd, struct gspca_dev, vdev); 988 struct gspca_dev *gspca_dev = container_of(vfd, struct gspca_dev, vdev);
982 989
983 PDEBUG(D_STREAM, "device released"); 990 PDEBUG(D_PROBE, "/dev/video%d released", gspca_dev->vdev.num);
984 991
985 kfree(gspca_dev->usb_buf); 992 kfree(gspca_dev->usb_buf);
986 kfree(gspca_dev); 993 kfree(gspca_dev);
@@ -991,7 +998,7 @@ static int dev_open(struct file *file)
991 struct gspca_dev *gspca_dev; 998 struct gspca_dev *gspca_dev;
992 int ret; 999 int ret;
993 1000
994 PDEBUG(D_STREAM, "%s open", current->comm); 1001 PDEBUG(D_STREAM, "[%s] open", current->comm);
995 gspca_dev = (struct gspca_dev *) video_devdata(file); 1002 gspca_dev = (struct gspca_dev *) video_devdata(file);
996 if (mutex_lock_interruptible(&gspca_dev->queue_lock)) 1003 if (mutex_lock_interruptible(&gspca_dev->queue_lock))
997 return -ERESTARTSYS; 1004 return -ERESTARTSYS;
@@ -1037,7 +1044,7 @@ static int dev_close(struct file *file)
1037{ 1044{
1038 struct gspca_dev *gspca_dev = file->private_data; 1045 struct gspca_dev *gspca_dev = file->private_data;
1039 1046
1040 PDEBUG(D_STREAM, "%s close", current->comm); 1047 PDEBUG(D_STREAM, "[%s] close", current->comm);
1041 if (mutex_lock_interruptible(&gspca_dev->queue_lock)) 1048 if (mutex_lock_interruptible(&gspca_dev->queue_lock))
1042 return -ERESTARTSYS; 1049 return -ERESTARTSYS;
1043 gspca_dev->users--; 1050 gspca_dev->users--;
@@ -1138,10 +1145,13 @@ static int vidioc_queryctrl(struct file *file, void *priv,
1138 } 1145 }
1139 } else { 1146 } else {
1140 ctrls = get_ctrl(gspca_dev, id); 1147 ctrls = get_ctrl(gspca_dev, id);
1148 i = ctrls - gspca_dev->sd_desc->ctrls;
1141 } 1149 }
1142 if (ctrls == NULL) 1150 if (ctrls == NULL)
1143 return -EINVAL; 1151 return -EINVAL;
1144 memcpy(q_ctrl, ctrls, sizeof *q_ctrl); 1152 memcpy(q_ctrl, ctrls, sizeof *q_ctrl);
1153 if (gspca_dev->ctrl_inac & (1 << i))
1154 q_ctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
1145 return 0; 1155 return 0;
1146} 1156}
1147 1157
@@ -1603,7 +1613,7 @@ static int dev_mmap(struct file *file, struct vm_area_struct *vma)
1603 size -= PAGE_SIZE; 1613 size -= PAGE_SIZE;
1604 } 1614 }
1605 1615
1606 vma->vm_ops = &gspca_vm_ops; 1616 vma->vm_ops = (struct vm_operations_struct *) &gspca_vm_ops;
1607 vma->vm_private_data = frame; 1617 vma->vm_private_data = frame;
1608 gspca_vm_open(vma); 1618 gspca_vm_open(vma);
1609 ret = 0; 1619 ret = 0;
@@ -2001,11 +2011,15 @@ int gspca_dev_probe(struct usb_interface *intf,
2001 PDEBUG(D_PROBE, "probing %04x:%04x", id->idVendor, id->idProduct); 2011 PDEBUG(D_PROBE, "probing %04x:%04x", id->idVendor, id->idProduct);
2002 2012
2003 /* we don't handle multi-config cameras */ 2013 /* we don't handle multi-config cameras */
2004 if (dev->descriptor.bNumConfigurations != 1) 2014 if (dev->descriptor.bNumConfigurations != 1) {
2015 PDEBUG(D_ERR, "Too many config");
2005 return -ENODEV; 2016 return -ENODEV;
2017 }
2006 interface = &intf->cur_altsetting->desc; 2018 interface = &intf->cur_altsetting->desc;
2007 if (interface->bInterfaceNumber > 0) 2019 if (interface->bInterfaceNumber > 0) {
2020 PDEBUG(D_ERR, "intf != 0");
2008 return -ENODEV; 2021 return -ENODEV;
2022 }
2009 2023
2010 /* create the device */ 2024 /* create the device */
2011 if (dev_size < sizeof *gspca_dev) 2025 if (dev_size < sizeof *gspca_dev)
@@ -2059,7 +2073,7 @@ int gspca_dev_probe(struct usb_interface *intf,
2059 } 2073 }
2060 2074
2061 usb_set_intfdata(intf, gspca_dev); 2075 usb_set_intfdata(intf, gspca_dev);
2062 PDEBUG(D_PROBE, "probe ok"); 2076 PDEBUG(D_PROBE, "/dev/video%d created", gspca_dev->vdev.num);
2063 return 0; 2077 return 0;
2064out: 2078out:
2065 kfree(gspca_dev->usb_buf); 2079 kfree(gspca_dev->usb_buf);
@@ -2078,6 +2092,7 @@ void gspca_disconnect(struct usb_interface *intf)
2078{ 2092{
2079 struct gspca_dev *gspca_dev = usb_get_intfdata(intf); 2093 struct gspca_dev *gspca_dev = usb_get_intfdata(intf);
2080 2094
2095 PDEBUG(D_PROBE, "/dev/video%d disconnect", gspca_dev->vdev.num);
2081 mutex_lock(&gspca_dev->usb_lock); 2096 mutex_lock(&gspca_dev->usb_lock);
2082 gspca_dev->present = 0; 2097 gspca_dev->present = 0;
2083 2098
@@ -2096,7 +2111,7 @@ void gspca_disconnect(struct usb_interface *intf)
2096 /* (this will call gspca_release() immediatly or on last close) */ 2111 /* (this will call gspca_release() immediatly or on last close) */
2097 video_unregister_device(&gspca_dev->vdev); 2112 video_unregister_device(&gspca_dev->vdev);
2098 2113
2099 PDEBUG(D_PROBE, "disconnect complete"); 2114/* PDEBUG(D_PROBE, "disconnect complete"); */
2100} 2115}
2101EXPORT_SYMBOL(gspca_disconnect); 2116EXPORT_SYMBOL(gspca_disconnect);
2102 2117
diff --git a/drivers/media/video/gspca/gspca.h b/drivers/media/video/gspca/gspca.h
index 70b1fd830876..181617355ec3 100644
--- a/drivers/media/video/gspca/gspca.h
+++ b/drivers/media/video/gspca/gspca.h
@@ -58,6 +58,7 @@ struct cam {
58 u8 npkt; /* number of packets in an ISOC message 58 u8 npkt; /* number of packets in an ISOC message
59 * 0 is the default value: 32 packets */ 59 * 0 is the default value: 32 packets */
60 u32 input_flags; /* value for ENUM_INPUT status flags */ 60 u32 input_flags; /* value for ENUM_INPUT status flags */
61 char reverse_alts; /* Alt settings are in high to low order */
61}; 62};
62 63
63struct gspca_dev; 64struct gspca_dev;
@@ -78,8 +79,7 @@ typedef int (*cam_streamparm_op) (struct gspca_dev *,
78typedef int (*cam_qmnu_op) (struct gspca_dev *, 79typedef int (*cam_qmnu_op) (struct gspca_dev *,
79 struct v4l2_querymenu *); 80 struct v4l2_querymenu *);
80typedef void (*cam_pkt_op) (struct gspca_dev *gspca_dev, 81typedef void (*cam_pkt_op) (struct gspca_dev *gspca_dev,
81 struct gspca_frame *frame, 82 u8 *data,
82 __u8 *data,
83 int len); 83 int len);
84 84
85struct ctrl { 85struct ctrl {
@@ -142,6 +142,7 @@ struct gspca_dev {
142 struct cam cam; /* device information */ 142 struct cam cam; /* device information */
143 const struct sd_desc *sd_desc; /* subdriver description */ 143 const struct sd_desc *sd_desc; /* subdriver description */
144 unsigned ctrl_dis; /* disabled controls (bit map) */ 144 unsigned ctrl_dis; /* disabled controls (bit map) */
145 unsigned ctrl_inac; /* inactive controls (bit map) */
145 146
146#define USB_BUF_SZ 64 147#define USB_BUF_SZ 64
147 __u8 *usb_buf; /* buffer for USB exchanges */ 148 __u8 *usb_buf; /* buffer for USB exchanges */
@@ -149,6 +150,7 @@ struct gspca_dev {
149 150
150 __u8 *frbuf; /* buffer for nframes */ 151 __u8 *frbuf; /* buffer for nframes */
151 struct gspca_frame frame[GSPCA_MAX_FRAMES]; 152 struct gspca_frame frame[GSPCA_MAX_FRAMES];
153 struct gspca_frame *cur_frame; /* frame beeing filled */
152 __u32 frsz; /* frame size */ 154 __u32 frsz; /* frame size */
153 char nframes; /* number of frames */ 155 char nframes; /* number of frames */
154 char fr_i; /* frame being filled */ 156 char fr_i; /* frame being filled */
@@ -189,11 +191,10 @@ int gspca_dev_probe(struct usb_interface *intf,
189 int dev_size, 191 int dev_size,
190 struct module *module); 192 struct module *module);
191void gspca_disconnect(struct usb_interface *intf); 193void gspca_disconnect(struct usb_interface *intf);
192struct gspca_frame *gspca_frame_add(struct gspca_dev *gspca_dev, 194void gspca_frame_add(struct gspca_dev *gspca_dev,
193 enum gspca_packet_type packet_type, 195 enum gspca_packet_type packet_type,
194 struct gspca_frame *frame, 196 const u8 *data,
195 const __u8 *data, 197 int len);
196 int len);
197struct gspca_frame *gspca_get_i_frame(struct gspca_dev *gspca_dev); 198struct gspca_frame *gspca_get_i_frame(struct gspca_dev *gspca_dev);
198#ifdef CONFIG_PM 199#ifdef CONFIG_PM
199int gspca_suspend(struct usb_interface *intf, pm_message_t message); 200int gspca_suspend(struct usb_interface *intf, pm_message_t message);
diff --git a/drivers/media/video/gspca/jeilinj.c b/drivers/media/video/gspca/jeilinj.c
index a11c97ebeb0f..2019b04f9235 100644
--- a/drivers/media/video/gspca/jeilinj.c
+++ b/drivers/media/video/gspca/jeilinj.c
@@ -181,11 +181,9 @@ static void jlj_dostream(struct work_struct *work)
181{ 181{
182 struct sd *dev = container_of(work, struct sd, work_struct); 182 struct sd *dev = container_of(work, struct sd, work_struct);
183 struct gspca_dev *gspca_dev = &dev->gspca_dev; 183 struct gspca_dev *gspca_dev = &dev->gspca_dev;
184 struct gspca_frame *frame;
185 int blocks_left; /* 0x200-sized blocks remaining in current frame. */ 184 int blocks_left; /* 0x200-sized blocks remaining in current frame. */
186 int size_in_blocks; 185 int size_in_blocks;
187 int act_len; 186 int act_len;
188 int discarding = 0; /* true if we failed to get space for frame. */
189 int packet_type; 187 int packet_type;
190 int ret; 188 int ret;
191 u8 *buffer; 189 u8 *buffer;
@@ -196,15 +194,6 @@ static void jlj_dostream(struct work_struct *work)
196 goto quit_stream; 194 goto quit_stream;
197 } 195 }
198 while (gspca_dev->present && gspca_dev->streaming) { 196 while (gspca_dev->present && gspca_dev->streaming) {
199 if (!gspca_dev->present)
200 goto quit_stream;
201 /* Start a new frame, and add the JPEG header, first thing */
202 frame = gspca_get_i_frame(gspca_dev);
203 if (frame && !discarding)
204 gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
205 dev->jpeg_hdr, JPEG_HDR_SZ);
206 else
207 discarding = 1;
208 /* 197 /*
209 * Now request data block 0. Line 0 reports the size 198 * Now request data block 0. Line 0 reports the size
210 * to download, in blocks of size 0x200, and also tells the 199 * to download, in blocks of size 0x200, and also tells the
@@ -222,14 +211,15 @@ static void jlj_dostream(struct work_struct *work)
222 size_in_blocks = buffer[0x0a]; 211 size_in_blocks = buffer[0x0a];
223 blocks_left = buffer[0x0a] - 1; 212 blocks_left = buffer[0x0a] - 1;
224 PDEBUG(D_STREAM, "blocks_left = 0x%x", blocks_left); 213 PDEBUG(D_STREAM, "blocks_left = 0x%x", blocks_left);
225 packet_type = INTER_PACKET; 214
226 if (frame && !discarding) 215 /* Start a new frame, and add the JPEG header, first thing */
227 /* Toss line 0 of data block 0, keep the rest. */ 216 gspca_frame_add(gspca_dev, FIRST_PACKET,
228 gspca_frame_add(gspca_dev, packet_type, 217 dev->jpeg_hdr, JPEG_HDR_SZ);
229 frame, buffer + FRAME_HEADER_LEN, 218 /* Toss line 0 of data block 0, keep the rest. */
219 gspca_frame_add(gspca_dev, INTER_PACKET,
220 buffer + FRAME_HEADER_LEN,
230 JEILINJ_MAX_TRANSFER - FRAME_HEADER_LEN); 221 JEILINJ_MAX_TRANSFER - FRAME_HEADER_LEN);
231 else 222
232 discarding = 1;
233 while (blocks_left > 0) { 223 while (blocks_left > 0) {
234 if (!gspca_dev->present) 224 if (!gspca_dev->present)
235 goto quit_stream; 225 goto quit_stream;
@@ -246,12 +236,8 @@ static void jlj_dostream(struct work_struct *work)
246 packet_type = LAST_PACKET; 236 packet_type = LAST_PACKET;
247 else 237 else
248 packet_type = INTER_PACKET; 238 packet_type = INTER_PACKET;
249 if (frame && !discarding) 239 gspca_frame_add(gspca_dev, packet_type,
250 gspca_frame_add(gspca_dev, packet_type, 240 buffer, JEILINJ_MAX_TRANSFER);
251 frame, buffer,
252 JEILINJ_MAX_TRANSFER);
253 else
254 discarding = 1;
255 } 241 }
256 } 242 }
257quit_stream: 243quit_stream:
diff --git a/drivers/media/video/gspca/m5602/m5602_core.c b/drivers/media/video/gspca/m5602/m5602_core.c
index 7f1e5415850b..844fc1d886d1 100644
--- a/drivers/media/video/gspca/m5602/m5602_core.c
+++ b/drivers/media/video/gspca/m5602/m5602_core.c
@@ -274,8 +274,7 @@ static int m5602_start_transfer(struct gspca_dev *gspca_dev)
274} 274}
275 275
276static void m5602_urb_complete(struct gspca_dev *gspca_dev, 276static void m5602_urb_complete(struct gspca_dev *gspca_dev,
277 struct gspca_frame *frame, 277 u8 *data, int len)
278 __u8 *data, int len)
279{ 278{
280 struct sd *sd = (struct sd *) gspca_dev; 279 struct sd *sd = (struct sd *) gspca_dev;
281 280
@@ -295,19 +294,27 @@ static void m5602_urb_complete(struct gspca_dev *gspca_dev,
295 len -= 6; 294 len -= 6;
296 295
297 /* Complete the last frame (if any) */ 296 /* Complete the last frame (if any) */
298 frame = gspca_frame_add(gspca_dev, LAST_PACKET, 297 gspca_frame_add(gspca_dev, LAST_PACKET,
299 frame, data, 0); 298 NULL, 0);
300 sd->frame_count++; 299 sd->frame_count++;
301 300
302 /* Create a new frame */ 301 /* Create a new frame */
303 gspca_frame_add(gspca_dev, FIRST_PACKET, frame, data, len); 302 gspca_frame_add(gspca_dev, FIRST_PACKET, data, len);
304 303
305 PDEBUG(D_FRAM, "Starting new frame %d", 304 PDEBUG(D_FRAM, "Starting new frame %d",
306 sd->frame_count); 305 sd->frame_count);
307 306
308 } else { 307 } else {
309 int cur_frame_len = frame->data_end - frame->data; 308 struct gspca_frame *frame;
309 int cur_frame_len;
310 310
311 frame = gspca_get_i_frame(gspca_dev);
312 if (frame == NULL) {
313 gspca_dev->last_packet_type = DISCARD_PACKET;
314 return;
315 }
316
317 cur_frame_len = frame->data_end - frame->data;
311 /* Remove urb header */ 318 /* Remove urb header */
312 data += 4; 319 data += 4;
313 len -= 4; 320 len -= 4;
@@ -316,12 +323,12 @@ static void m5602_urb_complete(struct gspca_dev *gspca_dev,
316 PDEBUG(D_FRAM, "Continuing frame %d copying %d bytes", 323 PDEBUG(D_FRAM, "Continuing frame %d copying %d bytes",
317 sd->frame_count, len); 324 sd->frame_count, len);
318 325
319 gspca_frame_add(gspca_dev, INTER_PACKET, frame, 326 gspca_frame_add(gspca_dev, INTER_PACKET,
320 data, len); 327 data, len);
321 } else if (frame->v4l2_buf.length - cur_frame_len > 0) { 328 } else if (frame->v4l2_buf.length - cur_frame_len > 0) {
322 /* Add the remaining data up to frame size */ 329 /* Add the remaining data up to frame size */
323 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, 330 gspca_frame_add(gspca_dev, INTER_PACKET, data,
324 frame->v4l2_buf.length - cur_frame_len); 331 frame->v4l2_buf.length - cur_frame_len);
325 } 332 }
326 } 333 }
327} 334}
diff --git a/drivers/media/video/gspca/mars.c b/drivers/media/video/gspca/mars.c
index de769caf013d..9cf8d68c71bf 100644
--- a/drivers/media/video/gspca/mars.c
+++ b/drivers/media/video/gspca/mars.c
@@ -325,8 +325,7 @@ static void sd_stop0(struct gspca_dev *gspca_dev)
325} 325}
326 326
327static void sd_pkt_scan(struct gspca_dev *gspca_dev, 327static void sd_pkt_scan(struct gspca_dev *gspca_dev,
328 struct gspca_frame *frame, /* target */ 328 u8 *data, /* isoc packet */
329 __u8 *data, /* isoc packet */
330 int len) /* iso packet length */ 329 int len) /* iso packet length */
331{ 330{
332 struct sd *sd = (struct sd *) gspca_dev; 331 struct sd *sd = (struct sd *) gspca_dev;
@@ -348,11 +347,11 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
348 || data[5 + p] == 0x67) { 347 || data[5 + p] == 0x67) {
349 PDEBUG(D_PACK, "sof offset: %d len: %d", 348 PDEBUG(D_PACK, "sof offset: %d len: %d",
350 p, len); 349 p, len);
351 frame = gspca_frame_add(gspca_dev, LAST_PACKET, 350 gspca_frame_add(gspca_dev, LAST_PACKET,
352 frame, data, p); 351 data, p);
353 352
354 /* put the JPEG header */ 353 /* put the JPEG header */
355 gspca_frame_add(gspca_dev, FIRST_PACKET, frame, 354 gspca_frame_add(gspca_dev, FIRST_PACKET,
356 sd->jpeg_hdr, JPEG_HDR_SZ); 355 sd->jpeg_hdr, JPEG_HDR_SZ);
357 data += p + 16; 356 data += p + 16;
358 len -= p + 16; 357 len -= p + 16;
@@ -360,7 +359,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
360 } 359 }
361 } 360 }
362 } 361 }
363 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); 362 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
364} 363}
365 364
366static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) 365static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
diff --git a/drivers/media/video/gspca/mr97310a.c b/drivers/media/video/gspca/mr97310a.c
index f8328b9efae5..126d968dd9e0 100644
--- a/drivers/media/video/gspca/mr97310a.c
+++ b/drivers/media/video/gspca/mr97310a.c
@@ -1,23 +1,30 @@
1/* 1/*
2 * Mars MR97310A library 2 * Mars MR97310A library
3 * 3 *
4 * The original mr97310a driver, which supported the Aiptek Pencam VGA+, is
4 * Copyright (C) 2009 Kyle Guinn <elyk03@gmail.com> 5 * Copyright (C) 2009 Kyle Guinn <elyk03@gmail.com>
5 * 6 *
6 * Support for the MR97310A cameras in addition to the Aiptek Pencam VGA+ 7 * Support for the MR97310A cameras in addition to the Aiptek Pencam VGA+
7 * and for the routines for detecting and classifying these various cameras, 8 * and for the routines for detecting and classifying these various cameras,
9 * is Copyright (C) 2009 Theodore Kilgore <kilgota@auburn.edu>
8 * 10 *
11 * Support for the control settings for the CIF cameras is
12 * Copyright (C) 2009 Hans de Goede <hdgoede@redhat.com> and
13 * Thomas Kaiser <thomas@kaiser-linux.li>
14 *
15 * Support for the control settings for the VGA cameras is
9 * Copyright (C) 2009 Theodore Kilgore <kilgota@auburn.edu> 16 * Copyright (C) 2009 Theodore Kilgore <kilgota@auburn.edu>
10 * 17 *
11 * Acknowledgements: 18 * Several previously unsupported cameras are owned and have been tested by
19 * Hans de Goede <hdgoede@redhat.com> and
20 * Thomas Kaiser <thomas@kaiser-linux.li> and
21 * Theodore Kilgore <kilgota@auburn.edu> and
22 * Edmond Rodriguez <erodrig_97@yahoo.com> and
23 * Aurelien Jacobs <aurel@gnuage.org>
12 * 24 *
13 * The MR97311A support in gspca/mars.c has been helpful in understanding some 25 * The MR97311A support in gspca/mars.c has been helpful in understanding some
14 * of the registers in these cameras. 26 * of the registers in these cameras.
15 * 27 *
16 * Hans de Goede <hdgoede@redhat.com> and
17 * Thomas Kaiser <thomas@kaiser-linux.li>
18 * have assisted with their experience. Each of them has also helped by
19 * testing a previously unsupported camera.
20 *
21 * This program is free software; you can redistribute it and/or modify 28 * This program is free software; you can redistribute it and/or modify
22 * it under the terms of the GNU General Public License as published by 29 * it under the terms of the GNU General Public License as published by
23 * the Free Software Foundation; either version 2 of the License, or 30 * the Free Software Foundation; either version 2 of the License, or
@@ -40,11 +47,9 @@
40#define CAM_TYPE_CIF 0 47#define CAM_TYPE_CIF 0
41#define CAM_TYPE_VGA 1 48#define CAM_TYPE_VGA 1
42 49
43#define MR97310A_BRIGHTNESS_MIN -254
44#define MR97310A_BRIGHTNESS_MAX 255
45#define MR97310A_BRIGHTNESS_DEFAULT 0 50#define MR97310A_BRIGHTNESS_DEFAULT 0
46 51
47#define MR97310A_EXPOSURE_MIN 300 52#define MR97310A_EXPOSURE_MIN 0
48#define MR97310A_EXPOSURE_MAX 4095 53#define MR97310A_EXPOSURE_MAX 4095
49#define MR97310A_EXPOSURE_DEFAULT 1000 54#define MR97310A_EXPOSURE_DEFAULT 1000
50 55
@@ -52,6 +57,10 @@
52#define MR97310A_GAIN_MAX 31 57#define MR97310A_GAIN_MAX 31
53#define MR97310A_GAIN_DEFAULT 25 58#define MR97310A_GAIN_DEFAULT 25
54 59
60#define MR97310A_MIN_CLOCKDIV_MIN 3
61#define MR97310A_MIN_CLOCKDIV_MAX 8
62#define MR97310A_MIN_CLOCKDIV_DEFAULT 3
63
55MODULE_AUTHOR("Kyle Guinn <elyk03@gmail.com>," 64MODULE_AUTHOR("Kyle Guinn <elyk03@gmail.com>,"
56 "Theodore Kilgore <kilgota@auburn.edu>"); 65 "Theodore Kilgore <kilgota@auburn.edu>");
57MODULE_DESCRIPTION("GSPCA/Mars-Semi MR97310A USB Camera Driver"); 66MODULE_DESCRIPTION("GSPCA/Mars-Semi MR97310A USB Camera Driver");
@@ -69,10 +78,12 @@ struct sd {
69 u8 cam_type; /* 0 is CIF and 1 is VGA */ 78 u8 cam_type; /* 0 is CIF and 1 is VGA */
70 u8 sensor_type; /* We use 0 and 1 here, too. */ 79 u8 sensor_type; /* We use 0 and 1 here, too. */
71 u8 do_lcd_stop; 80 u8 do_lcd_stop;
81 u8 adj_colors;
72 82
73 int brightness; 83 int brightness;
74 u16 exposure; 84 u16 exposure;
75 u8 gain; 85 u8 gain;
86 u8 min_clockdiv;
76}; 87};
77 88
78struct sensor_w_data { 89struct sensor_w_data {
@@ -82,26 +93,31 @@ struct sensor_w_data {
82 int len; 93 int len;
83}; 94};
84 95
96static void sd_stopN(struct gspca_dev *gspca_dev);
85static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); 97static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
86static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); 98static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
87static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val); 99static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val);
88static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val); 100static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val);
89static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val); 101static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val);
90static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val); 102static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val);
103static int sd_setmin_clockdiv(struct gspca_dev *gspca_dev, __s32 val);
104static int sd_getmin_clockdiv(struct gspca_dev *gspca_dev, __s32 *val);
91static void setbrightness(struct gspca_dev *gspca_dev); 105static void setbrightness(struct gspca_dev *gspca_dev);
92static void setexposure(struct gspca_dev *gspca_dev); 106static void setexposure(struct gspca_dev *gspca_dev);
93static void setgain(struct gspca_dev *gspca_dev); 107static void setgain(struct gspca_dev *gspca_dev);
94 108
95/* V4L2 controls supported by the driver */ 109/* V4L2 controls supported by the driver */
96static struct ctrl sd_ctrls[] = { 110static struct ctrl sd_ctrls[] = {
111/* Separate brightness control description for Argus QuickClix as it has
112 different limits from the other mr97310a cameras */
97 { 113 {
98#define BRIGHTNESS_IDX 0 114#define NORM_BRIGHTNESS_IDX 0
99 { 115 {
100 .id = V4L2_CID_BRIGHTNESS, 116 .id = V4L2_CID_BRIGHTNESS,
101 .type = V4L2_CTRL_TYPE_INTEGER, 117 .type = V4L2_CTRL_TYPE_INTEGER,
102 .name = "Brightness", 118 .name = "Brightness",
103 .minimum = MR97310A_BRIGHTNESS_MIN, 119 .minimum = -254,
104 .maximum = MR97310A_BRIGHTNESS_MAX, 120 .maximum = 255,
105 .step = 1, 121 .step = 1,
106 .default_value = MR97310A_BRIGHTNESS_DEFAULT, 122 .default_value = MR97310A_BRIGHTNESS_DEFAULT,
107 .flags = 0, 123 .flags = 0,
@@ -110,7 +126,22 @@ static struct ctrl sd_ctrls[] = {
110 .get = sd_getbrightness, 126 .get = sd_getbrightness,
111 }, 127 },
112 { 128 {
113#define EXPOSURE_IDX 1 129#define ARGUS_QC_BRIGHTNESS_IDX 1
130 {
131 .id = V4L2_CID_BRIGHTNESS,
132 .type = V4L2_CTRL_TYPE_INTEGER,
133 .name = "Brightness",
134 .minimum = 0,
135 .maximum = 15,
136 .step = 1,
137 .default_value = MR97310A_BRIGHTNESS_DEFAULT,
138 .flags = 0,
139 },
140 .set = sd_setbrightness,
141 .get = sd_getbrightness,
142 },
143 {
144#define EXPOSURE_IDX 2
114 { 145 {
115 .id = V4L2_CID_EXPOSURE, 146 .id = V4L2_CID_EXPOSURE,
116 .type = V4L2_CTRL_TYPE_INTEGER, 147 .type = V4L2_CTRL_TYPE_INTEGER,
@@ -125,7 +156,7 @@ static struct ctrl sd_ctrls[] = {
125 .get = sd_getexposure, 156 .get = sd_getexposure,
126 }, 157 },
127 { 158 {
128#define GAIN_IDX 2 159#define GAIN_IDX 3
129 { 160 {
130 .id = V4L2_CID_GAIN, 161 .id = V4L2_CID_GAIN,
131 .type = V4L2_CTRL_TYPE_INTEGER, 162 .type = V4L2_CTRL_TYPE_INTEGER,
@@ -139,6 +170,21 @@ static struct ctrl sd_ctrls[] = {
139 .set = sd_setgain, 170 .set = sd_setgain,
140 .get = sd_getgain, 171 .get = sd_getgain,
141 }, 172 },
173 {
174#define MIN_CLOCKDIV_IDX 4
175 {
176 .id = V4L2_CID_PRIVATE_BASE,
177 .type = V4L2_CTRL_TYPE_INTEGER,
178 .name = "Minimum Clock Divider",
179 .minimum = MR97310A_MIN_CLOCKDIV_MIN,
180 .maximum = MR97310A_MIN_CLOCKDIV_MAX,
181 .step = 1,
182 .default_value = MR97310A_MIN_CLOCKDIV_DEFAULT,
183 .flags = 0,
184 },
185 .set = sd_setmin_clockdiv,
186 .get = sd_getmin_clockdiv,
187 },
142}; 188};
143 189
144static const struct v4l2_pix_format vga_mode[] = { 190static const struct v4l2_pix_format vga_mode[] = {
@@ -230,12 +276,17 @@ static int sensor_write1(struct gspca_dev *gspca_dev, u8 reg, u8 data)
230 int rc; 276 int rc;
231 277
232 buf = data; 278 buf = data;
233 rc = sensor_write_reg(gspca_dev, reg, 0x01, &buf, 1); 279 if (sd->cam_type == CAM_TYPE_CIF) {
280 rc = sensor_write_reg(gspca_dev, reg, 0x01, &buf, 1);
281 confirm_reg = sd->sensor_type ? 0x13 : 0x11;
282 } else {
283 rc = sensor_write_reg(gspca_dev, reg, 0x00, &buf, 1);
284 confirm_reg = 0x11;
285 }
234 if (rc < 0) 286 if (rc < 0)
235 return rc; 287 return rc;
236 288
237 buf = 0x01; 289 buf = 0x01;
238 confirm_reg = sd->sensor_type ? 0x13 : 0x11;
239 rc = sensor_write_reg(gspca_dev, confirm_reg, 0x00, &buf, 1); 290 rc = sensor_write_reg(gspca_dev, confirm_reg, 0x00, &buf, 1);
240 if (rc < 0) 291 if (rc < 0)
241 return rc; 292 return rc;
@@ -243,18 +294,26 @@ static int sensor_write1(struct gspca_dev *gspca_dev, u8 reg, u8 data)
243 return 0; 294 return 0;
244} 295}
245 296
246static int cam_get_response16(struct gspca_dev *gspca_dev) 297static int cam_get_response16(struct gspca_dev *gspca_dev, u8 reg, int verbose)
247{ 298{
248 __u8 *data = gspca_dev->usb_buf;
249 int err_code; 299 int err_code;
250 300
251 data[0] = 0x21; 301 gspca_dev->usb_buf[0] = reg;
252 err_code = mr_write(gspca_dev, 1); 302 err_code = mr_write(gspca_dev, 1);
253 if (err_code < 0) 303 if (err_code < 0)
254 return err_code; 304 return err_code;
255 305
256 err_code = mr_read(gspca_dev, 16); 306 err_code = mr_read(gspca_dev, 16);
257 return err_code; 307 if (err_code < 0)
308 return err_code;
309
310 if (verbose)
311 PDEBUG(D_PROBE, "Register: %02x reads %02x%02x%02x", reg,
312 gspca_dev->usb_buf[0],
313 gspca_dev->usb_buf[1],
314 gspca_dev->usb_buf[2]);
315
316 return 0;
258} 317}
259 318
260static int zero_the_pointer(struct gspca_dev *gspca_dev) 319static int zero_the_pointer(struct gspca_dev *gspca_dev)
@@ -264,7 +323,7 @@ static int zero_the_pointer(struct gspca_dev *gspca_dev)
264 u8 status = 0; 323 u8 status = 0;
265 int tries = 0; 324 int tries = 0;
266 325
267 err_code = cam_get_response16(gspca_dev); 326 err_code = cam_get_response16(gspca_dev, 0x21, 0);
268 if (err_code < 0) 327 if (err_code < 0)
269 return err_code; 328 return err_code;
270 329
@@ -275,7 +334,7 @@ static int zero_the_pointer(struct gspca_dev *gspca_dev)
275 if (err_code < 0) 334 if (err_code < 0)
276 return err_code; 335 return err_code;
277 336
278 err_code = cam_get_response16(gspca_dev); 337 err_code = cam_get_response16(gspca_dev, 0x21, 0);
279 if (err_code < 0) 338 if (err_code < 0)
280 return err_code; 339 return err_code;
281 340
@@ -285,7 +344,7 @@ static int zero_the_pointer(struct gspca_dev *gspca_dev)
285 if (err_code < 0) 344 if (err_code < 0)
286 return err_code; 345 return err_code;
287 346
288 err_code = cam_get_response16(gspca_dev); 347 err_code = cam_get_response16(gspca_dev, 0x21, 0);
289 if (err_code < 0) 348 if (err_code < 0)
290 return err_code; 349 return err_code;
291 350
@@ -295,7 +354,7 @@ static int zero_the_pointer(struct gspca_dev *gspca_dev)
295 if (err_code < 0) 354 if (err_code < 0)
296 return err_code; 355 return err_code;
297 356
298 err_code = cam_get_response16(gspca_dev); 357 err_code = cam_get_response16(gspca_dev, 0x21, 0);
299 if (err_code < 0) 358 if (err_code < 0)
300 return err_code; 359 return err_code;
301 360
@@ -306,7 +365,7 @@ static int zero_the_pointer(struct gspca_dev *gspca_dev)
306 return err_code; 365 return err_code;
307 366
308 while (status != 0x0a && tries < 256) { 367 while (status != 0x0a && tries < 256) {
309 err_code = cam_get_response16(gspca_dev); 368 err_code = cam_get_response16(gspca_dev, 0x21, 0);
310 status = data[0]; 369 status = data[0];
311 tries++; 370 tries++;
312 if (err_code < 0) 371 if (err_code < 0)
@@ -323,7 +382,7 @@ static int zero_the_pointer(struct gspca_dev *gspca_dev)
323 if (err_code < 0) 382 if (err_code < 0)
324 return err_code; 383 return err_code;
325 384
326 err_code = cam_get_response16(gspca_dev); 385 err_code = cam_get_response16(gspca_dev, 0x21, 0);
327 status = data[0]; 386 status = data[0];
328 tries++; 387 tries++;
329 if (err_code < 0) 388 if (err_code < 0)
@@ -342,89 +401,202 @@ static int zero_the_pointer(struct gspca_dev *gspca_dev)
342 return 0; 401 return 0;
343} 402}
344 403
345static u8 get_sensor_id(struct gspca_dev *gspca_dev) 404static int stream_start(struct gspca_dev *gspca_dev)
346{ 405{
347 int err_code; 406 gspca_dev->usb_buf[0] = 0x01;
348 407 gspca_dev->usb_buf[1] = 0x01;
349 gspca_dev->usb_buf[0] = 0x1e; 408 return mr_write(gspca_dev, 2);
350 err_code = mr_write(gspca_dev, 1); 409}
351 if (err_code < 0)
352 return err_code;
353 410
354 err_code = mr_read(gspca_dev, 16); 411static void stream_stop(struct gspca_dev *gspca_dev)
355 if (err_code < 0) 412{
356 return err_code; 413 gspca_dev->usb_buf[0] = 0x01;
414 gspca_dev->usb_buf[1] = 0x00;
415 if (mr_write(gspca_dev, 2) < 0)
416 PDEBUG(D_ERR, "Stream Stop failed");
417}
357 418
358 PDEBUG(D_PROBE, "Byte zero reported is %01x", gspca_dev->usb_buf[0]); 419static void lcd_stop(struct gspca_dev *gspca_dev)
420{
421 gspca_dev->usb_buf[0] = 0x19;
422 gspca_dev->usb_buf[1] = 0x54;
423 if (mr_write(gspca_dev, 2) < 0)
424 PDEBUG(D_ERR, "LCD Stop failed");
425}
359 426
360 return gspca_dev->usb_buf[0]; 427static int isoc_enable(struct gspca_dev *gspca_dev)
428{
429 gspca_dev->usb_buf[0] = 0x00;
430 gspca_dev->usb_buf[1] = 0x4d; /* ISOC transfering enable... */
431 return mr_write(gspca_dev, 2);
361} 432}
362 433
363/* this function is called at probe time */ 434/* This function is called at probe time */
364static int sd_config(struct gspca_dev *gspca_dev, 435static int sd_config(struct gspca_dev *gspca_dev,
365 const struct usb_device_id *id) 436 const struct usb_device_id *id)
366{ 437{
367 struct sd *sd = (struct sd *) gspca_dev; 438 struct sd *sd = (struct sd *) gspca_dev;
368 struct cam *cam; 439 struct cam *cam;
369 __u8 *data = gspca_dev->usb_buf;
370 int err_code; 440 int err_code;
371 441
372 cam = &gspca_dev->cam; 442 cam = &gspca_dev->cam;
373 cam->cam_mode = vga_mode; 443 cam->cam_mode = vga_mode;
374 cam->nmodes = ARRAY_SIZE(vga_mode); 444 cam->nmodes = ARRAY_SIZE(vga_mode);
445 sd->do_lcd_stop = 0;
446
447 /* Several of the supported CIF cameras share the same USB ID but
448 * require different initializations and different control settings.
449 * The same is true of the VGA cameras. Therefore, we are forced
450 * to start the initialization process in order to determine which
451 * camera is present. Some of the supported cameras require the
452 * memory pointer to be set to 0 as the very first item of business
453 * or else they will not stream. So we do that immediately.
454 */
455 err_code = zero_the_pointer(gspca_dev);
456 if (err_code < 0)
457 return err_code;
458
459 err_code = stream_start(gspca_dev);
460 if (err_code < 0)
461 return err_code;
375 462
376 if (id->idProduct == 0x010e) { 463 if (id->idProduct == 0x0110 || id->idProduct == 0x010e) {
377 sd->cam_type = CAM_TYPE_CIF; 464 sd->cam_type = CAM_TYPE_CIF;
378 cam->nmodes--; 465 cam->nmodes--;
379 466 err_code = cam_get_response16(gspca_dev, 0x06, 1);
380 data[0] = 0x01;
381 data[1] = 0x01;
382 err_code = mr_write(gspca_dev, 2);
383 if (err_code < 0) 467 if (err_code < 0)
384 return err_code; 468 return err_code;
385
386 msleep(200);
387 data[0] = get_sensor_id(gspca_dev);
388 /* 469 /*
389 * Known CIF cameras. If you have another to report, please do 470 * 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
472 * settings are different, too. We need to detect which camera
473 * of the two known varieties is connected!
390 * 474 *
391 * Name byte just read sd->sensor_type 475 * A list of known CIF cameras follows. They all report either
392 * reported by 476 * 0002 for type 0 or 0003 for type 1.
393 * Sakar Spy-shot 0x28 T. Kilgore 0 477 * If you have another to report, please do
394 * Innovage 0xf5 (unstable) T. Kilgore 0 478 *
395 * Vivitar Mini 0x53 H. De Goede 0 479 * Name sd->sensor_type reported by
396 * Vivitar Mini 0x04 / 0x24 E. Rodriguez 0 480 *
397 * Vivitar Mini 0x08 T. Kilgore 1 481 * Sakar Spy-shot 0 T. Kilgore
398 * Elta-Media 8212dc 0x23 T. Kaiser 1 482 * Innovage 0 T. Kilgore
399 * Philips dig. keych. 0x37 T. Kilgore 1 483 * Vivitar Mini 0 H. De Goede
484 * Vivitar Mini 0 E. Rodriguez
485 * Vivitar Mini 1 T. Kilgore
486 * Elta-Media 8212dc 1 T. Kaiser
487 * Philips dig. keych. 1 T. Kilgore
488 * Trust Spyc@m 100 1 A. Jacobs
400 */ 489 */
401 if ((data[0] & 0x78) == 8 || 490 switch (gspca_dev->usb_buf[1]) {
402 ((data[0] & 0x2) == 0x2 && data[0] != 0x53)) 491 case 2:
403 sd->sensor_type = 1;
404 else
405 sd->sensor_type = 0; 492 sd->sensor_type = 0;
406 493 break;
494 case 3:
495 sd->sensor_type = 1;
496 break;
497 default:
498 PDEBUG(D_ERR, "Unknown CIF Sensor id : %02x",
499 gspca_dev->usb_buf[1]);
500 return -ENODEV;
501 }
407 PDEBUG(D_PROBE, "MR97310A CIF camera detected, sensor: %d", 502 PDEBUG(D_PROBE, "MR97310A CIF camera detected, sensor: %d",
408 sd->sensor_type); 503 sd->sensor_type);
504 } else {
505 sd->cam_type = CAM_TYPE_VGA;
409 506
410 if (force_sensor_type != -1) { 507 err_code = cam_get_response16(gspca_dev, 0x07, 1);
411 sd->sensor_type = !! force_sensor_type; 508 if (err_code < 0)
412 PDEBUG(D_PROBE, "Forcing sensor type to: %d", 509 return err_code;
413 sd->sensor_type); 510
511 /*
512 * Here is a table of the responses to the previous command
513 * from the known MR97310A VGA cameras.
514 *
515 * Name gspca_dev->usb_buf[] sd->sensor_type
516 * sd->do_lcd_stop
517 * Aiptek Pencam VGA+ 0300 0 1
518 * ION digital 0350 0 1
519 * Argus DC-1620 0450 1 0
520 * Argus QuickClix 0420 1 1
521 *
522 * Based upon these results, we assume default settings
523 * and then correct as necessary, as follows.
524 *
525 */
526
527 sd->sensor_type = 1;
528 sd->do_lcd_stop = 0;
529 sd->adj_colors = 0;
530 if ((gspca_dev->usb_buf[0] != 0x03) &&
531 (gspca_dev->usb_buf[0] != 0x04)) {
532 PDEBUG(D_ERR, "Unknown VGA Sensor id Byte 0: %02x",
533 gspca_dev->usb_buf[1]);
534 PDEBUG(D_ERR, "Defaults assumed, may not work");
535 PDEBUG(D_ERR, "Please report this");
536 }
537 /* Sakar Digital color needs to be adjusted. */
538 if ((gspca_dev->usb_buf[0] == 0x03) &&
539 (gspca_dev->usb_buf[1] == 0x50))
540 sd->adj_colors = 1;
541 if (gspca_dev->usb_buf[0] == 0x04) {
542 sd->do_lcd_stop = 1;
543 switch (gspca_dev->usb_buf[1]) {
544 case 0x50:
545 sd->sensor_type = 0;
546 PDEBUG(D_PROBE, "sensor_type corrected to 0");
547 break;
548 case 0x20:
549 /* Nothing to do here. */
550 break;
551 default:
552 PDEBUG(D_ERR,
553 "Unknown VGA Sensor id Byte 1: %02x",
554 gspca_dev->usb_buf[1]);
555 PDEBUG(D_ERR,
556 "Defaults assumed, may not work");
557 PDEBUG(D_ERR, "Please report this");
558 }
414 } 559 }
560 PDEBUG(D_PROBE, "MR97310A VGA camera detected, sensor: %d",
561 sd->sensor_type);
562 }
563 /* Stop streaming as we've started it to probe the sensor type. */
564 sd_stopN(gspca_dev);
565
566 if (force_sensor_type != -1) {
567 sd->sensor_type = !!force_sensor_type;
568 PDEBUG(D_PROBE, "Forcing sensor type to: %d",
569 sd->sensor_type);
570 }
415 571
572 /* Setup controls depending on camera type */
573 if (sd->cam_type == CAM_TYPE_CIF) {
574 /* No brightness for sensor_type 0 */
416 if (sd->sensor_type == 0) 575 if (sd->sensor_type == 0)
417 gspca_dev->ctrl_dis = (1 << BRIGHTNESS_IDX); 576 gspca_dev->ctrl_dis = (1 << NORM_BRIGHTNESS_IDX) |
577 (1 << ARGUS_QC_BRIGHTNESS_IDX);
578 else
579 gspca_dev->ctrl_dis = (1 << ARGUS_QC_BRIGHTNESS_IDX) |
580 (1 << MIN_CLOCKDIV_IDX);
418 } else { 581 } else {
419 sd->cam_type = CAM_TYPE_VGA; 582 /* All controls need to be disabled if VGA sensor_type is 0 */
420 PDEBUG(D_PROBE, "MR97310A VGA camera detected"); 583 if (sd->sensor_type == 0)
421 gspca_dev->ctrl_dis = (1 << BRIGHTNESS_IDX) | 584 gspca_dev->ctrl_dis = (1 << NORM_BRIGHTNESS_IDX) |
422 (1 << EXPOSURE_IDX) | (1 << GAIN_IDX); 585 (1 << ARGUS_QC_BRIGHTNESS_IDX) |
586 (1 << EXPOSURE_IDX) |
587 (1 << GAIN_IDX) |
588 (1 << MIN_CLOCKDIV_IDX);
589 else if (sd->do_lcd_stop)
590 /* Argus QuickClix has different brightness limits */
591 gspca_dev->ctrl_dis = (1 << NORM_BRIGHTNESS_IDX);
592 else
593 gspca_dev->ctrl_dis = (1 << ARGUS_QC_BRIGHTNESS_IDX);
423 } 594 }
424 595
425 sd->brightness = MR97310A_BRIGHTNESS_DEFAULT; 596 sd->brightness = MR97310A_BRIGHTNESS_DEFAULT;
426 sd->exposure = MR97310A_EXPOSURE_DEFAULT; 597 sd->exposure = MR97310A_EXPOSURE_DEFAULT;
427 sd->gain = MR97310A_GAIN_DEFAULT; 598 sd->gain = MR97310A_GAIN_DEFAULT;
599 sd->min_clockdiv = MR97310A_MIN_CLOCKDIV_DEFAULT;
428 600
429 return 0; 601 return 0;
430} 602}
@@ -455,11 +627,6 @@ static int start_cif_cam(struct gspca_dev *gspca_dev)
455 }; 627 };
456 628
457 /* Note: Some of the above descriptions guessed from MR97113A driver */ 629 /* Note: Some of the above descriptions guessed from MR97113A driver */
458 data[0] = 0x01;
459 data[1] = 0x01;
460 err_code = mr_write(gspca_dev, 2);
461 if (err_code < 0)
462 return err_code;
463 630
464 memcpy(data, startup_string, 11); 631 memcpy(data, startup_string, 11);
465 if (sd->sensor_type) 632 if (sd->sensor_type)
@@ -533,22 +700,7 @@ static int start_cif_cam(struct gspca_dev *gspca_dev)
533 err_code = sensor_write_regs(gspca_dev, cif_sensor1_init_data, 700 err_code = sensor_write_regs(gspca_dev, cif_sensor1_init_data,
534 ARRAY_SIZE(cif_sensor1_init_data)); 701 ARRAY_SIZE(cif_sensor1_init_data));
535 } 702 }
536 if (err_code < 0) 703 return err_code;
537 return err_code;
538
539 setbrightness(gspca_dev);
540 setexposure(gspca_dev);
541 setgain(gspca_dev);
542
543 msleep(200);
544
545 data[0] = 0x00;
546 data[1] = 0x4d; /* ISOC transfering enable... */
547 err_code = mr_write(gspca_dev, 2);
548 if (err_code < 0)
549 return err_code;
550
551 return 0;
552} 704}
553 705
554static int start_vga_cam(struct gspca_dev *gspca_dev) 706static int start_vga_cam(struct gspca_dev *gspca_dev)
@@ -558,84 +710,8 @@ static int start_vga_cam(struct gspca_dev *gspca_dev)
558 int err_code; 710 int err_code;
559 const __u8 startup_string[] = {0x00, 0x0d, 0x01, 0x00, 0x00, 0x2b, 711 const __u8 startup_string[] = {0x00, 0x0d, 0x01, 0x00, 0x00, 0x2b,
560 0x00, 0x00, 0x00, 0x50, 0xc0}; 712 0x00, 0x00, 0x00, 0x50, 0xc0};
561
562 /* What some of these mean is explained in start_cif_cam(), above */ 713 /* What some of these mean is explained in start_cif_cam(), above */
563 sd->sof_read = 0;
564
565 /*
566 * We have to know which camera we have, because the register writes
567 * depend upon the camera. This test, run before we actually enter
568 * the initialization routine, distinguishes most of the cameras, If
569 * needed, another routine is done later, too.
570 */
571 memset(data, 0, 16);
572 data[0] = 0x20;
573 err_code = mr_write(gspca_dev, 1);
574 if (err_code < 0)
575 return err_code;
576
577 err_code = mr_read(gspca_dev, 16);
578 if (err_code < 0)
579 return err_code;
580
581 PDEBUG(D_PROBE, "Byte reported is %02x", data[0]);
582
583 msleep(200);
584 /*
585 * Known VGA cameras. If you have another to report, please do
586 *
587 * Name byte just read sd->sensor_type
588 * sd->do_lcd_stop
589 * Aiptek Pencam VGA+ 0x31 0 1
590 * ION digital 0x31 0 1
591 * Argus DC-1620 0x30 1 0
592 * Argus QuickClix 0x30 1 1 (not caught here)
593 */
594 sd->sensor_type = data[0] & 1;
595 sd->do_lcd_stop = (~data[0]) & 1;
596
597
598
599 /* Streaming setup begins here. */
600
601
602 data[0] = 0x01;
603 data[1] = 0x01;
604 err_code = mr_write(gspca_dev, 2);
605 if (err_code < 0)
606 return err_code;
607 714
608 /*
609 * A second test can now resolve any remaining ambiguity in the
610 * identification of the camera type,
611 */
612 if (!sd->sensor_type) {
613 data[0] = get_sensor_id(gspca_dev);
614 if (data[0] == 0x7f) {
615 sd->sensor_type = 1;
616 PDEBUG(D_PROBE, "sensor_type corrected to 1");
617 }
618 msleep(200);
619 }
620
621 if (force_sensor_type != -1) {
622 sd->sensor_type = !! force_sensor_type;
623 PDEBUG(D_PROBE, "Forcing sensor type to: %d",
624 sd->sensor_type);
625 }
626
627 /*
628 * Known VGA cameras.
629 * This test is only run if the previous test returned 0x30, but
630 * here is the information for all others, too, just for reference.
631 *
632 * Name byte just read sd->sensor_type
633 *
634 * Aiptek Pencam VGA+ 0xfb (this test not run) 1
635 * ION digital 0xbd (this test not run) 1
636 * Argus DC-1620 0xe5 (no change) 0
637 * Argus QuickClix 0x7f (reclassified) 1
638 */
639 memcpy(data, startup_string, 11); 715 memcpy(data, startup_string, 11);
640 if (!sd->sensor_type) { 716 if (!sd->sensor_type) {
641 data[5] = 0x00; 717 data[5] = 0x00;
@@ -689,29 +765,44 @@ static int start_vga_cam(struct gspca_dev *gspca_dev)
689 err_code = sensor_write_regs(gspca_dev, vga_sensor0_init_data, 765 err_code = sensor_write_regs(gspca_dev, vga_sensor0_init_data,
690 ARRAY_SIZE(vga_sensor0_init_data)); 766 ARRAY_SIZE(vga_sensor0_init_data));
691 } else { /* sd->sensor_type = 1 */ 767 } else { /* sd->sensor_type = 1 */
692 const struct sensor_w_data vga_sensor1_init_data[] = { 768 const struct sensor_w_data color_adj[] = {
693 {0x02, 0x00, {0x06, 0x59, 0x0c, 0x16, 0x00, 769 {0x02, 0x00, {0x06, 0x59, 0x0c, 0x16, 0x00,
694 0x07, 0x00, 0x01}, 8}, 770 /* adjusted blue, green, red gain correct
771 too much blue from the Sakar Digital */
772 0x05, 0x01, 0x04}, 8}
773 };
774
775 const struct sensor_w_data color_no_adj[] = {
776 {0x02, 0x00, {0x06, 0x59, 0x0c, 0x16, 0x00,
777 /* default blue, green, red gain settings */
778 0x07, 0x00, 0x01}, 8}
779 };
780
781 const struct sensor_w_data vga_sensor1_init_data[] = {
695 {0x11, 0x04, {0x01}, 1}, 782 {0x11, 0x04, {0x01}, 1},
696 /*{0x0a, 0x00, {0x00, 0x01, 0x00, 0x00, 0x01, */ 783 {0x0a, 0x00, {0x00, 0x01, 0x00, 0x00, 0x01,
697 {0x0a, 0x00, {0x01, 0x06, 0x00, 0x00, 0x01, 784 /* These settings may be better for some cameras */
785 /* {0x0a, 0x00, {0x01, 0x06, 0x00, 0x00, 0x01, */
698 0x00, 0x0a}, 7}, 786 0x00, 0x0a}, 7},
699 {0x11, 0x04, {0x01}, 1}, 787 {0x11, 0x04, {0x01}, 1},
700 {0x12, 0x00, {0x00, 0x63, 0x00, 0x70, 0x00, 0x00}, 6}, 788 {0x12, 0x00, {0x00, 0x63, 0x00, 0x70, 0x00, 0x00}, 6},
701 {0x11, 0x04, {0x01}, 1}, 789 {0x11, 0x04, {0x01}, 1},
702 {0, 0, {0}, 0} 790 {0, 0, {0}, 0}
703 }; 791 };
792
793 if (sd->adj_colors)
794 err_code = sensor_write_regs(gspca_dev, color_adj,
795 ARRAY_SIZE(color_adj));
796 else
797 err_code = sensor_write_regs(gspca_dev, color_no_adj,
798 ARRAY_SIZE(color_no_adj));
799
800 if (err_code < 0)
801 return err_code;
802
704 err_code = sensor_write_regs(gspca_dev, vga_sensor1_init_data, 803 err_code = sensor_write_regs(gspca_dev, vga_sensor1_init_data,
705 ARRAY_SIZE(vga_sensor1_init_data)); 804 ARRAY_SIZE(vga_sensor1_init_data));
706 } 805 }
707 if (err_code < 0)
708 return err_code;
709
710 msleep(200);
711 data[0] = 0x00;
712 data[1] = 0x4d; /* ISOC transfering enable... */
713 err_code = mr_write(gspca_dev, 2);
714
715 return err_code; 806 return err_code;
716} 807}
717 808
@@ -719,97 +810,120 @@ static int sd_start(struct gspca_dev *gspca_dev)
719{ 810{
720 struct sd *sd = (struct sd *) gspca_dev; 811 struct sd *sd = (struct sd *) gspca_dev;
721 int err_code; 812 int err_code;
722 struct cam *cam;
723 813
724 cam = &gspca_dev->cam;
725 sd->sof_read = 0; 814 sd->sof_read = 0;
726 /* 815
727 * Some of the supported cameras require the memory pointer to be 816 /* Some of the VGA cameras require the memory pointer
728 * set to 0, or else they will not stream. 817 * to be set to 0 again. We have been forced to start the
729 */ 818 * stream in sd_config() to detect the hardware, and closed it.
730 zero_the_pointer(gspca_dev); 819 * Thus, we need here to do a completely fresh and clean start. */
731 msleep(200); 820 err_code = zero_the_pointer(gspca_dev);
821 if (err_code < 0)
822 return err_code;
823
824 err_code = stream_start(gspca_dev);
825 if (err_code < 0)
826 return err_code;
827
732 if (sd->cam_type == CAM_TYPE_CIF) { 828 if (sd->cam_type == CAM_TYPE_CIF) {
733 err_code = start_cif_cam(gspca_dev); 829 err_code = start_cif_cam(gspca_dev);
734 } else { 830 } else {
735 err_code = start_vga_cam(gspca_dev); 831 err_code = start_vga_cam(gspca_dev);
736 } 832 }
737 return err_code; 833 if (err_code < 0)
834 return err_code;
835
836 setbrightness(gspca_dev);
837 setexposure(gspca_dev);
838 setgain(gspca_dev);
839
840 return isoc_enable(gspca_dev);
738} 841}
739 842
740static void sd_stopN(struct gspca_dev *gspca_dev) 843static void sd_stopN(struct gspca_dev *gspca_dev)
741{ 844{
742 struct sd *sd = (struct sd *) gspca_dev; 845 struct sd *sd = (struct sd *) gspca_dev;
743 int result;
744
745 gspca_dev->usb_buf[0] = 1;
746 gspca_dev->usb_buf[1] = 0;
747 result = mr_write(gspca_dev, 2);
748 if (result < 0)
749 PDEBUG(D_ERR, "Camera Stop failed");
750 846
847 stream_stop(gspca_dev);
751 /* Not all the cams need this, but even if not, probably a good idea */ 848 /* Not all the cams need this, but even if not, probably a good idea */
752 zero_the_pointer(gspca_dev); 849 zero_the_pointer(gspca_dev);
753 if (sd->do_lcd_stop) { 850 if (sd->do_lcd_stop)
754 gspca_dev->usb_buf[0] = 0x19; 851 lcd_stop(gspca_dev);
755 gspca_dev->usb_buf[1] = 0x54;
756 result = mr_write(gspca_dev, 2);
757 if (result < 0)
758 PDEBUG(D_ERR, "Camera Stop failed");
759 }
760} 852}
761 853
762static void setbrightness(struct gspca_dev *gspca_dev) 854static void setbrightness(struct gspca_dev *gspca_dev)
763{ 855{
764 struct sd *sd = (struct sd *) gspca_dev; 856 struct sd *sd = (struct sd *) gspca_dev;
765 u8 val; 857 u8 val;
766 858 u8 sign_reg = 7; /* This reg and the next one used on CIF cams. */
767 if (gspca_dev->ctrl_dis & (1 << BRIGHTNESS_IDX)) 859 u8 value_reg = 8; /* VGA cams seem to use regs 0x0b and 0x0c */
860 const u8 quick_clix_table[] =
861 /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 */
862 { 0, 4, 8, 12, 1, 2, 3, 5, 6, 9, 7, 10, 13, 11, 14, 15};
863 /*
864 * This control is disabled for CIF type 1 and VGA type 0 cameras.
865 * It does not quite act linearly for the Argus QuickClix camera,
866 * but it does control brightness. The values are 0 - 15 only, and
867 * the table above makes them act consecutively.
868 */
869 if ((gspca_dev->ctrl_dis & (1 << NORM_BRIGHTNESS_IDX)) &&
870 (gspca_dev->ctrl_dis & (1 << ARGUS_QC_BRIGHTNESS_IDX)))
768 return; 871 return;
769 872
770 /* Note register 7 is also seen as 0x8x or 0xCx in dumps */ 873 if (sd->cam_type == CAM_TYPE_VGA) {
874 sign_reg += 4;
875 value_reg += 4;
876 }
877
878 /* Note register 7 is also seen as 0x8x or 0xCx in some dumps */
771 if (sd->brightness > 0) { 879 if (sd->brightness > 0) {
772 sensor_write1(gspca_dev, 7, 0x00); 880 sensor_write1(gspca_dev, sign_reg, 0x00);
773 val = sd->brightness; 881 val = sd->brightness;
774 } else { 882 } else {
775 sensor_write1(gspca_dev, 7, 0x01); 883 sensor_write1(gspca_dev, sign_reg, 0x01);
776 val = 257 - sd->brightness; 884 val = (257 - sd->brightness);
777 } 885 }
778 sensor_write1(gspca_dev, 8, val); 886 /* Use lookup table for funky Argus QuickClix brightness */
887 if (sd->do_lcd_stop)
888 val = quick_clix_table[val];
889
890 sensor_write1(gspca_dev, value_reg, val);
779} 891}
780 892
781static void setexposure(struct gspca_dev *gspca_dev) 893static void setexposure(struct gspca_dev *gspca_dev)
782{ 894{
783 struct sd *sd = (struct sd *) gspca_dev; 895 struct sd *sd = (struct sd *) gspca_dev;
784 u8 val; 896 int exposure;
897 u8 buf[2];
785 898
786 if (gspca_dev->ctrl_dis & (1 << EXPOSURE_IDX)) 899 if (gspca_dev->ctrl_dis & (1 << EXPOSURE_IDX))
787 return; 900 return;
788 901
789 if (sd->sensor_type) { 902 if (sd->cam_type == CAM_TYPE_CIF && sd->sensor_type == 1) {
790 val = sd->exposure >> 4; 903 /* This cam does not like exposure settings < 300,
791 sensor_write1(gspca_dev, 3, val); 904 so scale 0 - 4095 to 300 - 4095 */
792 val = sd->exposure & 0xf; 905 exposure = (sd->exposure * 9267) / 10000 + 300;
793 sensor_write1(gspca_dev, 4, val); 906 sensor_write1(gspca_dev, 3, exposure >> 4);
907 sensor_write1(gspca_dev, 4, exposure & 0x0f);
794 } else { 908 } else {
795 u8 clockdiv;
796 int exposure;
797
798 /* We have both a clock divider and an exposure register. 909 /* We have both a clock divider and an exposure register.
799 We first calculate the clock divider, as that determines 910 We first calculate the clock divider, as that determines
800 the maximum exposure and then we calculayte the exposure 911 the maximum exposure and then we calculate the exposure
801 register setting (which goes from 0 - 511). 912 register setting (which goes from 0 - 511).
802 913
803 Note our 0 - 4095 exposure is mapped to 0 - 511 914 Note our 0 - 4095 exposure is mapped to 0 - 511
804 milliseconds exposure time */ 915 milliseconds exposure time */
805 clockdiv = (60 * sd->exposure + 7999) / 8000; 916 u8 clockdiv = (60 * sd->exposure + 7999) / 8000;
806 917
807 /* Limit framerate to not exceed usb bandwidth */ 918 /* Limit framerate to not exceed usb bandwidth */
808 if (clockdiv < 3 && gspca_dev->width >= 320) 919 if (clockdiv < sd->min_clockdiv && gspca_dev->width >= 320)
809 clockdiv = 3; 920 clockdiv = sd->min_clockdiv;
810 else if (clockdiv < 2) 921 else if (clockdiv < 2)
811 clockdiv = 2; 922 clockdiv = 2;
812 923
924 if (sd->cam_type == CAM_TYPE_VGA && clockdiv < 4)
925 clockdiv = 4;
926
813 /* Frame exposure time in ms = 1000 * clockdiv / 60 -> 927 /* Frame exposure time in ms = 1000 * clockdiv / 60 ->
814 exposure = (sd->exposure / 8) * 511 / (1000 * clockdiv / 60) */ 928 exposure = (sd->exposure / 8) * 511 / (1000 * clockdiv / 60) */
815 exposure = (60 * 511 * sd->exposure) / (8000 * clockdiv); 929 exposure = (60 * 511 * sd->exposure) / (8000 * clockdiv);
@@ -819,9 +933,10 @@ static void setexposure(struct gspca_dev *gspca_dev)
819 /* exposure register value is reversed! */ 933 /* exposure register value is reversed! */
820 exposure = 511 - exposure; 934 exposure = 511 - exposure;
821 935
936 buf[0] = exposure & 0xff;
937 buf[1] = exposure >> 8;
938 sensor_write_reg(gspca_dev, 0x0e, 0, buf, 2);
822 sensor_write1(gspca_dev, 0x02, clockdiv); 939 sensor_write1(gspca_dev, 0x02, clockdiv);
823 sensor_write1(gspca_dev, 0x0e, exposure & 0xff);
824 sensor_write1(gspca_dev, 0x0f, exposure >> 8);
825 } 940 }
826} 941}
827 942
@@ -832,7 +947,7 @@ static void setgain(struct gspca_dev *gspca_dev)
832 if (gspca_dev->ctrl_dis & (1 << GAIN_IDX)) 947 if (gspca_dev->ctrl_dis & (1 << GAIN_IDX))
833 return; 948 return;
834 949
835 if (sd->sensor_type) { 950 if (sd->cam_type == CAM_TYPE_CIF && sd->sensor_type == 1) {
836 sensor_write1(gspca_dev, 0x0e, sd->gain); 951 sensor_write1(gspca_dev, 0x0e, sd->gain);
837 } else { 952 } else {
838 sensor_write1(gspca_dev, 0x10, sd->gain); 953 sensor_write1(gspca_dev, 0x10, sd->gain);
@@ -893,17 +1008,35 @@ static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val)
893 return 0; 1008 return 0;
894} 1009}
895 1010
1011static int sd_setmin_clockdiv(struct gspca_dev *gspca_dev, __s32 val)
1012{
1013 struct sd *sd = (struct sd *) gspca_dev;
1014
1015 sd->min_clockdiv = val;
1016 if (gspca_dev->streaming)
1017 setexposure(gspca_dev);
1018 return 0;
1019}
1020
1021static int sd_getmin_clockdiv(struct gspca_dev *gspca_dev, __s32 *val)
1022{
1023 struct sd *sd = (struct sd *) gspca_dev;
1024
1025 *val = sd->min_clockdiv;
1026 return 0;
1027}
1028
896/* Include pac common sof detection functions */ 1029/* Include pac common sof detection functions */
897#include "pac_common.h" 1030#include "pac_common.h"
898 1031
899static void sd_pkt_scan(struct gspca_dev *gspca_dev, 1032static void sd_pkt_scan(struct gspca_dev *gspca_dev,
900 struct gspca_frame *frame, /* target */ 1033 u8 *data, /* isoc packet */
901 __u8 *data, /* isoc packet */ 1034 int len) /* iso packet length */
902 int len) /* iso packet length */
903{ 1035{
1036 struct sd *sd = (struct sd *) gspca_dev;
904 unsigned char *sof; 1037 unsigned char *sof;
905 1038
906 sof = pac_find_sof(gspca_dev, data, len); 1039 sof = pac_find_sof(&sd->sof_read, data, len);
907 if (sof) { 1040 if (sof) {
908 int n; 1041 int n;
909 1042
@@ -913,15 +1046,15 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
913 n -= sizeof pac_sof_marker; 1046 n -= sizeof pac_sof_marker;
914 else 1047 else
915 n = 0; 1048 n = 0;
916 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, 1049 gspca_frame_add(gspca_dev, LAST_PACKET,
917 data, n); 1050 data, n);
918 /* Start next frame. */ 1051 /* Start next frame. */
919 gspca_frame_add(gspca_dev, FIRST_PACKET, frame, 1052 gspca_frame_add(gspca_dev, FIRST_PACKET,
920 pac_sof_marker, sizeof pac_sof_marker); 1053 pac_sof_marker, sizeof pac_sof_marker);
921 len -= sof - data; 1054 len -= sof - data;
922 data = sof; 1055 data = sof;
923 } 1056 }
924 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); 1057 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
925} 1058}
926 1059
927/* sub-driver description */ 1060/* sub-driver description */
@@ -938,6 +1071,7 @@ static const struct sd_desc sd_desc = {
938 1071
939/* -- module initialisation -- */ 1072/* -- module initialisation -- */
940static const __devinitdata struct usb_device_id device_table[] = { 1073static const __devinitdata struct usb_device_id device_table[] = {
1074 {USB_DEVICE(0x08ca, 0x0110)}, /* Trust Spyc@m 100 */
941 {USB_DEVICE(0x08ca, 0x0111)}, /* Aiptek Pencam VGA+ */ 1075 {USB_DEVICE(0x08ca, 0x0111)}, /* Aiptek Pencam VGA+ */
942 {USB_DEVICE(0x093a, 0x010f)}, /* All other known MR97310A VGA cams */ 1076 {USB_DEVICE(0x093a, 0x010f)}, /* All other known MR97310A VGA cams */
943 {USB_DEVICE(0x093a, 0x010e)}, /* All known MR97310A CIF cams */ 1077 {USB_DEVICE(0x093a, 0x010e)}, /* All known MR97310A CIF cams */
diff --git a/drivers/media/video/gspca/ov519.c b/drivers/media/video/gspca/ov519.c
index a5c190e93799..ad9ec339981d 100644
--- a/drivers/media/video/gspca/ov519.c
+++ b/drivers/media/video/gspca/ov519.c
@@ -2,14 +2,19 @@
2 * OV519 driver 2 * OV519 driver
3 * 3 *
4 * Copyright (C) 2008 Jean-Francois Moine (http://moinejf.free.fr) 4 * Copyright (C) 2008 Jean-Francois Moine (http://moinejf.free.fr)
5 * Copyright (C) 2009 Hans de Goede <hdegoede@redhat.com>
5 * 6 *
6 * This module is adapted from the ov51x-jpeg package, which itself 7 * This module is adapted from the ov51x-jpeg package, which itself
7 * was adapted from the ov511 driver. 8 * was adapted from the ov511 driver.
8 * 9 *
9 * Original copyright for the ov511 driver is: 10 * Original copyright for the ov511 driver is:
10 * 11 *
11 * Copyright (c) 1999-2004 Mark W. McClelland 12 * Copyright (c) 1999-2006 Mark W. McClelland
12 * Support for OV519, OV8610 Copyright (c) 2003 Joerg Heckenbach 13 * Support for OV519, OV8610 Copyright (c) 2003 Joerg Heckenbach
14 * Many improvements by Bret Wallach <bwallac1@san.rr.com>
15 * Color fixes by by Orion Sky Lawlor <olawlor@acm.org> (2/26/2000)
16 * OV7620 fixes by Charl P. Botha <cpbotha@ieee.org>
17 * Changes by Claudio Matsuoka <claudio@conectiva.com>
13 * 18 *
14 * ov51x-jpeg original copyright is: 19 * ov51x-jpeg original copyright is:
15 * 20 *
@@ -58,6 +63,8 @@ struct sd {
58#define BRIDGE_OV518 2 63#define BRIDGE_OV518 2
59#define BRIDGE_OV518PLUS 3 64#define BRIDGE_OV518PLUS 3
60#define BRIDGE_OV519 4 65#define BRIDGE_OV519 4
66#define BRIDGE_OVFX2 5
67#define BRIDGE_W9968CF 6
61#define BRIDGE_MASK 7 68#define BRIDGE_MASK 7
62 69
63 char invert_led; 70 char invert_led;
@@ -73,6 +80,10 @@ struct sd {
73 __u8 vflip; 80 __u8 vflip;
74 __u8 autobrightness; 81 __u8 autobrightness;
75 __u8 freq; 82 __u8 freq;
83 __u8 quality;
84#define QUALITY_MIN 50
85#define QUALITY_MAX 70
86#define QUALITY_DEF 50
76 87
77 __u8 stopped; /* Streaming is temporarily paused */ 88 __u8 stopped; /* Streaming is temporarily paused */
78 89
@@ -81,17 +92,31 @@ struct sd {
81 92
82 char sensor; /* Type of image sensor chip (SEN_*) */ 93 char sensor; /* Type of image sensor chip (SEN_*) */
83#define SEN_UNKNOWN 0 94#define SEN_UNKNOWN 0
84#define SEN_OV6620 1 95#define SEN_OV2610 1
85#define SEN_OV6630 2 96#define SEN_OV3610 2
86#define SEN_OV66308AF 3 97#define SEN_OV6620 3
87#define SEN_OV7610 4 98#define SEN_OV6630 4
88#define SEN_OV7620 5 99#define SEN_OV66308AF 5
89#define SEN_OV7640 6 100#define SEN_OV7610 6
90#define SEN_OV7670 7 101#define SEN_OV7620 7
91#define SEN_OV76BE 8 102#define SEN_OV7640 8
92#define SEN_OV8610 9 103#define SEN_OV7670 9
104#define SEN_OV76BE 10
105#define SEN_OV8610 11
106
107 u8 sensor_addr;
108 int sensor_width;
109 int sensor_height;
110 int sensor_reg_cache[256];
111
112 u8 *jpeg_hdr;
93}; 113};
94 114
115/* Note this is a bit of a hack, but the w9968cf driver needs the code for all
116 the ov sensors which is already present here. When we have the time we
117 really should move the sensor drivers to v4l2 sub drivers. */
118#include "w996Xcf.c"
119
95/* V4L2 controls supported by the driver */ 120/* V4L2 controls supported by the driver */
96static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); 121static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
97static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); 122static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
@@ -345,6 +370,75 @@ static const struct v4l2_pix_format ov511_sif_mode[] = {
345 .priv = 0}, 370 .priv = 0},
346}; 371};
347 372
373static const struct v4l2_pix_format ovfx2_vga_mode[] = {
374 {320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
375 .bytesperline = 320,
376 .sizeimage = 320 * 240,
377 .colorspace = V4L2_COLORSPACE_SRGB,
378 .priv = 1},
379 {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
380 .bytesperline = 640,
381 .sizeimage = 640 * 480,
382 .colorspace = V4L2_COLORSPACE_SRGB,
383 .priv = 0},
384};
385static const struct v4l2_pix_format ovfx2_cif_mode[] = {
386 {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
387 .bytesperline = 160,
388 .sizeimage = 160 * 120,
389 .colorspace = V4L2_COLORSPACE_SRGB,
390 .priv = 3},
391 {176, 144, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
392 .bytesperline = 176,
393 .sizeimage = 176 * 144,
394 .colorspace = V4L2_COLORSPACE_SRGB,
395 .priv = 1},
396 {320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
397 .bytesperline = 320,
398 .sizeimage = 320 * 240,
399 .colorspace = V4L2_COLORSPACE_SRGB,
400 .priv = 2},
401 {352, 288, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
402 .bytesperline = 352,
403 .sizeimage = 352 * 288,
404 .colorspace = V4L2_COLORSPACE_SRGB,
405 .priv = 0},
406};
407static const struct v4l2_pix_format ovfx2_ov2610_mode[] = {
408 {1600, 1200, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
409 .bytesperline = 1600,
410 .sizeimage = 1600 * 1200,
411 .colorspace = V4L2_COLORSPACE_SRGB},
412};
413static const struct v4l2_pix_format ovfx2_ov3610_mode[] = {
414 {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
415 .bytesperline = 640,
416 .sizeimage = 640 * 480,
417 .colorspace = V4L2_COLORSPACE_SRGB,
418 .priv = 1},
419 {800, 600, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
420 .bytesperline = 800,
421 .sizeimage = 800 * 600,
422 .colorspace = V4L2_COLORSPACE_SRGB,
423 .priv = 1},
424 {1024, 768, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
425 .bytesperline = 1024,
426 .sizeimage = 1024 * 768,
427 .colorspace = V4L2_COLORSPACE_SRGB,
428 .priv = 1},
429 {1600, 1200, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
430 .bytesperline = 1600,
431 .sizeimage = 1600 * 1200,
432 .colorspace = V4L2_COLORSPACE_SRGB,
433 .priv = 0},
434 {2048, 1536, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
435 .bytesperline = 2048,
436 .sizeimage = 2048 * 1536,
437 .colorspace = V4L2_COLORSPACE_SRGB,
438 .priv = 0},
439};
440
441
348/* Registers common to OV511 / OV518 */ 442/* Registers common to OV511 / OV518 */
349#define R51x_FIFO_PSIZE 0x30 /* 2 bytes wide w/ OV518(+) */ 443#define R51x_FIFO_PSIZE 0x30 /* 2 bytes wide w/ OV518(+) */
350#define R51x_SYS_RESET 0x50 444#define R51x_SYS_RESET 0x50
@@ -406,6 +500,30 @@ static const struct v4l2_pix_format ov511_sif_mode[] = {
406 500
407#define OV511_ENDPOINT_ADDRESS 1 /* Isoc endpoint number */ 501#define OV511_ENDPOINT_ADDRESS 1 /* Isoc endpoint number */
408 502
503/*
504 * The FX2 chip does not give us a zero length read at end of frame.
505 * It does, however, give a short read at the end of a frame, if
506 * neccessary, rather than run two frames together.
507 *
508 * By choosing the right bulk transfer size, we are guaranteed to always
509 * get a short read for the last read of each frame. Frame sizes are
510 * always a composite number (width * height, or a multiple) so if we
511 * choose a prime number, we are guaranteed that the last read of a
512 * frame will be short.
513 *
514 * But it isn't that easy: the 2.6 kernel requires a multiple of 4KB,
515 * otherwise EOVERFLOW "babbling" errors occur. I have not been able
516 * to figure out why. [PMiller]
517 *
518 * The constant (13 * 4096) is the largest "prime enough" number less than 64KB.
519 *
520 * It isn't enough to know the number of bytes per frame, in case we
521 * have data dropouts or buffer overruns (even though the FX2 double
522 * buffers, there are some pretty strict real time constraints for
523 * isochronous transfer for larger frame sizes).
524 */
525#define OVFX2_BULK_SIZE (13 * 4096)
526
409/* I2C registers */ 527/* I2C registers */
410#define R51x_I2C_W_SID 0x41 528#define R51x_I2C_W_SID 0x41
411#define R51x_I2C_SADDR_3 0x42 529#define R51x_I2C_SADDR_3 0x42
@@ -413,9 +531,11 @@ static const struct v4l2_pix_format ov511_sif_mode[] = {
413#define R51x_I2C_R_SID 0x44 531#define R51x_I2C_R_SID 0x44
414#define R51x_I2C_DATA 0x45 532#define R51x_I2C_DATA 0x45
415#define R518_I2C_CTL 0x47 /* OV518(+) only */ 533#define R518_I2C_CTL 0x47 /* OV518(+) only */
534#define OVFX2_I2C_ADDR 0x00
416 535
417/* I2C ADDRESSES */ 536/* I2C ADDRESSES */
418#define OV7xx0_SID 0x42 537#define OV7xx0_SID 0x42
538#define OV_HIRES_SID 0x60 /* OV9xxx / OV2xxx / OV3xxx */
419#define OV8xx0_SID 0xa0 539#define OV8xx0_SID 0xa0
420#define OV6xx0_SID 0xc0 540#define OV6xx0_SID 0xc0
421 541
@@ -508,6 +628,696 @@ struct ov_i2c_regvals {
508 __u8 val; 628 __u8 val;
509}; 629};
510 630
631/* Settings for OV2610 camera chip */
632static const struct ov_i2c_regvals norm_2610[] =
633{
634 { 0x12, 0x80 }, /* reset */
635};
636
637static const struct ov_i2c_regvals norm_3620b[] =
638{
639 /*
640 * From the datasheet: "Note that after writing to register COMH
641 * (0x12) to change the sensor mode, registers related to the
642 * sensor’s cropping window will be reset back to their default
643 * values."
644 *
645 * "wait 4096 external clock ... to make sure the sensor is
646 * stable and ready to access registers" i.e. 160us at 24MHz
647 */
648
649 { 0x12, 0x80 }, /* COMH reset */
650 { 0x12, 0x00 }, /* QXGA, master */
651
652 /*
653 * 11 CLKRC "Clock Rate Control"
654 * [7] internal frequency doublers: on
655 * [6] video port mode: master
656 * [5:0] clock divider: 1
657 */
658 { 0x11, 0x80 },
659
660 /*
661 * 13 COMI "Common Control I"
662 * = 192 (0xC0) 11000000
663 * COMI[7] "AEC speed selection"
664 * = 1 (0x01) 1....... "Faster AEC correction"
665 * COMI[6] "AEC speed step selection"
666 * = 1 (0x01) .1...... "Big steps, fast"
667 * COMI[5] "Banding filter on off"
668 * = 0 (0x00) ..0..... "Off"
669 * COMI[4] "Banding filter option"
670 * = 0 (0x00) ...0.... "Main clock is 48 MHz and
671 * the PLL is ON"
672 * COMI[3] "Reserved"
673 * = 0 (0x00) ....0...
674 * COMI[2] "AGC auto manual control selection"
675 * = 0 (0x00) .....0.. "Manual"
676 * COMI[1] "AWB auto manual control selection"
677 * = 0 (0x00) ......0. "Manual"
678 * COMI[0] "Exposure control"
679 * = 0 (0x00) .......0 "Manual"
680 */
681 { 0x13, 0xC0 },
682
683 /*
684 * 09 COMC "Common Control C"
685 * = 8 (0x08) 00001000
686 * COMC[7:5] "Reserved"
687 * = 0 (0x00) 000.....
688 * COMC[4] "Sleep Mode Enable"
689 * = 0 (0x00) ...0.... "Normal mode"
690 * COMC[3:2] "Sensor sampling reset timing selection"
691 * = 2 (0x02) ....10.. "Longer reset time"
692 * COMC[1:0] "Output drive current select"
693 * = 0 (0x00) ......00 "Weakest"
694 */
695 { 0x09, 0x08 },
696
697 /*
698 * 0C COMD "Common Control D"
699 * = 8 (0x08) 00001000
700 * COMD[7] "Reserved"
701 * = 0 (0x00) 0.......
702 * COMD[6] "Swap MSB and LSB at the output port"
703 * = 0 (0x00) .0...... "False"
704 * COMD[5:3] "Reserved"
705 * = 1 (0x01) ..001...
706 * COMD[2] "Output Average On Off"
707 * = 0 (0x00) .....0.. "Output Normal"
708 * COMD[1] "Sensor precharge voltage selection"
709 * = 0 (0x00) ......0. "Selects internal
710 * reference precharge
711 * voltage"
712 * COMD[0] "Snapshot option"
713 * = 0 (0x00) .......0 "Enable live video output
714 * after snapshot sequence"
715 */
716 { 0x0c, 0x08 },
717
718 /*
719 * 0D COME "Common Control E"
720 * = 161 (0xA1) 10100001
721 * COME[7] "Output average option"
722 * = 1 (0x01) 1....... "Output average of 4 pixels"
723 * COME[6] "Anti-blooming control"
724 * = 0 (0x00) .0...... "Off"
725 * COME[5:3] "Reserved"
726 * = 4 (0x04) ..100...
727 * COME[2] "Clock output power down pin status"
728 * = 0 (0x00) .....0.. "Tri-state data output pin
729 * on power down"
730 * COME[1] "Data output pin status selection at power down"
731 * = 0 (0x00) ......0. "Tri-state VSYNC, PCLK,
732 * HREF, and CHSYNC pins on
733 * power down"
734 * COME[0] "Auto zero circuit select"
735 * = 1 (0x01) .......1 "On"
736 */
737 { 0x0d, 0xA1 },
738
739 /*
740 * 0E COMF "Common Control F"
741 * = 112 (0x70) 01110000
742 * COMF[7] "System clock selection"
743 * = 0 (0x00) 0....... "Use 24 MHz system clock"
744 * COMF[6:4] "Reserved"
745 * = 7 (0x07) .111....
746 * COMF[3] "Manual auto negative offset canceling selection"
747 * = 0 (0x00) ....0... "Auto detect negative
748 * offset and cancel it"
749 * COMF[2:0] "Reserved"
750 * = 0 (0x00) .....000
751 */
752 { 0x0e, 0x70 },
753
754 /*
755 * 0F COMG "Common Control G"
756 * = 66 (0x42) 01000010
757 * COMG[7] "Optical black output selection"
758 * = 0 (0x00) 0....... "Disable"
759 * COMG[6] "Black level calibrate selection"
760 * = 1 (0x01) .1...... "Use optical black pixels
761 * to calibrate"
762 * COMG[5:4] "Reserved"
763 * = 0 (0x00) ..00....
764 * COMG[3] "Channel offset adjustment"
765 * = 0 (0x00) ....0... "Disable offset adjustment"
766 * COMG[2] "ADC black level calibration option"
767 * = 0 (0x00) .....0.. "Use B/G line and G/R
768 * line to calibrate each
769 * channel's black level"
770 * COMG[1] "Reserved"
771 * = 1 (0x01) ......1.
772 * COMG[0] "ADC black level calibration enable"
773 * = 0 (0x00) .......0 "Disable"
774 */
775 { 0x0f, 0x42 },
776
777 /*
778 * 14 COMJ "Common Control J"
779 * = 198 (0xC6) 11000110
780 * COMJ[7:6] "AGC gain ceiling"
781 * = 3 (0x03) 11...... "8x"
782 * COMJ[5:4] "Reserved"
783 * = 0 (0x00) ..00....
784 * COMJ[3] "Auto banding filter"
785 * = 0 (0x00) ....0... "Banding filter is always
786 * on off depending on
787 * COMI[5] setting"
788 * COMJ[2] "VSYNC drop option"
789 * = 1 (0x01) .....1.. "SYNC is dropped if frame
790 * data is dropped"
791 * COMJ[1] "Frame data drop"
792 * = 1 (0x01) ......1. "Drop frame data if
793 * exposure is not within
794 * tolerance. In AEC mode,
795 * data is normally dropped
796 * when data is out of
797 * range."
798 * COMJ[0] "Reserved"
799 * = 0 (0x00) .......0
800 */
801 { 0x14, 0xC6 },
802
803 /*
804 * 15 COMK "Common Control K"
805 * = 2 (0x02) 00000010
806 * COMK[7] "CHSYNC pin output swap"
807 * = 0 (0x00) 0....... "CHSYNC"
808 * COMK[6] "HREF pin output swap"
809 * = 0 (0x00) .0...... "HREF"
810 * COMK[5] "PCLK output selection"
811 * = 0 (0x00) ..0..... "PCLK always output"
812 * COMK[4] "PCLK edge selection"
813 * = 0 (0x00) ...0.... "Data valid on falling edge"
814 * COMK[3] "HREF output polarity"
815 * = 0 (0x00) ....0... "positive"
816 * COMK[2] "Reserved"
817 * = 0 (0x00) .....0..
818 * COMK[1] "VSYNC polarity"
819 * = 1 (0x01) ......1. "negative"
820 * COMK[0] "HSYNC polarity"
821 * = 0 (0x00) .......0 "positive"
822 */
823 { 0x15, 0x02 },
824
825 /*
826 * 33 CHLF "Current Control"
827 * = 9 (0x09) 00001001
828 * CHLF[7:6] "Sensor current control"
829 * = 0 (0x00) 00......
830 * CHLF[5] "Sensor current range control"
831 * = 0 (0x00) ..0..... "normal range"
832 * CHLF[4] "Sensor current"
833 * = 0 (0x00) ...0.... "normal current"
834 * CHLF[3] "Sensor buffer current control"
835 * = 1 (0x01) ....1... "half current"
836 * CHLF[2] "Column buffer current control"
837 * = 0 (0x00) .....0.. "normal current"
838 * CHLF[1] "Analog DSP current control"
839 * = 0 (0x00) ......0. "normal current"
840 * CHLF[1] "ADC current control"
841 * = 0 (0x00) ......0. "normal current"
842 */
843 { 0x33, 0x09 },
844
845 /*
846 * 34 VBLM "Blooming Control"
847 * = 80 (0x50) 01010000
848 * VBLM[7] "Hard soft reset switch"
849 * = 0 (0x00) 0....... "Hard reset"
850 * VBLM[6:4] "Blooming voltage selection"
851 * = 5 (0x05) .101....
852 * VBLM[3:0] "Sensor current control"
853 * = 0 (0x00) ....0000
854 */
855 { 0x34, 0x50 },
856
857 /*
858 * 36 VCHG "Sensor Precharge Voltage Control"
859 * = 0 (0x00) 00000000
860 * VCHG[7] "Reserved"
861 * = 0 (0x00) 0.......
862 * VCHG[6:4] "Sensor precharge voltage control"
863 * = 0 (0x00) .000....
864 * VCHG[3:0] "Sensor array common reference"
865 * = 0 (0x00) ....0000
866 */
867 { 0x36, 0x00 },
868
869 /*
870 * 37 ADC "ADC Reference Control"
871 * = 4 (0x04) 00000100
872 * ADC[7:4] "Reserved"
873 * = 0 (0x00) 0000....
874 * ADC[3] "ADC input signal range"
875 * = 0 (0x00) ....0... "Input signal 1.0x"
876 * ADC[2:0] "ADC range control"
877 * = 4 (0x04) .....100
878 */
879 { 0x37, 0x04 },
880
881 /*
882 * 38 ACOM "Analog Common Ground"
883 * = 82 (0x52) 01010010
884 * ACOM[7] "Analog gain control"
885 * = 0 (0x00) 0....... "Gain 1x"
886 * ACOM[6] "Analog black level calibration"
887 * = 1 (0x01) .1...... "On"
888 * ACOM[5:0] "Reserved"
889 * = 18 (0x12) ..010010
890 */
891 { 0x38, 0x52 },
892
893 /*
894 * 3A FREFA "Internal Reference Adjustment"
895 * = 0 (0x00) 00000000
896 * FREFA[7:0] "Range"
897 * = 0 (0x00) 00000000
898 */
899 { 0x3a, 0x00 },
900
901 /*
902 * 3C FVOPT "Internal Reference Adjustment"
903 * = 31 (0x1F) 00011111
904 * FVOPT[7:0] "Range"
905 * = 31 (0x1F) 00011111
906 */
907 { 0x3c, 0x1F },
908
909 /*
910 * 44 Undocumented = 0 (0x00) 00000000
911 * 44[7:0] "It's a secret"
912 * = 0 (0x00) 00000000
913 */
914 { 0x44, 0x00 },
915
916 /*
917 * 40 Undocumented = 0 (0x00) 00000000
918 * 40[7:0] "It's a secret"
919 * = 0 (0x00) 00000000
920 */
921 { 0x40, 0x00 },
922
923 /*
924 * 41 Undocumented = 0 (0x00) 00000000
925 * 41[7:0] "It's a secret"
926 * = 0 (0x00) 00000000
927 */
928 { 0x41, 0x00 },
929
930 /*
931 * 42 Undocumented = 0 (0x00) 00000000
932 * 42[7:0] "It's a secret"
933 * = 0 (0x00) 00000000
934 */
935 { 0x42, 0x00 },
936
937 /*
938 * 43 Undocumented = 0 (0x00) 00000000
939 * 43[7:0] "It's a secret"
940 * = 0 (0x00) 00000000
941 */
942 { 0x43, 0x00 },
943
944 /*
945 * 45 Undocumented = 128 (0x80) 10000000
946 * 45[7:0] "It's a secret"
947 * = 128 (0x80) 10000000
948 */
949 { 0x45, 0x80 },
950
951 /*
952 * 48 Undocumented = 192 (0xC0) 11000000
953 * 48[7:0] "It's a secret"
954 * = 192 (0xC0) 11000000
955 */
956 { 0x48, 0xC0 },
957
958 /*
959 * 49 Undocumented = 25 (0x19) 00011001
960 * 49[7:0] "It's a secret"
961 * = 25 (0x19) 00011001
962 */
963 { 0x49, 0x19 },
964
965 /*
966 * 4B Undocumented = 128 (0x80) 10000000
967 * 4B[7:0] "It's a secret"
968 * = 128 (0x80) 10000000
969 */
970 { 0x4B, 0x80 },
971
972 /*
973 * 4D Undocumented = 196 (0xC4) 11000100
974 * 4D[7:0] "It's a secret"
975 * = 196 (0xC4) 11000100
976 */
977 { 0x4D, 0xC4 },
978
979 /*
980 * 35 VREF "Reference Voltage Control"
981 * = 76 (0x4C) 01001100
982 * VREF[7:5] "Column high reference control"
983 * = 2 (0x02) 010..... "higher voltage"
984 * VREF[4:2] "Column low reference control"
985 * = 3 (0x03) ...011.. "Highest voltage"
986 * VREF[1:0] "Reserved"
987 * = 0 (0x00) ......00
988 */
989 { 0x35, 0x4C },
990
991 /*
992 * 3D Undocumented = 0 (0x00) 00000000
993 * 3D[7:0] "It's a secret"
994 * = 0 (0x00) 00000000
995 */
996 { 0x3D, 0x00 },
997
998 /*
999 * 3E Undocumented = 0 (0x00) 00000000
1000 * 3E[7:0] "It's a secret"
1001 * = 0 (0x00) 00000000
1002 */
1003 { 0x3E, 0x00 },
1004
1005 /*
1006 * 3B FREFB "Internal Reference Adjustment"
1007 * = 24 (0x18) 00011000
1008 * FREFB[7:0] "Range"
1009 * = 24 (0x18) 00011000
1010 */
1011 { 0x3b, 0x18 },
1012
1013 /*
1014 * 33 CHLF "Current Control"
1015 * = 25 (0x19) 00011001
1016 * CHLF[7:6] "Sensor current control"
1017 * = 0 (0x00) 00......
1018 * CHLF[5] "Sensor current range control"
1019 * = 0 (0x00) ..0..... "normal range"
1020 * CHLF[4] "Sensor current"
1021 * = 1 (0x01) ...1.... "double current"
1022 * CHLF[3] "Sensor buffer current control"
1023 * = 1 (0x01) ....1... "half current"
1024 * CHLF[2] "Column buffer current control"
1025 * = 0 (0x00) .....0.. "normal current"
1026 * CHLF[1] "Analog DSP current control"
1027 * = 0 (0x00) ......0. "normal current"
1028 * CHLF[1] "ADC current control"
1029 * = 0 (0x00) ......0. "normal current"
1030 */
1031 { 0x33, 0x19 },
1032
1033 /*
1034 * 34 VBLM "Blooming Control"
1035 * = 90 (0x5A) 01011010
1036 * VBLM[7] "Hard soft reset switch"
1037 * = 0 (0x00) 0....... "Hard reset"
1038 * VBLM[6:4] "Blooming voltage selection"
1039 * = 5 (0x05) .101....
1040 * VBLM[3:0] "Sensor current control"
1041 * = 10 (0x0A) ....1010
1042 */
1043 { 0x34, 0x5A },
1044
1045 /*
1046 * 3B FREFB "Internal Reference Adjustment"
1047 * = 0 (0x00) 00000000
1048 * FREFB[7:0] "Range"
1049 * = 0 (0x00) 00000000
1050 */
1051 { 0x3b, 0x00 },
1052
1053 /*
1054 * 33 CHLF "Current Control"
1055 * = 9 (0x09) 00001001
1056 * CHLF[7:6] "Sensor current control"
1057 * = 0 (0x00) 00......
1058 * CHLF[5] "Sensor current range control"
1059 * = 0 (0x00) ..0..... "normal range"
1060 * CHLF[4] "Sensor current"
1061 * = 0 (0x00) ...0.... "normal current"
1062 * CHLF[3] "Sensor buffer current control"
1063 * = 1 (0x01) ....1... "half current"
1064 * CHLF[2] "Column buffer current control"
1065 * = 0 (0x00) .....0.. "normal current"
1066 * CHLF[1] "Analog DSP current control"
1067 * = 0 (0x00) ......0. "normal current"
1068 * CHLF[1] "ADC current control"
1069 * = 0 (0x00) ......0. "normal current"
1070 */
1071 { 0x33, 0x09 },
1072
1073 /*
1074 * 34 VBLM "Blooming Control"
1075 * = 80 (0x50) 01010000
1076 * VBLM[7] "Hard soft reset switch"
1077 * = 0 (0x00) 0....... "Hard reset"
1078 * VBLM[6:4] "Blooming voltage selection"
1079 * = 5 (0x05) .101....
1080 * VBLM[3:0] "Sensor current control"
1081 * = 0 (0x00) ....0000
1082 */
1083 { 0x34, 0x50 },
1084
1085 /*
1086 * 12 COMH "Common Control H"
1087 * = 64 (0x40) 01000000
1088 * COMH[7] "SRST"
1089 * = 0 (0x00) 0....... "No-op"
1090 * COMH[6:4] "Resolution selection"
1091 * = 4 (0x04) .100.... "XGA"
1092 * COMH[3] "Master slave selection"
1093 * = 0 (0x00) ....0... "Master mode"
1094 * COMH[2] "Internal B/R channel option"
1095 * = 0 (0x00) .....0.. "B/R use same channel"
1096 * COMH[1] "Color bar test pattern"
1097 * = 0 (0x00) ......0. "Off"
1098 * COMH[0] "Reserved"
1099 * = 0 (0x00) .......0
1100 */
1101 { 0x12, 0x40 },
1102
1103 /*
1104 * 17 HREFST "Horizontal window start"
1105 * = 31 (0x1F) 00011111
1106 * HREFST[7:0] "Horizontal window start, 8 MSBs"
1107 * = 31 (0x1F) 00011111
1108 */
1109 { 0x17, 0x1F },
1110
1111 /*
1112 * 18 HREFEND "Horizontal window end"
1113 * = 95 (0x5F) 01011111
1114 * HREFEND[7:0] "Horizontal Window End, 8 MSBs"
1115 * = 95 (0x5F) 01011111
1116 */
1117 { 0x18, 0x5F },
1118
1119 /*
1120 * 19 VSTRT "Vertical window start"
1121 * = 0 (0x00) 00000000
1122 * VSTRT[7:0] "Vertical Window Start, 8 MSBs"
1123 * = 0 (0x00) 00000000
1124 */
1125 { 0x19, 0x00 },
1126
1127 /*
1128 * 1A VEND "Vertical window end"
1129 * = 96 (0x60) 01100000
1130 * VEND[7:0] "Vertical Window End, 8 MSBs"
1131 * = 96 (0x60) 01100000
1132 */
1133 { 0x1a, 0x60 },
1134
1135 /*
1136 * 32 COMM "Common Control M"
1137 * = 18 (0x12) 00010010
1138 * COMM[7:6] "Pixel clock divide option"
1139 * = 0 (0x00) 00...... "/1"
1140 * COMM[5:3] "Horizontal window end position, 3 LSBs"
1141 * = 2 (0x02) ..010...
1142 * COMM[2:0] "Horizontal window start position, 3 LSBs"
1143 * = 2 (0x02) .....010
1144 */
1145 { 0x32, 0x12 },
1146
1147 /*
1148 * 03 COMA "Common Control A"
1149 * = 74 (0x4A) 01001010
1150 * COMA[7:4] "AWB Update Threshold"
1151 * = 4 (0x04) 0100....
1152 * COMA[3:2] "Vertical window end line control 2 LSBs"
1153 * = 2 (0x02) ....10..
1154 * COMA[1:0] "Vertical window start line control 2 LSBs"
1155 * = 2 (0x02) ......10
1156 */
1157 { 0x03, 0x4A },
1158
1159 /*
1160 * 11 CLKRC "Clock Rate Control"
1161 * = 128 (0x80) 10000000
1162 * CLKRC[7] "Internal frequency doublers on off seclection"
1163 * = 1 (0x01) 1....... "On"
1164 * CLKRC[6] "Digital video master slave selection"
1165 * = 0 (0x00) .0...... "Master mode, sensor
1166 * provides PCLK"
1167 * CLKRC[5:0] "Clock divider { CLK = PCLK/(1+CLKRC[5:0]) }"
1168 * = 0 (0x00) ..000000
1169 */
1170 { 0x11, 0x80 },
1171
1172 /*
1173 * 12 COMH "Common Control H"
1174 * = 0 (0x00) 00000000
1175 * COMH[7] "SRST"
1176 * = 0 (0x00) 0....... "No-op"
1177 * COMH[6:4] "Resolution selection"
1178 * = 0 (0x00) .000.... "QXGA"
1179 * COMH[3] "Master slave selection"
1180 * = 0 (0x00) ....0... "Master mode"
1181 * COMH[2] "Internal B/R channel option"
1182 * = 0 (0x00) .....0.. "B/R use same channel"
1183 * COMH[1] "Color bar test pattern"
1184 * = 0 (0x00) ......0. "Off"
1185 * COMH[0] "Reserved"
1186 * = 0 (0x00) .......0
1187 */
1188 { 0x12, 0x00 },
1189
1190 /*
1191 * 12 COMH "Common Control H"
1192 * = 64 (0x40) 01000000
1193 * COMH[7] "SRST"
1194 * = 0 (0x00) 0....... "No-op"
1195 * COMH[6:4] "Resolution selection"
1196 * = 4 (0x04) .100.... "XGA"
1197 * COMH[3] "Master slave selection"
1198 * = 0 (0x00) ....0... "Master mode"
1199 * COMH[2] "Internal B/R channel option"
1200 * = 0 (0x00) .....0.. "B/R use same channel"
1201 * COMH[1] "Color bar test pattern"
1202 * = 0 (0x00) ......0. "Off"
1203 * COMH[0] "Reserved"
1204 * = 0 (0x00) .......0
1205 */
1206 { 0x12, 0x40 },
1207
1208 /*
1209 * 17 HREFST "Horizontal window start"
1210 * = 31 (0x1F) 00011111
1211 * HREFST[7:0] "Horizontal window start, 8 MSBs"
1212 * = 31 (0x1F) 00011111
1213 */
1214 { 0x17, 0x1F },
1215
1216 /*
1217 * 18 HREFEND "Horizontal window end"
1218 * = 95 (0x5F) 01011111
1219 * HREFEND[7:0] "Horizontal Window End, 8 MSBs"
1220 * = 95 (0x5F) 01011111
1221 */
1222 { 0x18, 0x5F },
1223
1224 /*
1225 * 19 VSTRT "Vertical window start"
1226 * = 0 (0x00) 00000000
1227 * VSTRT[7:0] "Vertical Window Start, 8 MSBs"
1228 * = 0 (0x00) 00000000
1229 */
1230 { 0x19, 0x00 },
1231
1232 /*
1233 * 1A VEND "Vertical window end"
1234 * = 96 (0x60) 01100000
1235 * VEND[7:0] "Vertical Window End, 8 MSBs"
1236 * = 96 (0x60) 01100000
1237 */
1238 { 0x1a, 0x60 },
1239
1240 /*
1241 * 32 COMM "Common Control M"
1242 * = 18 (0x12) 00010010
1243 * COMM[7:6] "Pixel clock divide option"
1244 * = 0 (0x00) 00...... "/1"
1245 * COMM[5:3] "Horizontal window end position, 3 LSBs"
1246 * = 2 (0x02) ..010...
1247 * COMM[2:0] "Horizontal window start position, 3 LSBs"
1248 * = 2 (0x02) .....010
1249 */
1250 { 0x32, 0x12 },
1251
1252 /*
1253 * 03 COMA "Common Control A"
1254 * = 74 (0x4A) 01001010
1255 * COMA[7:4] "AWB Update Threshold"
1256 * = 4 (0x04) 0100....
1257 * COMA[3:2] "Vertical window end line control 2 LSBs"
1258 * = 2 (0x02) ....10..
1259 * COMA[1:0] "Vertical window start line control 2 LSBs"
1260 * = 2 (0x02) ......10
1261 */
1262 { 0x03, 0x4A },
1263
1264 /*
1265 * 02 RED "Red Gain Control"
1266 * = 175 (0xAF) 10101111
1267 * RED[7] "Action"
1268 * = 1 (0x01) 1....... "gain = 1/(1+bitrev([6:0]))"
1269 * RED[6:0] "Value"
1270 * = 47 (0x2F) .0101111
1271 */
1272 { 0x02, 0xAF },
1273
1274 /*
1275 * 2D ADDVSL "VSYNC Pulse Width"
1276 * = 210 (0xD2) 11010010
1277 * ADDVSL[7:0] "VSYNC pulse width, LSB"
1278 * = 210 (0xD2) 11010010
1279 */
1280 { 0x2d, 0xD2 },
1281
1282 /*
1283 * 00 GAIN = 24 (0x18) 00011000
1284 * GAIN[7:6] "Reserved"
1285 * = 0 (0x00) 00......
1286 * GAIN[5] "Double"
1287 * = 0 (0x00) ..0..... "False"
1288 * GAIN[4] "Double"
1289 * = 1 (0x01) ...1.... "True"
1290 * GAIN[3:0] "Range"
1291 * = 8 (0x08) ....1000
1292 */
1293 { 0x00, 0x18 },
1294
1295 /*
1296 * 01 BLUE "Blue Gain Control"
1297 * = 240 (0xF0) 11110000
1298 * BLUE[7] "Action"
1299 * = 1 (0x01) 1....... "gain = 1/(1+bitrev([6:0]))"
1300 * BLUE[6:0] "Value"
1301 * = 112 (0x70) .1110000
1302 */
1303 { 0x01, 0xF0 },
1304
1305 /*
1306 * 10 AEC "Automatic Exposure Control"
1307 * = 10 (0x0A) 00001010
1308 * AEC[7:0] "Automatic Exposure Control, 8 MSBs"
1309 * = 10 (0x0A) 00001010
1310 */
1311 { 0x10, 0x0A },
1312
1313 { 0xE1, 0x67 },
1314 { 0xE3, 0x03 },
1315 { 0xE4, 0x26 },
1316 { 0xE5, 0x3E },
1317 { 0xF8, 0x01 },
1318 { 0xFF, 0x01 },
1319};
1320
511static const struct ov_i2c_regvals norm_6x20[] = { 1321static const struct ov_i2c_regvals norm_6x20[] = {
512 { 0x12, 0x80 }, /* reset */ 1322 { 0x12, 0x80 }, /* reset */
513 { 0x11, 0x01 }, 1323 { 0x11, 0x01 },
@@ -678,6 +1488,7 @@ static const struct ov_i2c_regvals norm_7610[] = {
678}; 1488};
679 1489
680static const struct ov_i2c_regvals norm_7620[] = { 1490static const struct ov_i2c_regvals norm_7620[] = {
1491 { 0x12, 0x80 }, /* reset */
681 { 0x00, 0x00 }, /* gain */ 1492 { 0x00, 0x00 }, /* gain */
682 { 0x01, 0x80 }, /* blue gain */ 1493 { 0x01, 0x80 }, /* blue gain */
683 { 0x02, 0x80 }, /* red gain */ 1494 { 0x02, 0x80 }, /* red gain */
@@ -1042,10 +1853,28 @@ static unsigned char ov7670_abs_to_sm(unsigned char v)
1042} 1853}
1043 1854
1044/* Write a OV519 register */ 1855/* Write a OV519 register */
1045static int reg_w(struct sd *sd, __u16 index, __u8 value) 1856static int reg_w(struct sd *sd, __u16 index, __u16 value)
1046{ 1857{
1047 int ret; 1858 int ret, req = 0;
1048 int req = (sd->bridge <= BRIDGE_OV511PLUS) ? 2 : 1; 1859
1860 switch (sd->bridge) {
1861 case BRIDGE_OV511:
1862 case BRIDGE_OV511PLUS:
1863 req = 2;
1864 break;
1865 case BRIDGE_OVFX2:
1866 req = 0x0a;
1867 /* fall through */
1868 case BRIDGE_W9968CF:
1869 ret = usb_control_msg(sd->gspca_dev.dev,
1870 usb_sndctrlpipe(sd->gspca_dev.dev, 0),
1871 req,
1872 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
1873 value, index, NULL, 0, 500);
1874 goto leave;
1875 default:
1876 req = 1;
1877 }
1049 1878
1050 sd->gspca_dev.usb_buf[0] = value; 1879 sd->gspca_dev.usb_buf[0] = value;
1051 ret = usb_control_msg(sd->gspca_dev.dev, 1880 ret = usb_control_msg(sd->gspca_dev.dev,
@@ -1054,17 +1883,35 @@ static int reg_w(struct sd *sd, __u16 index, __u8 value)
1054 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 1883 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
1055 0, index, 1884 0, index,
1056 sd->gspca_dev.usb_buf, 1, 500); 1885 sd->gspca_dev.usb_buf, 1, 500);
1057 if (ret < 0) 1886leave:
1058 PDEBUG(D_ERR, "Write reg [%02x] %02x failed", index, value); 1887 if (ret < 0) {
1059 return ret; 1888 PDEBUG(D_ERR, "Write reg 0x%04x -> [0x%02x] failed",
1889 value, index);
1890 return ret;
1891 }
1892
1893 PDEBUG(D_USBO, "Write reg 0x%04x -> [0x%02x]", value, index);
1894 return 0;
1060} 1895}
1061 1896
1062/* Read from a OV519 register */ 1897/* Read from a OV519 register, note not valid for the w9968cf!! */
1063/* returns: negative is error, pos or zero is data */ 1898/* returns: negative is error, pos or zero is data */
1064static int reg_r(struct sd *sd, __u16 index) 1899static int reg_r(struct sd *sd, __u16 index)
1065{ 1900{
1066 int ret; 1901 int ret;
1067 int req = (sd->bridge <= BRIDGE_OV511PLUS) ? 3 : 1; 1902 int req;
1903
1904 switch (sd->bridge) {
1905 case BRIDGE_OV511:
1906 case BRIDGE_OV511PLUS:
1907 req = 3;
1908 break;
1909 case BRIDGE_OVFX2:
1910 req = 0x0b;
1911 break;
1912 default:
1913 req = 1;
1914 }
1068 1915
1069 ret = usb_control_msg(sd->gspca_dev.dev, 1916 ret = usb_control_msg(sd->gspca_dev.dev,
1070 usb_rcvctrlpipe(sd->gspca_dev.dev, 0), 1917 usb_rcvctrlpipe(sd->gspca_dev.dev, 0),
@@ -1072,10 +1919,12 @@ static int reg_r(struct sd *sd, __u16 index)
1072 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 1919 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
1073 0, index, sd->gspca_dev.usb_buf, 1, 500); 1920 0, index, sd->gspca_dev.usb_buf, 1, 500);
1074 1921
1075 if (ret >= 0) 1922 if (ret >= 0) {
1076 ret = sd->gspca_dev.usb_buf[0]; 1923 ret = sd->gspca_dev.usb_buf[0];
1077 else 1924 PDEBUG(D_USBI, "Read reg [0x%02X] -> 0x%04X", index, ret);
1925 } else
1078 PDEBUG(D_ERR, "Read reg [0x%02x] failed", index); 1926 PDEBUG(D_ERR, "Read reg [0x%02x] failed", index);
1927
1079 return ret; 1928 return ret;
1080} 1929}
1081 1930
@@ -1095,6 +1944,7 @@ static int reg_r8(struct sd *sd,
1095 ret = sd->gspca_dev.usb_buf[0]; 1944 ret = sd->gspca_dev.usb_buf[0];
1096 else 1945 else
1097 PDEBUG(D_ERR, "Read reg 8 [0x%02x] failed", index); 1946 PDEBUG(D_ERR, "Read reg 8 [0x%02x] failed", index);
1947
1098 return ret; 1948 return ret;
1099} 1949}
1100 1950
@@ -1140,9 +1990,12 @@ static int ov518_reg_w32(struct sd *sd, __u16 index, u32 value, int n)
1140 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 1990 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
1141 0, index, 1991 0, index,
1142 sd->gspca_dev.usb_buf, n, 500); 1992 sd->gspca_dev.usb_buf, n, 500);
1143 if (ret < 0) 1993 if (ret < 0) {
1144 PDEBUG(D_ERR, "Write reg32 [%02x] %08x failed", index, value); 1994 PDEBUG(D_ERR, "Write reg32 [%02x] %08x failed", index, value);
1145 return ret; 1995 return ret;
1996 }
1997
1998 return 0;
1146} 1999}
1147 2000
1148static int ov511_i2c_w(struct sd *sd, __u8 reg, __u8 value) 2001static int ov511_i2c_w(struct sd *sd, __u8 reg, __u8 value)
@@ -1324,32 +2177,110 @@ static int ov518_i2c_r(struct sd *sd, __u8 reg)
1324 return value; 2177 return value;
1325} 2178}
1326 2179
2180static int ovfx2_i2c_w(struct sd *sd, __u8 reg, __u8 value)
2181{
2182 int ret;
2183
2184 ret = usb_control_msg(sd->gspca_dev.dev,
2185 usb_sndctrlpipe(sd->gspca_dev.dev, 0),
2186 0x02,
2187 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
2188 (__u16)value, (__u16)reg, NULL, 0, 500);
2189
2190 if (ret < 0) {
2191 PDEBUG(D_ERR, "i2c 0x%02x -> [0x%02x] failed", value, reg);
2192 return ret;
2193 }
2194
2195 PDEBUG(D_USBO, "i2c 0x%02x -> [0x%02x]", value, reg);
2196 return 0;
2197}
2198
2199static int ovfx2_i2c_r(struct sd *sd, __u8 reg)
2200{
2201 int ret;
2202
2203 ret = usb_control_msg(sd->gspca_dev.dev,
2204 usb_rcvctrlpipe(sd->gspca_dev.dev, 0),
2205 0x03,
2206 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
2207 0, (__u16)reg, sd->gspca_dev.usb_buf, 1, 500);
2208
2209 if (ret >= 0) {
2210 ret = sd->gspca_dev.usb_buf[0];
2211 PDEBUG(D_USBI, "i2c [0x%02X] -> 0x%02X", reg, ret);
2212 } else
2213 PDEBUG(D_ERR, "i2c read [0x%02x] failed", reg);
2214
2215 return ret;
2216}
2217
1327static int i2c_w(struct sd *sd, __u8 reg, __u8 value) 2218static int i2c_w(struct sd *sd, __u8 reg, __u8 value)
1328{ 2219{
2220 int ret = -1;
2221
2222 if (sd->sensor_reg_cache[reg] == value)
2223 return 0;
2224
1329 switch (sd->bridge) { 2225 switch (sd->bridge) {
1330 case BRIDGE_OV511: 2226 case BRIDGE_OV511:
1331 case BRIDGE_OV511PLUS: 2227 case BRIDGE_OV511PLUS:
1332 return ov511_i2c_w(sd, reg, value); 2228 ret = ov511_i2c_w(sd, reg, value);
2229 break;
1333 case BRIDGE_OV518: 2230 case BRIDGE_OV518:
1334 case BRIDGE_OV518PLUS: 2231 case BRIDGE_OV518PLUS:
1335 case BRIDGE_OV519: 2232 case BRIDGE_OV519:
1336 return ov518_i2c_w(sd, reg, value); 2233 ret = ov518_i2c_w(sd, reg, value);
2234 break;
2235 case BRIDGE_OVFX2:
2236 ret = ovfx2_i2c_w(sd, reg, value);
2237 break;
2238 case BRIDGE_W9968CF:
2239 ret = w9968cf_i2c_w(sd, reg, value);
2240 break;
1337 } 2241 }
1338 return -1; /* Should never happen */ 2242
2243 if (ret >= 0) {
2244 /* Up on sensor reset empty the register cache */
2245 if (reg == 0x12 && (value & 0x80))
2246 memset(sd->sensor_reg_cache, -1,
2247 sizeof(sd->sensor_reg_cache));
2248 else
2249 sd->sensor_reg_cache[reg] = value;
2250 }
2251
2252 return ret;
1339} 2253}
1340 2254
1341static int i2c_r(struct sd *sd, __u8 reg) 2255static int i2c_r(struct sd *sd, __u8 reg)
1342{ 2256{
2257 int ret = -1;
2258
2259 if (sd->sensor_reg_cache[reg] != -1)
2260 return sd->sensor_reg_cache[reg];
2261
1343 switch (sd->bridge) { 2262 switch (sd->bridge) {
1344 case BRIDGE_OV511: 2263 case BRIDGE_OV511:
1345 case BRIDGE_OV511PLUS: 2264 case BRIDGE_OV511PLUS:
1346 return ov511_i2c_r(sd, reg); 2265 ret = ov511_i2c_r(sd, reg);
2266 break;
1347 case BRIDGE_OV518: 2267 case BRIDGE_OV518:
1348 case BRIDGE_OV518PLUS: 2268 case BRIDGE_OV518PLUS:
1349 case BRIDGE_OV519: 2269 case BRIDGE_OV519:
1350 return ov518_i2c_r(sd, reg); 2270 ret = ov518_i2c_r(sd, reg);
2271 break;
2272 case BRIDGE_OVFX2:
2273 ret = ovfx2_i2c_r(sd, reg);
2274 break;
2275 case BRIDGE_W9968CF:
2276 ret = w9968cf_i2c_r(sd, reg);
2277 break;
1351 } 2278 }
1352 return -1; /* Should never happen */ 2279
2280 if (ret >= 0)
2281 sd->sensor_reg_cache[reg] = ret;
2282
2283 return ret;
1353} 2284}
1354 2285
1355/* Writes bits at positions specified by mask to an I2C reg. Bits that are in 2286/* Writes bits at positions specified by mask to an I2C reg. Bits that are in
@@ -1389,6 +2320,10 @@ static inline int ov51x_stop(struct sd *sd)
1389 return reg_w_mask(sd, R51x_SYS_RESET, 0x3a, 0x3a); 2320 return reg_w_mask(sd, R51x_SYS_RESET, 0x3a, 0x3a);
1390 case BRIDGE_OV519: 2321 case BRIDGE_OV519:
1391 return reg_w(sd, OV519_SYS_RESET1, 0x0f); 2322 return reg_w(sd, OV519_SYS_RESET1, 0x0f);
2323 case BRIDGE_OVFX2:
2324 return reg_w_mask(sd, 0x0f, 0x00, 0x02);
2325 case BRIDGE_W9968CF:
2326 return reg_w(sd, 0x3c, 0x0a05); /* stop USB transfer */
1392 } 2327 }
1393 2328
1394 return 0; 2329 return 0;
@@ -1418,18 +2353,27 @@ static inline int ov51x_restart(struct sd *sd)
1418 return reg_w(sd, R51x_SYS_RESET, 0x00); 2353 return reg_w(sd, R51x_SYS_RESET, 0x00);
1419 case BRIDGE_OV519: 2354 case BRIDGE_OV519:
1420 return reg_w(sd, OV519_SYS_RESET1, 0x00); 2355 return reg_w(sd, OV519_SYS_RESET1, 0x00);
2356 case BRIDGE_OVFX2:
2357 return reg_w_mask(sd, 0x0f, 0x02, 0x02);
2358 case BRIDGE_W9968CF:
2359 return reg_w(sd, 0x3c, 0x8a05); /* USB FIFO enable */
1421 } 2360 }
1422 2361
1423 return 0; 2362 return 0;
1424} 2363}
1425 2364
2365static int ov51x_set_slave_ids(struct sd *sd, __u8 slave);
2366
1426/* This does an initial reset of an OmniVision sensor and ensures that I2C 2367/* This does an initial reset of an OmniVision sensor and ensures that I2C
1427 * is synchronized. Returns <0 on failure. 2368 * is synchronized. Returns <0 on failure.
1428 */ 2369 */
1429static int init_ov_sensor(struct sd *sd) 2370static int init_ov_sensor(struct sd *sd, __u8 slave)
1430{ 2371{
1431 int i; 2372 int i;
1432 2373
2374 if (ov51x_set_slave_ids(sd, slave) < 0)
2375 return -EIO;
2376
1433 /* Reset the sensor */ 2377 /* Reset the sensor */
1434 if (i2c_w(sd, 0x12, 0x80) < 0) 2378 if (i2c_w(sd, 0x12, 0x80) < 0)
1435 return -EIO; 2379 return -EIO;
@@ -1466,6 +2410,14 @@ static int ov51x_set_slave_ids(struct sd *sd,
1466{ 2410{
1467 int rc; 2411 int rc;
1468 2412
2413 switch (sd->bridge) {
2414 case BRIDGE_OVFX2:
2415 return reg_w(sd, OVFX2_I2C_ADDR, slave);
2416 case BRIDGE_W9968CF:
2417 sd->sensor_addr = slave;
2418 return 0;
2419 }
2420
1469 rc = reg_w(sd, R51x_I2C_W_SID, slave); 2421 rc = reg_w(sd, R51x_I2C_W_SID, slave);
1470 if (rc < 0) 2422 if (rc < 0)
1471 return rc; 2423 return rc;
@@ -1508,6 +2460,39 @@ static int write_i2c_regvals(struct sd *sd,
1508 * 2460 *
1509 ***************************************************************************/ 2461 ***************************************************************************/
1510 2462
2463/* This initializes the OV2x10 / OV3610 / OV3620 */
2464static int ov_hires_configure(struct sd *sd)
2465{
2466 int high, low;
2467
2468 if (sd->bridge != BRIDGE_OVFX2) {
2469 PDEBUG(D_ERR, "error hires sensors only supported with ovfx2");
2470 return -1;
2471 }
2472
2473 PDEBUG(D_PROBE, "starting ov hires configuration");
2474
2475 /* Detect sensor (sub)type */
2476 high = i2c_r(sd, 0x0a);
2477 low = i2c_r(sd, 0x0b);
2478 /* info("%x, %x", high, low); */
2479 if (high == 0x96 && low == 0x40) {
2480 PDEBUG(D_PROBE, "Sensor is an OV2610");
2481 sd->sensor = SEN_OV2610;
2482 } else if (high == 0x36 && (low & 0x0f) == 0x00) {
2483 PDEBUG(D_PROBE, "Sensor is an OV3610");
2484 sd->sensor = SEN_OV3610;
2485 } else {
2486 PDEBUG(D_ERR, "Error unknown sensor type: 0x%02x%02x",
2487 high, low);
2488 return -1;
2489 }
2490
2491 /* Set sensor-specific vars */
2492 return 0;
2493}
2494
2495
1511/* This initializes the OV8110, OV8610 sensor. The OV8110 uses 2496/* This initializes the OV8110, OV8610 sensor. The OV8110 uses
1512 * the same register settings as the OV8610, since they are very similar. 2497 * the same register settings as the OV8610, since they are very similar.
1513 */ 2498 */
@@ -1966,12 +2951,29 @@ static int ov519_configure(struct sd *sd)
1966 return write_regvals(sd, init_519, ARRAY_SIZE(init_519)); 2951 return write_regvals(sd, init_519, ARRAY_SIZE(init_519));
1967} 2952}
1968 2953
2954static int ovfx2_configure(struct sd *sd)
2955{
2956 static const struct ov_regvals init_fx2[] = {
2957 { 0x00, 0x60 },
2958 { 0x02, 0x01 },
2959 { 0x0f, 0x1d },
2960 { 0xe9, 0x82 },
2961 { 0xea, 0xc7 },
2962 { 0xeb, 0x10 },
2963 { 0xec, 0xf6 },
2964 };
2965
2966 sd->stopped = 1;
2967
2968 return write_regvals(sd, init_fx2, ARRAY_SIZE(init_fx2));
2969}
2970
1969/* this function is called at probe time */ 2971/* this function is called at probe time */
1970static int sd_config(struct gspca_dev *gspca_dev, 2972static int sd_config(struct gspca_dev *gspca_dev,
1971 const struct usb_device_id *id) 2973 const struct usb_device_id *id)
1972{ 2974{
1973 struct sd *sd = (struct sd *) gspca_dev; 2975 struct sd *sd = (struct sd *) gspca_dev;
1974 struct cam *cam; 2976 struct cam *cam = &gspca_dev->cam;
1975 int ret = 0; 2977 int ret = 0;
1976 2978
1977 sd->bridge = id->driver_info & BRIDGE_MASK; 2979 sd->bridge = id->driver_info & BRIDGE_MASK;
@@ -1989,6 +2991,16 @@ static int sd_config(struct gspca_dev *gspca_dev,
1989 case BRIDGE_OV519: 2991 case BRIDGE_OV519:
1990 ret = ov519_configure(sd); 2992 ret = ov519_configure(sd);
1991 break; 2993 break;
2994 case BRIDGE_OVFX2:
2995 ret = ovfx2_configure(sd);
2996 cam->bulk_size = OVFX2_BULK_SIZE;
2997 cam->bulk_nurbs = MAX_NURBS;
2998 cam->bulk = 1;
2999 break;
3000 case BRIDGE_W9968CF:
3001 ret = w9968cf_configure(sd);
3002 cam->reverse_alts = 1;
3003 break;
1992 } 3004 }
1993 3005
1994 if (ret) 3006 if (ret)
@@ -1996,49 +3008,39 @@ static int sd_config(struct gspca_dev *gspca_dev,
1996 3008
1997 ov51x_led_control(sd, 0); /* turn LED off */ 3009 ov51x_led_control(sd, 0); /* turn LED off */
1998 3010
1999 /* Test for 76xx */
2000 if (ov51x_set_slave_ids(sd, OV7xx0_SID) < 0)
2001 goto error;
2002
2003 /* The OV519 must be more aggressive about sensor detection since 3011 /* The OV519 must be more aggressive about sensor detection since
2004 * I2C write will never fail if the sensor is not present. We have 3012 * I2C write will never fail if the sensor is not present. We have
2005 * to try to initialize the sensor to detect its presence */ 3013 * to try to initialize the sensor to detect its presence */
2006 if (init_ov_sensor(sd) >= 0) { 3014
3015 /* Test for 76xx */
3016 if (init_ov_sensor(sd, OV7xx0_SID) >= 0) {
2007 if (ov7xx0_configure(sd) < 0) { 3017 if (ov7xx0_configure(sd) < 0) {
2008 PDEBUG(D_ERR, "Failed to configure OV7xx0"); 3018 PDEBUG(D_ERR, "Failed to configure OV7xx0");
2009 goto error; 3019 goto error;
2010 } 3020 }
2011 } else { 3021 /* Test for 6xx0 */
2012 3022 } else if (init_ov_sensor(sd, OV6xx0_SID) >= 0) {
2013 /* Test for 6xx0 */ 3023 if (ov6xx0_configure(sd) < 0) {
2014 if (ov51x_set_slave_ids(sd, OV6xx0_SID) < 0) 3024 PDEBUG(D_ERR, "Failed to configure OV6xx0");
3025 goto error;
3026 }
3027 /* Test for 8xx0 */
3028 } else if (init_ov_sensor(sd, OV8xx0_SID) >= 0) {
3029 if (ov8xx0_configure(sd) < 0) {
3030 PDEBUG(D_ERR, "Failed to configure OV8xx0");
2015 goto error; 3031 goto error;
2016
2017 if (init_ov_sensor(sd) >= 0) {
2018 if (ov6xx0_configure(sd) < 0) {
2019 PDEBUG(D_ERR, "Failed to configure OV6xx0");
2020 goto error;
2021 }
2022 } else {
2023
2024 /* Test for 8xx0 */
2025 if (ov51x_set_slave_ids(sd, OV8xx0_SID) < 0)
2026 goto error;
2027
2028 if (init_ov_sensor(sd) < 0) {
2029 PDEBUG(D_ERR,
2030 "Can't determine sensor slave IDs");
2031 goto error;
2032 }
2033 if (ov8xx0_configure(sd) < 0) {
2034 PDEBUG(D_ERR,
2035 "Failed to configure OV8xx0 sensor");
2036 goto error;
2037 }
2038 } 3032 }
3033 /* Test for 3xxx / 2xxx */
3034 } else if (init_ov_sensor(sd, OV_HIRES_SID) >= 0) {
3035 if (ov_hires_configure(sd) < 0) {
3036 PDEBUG(D_ERR, "Failed to configure high res OV");
3037 goto error;
3038 }
3039 } else {
3040 PDEBUG(D_ERR, "Can't determine sensor slave IDs");
3041 goto error;
2039 } 3042 }
2040 3043
2041 cam = &gspca_dev->cam;
2042 switch (sd->bridge) { 3044 switch (sd->bridge) {
2043 case BRIDGE_OV511: 3045 case BRIDGE_OV511:
2044 case BRIDGE_OV511PLUS: 3046 case BRIDGE_OV511PLUS:
@@ -2069,6 +3071,31 @@ static int sd_config(struct gspca_dev *gspca_dev,
2069 cam->nmodes = ARRAY_SIZE(ov519_sif_mode); 3071 cam->nmodes = ARRAY_SIZE(ov519_sif_mode);
2070 } 3072 }
2071 break; 3073 break;
3074 case BRIDGE_OVFX2:
3075 if (sd->sensor == SEN_OV2610) {
3076 cam->cam_mode = ovfx2_ov2610_mode;
3077 cam->nmodes = ARRAY_SIZE(ovfx2_ov2610_mode);
3078 } else if (sd->sensor == SEN_OV3610) {
3079 cam->cam_mode = ovfx2_ov3610_mode;
3080 cam->nmodes = ARRAY_SIZE(ovfx2_ov3610_mode);
3081 } else if (!sd->sif) {
3082 cam->cam_mode = ov519_vga_mode;
3083 cam->nmodes = ARRAY_SIZE(ov519_vga_mode);
3084 } else {
3085 cam->cam_mode = ov519_sif_mode;
3086 cam->nmodes = ARRAY_SIZE(ov519_sif_mode);
3087 }
3088 break;
3089 case BRIDGE_W9968CF:
3090 cam->cam_mode = w9968cf_vga_mode;
3091 cam->nmodes = ARRAY_SIZE(w9968cf_vga_mode);
3092 if (sd->sif)
3093 cam->nmodes--;
3094
3095 /* w9968cf needs initialisation once the sensor is known */
3096 if (w9968cf_init(sd) < 0)
3097 goto error;
3098 break;
2072 } 3099 }
2073 sd->brightness = BRIGHTNESS_DEF; 3100 sd->brightness = BRIGHTNESS_DEF;
2074 if (sd->sensor == SEN_OV6630 || sd->sensor == SEN_OV66308AF) 3101 if (sd->sensor == SEN_OV6630 || sd->sensor == SEN_OV66308AF)
@@ -2087,11 +3114,15 @@ static int sd_config(struct gspca_dev *gspca_dev,
2087 gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX) | 3114 gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX) |
2088 (1 << OV7670_FREQ_IDX); 3115 (1 << OV7670_FREQ_IDX);
2089 } 3116 }
3117 sd->quality = QUALITY_DEF;
2090 if (sd->sensor == SEN_OV7640 || sd->sensor == SEN_OV7670) 3118 if (sd->sensor == SEN_OV7640 || sd->sensor == SEN_OV7670)
2091 gspca_dev->ctrl_dis |= 1 << AUTOBRIGHT_IDX; 3119 gspca_dev->ctrl_dis |= 1 << AUTOBRIGHT_IDX;
2092 /* OV8610 Frequency filter control should work but needs testing */ 3120 /* OV8610 Frequency filter control should work but needs testing */
2093 if (sd->sensor == SEN_OV8610) 3121 if (sd->sensor == SEN_OV8610)
2094 gspca_dev->ctrl_dis |= 1 << FREQ_IDX; 3122 gspca_dev->ctrl_dis |= 1 << FREQ_IDX;
3123 /* No controls for the OV2610/OV3610 */
3124 if (sd->sensor == SEN_OV2610 || sd->sensor == SEN_OV3610)
3125 gspca_dev->ctrl_dis |= 0xFF;
2095 3126
2096 return 0; 3127 return 0;
2097error: 3128error:
@@ -2106,6 +3137,20 @@ static int sd_init(struct gspca_dev *gspca_dev)
2106 3137
2107 /* initialize the sensor */ 3138 /* initialize the sensor */
2108 switch (sd->sensor) { 3139 switch (sd->sensor) {
3140 case SEN_OV2610:
3141 if (write_i2c_regvals(sd, norm_2610, ARRAY_SIZE(norm_2610)))
3142 return -EIO;
3143 /* Enable autogain, autoexpo, awb, bandfilter */
3144 if (i2c_w_mask(sd, 0x13, 0x27, 0x27) < 0)
3145 return -EIO;
3146 break;
3147 case SEN_OV3610:
3148 if (write_i2c_regvals(sd, norm_3620b, ARRAY_SIZE(norm_3620b)))
3149 return -EIO;
3150 /* Enable autogain, autoexpo, awb, bandfilter */
3151 if (i2c_w_mask(sd, 0x13, 0x27, 0x27) < 0)
3152 return -EIO;
3153 break;
2109 case SEN_OV6620: 3154 case SEN_OV6620:
2110 if (write_i2c_regvals(sd, norm_6x20, ARRAY_SIZE(norm_6x20))) 3155 if (write_i2c_regvals(sd, norm_6x20, ARRAY_SIZE(norm_6x20)))
2111 return -EIO; 3156 return -EIO;
@@ -2548,19 +3593,60 @@ static int ov519_mode_init_regs(struct sd *sd)
2548static int mode_init_ov_sensor_regs(struct sd *sd) 3593static int mode_init_ov_sensor_regs(struct sd *sd)
2549{ 3594{
2550 struct gspca_dev *gspca_dev; 3595 struct gspca_dev *gspca_dev;
2551 int qvga; 3596 int qvga, xstart, xend, ystart, yend;
3597 __u8 v;
2552 3598
2553 gspca_dev = &sd->gspca_dev; 3599 gspca_dev = &sd->gspca_dev;
2554 qvga = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv & 1; 3600 qvga = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv & 1;
2555 3601
2556 /******** Mode (VGA/QVGA) and sensor specific regs ********/ 3602 /******** Mode (VGA/QVGA) and sensor specific regs ********/
2557 switch (sd->sensor) { 3603 switch (sd->sensor) {
3604 case SEN_OV2610:
3605 i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
3606 i2c_w_mask(sd, 0x28, qvga ? 0x00 : 0x20, 0x20);
3607 i2c_w(sd, 0x24, qvga ? 0x20 : 0x3a);
3608 i2c_w(sd, 0x25, qvga ? 0x30 : 0x60);
3609 i2c_w_mask(sd, 0x2d, qvga ? 0x40 : 0x00, 0x40);
3610 i2c_w_mask(sd, 0x67, qvga ? 0xf0 : 0x90, 0xf0);
3611 i2c_w_mask(sd, 0x74, qvga ? 0x20 : 0x00, 0x20);
3612 return 0;
3613 case SEN_OV3610:
3614 if (qvga) {
3615 xstart = (1040 - gspca_dev->width) / 2 + (0x1f << 4);
3616 ystart = (776 - gspca_dev->height) / 2;
3617 } else {
3618 xstart = (2076 - gspca_dev->width) / 2 + (0x10 << 4);
3619 ystart = (1544 - gspca_dev->height) / 2;
3620 }
3621 xend = xstart + gspca_dev->width;
3622 yend = ystart + gspca_dev->height;
3623 /* Writing to the COMH register resets the other windowing regs
3624 to their default values, so we must do this first. */
3625 i2c_w_mask(sd, 0x12, qvga ? 0x40 : 0x00, 0xf0);
3626 i2c_w_mask(sd, 0x32,
3627 (((xend >> 1) & 7) << 3) | ((xstart >> 1) & 7),
3628 0x3f);
3629 i2c_w_mask(sd, 0x03,
3630 (((yend >> 1) & 3) << 2) | ((ystart >> 1) & 3),
3631 0x0f);
3632 i2c_w(sd, 0x17, xstart >> 4);
3633 i2c_w(sd, 0x18, xend >> 4);
3634 i2c_w(sd, 0x19, ystart >> 3);
3635 i2c_w(sd, 0x1a, yend >> 3);
3636 return 0;
2558 case SEN_OV8610: 3637 case SEN_OV8610:
2559 /* For OV8610 qvga means qsvga */ 3638 /* For OV8610 qvga means qsvga */
2560 i2c_w_mask(sd, OV7610_REG_COM_C, qvga ? (1 << 5) : 0, 1 << 5); 3639 i2c_w_mask(sd, OV7610_REG_COM_C, qvga ? (1 << 5) : 0, 1 << 5);
3640 i2c_w_mask(sd, 0x13, 0x00, 0x20); /* Select 16 bit data bus */
3641 i2c_w_mask(sd, 0x12, 0x04, 0x06); /* AWB: 1 Test pattern: 0 */
3642 i2c_w_mask(sd, 0x2d, 0x00, 0x40); /* from windrv 090403 */
3643 i2c_w_mask(sd, 0x28, 0x20, 0x20); /* progressive mode on */
2561 break; 3644 break;
2562 case SEN_OV7610: 3645 case SEN_OV7610:
2563 i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20); 3646 i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
3647 i2c_w(sd, 0x35, qvga?0x1e:0x9e);
3648 i2c_w_mask(sd, 0x13, 0x00, 0x20); /* Select 16 bit data bus */
3649 i2c_w_mask(sd, 0x12, 0x04, 0x06); /* AWB: 1 Test pattern: 0 */
2564 break; 3650 break;
2565 case SEN_OV7620: 3651 case SEN_OV7620:
2566 case SEN_OV76BE: 3652 case SEN_OV76BE:
@@ -2571,6 +3657,10 @@ static int mode_init_ov_sensor_regs(struct sd *sd)
2571 i2c_w_mask(sd, 0x2d, qvga ? 0x40 : 0x00, 0x40); 3657 i2c_w_mask(sd, 0x2d, qvga ? 0x40 : 0x00, 0x40);
2572 i2c_w_mask(sd, 0x67, qvga ? 0xb0 : 0x90, 0xf0); 3658 i2c_w_mask(sd, 0x67, qvga ? 0xb0 : 0x90, 0xf0);
2573 i2c_w_mask(sd, 0x74, qvga ? 0x20 : 0x00, 0x20); 3659 i2c_w_mask(sd, 0x74, qvga ? 0x20 : 0x00, 0x20);
3660 i2c_w_mask(sd, 0x13, 0x00, 0x20); /* Select 16 bit data bus */
3661 i2c_w_mask(sd, 0x12, 0x04, 0x06); /* AWB: 1 Test pattern: 0 */
3662 if (sd->sensor == SEN_OV76BE)
3663 i2c_w(sd, 0x35, qvga ? 0x1e : 0x9e);
2574 break; 3664 break;
2575 case SEN_OV7640: 3665 case SEN_OV7640:
2576 i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20); 3666 i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
@@ -2580,6 +3670,7 @@ static int mode_init_ov_sensor_regs(struct sd *sd)
2580/* i2c_w_mask(sd, 0x2d, qvga ? 0x40 : 0x00, 0x40); */ 3670/* i2c_w_mask(sd, 0x2d, qvga ? 0x40 : 0x00, 0x40); */
2581/* i2c_w_mask(sd, 0x67, qvga ? 0xf0 : 0x90, 0xf0); */ 3671/* i2c_w_mask(sd, 0x67, qvga ? 0xf0 : 0x90, 0xf0); */
2582/* i2c_w_mask(sd, 0x74, qvga ? 0x20 : 0x00, 0x20); */ 3672/* i2c_w_mask(sd, 0x74, qvga ? 0x20 : 0x00, 0x20); */
3673 i2c_w_mask(sd, 0x12, 0x04, 0x04); /* AWB: 1 */
2583 break; 3674 break;
2584 case SEN_OV7670: 3675 case SEN_OV7670:
2585 /* set COM7_FMT_VGA or COM7_FMT_QVGA 3676 /* set COM7_FMT_VGA or COM7_FMT_QVGA
@@ -2588,55 +3679,56 @@ static int mode_init_ov_sensor_regs(struct sd *sd)
2588 i2c_w_mask(sd, OV7670_REG_COM7, 3679 i2c_w_mask(sd, OV7670_REG_COM7,
2589 qvga ? OV7670_COM7_FMT_QVGA : OV7670_COM7_FMT_VGA, 3680 qvga ? OV7670_COM7_FMT_QVGA : OV7670_COM7_FMT_VGA,
2590 OV7670_COM7_FMT_MASK); 3681 OV7670_COM7_FMT_MASK);
3682 i2c_w_mask(sd, 0x13, 0x00, 0x20); /* Select 16 bit data bus */
3683 i2c_w_mask(sd, OV7670_REG_COM8, OV7670_COM8_AWB,
3684 OV7670_COM8_AWB);
3685 if (qvga) { /* QVGA from ov7670.c by
3686 * Jonathan Corbet */
3687 xstart = 164;
3688 xend = 28;
3689 ystart = 14;
3690 yend = 494;
3691 } else { /* VGA */
3692 xstart = 158;
3693 xend = 14;
3694 ystart = 10;
3695 yend = 490;
3696 }
3697 /* OV7670 hardware window registers are split across
3698 * multiple locations */
3699 i2c_w(sd, OV7670_REG_HSTART, xstart >> 3);
3700 i2c_w(sd, OV7670_REG_HSTOP, xend >> 3);
3701 v = i2c_r(sd, OV7670_REG_HREF);
3702 v = (v & 0xc0) | ((xend & 0x7) << 3) | (xstart & 0x07);
3703 msleep(10); /* need to sleep between read and write to
3704 * same reg! */
3705 i2c_w(sd, OV7670_REG_HREF, v);
3706
3707 i2c_w(sd, OV7670_REG_VSTART, ystart >> 2);
3708 i2c_w(sd, OV7670_REG_VSTOP, yend >> 2);
3709 v = i2c_r(sd, OV7670_REG_VREF);
3710 v = (v & 0xc0) | ((yend & 0x3) << 2) | (ystart & 0x03);
3711 msleep(10); /* need to sleep between read and write to
3712 * same reg! */
3713 i2c_w(sd, OV7670_REG_VREF, v);
2591 break; 3714 break;
2592 case SEN_OV6620: 3715 case SEN_OV6620:
3716 i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
3717 i2c_w_mask(sd, 0x13, 0x00, 0x20); /* Select 16 bit data bus */
3718 i2c_w_mask(sd, 0x12, 0x04, 0x06); /* AWB: 1 Test pattern: 0 */
3719 break;
2593 case SEN_OV6630: 3720 case SEN_OV6630:
2594 case SEN_OV66308AF: 3721 case SEN_OV66308AF:
2595 i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20); 3722 i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
3723 i2c_w_mask(sd, 0x12, 0x04, 0x06); /* AWB: 1 Test pattern: 0 */
2596 break; 3724 break;
2597 default: 3725 default:
2598 return -EINVAL; 3726 return -EINVAL;
2599 } 3727 }
2600 3728
2601 /******** Palette-specific regs ********/
2602
2603 /* The OV518 needs special treatment. Although both the OV518
2604 * and the OV6630 support a 16-bit video bus, only the 8 bit Y
2605 * bus is actually used. The UV bus is tied to ground.
2606 * Therefore, the OV6630 needs to be in 8-bit multiplexed
2607 * output mode */
2608
2609 /* OV7640 is 8-bit only */
2610
2611 if (sd->sensor != SEN_OV6630 && sd->sensor != SEN_OV66308AF &&
2612 sd->sensor != SEN_OV7640)
2613 i2c_w_mask(sd, 0x13, 0x00, 0x20);
2614
2615 /******** Clock programming ********/ 3729 /******** Clock programming ********/
2616 i2c_w(sd, 0x11, sd->clockdiv); 3730 i2c_w(sd, 0x11, sd->clockdiv);
2617 3731
2618 /******** Special Features ********/
2619/* no evidence this is possible with OV7670, either */
2620 /* Test Pattern */
2621 if (sd->sensor != SEN_OV7640 && sd->sensor != SEN_OV7670)
2622 i2c_w_mask(sd, 0x12, 0x00, 0x02);
2623
2624 /* Enable auto white balance */
2625 if (sd->sensor == SEN_OV7670)
2626 i2c_w_mask(sd, OV7670_REG_COM8, OV7670_COM8_AWB,
2627 OV7670_COM8_AWB);
2628 else
2629 i2c_w_mask(sd, 0x12, 0x04, 0x04);
2630
2631 /* This will go away as soon as ov51x_mode_init_sensor_regs() */
2632 /* is fully tested. */
2633 /* 7620/6620/6630? don't have register 0x35, so play it safe */
2634 if (sd->sensor == SEN_OV7610 || sd->sensor == SEN_OV76BE) {
2635 if (!qvga)
2636 i2c_w(sd, 0x35, 0x9e);
2637 else
2638 i2c_w(sd, 0x35, 0x1e);
2639 }
2640 return 0; 3732 return 0;
2641} 3733}
2642 3734
@@ -2659,8 +3751,12 @@ static int set_ov_sensor_window(struct sd *sd)
2659 struct gspca_dev *gspca_dev; 3751 struct gspca_dev *gspca_dev;
2660 int qvga, crop; 3752 int qvga, crop;
2661 int hwsbase, hwebase, vwsbase, vwebase, hwscale, vwscale; 3753 int hwsbase, hwebase, vwsbase, vwebase, hwscale, vwscale;
2662 int ret, hstart, hstop, vstop, vstart; 3754 int ret;
2663 __u8 v; 3755
3756 /* mode setup is fully handled in mode_init_ov_sensor_regs for these */
3757 if (sd->sensor == SEN_OV2610 || sd->sensor == SEN_OV3610 ||
3758 sd->sensor == SEN_OV7670)
3759 return mode_init_ov_sensor_regs(sd);
2664 3760
2665 gspca_dev = &sd->gspca_dev; 3761 gspca_dev = &sd->gspca_dev;
2666 qvga = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv & 1; 3762 qvga = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv & 1;
@@ -2708,11 +3804,6 @@ static int set_ov_sensor_window(struct sd *sd)
2708 hwebase = 0x1a; 3804 hwebase = 0x1a;
2709 vwsbase = vwebase = 0x03; 3805 vwsbase = vwebase = 0x03;
2710 break; 3806 break;
2711 case SEN_OV7670:
2712 /*handling of OV7670 hardware sensor start and stop values
2713 * is very odd, compared to the other OV sensors */
2714 vwsbase = vwebase = hwebase = hwsbase = 0x00;
2715 break;
2716 default: 3807 default:
2717 return -EINVAL; 3808 return -EINVAL;
2718 } 3809 }
@@ -2753,58 +3844,11 @@ static int set_ov_sensor_window(struct sd *sd)
2753 if (ret < 0) 3844 if (ret < 0)
2754 return ret; 3845 return ret;
2755 3846
2756 if (sd->sensor == SEN_OV8610) { 3847 i2c_w(sd, 0x17, hwsbase);
2757 i2c_w_mask(sd, 0x2d, 0x05, 0x40); 3848 i2c_w(sd, 0x18, hwebase + (sd->sensor_width >> hwscale));
2758 /* old 0x95, new 0x05 from windrv 090403 */ 3849 i2c_w(sd, 0x19, vwsbase);
2759 /* bits 5-7: reserved */ 3850 i2c_w(sd, 0x1a, vwebase + (sd->sensor_height >> vwscale));
2760 i2c_w_mask(sd, 0x28, 0x20, 0x20);
2761 /* bit 5: progressive mode on */
2762 }
2763
2764 /* The below is wrong for OV7670s because their window registers
2765 * only store the high bits in 0x17 to 0x1a */
2766
2767 /* SRH Use sd->max values instead of requested win values */
2768 /* SCS Since we're sticking with only the max hardware widths
2769 * for a given mode */
2770 /* I can hard code this for OV7670s */
2771 /* Yes, these numbers do look odd, but they're tested and work! */
2772 if (sd->sensor == SEN_OV7670) {
2773 if (qvga) { /* QVGA from ov7670.c by
2774 * Jonathan Corbet */
2775 hstart = 164;
2776 hstop = 28;
2777 vstart = 14;
2778 vstop = 494;
2779 } else { /* VGA */
2780 hstart = 158;
2781 hstop = 14;
2782 vstart = 10;
2783 vstop = 490;
2784 }
2785 /* OV7670 hardware window registers are split across
2786 * multiple locations */
2787 i2c_w(sd, OV7670_REG_HSTART, hstart >> 3);
2788 i2c_w(sd, OV7670_REG_HSTOP, hstop >> 3);
2789 v = i2c_r(sd, OV7670_REG_HREF);
2790 v = (v & 0xc0) | ((hstop & 0x7) << 3) | (hstart & 0x07);
2791 msleep(10); /* need to sleep between read and write to
2792 * same reg! */
2793 i2c_w(sd, OV7670_REG_HREF, v);
2794 3851
2795 i2c_w(sd, OV7670_REG_VSTART, vstart >> 2);
2796 i2c_w(sd, OV7670_REG_VSTOP, vstop >> 2);
2797 v = i2c_r(sd, OV7670_REG_VREF);
2798 v = (v & 0xc0) | ((vstop & 0x3) << 2) | (vstart & 0x03);
2799 msleep(10); /* need to sleep between read and write to
2800 * same reg! */
2801 i2c_w(sd, OV7670_REG_VREF, v);
2802 } else {
2803 i2c_w(sd, 0x17, hwsbase);
2804 i2c_w(sd, 0x18, hwebase + (sd->gspca_dev.width >> hwscale));
2805 i2c_w(sd, 0x19, vwsbase);
2806 i2c_w(sd, 0x1a, vwebase + (sd->gspca_dev.height >> vwscale));
2807 }
2808 return 0; 3852 return 0;
2809} 3853}
2810 3854
@@ -2814,6 +3858,10 @@ static int sd_start(struct gspca_dev *gspca_dev)
2814 struct sd *sd = (struct sd *) gspca_dev; 3858 struct sd *sd = (struct sd *) gspca_dev;
2815 int ret = 0; 3859 int ret = 0;
2816 3860
3861 /* Default for most bridges, allow bridge_mode_init_regs to override */
3862 sd->sensor_width = sd->gspca_dev.width;
3863 sd->sensor_height = sd->gspca_dev.height;
3864
2817 switch (sd->bridge) { 3865 switch (sd->bridge) {
2818 case BRIDGE_OV511: 3866 case BRIDGE_OV511:
2819 case BRIDGE_OV511PLUS: 3867 case BRIDGE_OV511PLUS:
@@ -2826,6 +3874,10 @@ static int sd_start(struct gspca_dev *gspca_dev)
2826 case BRIDGE_OV519: 3874 case BRIDGE_OV519:
2827 ret = ov519_mode_init_regs(sd); 3875 ret = ov519_mode_init_regs(sd);
2828 break; 3876 break;
3877 /* case BRIDGE_OVFX2: nothing to do */
3878 case BRIDGE_W9968CF:
3879 ret = w9968cf_mode_init_regs(sd);
3880 break;
2829 } 3881 }
2830 if (ret < 0) 3882 if (ret < 0)
2831 goto out; 3883 goto out;
@@ -2859,10 +3911,17 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
2859 ov51x_led_control(sd, 0); 3911 ov51x_led_control(sd, 0);
2860} 3912}
2861 3913
3914static void sd_stop0(struct gspca_dev *gspca_dev)
3915{
3916 struct sd *sd = (struct sd *) gspca_dev;
3917
3918 if (sd->bridge == BRIDGE_W9968CF)
3919 w9968cf_stop0(sd);
3920}
3921
2862static void ov511_pkt_scan(struct gspca_dev *gspca_dev, 3922static void ov511_pkt_scan(struct gspca_dev *gspca_dev,
2863 struct gspca_frame *frame, /* target */ 3923 u8 *in, /* isoc packet */
2864 __u8 *in, /* isoc packet */ 3924 int len) /* iso packet length */
2865 int len) /* iso packet length */
2866{ 3925{
2867 struct sd *sd = (struct sd *) gspca_dev; 3926 struct sd *sd = (struct sd *) gspca_dev;
2868 3927
@@ -2893,11 +3952,11 @@ static void ov511_pkt_scan(struct gspca_dev *gspca_dev,
2893 return; 3952 return;
2894 } 3953 }
2895 /* Add 11 byte footer to frame, might be usefull */ 3954 /* Add 11 byte footer to frame, might be usefull */
2896 gspca_frame_add(gspca_dev, LAST_PACKET, frame, in, 11); 3955 gspca_frame_add(gspca_dev, LAST_PACKET, in, 11);
2897 return; 3956 return;
2898 } else { 3957 } else {
2899 /* Frame start */ 3958 /* Frame start */
2900 gspca_frame_add(gspca_dev, FIRST_PACKET, frame, in, 0); 3959 gspca_frame_add(gspca_dev, FIRST_PACKET, in, 0);
2901 sd->packet_nr = 0; 3960 sd->packet_nr = 0;
2902 } 3961 }
2903 } 3962 }
@@ -2906,12 +3965,11 @@ static void ov511_pkt_scan(struct gspca_dev *gspca_dev,
2906 len--; 3965 len--;
2907 3966
2908 /* intermediate packet */ 3967 /* intermediate packet */
2909 gspca_frame_add(gspca_dev, INTER_PACKET, frame, in, len); 3968 gspca_frame_add(gspca_dev, INTER_PACKET, in, len);
2910} 3969}
2911 3970
2912static void ov518_pkt_scan(struct gspca_dev *gspca_dev, 3971static void ov518_pkt_scan(struct gspca_dev *gspca_dev,
2913 struct gspca_frame *frame, /* target */ 3972 u8 *data, /* isoc packet */
2914 __u8 *data, /* isoc packet */
2915 int len) /* iso packet length */ 3973 int len) /* iso packet length */
2916{ 3974{
2917 struct sd *sd = (struct sd *) gspca_dev; 3975 struct sd *sd = (struct sd *) gspca_dev;
@@ -2919,8 +3977,8 @@ static void ov518_pkt_scan(struct gspca_dev *gspca_dev,
2919 /* A false positive here is likely, until OVT gives me 3977 /* A false positive here is likely, until OVT gives me
2920 * the definitive SOF/EOF format */ 3978 * the definitive SOF/EOF format */
2921 if ((!(data[0] | data[1] | data[2] | data[3] | data[5])) && data[6]) { 3979 if ((!(data[0] | data[1] | data[2] | data[3] | data[5])) && data[6]) {
2922 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, data, 0); 3980 gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
2923 gspca_frame_add(gspca_dev, FIRST_PACKET, frame, data, 0); 3981 gspca_frame_add(gspca_dev, FIRST_PACKET, NULL, 0);
2924 sd->packet_nr = 0; 3982 sd->packet_nr = 0;
2925 } 3983 }
2926 3984
@@ -2944,12 +4002,11 @@ static void ov518_pkt_scan(struct gspca_dev *gspca_dev,
2944 } 4002 }
2945 4003
2946 /* intermediate packet */ 4004 /* intermediate packet */
2947 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); 4005 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
2948} 4006}
2949 4007
2950static void ov519_pkt_scan(struct gspca_dev *gspca_dev, 4008static void ov519_pkt_scan(struct gspca_dev *gspca_dev,
2951 struct gspca_frame *frame, /* target */ 4009 u8 *data, /* isoc packet */
2952 __u8 *data, /* isoc packet */
2953 int len) /* iso packet length */ 4010 int len) /* iso packet length */
2954{ 4011{
2955 /* Header of ov519 is 16 bytes: 4012 /* Header of ov519 is 16 bytes:
@@ -2972,7 +4029,7 @@ static void ov519_pkt_scan(struct gspca_dev *gspca_dev,
2972 len -= HDRSZ; 4029 len -= HDRSZ;
2973#undef HDRSZ 4030#undef HDRSZ
2974 if (data[0] == 0xff || data[1] == 0xd8) 4031 if (data[0] == 0xff || data[1] == 0xd8)
2975 gspca_frame_add(gspca_dev, FIRST_PACKET, frame, 4032 gspca_frame_add(gspca_dev, FIRST_PACKET,
2976 data, len); 4033 data, len);
2977 else 4034 else
2978 gspca_dev->last_packet_type = DISCARD_PACKET; 4035 gspca_dev->last_packet_type = DISCARD_PACKET;
@@ -2980,20 +4037,31 @@ static void ov519_pkt_scan(struct gspca_dev *gspca_dev,
2980 case 0x51: /* end of frame */ 4037 case 0x51: /* end of frame */
2981 if (data[9] != 0) 4038 if (data[9] != 0)
2982 gspca_dev->last_packet_type = DISCARD_PACKET; 4039 gspca_dev->last_packet_type = DISCARD_PACKET;
2983 gspca_frame_add(gspca_dev, LAST_PACKET, frame, 4040 gspca_frame_add(gspca_dev, LAST_PACKET,
2984 data, 0); 4041 NULL, 0);
2985 return; 4042 return;
2986 } 4043 }
2987 } 4044 }
2988 4045
2989 /* intermediate packet */ 4046 /* intermediate packet */
2990 gspca_frame_add(gspca_dev, INTER_PACKET, frame, 4047 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
2991 data, len); 4048}
4049
4050static void ovfx2_pkt_scan(struct gspca_dev *gspca_dev,
4051 u8 *data, /* isoc packet */
4052 int len) /* iso packet length */
4053{
4054 /* A short read signals EOF */
4055 if (len < OVFX2_BULK_SIZE) {
4056 gspca_frame_add(gspca_dev, LAST_PACKET, data, len);
4057 gspca_frame_add(gspca_dev, FIRST_PACKET, NULL, 0);
4058 return;
4059 }
4060 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
2992} 4061}
2993 4062
2994static void sd_pkt_scan(struct gspca_dev *gspca_dev, 4063static void sd_pkt_scan(struct gspca_dev *gspca_dev,
2995 struct gspca_frame *frame, /* target */ 4064 u8 *data, /* isoc packet */
2996 __u8 *data, /* isoc packet */
2997 int len) /* iso packet length */ 4065 int len) /* iso packet length */
2998{ 4066{
2999 struct sd *sd = (struct sd *) gspca_dev; 4067 struct sd *sd = (struct sd *) gspca_dev;
@@ -3001,14 +4069,20 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
3001 switch (sd->bridge) { 4069 switch (sd->bridge) {
3002 case BRIDGE_OV511: 4070 case BRIDGE_OV511:
3003 case BRIDGE_OV511PLUS: 4071 case BRIDGE_OV511PLUS:
3004 ov511_pkt_scan(gspca_dev, frame, data, len); 4072 ov511_pkt_scan(gspca_dev, data, len);
3005 break; 4073 break;
3006 case BRIDGE_OV518: 4074 case BRIDGE_OV518:
3007 case BRIDGE_OV518PLUS: 4075 case BRIDGE_OV518PLUS:
3008 ov518_pkt_scan(gspca_dev, frame, data, len); 4076 ov518_pkt_scan(gspca_dev, data, len);
3009 break; 4077 break;
3010 case BRIDGE_OV519: 4078 case BRIDGE_OV519:
3011 ov519_pkt_scan(gspca_dev, frame, data, len); 4079 ov519_pkt_scan(gspca_dev, data, len);
4080 break;
4081 case BRIDGE_OVFX2:
4082 ovfx2_pkt_scan(gspca_dev, data, len);
4083 break;
4084 case BRIDGE_W9968CF:
4085 w9968cf_pkt_scan(gspca_dev, data, len);
3012 break; 4086 break;
3013 } 4087 }
3014} 4088}
@@ -3124,7 +4198,8 @@ static void setcolors(struct gspca_dev *gspca_dev)
3124 4198
3125static void setautobrightness(struct sd *sd) 4199static void setautobrightness(struct sd *sd)
3126{ 4200{
3127 if (sd->sensor == SEN_OV7640 || sd->sensor == SEN_OV7670) 4201 if (sd->sensor == SEN_OV7640 || sd->sensor == SEN_OV7670 ||
4202 sd->sensor == SEN_OV2610 || sd->sensor == SEN_OV3610)
3128 return; 4203 return;
3129 4204
3130 i2c_w_mask(sd, 0x2d, sd->autobrightness ? 0x10 : 0x00, 0x10); 4205 i2c_w_mask(sd, 0x2d, sd->autobrightness ? 0x10 : 0x00, 0x10);
@@ -3132,6 +4207,9 @@ static void setautobrightness(struct sd *sd)
3132 4207
3133static void setfreq(struct sd *sd) 4208static void setfreq(struct sd *sd)
3134{ 4209{
4210 if (sd->sensor == SEN_OV2610 || sd->sensor == SEN_OV3610)
4211 return;
4212
3135 if (sd->sensor == SEN_OV7670) { 4213 if (sd->sensor == SEN_OV7670) {
3136 switch (sd->freq) { 4214 switch (sd->freq) {
3137 case 0: /* Banding filter disabled */ 4215 case 0: /* Banding filter disabled */
@@ -3301,8 +4379,12 @@ static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val)
3301 struct sd *sd = (struct sd *) gspca_dev; 4379 struct sd *sd = (struct sd *) gspca_dev;
3302 4380
3303 sd->freq = val; 4381 sd->freq = val;
3304 if (gspca_dev->streaming) 4382 if (gspca_dev->streaming) {
3305 setfreq(sd); 4383 setfreq(sd);
4384 /* Ugly but necessary */
4385 if (sd->bridge == BRIDGE_W9968CF)
4386 w9968cf_set_crop_window(sd);
4387 }
3306 return 0; 4388 return 0;
3307} 4389}
3308 4390
@@ -3343,6 +4425,45 @@ static int sd_querymenu(struct gspca_dev *gspca_dev,
3343 return -EINVAL; 4425 return -EINVAL;
3344} 4426}
3345 4427
4428static int sd_get_jcomp(struct gspca_dev *gspca_dev,
4429 struct v4l2_jpegcompression *jcomp)
4430{
4431 struct sd *sd = (struct sd *) gspca_dev;
4432
4433 if (sd->bridge != BRIDGE_W9968CF)
4434 return -EINVAL;
4435
4436 memset(jcomp, 0, sizeof *jcomp);
4437 jcomp->quality = sd->quality;
4438 jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT | V4L2_JPEG_MARKER_DQT |
4439 V4L2_JPEG_MARKER_DRI;
4440 return 0;
4441}
4442
4443static int sd_set_jcomp(struct gspca_dev *gspca_dev,
4444 struct v4l2_jpegcompression *jcomp)
4445{
4446 struct sd *sd = (struct sd *) gspca_dev;
4447
4448 if (sd->bridge != BRIDGE_W9968CF)
4449 return -EINVAL;
4450
4451 if (gspca_dev->streaming)
4452 return -EBUSY;
4453
4454 if (jcomp->quality < QUALITY_MIN)
4455 sd->quality = QUALITY_MIN;
4456 else if (jcomp->quality > QUALITY_MAX)
4457 sd->quality = QUALITY_MAX;
4458 else
4459 sd->quality = jcomp->quality;
4460
4461 /* Return resulting jcomp params to app */
4462 sd_get_jcomp(gspca_dev, jcomp);
4463
4464 return 0;
4465}
4466
3346/* sub-driver description */ 4467/* sub-driver description */
3347static const struct sd_desc sd_desc = { 4468static const struct sd_desc sd_desc = {
3348 .name = MODULE_NAME, 4469 .name = MODULE_NAME,
@@ -3352,18 +4473,23 @@ static const struct sd_desc sd_desc = {
3352 .init = sd_init, 4473 .init = sd_init,
3353 .start = sd_start, 4474 .start = sd_start,
3354 .stopN = sd_stopN, 4475 .stopN = sd_stopN,
4476 .stop0 = sd_stop0,
3355 .pkt_scan = sd_pkt_scan, 4477 .pkt_scan = sd_pkt_scan,
3356 .querymenu = sd_querymenu, 4478 .querymenu = sd_querymenu,
4479 .get_jcomp = sd_get_jcomp,
4480 .set_jcomp = sd_set_jcomp,
3357}; 4481};
3358 4482
3359/* -- module initialisation -- */ 4483/* -- module initialisation -- */
3360static const __devinitdata struct usb_device_id device_table[] = { 4484static const __devinitdata struct usb_device_id device_table[] = {
4485 {USB_DEVICE(0x041e, 0x4003), .driver_info = BRIDGE_W9968CF },
3361 {USB_DEVICE(0x041e, 0x4052), .driver_info = BRIDGE_OV519 }, 4486 {USB_DEVICE(0x041e, 0x4052), .driver_info = BRIDGE_OV519 },
3362 {USB_DEVICE(0x041e, 0x405f), .driver_info = BRIDGE_OV519 }, 4487 {USB_DEVICE(0x041e, 0x405f), .driver_info = BRIDGE_OV519 },
3363 {USB_DEVICE(0x041e, 0x4060), .driver_info = BRIDGE_OV519 }, 4488 {USB_DEVICE(0x041e, 0x4060), .driver_info = BRIDGE_OV519 },
3364 {USB_DEVICE(0x041e, 0x4061), .driver_info = BRIDGE_OV519 }, 4489 {USB_DEVICE(0x041e, 0x4061), .driver_info = BRIDGE_OV519 },
3365 {USB_DEVICE(0x041e, 0x4064), 4490 {USB_DEVICE(0x041e, 0x4064),
3366 .driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED }, 4491 .driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED },
4492 {USB_DEVICE(0x041e, 0x4067), .driver_info = BRIDGE_OV519 },
3367 {USB_DEVICE(0x041e, 0x4068), 4493 {USB_DEVICE(0x041e, 0x4068),
3368 .driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED }, 4494 .driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED },
3369 {USB_DEVICE(0x045e, 0x028c), .driver_info = BRIDGE_OV519 }, 4495 {USB_DEVICE(0x045e, 0x028c), .driver_info = BRIDGE_OV519 },
@@ -3373,11 +4499,16 @@ static const __devinitdata struct usb_device_id device_table[] = {
3373 {USB_DEVICE(0x05a9, 0x0518), .driver_info = BRIDGE_OV518 }, 4499 {USB_DEVICE(0x05a9, 0x0518), .driver_info = BRIDGE_OV518 },
3374 {USB_DEVICE(0x05a9, 0x0519), .driver_info = BRIDGE_OV519 }, 4500 {USB_DEVICE(0x05a9, 0x0519), .driver_info = BRIDGE_OV519 },
3375 {USB_DEVICE(0x05a9, 0x0530), .driver_info = BRIDGE_OV519 }, 4501 {USB_DEVICE(0x05a9, 0x0530), .driver_info = BRIDGE_OV519 },
4502 {USB_DEVICE(0x05a9, 0x2800), .driver_info = BRIDGE_OVFX2 },
3376 {USB_DEVICE(0x05a9, 0x4519), .driver_info = BRIDGE_OV519 }, 4503 {USB_DEVICE(0x05a9, 0x4519), .driver_info = BRIDGE_OV519 },
3377 {USB_DEVICE(0x05a9, 0x8519), .driver_info = BRIDGE_OV519 }, 4504 {USB_DEVICE(0x05a9, 0x8519), .driver_info = BRIDGE_OV519 },
3378 {USB_DEVICE(0x05a9, 0xa511), .driver_info = BRIDGE_OV511PLUS }, 4505 {USB_DEVICE(0x05a9, 0xa511), .driver_info = BRIDGE_OV511PLUS },
3379 {USB_DEVICE(0x05a9, 0xa518), .driver_info = BRIDGE_OV518PLUS }, 4506 {USB_DEVICE(0x05a9, 0xa518), .driver_info = BRIDGE_OV518PLUS },
3380 {USB_DEVICE(0x0813, 0x0002), .driver_info = BRIDGE_OV511PLUS }, 4507 {USB_DEVICE(0x0813, 0x0002), .driver_info = BRIDGE_OV511PLUS },
4508 {USB_DEVICE(0x0b62, 0x0059), .driver_info = BRIDGE_OVFX2 },
4509 {USB_DEVICE(0x0e96, 0xc001), .driver_info = BRIDGE_OVFX2 },
4510 {USB_DEVICE(0x1046, 0x9967), .driver_info = BRIDGE_W9968CF },
4511 {USB_DEVICE(0x8020, 0xEF04), .driver_info = BRIDGE_OVFX2 },
3381 {} 4512 {}
3382}; 4513};
3383 4514
diff --git a/drivers/media/video/gspca/ov534.c b/drivers/media/video/gspca/ov534.c
index 4b528b372911..4dbb882c83dc 100644
--- a/drivers/media/video/gspca/ov534.c
+++ b/drivers/media/video/gspca/ov534.c
@@ -1,5 +1,6 @@
1/* 1/*
2 * ov534 gspca driver 2 * ov534 gspca driver
3 *
3 * Copyright (C) 2008 Antonio Ospite <ospite@studenti.unina.it> 4 * Copyright (C) 2008 Antonio Ospite <ospite@studenti.unina.it>
4 * Copyright (C) 2008 Jim Paris <jim@jtan.com> 5 * Copyright (C) 2008 Jim Paris <jim@jtan.com>
5 * Copyright (C) 2009 Jean-Francois Moine http://moinejf.free.fr 6 * Copyright (C) 2009 Jean-Francois Moine http://moinejf.free.fr
@@ -8,6 +9,10 @@
8 * USB protocol reverse engineered by Jim Paris <jim@jtan.com> 9 * USB protocol reverse engineered by Jim Paris <jim@jtan.com>
9 * https://jim.sh/svn/jim/devl/playstation/ps3/eye/test/ 10 * https://jim.sh/svn/jim/devl/playstation/ps3/eye/test/
10 * 11 *
12 * PS3 Eye camera enhanced by Richard Kaswy http://kaswy.free.fr
13 * PS3 Eye camera, brightness, contrast, hue, AWB control added
14 * by Max Thrun <bear24rw@gmail.com>
15 *
11 * This program is free software; you can redistribute it and/or modify 16 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by 17 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or 18 * the Free Software Foundation; either version 2 of the License, or
@@ -51,16 +56,335 @@ struct sd {
51 u16 last_fid; 56 u16 last_fid;
52 u8 frame_rate; 57 u8 frame_rate;
53 58
59 u8 brightness;
60 u8 contrast;
61 u8 gain;
62 u8 exposure;
63 u8 redblc;
64 u8 blueblc;
65 u8 hue;
66 u8 autogain;
67 u8 awb;
68 s8 sharpness;
69 u8 hflip;
70 u8 vflip;
71 u8 satur;
72 u8 lightfreq;
73
54 u8 sensor; 74 u8 sensor;
55#define SENSOR_OV772X 0 75#define SENSOR_OV772X 0
56#define SENSOR_OV965X 1 76#define SENSOR_OV965X 1
57}; 77};
58 78
59/* V4L2 controls supported by the driver */ 79/* V4L2 controls supported by the driver */
60static struct ctrl sd_ctrls[] = { 80static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val);
81static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val);
82static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val);
83static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val);
84static int sd_setredblc(struct gspca_dev *gspca_dev, __s32 val);
85static int sd_getredblc(struct gspca_dev *gspca_dev, __s32 *val);
86static int sd_setblueblc(struct gspca_dev *gspca_dev, __s32 val);
87static int sd_getblueblc(struct gspca_dev *gspca_dev, __s32 *val);
88static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
89static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
90static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val);
91static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val);
92static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val);
93static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val);
94static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val);
95static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val);
96static int sd_sethue(struct gspca_dev *gspca_dev, __s32 val);
97static int sd_gethue(struct gspca_dev *gspca_dev, __s32 *val);
98static int sd_setawb(struct gspca_dev *gspca_dev, __s32 val);
99static int sd_getawb(struct gspca_dev *gspca_dev, __s32 *val);
100static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
101static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
102static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
103static 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
109static struct ctrl sd_ctrls_ov772x[] = {
110 { /* 0 */
111 {
112 .id = V4L2_CID_BRIGHTNESS,
113 .type = V4L2_CTRL_TYPE_INTEGER,
114 .name = "Brightness",
115 .minimum = 0,
116 .maximum = 255,
117 .step = 1,
118#define BRIGHTNESS_77_DEF 20
119 .default_value = BRIGHTNESS_77_DEF,
120 },
121 .set = sd_setbrightness,
122 .get = sd_getbrightness,
123 },
124 { /* 1 */
125 {
126 .id = V4L2_CID_CONTRAST,
127 .type = V4L2_CTRL_TYPE_INTEGER,
128 .name = "Contrast",
129 .minimum = 0,
130 .maximum = 255,
131 .step = 1,
132#define CONTRAST_77_DEF 37
133 .default_value = CONTRAST_77_DEF,
134 },
135 .set = sd_setcontrast,
136 .get = sd_getcontrast,
137 },
138 { /* 2 */
139 {
140 .id = V4L2_CID_GAIN,
141 .type = V4L2_CTRL_TYPE_INTEGER,
142 .name = "Main Gain",
143 .minimum = 0,
144 .maximum = 63,
145 .step = 1,
146#define GAIN_DEF 20
147 .default_value = GAIN_DEF,
148 },
149 .set = sd_setgain,
150 .get = sd_getgain,
151 },
152 { /* 3 */
153 {
154 .id = V4L2_CID_EXPOSURE,
155 .type = V4L2_CTRL_TYPE_INTEGER,
156 .name = "Exposure",
157 .minimum = 0,
158 .maximum = 255,
159 .step = 1,
160#define EXPO_77_DEF 120
161 .default_value = EXPO_77_DEF,
162 },
163 .set = sd_setexposure,
164 .get = sd_getexposure,
165 },
166 { /* 4 */
167 {
168 .id = V4L2_CID_RED_BALANCE,
169 .type = V4L2_CTRL_TYPE_INTEGER,
170 .name = "Red Balance",
171 .minimum = 0,
172 .maximum = 255,
173 .step = 1,
174#define RED_BALANCE_DEF 128
175 .default_value = RED_BALANCE_DEF,
176 },
177 .set = sd_setredblc,
178 .get = sd_getredblc,
179 },
180 { /* 5 */
181 {
182 .id = V4L2_CID_BLUE_BALANCE,
183 .type = V4L2_CTRL_TYPE_INTEGER,
184 .name = "Blue Balance",
185 .minimum = 0,
186 .maximum = 255,
187 .step = 1,
188#define BLUE_BALANCE_DEF 128
189 .default_value = BLUE_BALANCE_DEF,
190 },
191 .set = sd_setblueblc,
192 .get = sd_getblueblc,
193 },
194 { /* 6 */
195 {
196 .id = V4L2_CID_HUE,
197 .type = V4L2_CTRL_TYPE_INTEGER,
198 .name = "Hue",
199 .minimum = 0,
200 .maximum = 255,
201 .step = 1,
202#define HUE_DEF 143
203 .default_value = HUE_DEF,
204 },
205 .set = sd_sethue,
206 .get = sd_gethue,
207 },
208 { /* 7 */
209 {
210 .id = V4L2_CID_AUTOGAIN,
211 .type = V4L2_CTRL_TYPE_BOOLEAN,
212 .name = "Autogain",
213 .minimum = 0,
214 .maximum = 1,
215 .step = 1,
216#define AUTOGAIN_77_DEF 0
217 .default_value = AUTOGAIN_77_DEF,
218 },
219 .set = sd_setautogain,
220 .get = sd_getautogain,
221 },
222#define AWB_77_IDX 8
223 { /* 8 */
224 {
225 .id = V4L2_CID_AUTO_WHITE_BALANCE,
226 .type = V4L2_CTRL_TYPE_BOOLEAN,
227 .name = "Auto White Balance",
228 .minimum = 0,
229 .maximum = 1,
230 .step = 1,
231#define AWB_DEF 0
232 .default_value = AWB_DEF,
233 },
234 .set = sd_setawb,
235 .get = sd_getawb,
236 },
237 { /* 9 */
238 {
239 .id = V4L2_CID_SHARPNESS,
240 .type = V4L2_CTRL_TYPE_INTEGER,
241 .name = "Sharpness",
242 .minimum = 0,
243 .maximum = 63,
244 .step = 1,
245#define SHARPNESS_77_DEF 0
246 .default_value = SHARPNESS_77_DEF,
247 },
248 .set = sd_setsharpness,
249 .get = sd_getsharpness,
250 },
251 { /* 10 */
252 {
253 .id = V4L2_CID_HFLIP,
254 .type = V4L2_CTRL_TYPE_BOOLEAN,
255 .name = "HFlip",
256 .minimum = 0,
257 .maximum = 1,
258 .step = 1,
259#define HFLIP_DEF 0
260 .default_value = HFLIP_DEF,
261 },
262 .set = sd_sethflip,
263 .get = sd_gethflip,
264 },
265 { /* 11 */
266 {
267 .id = V4L2_CID_VFLIP,
268 .type = V4L2_CTRL_TYPE_BOOLEAN,
269 .name = "VFlip",
270 .minimum = 0,
271 .maximum = 1,
272 .step = 1,
273#define VFLIP_DEF 0
274 .default_value = VFLIP_DEF,
275 },
276 .set = sd_setvflip,
277 .get = sd_getvflip,
278 },
279};
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 },
61}; 380};
62 381
63static const struct v4l2_pix_format vga_yuyv_mode[] = { 382static const struct v4l2_pix_format ov772x_mode[] = {
383 {320, 240, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE,
384 .bytesperline = 320 * 2,
385 .sizeimage = 320 * 240 * 2,
386 .colorspace = V4L2_COLORSPACE_SRGB,
387 .priv = 1},
64 {640, 480, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, 388 {640, 480, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE,
65 .bytesperline = 640 * 2, 389 .bytesperline = 640 * 2,
66 .sizeimage = 640 * 480 * 2, 390 .sizeimage = 640 * 480 * 2,
@@ -68,20 +392,35 @@ static const struct v4l2_pix_format vga_yuyv_mode[] = {
68 .priv = 0}, 392 .priv = 0},
69}; 393};
70 394
71static const struct v4l2_pix_format vga_jpeg_mode[] = { 395static const struct v4l2_pix_format ov965x_mode[] = {
72 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 396 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
73 .bytesperline = 320, 397 .bytesperline = 320,
74 .sizeimage = 320 * 240 * 3 / 8 + 590, 398 .sizeimage = 320 * 240 * 3 / 8 + 590,
75 .colorspace = V4L2_COLORSPACE_JPEG, 399 .colorspace = V4L2_COLORSPACE_JPEG,
76 .priv = 1}, 400 .priv = 4},
77 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 401 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
78 .bytesperline = 640, 402 .bytesperline = 640,
79 .sizeimage = 640 * 480 * 3 / 8 + 590, 403 .sizeimage = 640 * 480 * 3 / 8 + 590,
80 .colorspace = V4L2_COLORSPACE_JPEG, 404 .colorspace = V4L2_COLORSPACE_JPEG,
405 .priv = 3},
406 {800, 600, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
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,
81 .priv = 0}, 420 .priv = 0},
82}; 421};
83 422
84static const u8 bridge_init_ov722x[][2] = { 423static const u8 bridge_init_ov772x[][2] = {
85 { 0xc2, 0x0c }, 424 { 0xc2, 0x0c },
86 { 0x88, 0xf8 }, 425 { 0x88, 0xf8 },
87 { 0xc3, 0x69 }, 426 { 0xc3, 0x69 },
@@ -122,6 +461,7 @@ static const u8 bridge_init_ov722x[][2] = {
122 { 0x1d, 0x40 }, 461 { 0x1d, 0x40 },
123 { 0x1d, 0x02 }, /* payload size 0x0200 * 4 = 2048 bytes */ 462 { 0x1d, 0x02 }, /* payload size 0x0200 * 4 = 2048 bytes */
124 { 0x1d, 0x00 }, /* payload size */ 463 { 0x1d, 0x00 }, /* payload size */
464
125 { 0x1d, 0x02 }, /* frame size 0x025800 * 4 = 614400 */ 465 { 0x1d, 0x02 }, /* frame size 0x025800 * 4 = 614400 */
126 { 0x1d, 0x58 }, /* frame size */ 466 { 0x1d, 0x58 }, /* frame size */
127 { 0x1d, 0x00 }, /* frame size */ 467 { 0x1d, 0x00 }, /* frame size */
@@ -138,10 +478,20 @@ static const u8 bridge_init_ov722x[][2] = {
138 { 0xc1, 0x3c }, 478 { 0xc1, 0x3c },
139 { 0xc2, 0x0c }, 479 { 0xc2, 0x0c },
140}; 480};
141 481static const u8 sensor_init_ov772x[][2] = {
142static const u8 sensor_init_ov722x[][2] = {
143 { 0x12, 0x80 }, 482 { 0x12, 0x80 },
144 { 0x11, 0x01 }, 483 { 0x11, 0x01 },
484/*fixme: better have a delay?*/
485 { 0x11, 0x01 },
486 { 0x11, 0x01 },
487 { 0x11, 0x01 },
488 { 0x11, 0x01 },
489 { 0x11, 0x01 },
490 { 0x11, 0x01 },
491 { 0x11, 0x01 },
492 { 0x11, 0x01 },
493 { 0x11, 0x01 },
494 { 0x11, 0x01 },
145 495
146 { 0x3d, 0x03 }, 496 { 0x3d, 0x03 },
147 { 0x17, 0x26 }, 497 { 0x17, 0x26 },
@@ -154,10 +504,10 @@ static const u8 sensor_init_ov722x[][2] = {
154 { 0x65, 0x20 }, 504 { 0x65, 0x20 },
155 { 0x11, 0x01 }, 505 { 0x11, 0x01 },
156 { 0x42, 0x7f }, 506 { 0x42, 0x7f },
157 { 0x63, 0xe0 }, 507 { 0x63, 0xaa }, /* AWB - was e0 */
158 { 0x64, 0xff }, 508 { 0x64, 0xff },
159 { 0x66, 0x00 }, 509 { 0x66, 0x00 },
160 { 0x13, 0xf0 }, 510 { 0x13, 0xf0 }, /* com8 */
161 { 0x0d, 0x41 }, 511 { 0x0d, 0x41 },
162 { 0x0f, 0xc5 }, 512 { 0x0f, 0xc5 },
163 { 0x14, 0x11 }, 513 { 0x14, 0x11 },
@@ -170,7 +520,7 @@ static const u8 sensor_init_ov722x[][2] = {
170 { 0x2a, 0x00 }, 520 { 0x2a, 0x00 },
171 { 0x2b, 0x00 }, 521 { 0x2b, 0x00 },
172 { 0x6b, 0xaa }, 522 { 0x6b, 0xaa },
173 { 0x13, 0xff }, 523 { 0x13, 0xff }, /* AWB */
174 524
175 { 0x90, 0x05 }, 525 { 0x90, 0x05 },
176 { 0x91, 0x01 }, 526 { 0x91, 0x01 },
@@ -218,9 +568,51 @@ static const u8 sensor_init_ov722x[][2] = {
218 { 0x14, 0x41 }, 568 { 0x14, 0x41 },
219 { 0x0e, 0xcd }, 569 { 0x0e, 0xcd },
220 { 0xac, 0xbf }, 570 { 0xac, 0xbf },
221 { 0x8e, 0x00 }, 571 { 0x8e, 0x00 }, /* De-noise threshold */
222 { 0x0c, 0xd0 } 572 { 0x0c, 0xd0 }
223}; 573};
574static const u8 bridge_start_ov772x_vga[][2] = {
575 {0x1c, 0x00},
576 {0x1d, 0x40},
577 {0x1d, 0x02},
578 {0x1d, 0x00},
579 {0x1d, 0x02},
580 {0x1d, 0x58},
581 {0x1d, 0x00},
582 {0xc0, 0x50},
583 {0xc1, 0x3c},
584};
585static const u8 sensor_start_ov772x_vga[][2] = {
586 {0x12, 0x00},
587 {0x17, 0x26},
588 {0x18, 0xa0},
589 {0x19, 0x07},
590 {0x1a, 0xf0},
591 {0x29, 0xa0},
592 {0x2c, 0xf0},
593 {0x65, 0x20},
594};
595static const u8 bridge_start_ov772x_qvga[][2] = {
596 {0x1c, 0x00},
597 {0x1d, 0x40},
598 {0x1d, 0x02},
599 {0x1d, 0x00},
600 {0x1d, 0x01},
601 {0x1d, 0x4b},
602 {0x1d, 0x00},
603 {0xc0, 0x28},
604 {0xc1, 0x1e},
605};
606static const u8 sensor_start_ov772x_qvga[][2] = {
607 {0x12, 0x40},
608 {0x17, 0x3f},
609 {0x18, 0x50},
610 {0x19, 0x03},
611 {0x1a, 0x78},
612 {0x29, 0x50},
613 {0x2c, 0x78},
614 {0x65, 0x2f},
615};
224 616
225static const u8 bridge_init_ov965x[][2] = { 617static const u8 bridge_init_ov965x[][2] = {
226 {0x88, 0xf8}, 618 {0x88, 0xf8},
@@ -403,7 +795,7 @@ static const u8 sensor_init_ov965x[][2] = {
403 {0xcb, 0xf0}, 795 {0xcb, 0xf0},
404 {0xcc, 0xd8}, 796 {0xcc, 0xd8},
405 {0xcd, 0xf1}, 797 {0xcd, 0xf1},
406 {0x4f, 0x98}, 798 {0x4f, 0x98}, /* matrix */
407 {0x50, 0x98}, 799 {0x50, 0x98},
408 {0x51, 0x00}, 800 {0x51, 0x00},
409 {0x52, 0x28}, 801 {0x52, 0x28},
@@ -412,6 +804,7 @@ static const u8 sensor_init_ov965x[][2] = {
412 {0x58, 0x1a}, 804 {0x58, 0x1a},
413 {0xff, 0x41}, /* read 41, write ff 00 */ 805 {0xff, 0x41}, /* read 41, write ff 00 */
414 {0x41, 0x40}, /* com16 */ 806 {0x41, 0x40}, /* com16 */
807
415 {0xc5, 0x03}, /* 60 Hz banding filter */ 808 {0xc5, 0x03}, /* 60 Hz banding filter */
416 {0x6a, 0x02}, /* 50 Hz banding filter */ 809 {0x6a, 0x02}, /* 50 Hz banding filter */
417 810
@@ -455,8 +848,8 @@ static const u8 bridge_init_ov965x_2[][2] = {
455 {0x52, 0x3c}, 848 {0x52, 0x3c},
456 {0x53, 0x00}, 849 {0x53, 0x00},
457 {0x54, 0x00}, 850 {0x54, 0x00},
458 {0x55, 0x00}, /* brightness */ 851 {0x55, 0x00},
459 {0x57, 0x00}, /* contrast 2 */ 852 {0x57, 0x00},
460 {0x5c, 0x00}, 853 {0x5c, 0x00},
461 {0x5a, 0xa0}, 854 {0x5a, 0xa0},
462 {0x5b, 0x78}, 855 {0x5b, 0x78},
@@ -479,14 +872,16 @@ static const u8 sensor_init_ov965x_2[][2] = {
479 {0xa3, 0x3e}, 872 {0xa3, 0x3e},
480 {0x2d, 0x00}, 873 {0x2d, 0x00},
481 {0xff, 0x42}, /* read 42, write ff 00 */ 874 {0xff, 0x42}, /* read 42, write ff 00 */
482 {0x42, 0xc0}, 875 {0x42, 0xc0}, /* com17 */
483 {0x2d, 0x00}, 876 {0x2d, 0x00},
484 {0xff, 0x42}, /* read 42, write ff 00 */ 877 {0xff, 0x42}, /* read 42, write ff 00 */
485 {0x42, 0xc1}, 878 {0x42, 0xc1}, /* com17 */
879/* sharpness */
486 {0x3f, 0x01}, 880 {0x3f, 0x01},
487 {0xff, 0x42}, /* read 42, write ff 00 */ 881 {0xff, 0x42}, /* read 42, write ff 00 */
488 {0x42, 0xc1}, 882 {0x42, 0xc1}, /* com17 */
489 {0x4f, 0x98}, 883/* saturation */
884 {0x4f, 0x98}, /* matrix */
490 {0x50, 0x98}, 885 {0x50, 0x98},
491 {0x51, 0x00}, 886 {0x51, 0x00},
492 {0x52, 0x28}, 887 {0x52, 0x28},
@@ -495,14 +890,17 @@ static const u8 sensor_init_ov965x_2[][2] = {
495 {0x58, 0x1a}, 890 {0x58, 0x1a},
496 {0xff, 0x41}, /* read 41, write ff 00 */ 891 {0xff, 0x41}, /* read 41, write ff 00 */
497 {0x41, 0x40}, /* com16 */ 892 {0x41, 0x40}, /* com16 */
893/* contrast */
498 {0x56, 0x40}, 894 {0x56, 0x40},
895/* brightness */
499 {0x55, 0x8f}, 896 {0x55, 0x8f},
897/* expo */
500 {0x10, 0x25}, /* aech - exposure high bits */ 898 {0x10, 0x25}, /* aech - exposure high bits */
501 {0xff, 0x13}, /* read 13, write ff 00 */ 899 {0xff, 0x13}, /* read 13, write ff 00 */
502 {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */ 900 {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */
503}; 901};
504 902
505static const u8 sensor_start_ov965x[][2] = { 903static const u8 sensor_start_ov965x_1_vga[][2] = { /* same for qvga */
506 {0x12, 0x62}, /* com7 - 30fps VGA YUV */ 904 {0x12, 0x62}, /* com7 - 30fps VGA YUV */
507 {0x36, 0xfa}, /* aref3 */ 905 {0x36, 0xfa}, /* aref3 */
508 {0x69, 0x0a}, /* hv */ 906 {0x69, 0x0a}, /* hv */
@@ -523,10 +921,77 @@ static const u8 sensor_start_ov965x[][2] = {
523 {0x1a, 0x3d}, /* vstop */ 921 {0x1a, 0x3d}, /* vstop */
524 {0x32, 0xff}, /* href */ 922 {0x32, 0xff}, /* href */
525 {0xc0, 0xaa}, 923 {0xc0, 0xaa},
526 {}
527}; 924};
528 925
529static const u8 bridge_start_ov965x[][2] = { 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] = {
530 {0x94, 0xaa}, 995 {0x94, 0xaa},
531 {0xf1, 0x60}, 996 {0xf1, 0x60},
532 {0xe5, 0x04}, 997 {0xe5, 0x04},
@@ -535,10 +1000,34 @@ static const u8 bridge_start_ov965x[][2] = {
535 {0x8c, 0x00}, 1000 {0x8c, 0x00},
536 {0x8d, 0x1c}, 1001 {0x8d, 0x1c},
537 {0x34, 0x05}, 1002 {0x34, 0x05},
538 {} 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},
539}; 1020};
540 1021
541static const u8 bridge_start_ov965x_vga[][2] = { 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},
542 {0xc2, 0x0c}, 1031 {0xc2, 0x0c},
543 {0xc3, 0xf9}, 1032 {0xc3, 0xf9},
544 {0xda, 0x01}, 1033 {0xda, 0x01},
@@ -555,30 +1044,98 @@ static const u8 bridge_start_ov965x_vga[][2] = {
555 {0x35, 0x02}, 1044 {0x35, 0x02},
556 {0xd9, 0x10}, 1045 {0xd9, 0x10},
557 {0x94, 0x11}, 1046 {0x94, 0x11},
558 {}
559}; 1047};
560 1048
561static const u8 bridge_start_ov965x_cif[][2] = { 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},
562 {0xc2, 0x4c}, 1058 {0xc2, 0x4c},
563 {0xc3, 0xf9}, 1059 {0xc3, 0xf9},
564 {0xda, 0x00},
565 {0x50, 0x00}, 1060 {0x50, 0x00},
566 {0x51, 0xa0}, 1061 {0x51, 0x40},
567 {0x52, 0x78}, 1062 {0x52, 0x00},
568 {0x53, 0x00}, 1063 {0x53, 0x00},
569 {0x54, 0x00}, 1064 {0x54, 0x00},
570 {0x55, 0x00}, 1065 {0x55, 0x88},
571 {0x57, 0x00}, 1066 {0x57, 0x00},
572 {0x5c, 0x00}, 1067 {0x5c, 0x00},
573 {0x5a, 0x50}, 1068 {0x5a, 0xc8},
574 {0x5b, 0x3c}, 1069 {0x5b, 0x96},
575 {0x35, 0x02}, 1070 {0x35, 0x02},
576 {0xd9, 0x10}, 1071 {0xd9, 0x10},
1072 {0xda, 0x00},
577 {0x94, 0x11}, 1073 {0x94, 0x11},
578 {}
579}; 1074};
580 1075
581static const u8 sensor_start_ov965x_vga[][2] = { 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] = {
582 {0x3b, 0xc4}, /* com11 - night mode 1/4 frame rate */ 1139 {0x3b, 0xc4}, /* com11 - night mode 1/4 frame rate */
583 {0x1e, 0x04}, /* mvfp */ 1140 {0x1e, 0x04}, /* mvfp */
584 {0x13, 0xe0}, /* com8 */ 1141 {0x13, 0xe0}, /* com8 */
@@ -592,35 +1149,36 @@ static const u8 sensor_start_ov965x_vga[][2] = {
592 {0xa3, 0x3e}, /* bd60 */ 1149 {0xa3, 0x3e}, /* bd60 */
593 1150
594 {0x2d, 0x00}, /* advfl */ 1151 {0x2d, 0x00}, /* advfl */
595 {}
596}; 1152};
597 1153
598static const u8 sensor_start_ov965x_cif[][2] = { 1154static const u8 sensor_start_ov965x_2_svga[][2] = { /* same for xga */
599 {0x3b, 0xe4}, /* com11 - night mode 1/4 frame rate */ 1155 {0x3b, 0xc4}, /* com11 - night mode 1/4 frame rate */
600 {0x1e, 0x04}, /* mvfp */ 1156 {0x1e, 0x04}, /* mvfp */
601 {0x13, 0xe0}, /* com8 */ 1157 {0x13, 0xe0}, /* com8 */
602 {0x00, 0x00}, 1158 {0x00, 0x00},
603 {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */ 1159 {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */
604 {0x11, 0x01}, /* clkrc */ 1160 {0x11, 0x01}, /* clkrc */
605 {0x6b, 0x5a}, /* dblv */ 1161 {0x6b, 0x5a}, /* dblv */
606 {0x6a, 0x02}, /* 50 Hz banding filter */ 1162 {0x6a, 0x0c}, /* 50 Hz banding filter */
607 {0xc5, 0x03}, /* 60 Hz banding filter */ 1163 {0xc5, 0x0f}, /* 60 Hz banding filter */
608 {0xa2, 0x96}, /* bd50 */ 1164 {0xa2, 0x4e}, /* bd50 */
609 {0xa3, 0x7d}, /* bd60 */ 1165 {0xa3, 0x41}, /* bd60 */
610
611 {0xff, 0x13}, /* read 13, write ff 00 */
612 {0x13, 0xe7},
613 {0x3a, 0x80}, /* tslb - yuyv */
614 {}
615}; 1166};
616 1167
617static const u8 sensor_start_ov965x_2[][2] = { 1168static const u8 sensor_start_ov965x_2_sxga[][2] = {
618 {0xff, 0x42}, /* read 42, write ff 00 */ 1169 {0x13, 0xe0}, /* com8 */
619 {0x42, 0xc1}, /* com17 - 50 Hz filter */ 1170 {0x00, 0x00},
620 {} 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 */
621}; 1180};
622 1181
623
624static void ov534_reg_write(struct gspca_dev *gspca_dev, u16 reg, u8 val) 1182static void ov534_reg_write(struct gspca_dev *gspca_dev, u16 reg, u8 val)
625{ 1183{
626 struct usb_device *udev = gspca_dev->dev; 1184 struct usb_device *udev = gspca_dev->dev;
@@ -753,39 +1311,310 @@ static void sccb_w_array(struct gspca_dev *gspca_dev,
753 } 1311 }
754} 1312}
755 1313
756/* set framerate */ 1314/* ov772x specific controls */
757static void ov534_set_frame_rate(struct gspca_dev *gspca_dev) 1315static void set_frame_rate(struct gspca_dev *gspca_dev)
1316{
1317 struct sd *sd = (struct sd *) gspca_dev;
1318 int i;
1319 struct rate_s {
1320 u8 fps;
1321 u8 r11;
1322 u8 r0d;
1323 u8 re5;
1324 };
1325 const struct rate_s *r;
1326 static const struct rate_s rate_0[] = { /* 640x480 */
1327 {60, 0x01, 0xc1, 0x04},
1328 {50, 0x01, 0x41, 0x02},
1329 {40, 0x02, 0xc1, 0x04},
1330 {30, 0x04, 0x81, 0x02},
1331 {15, 0x03, 0x41, 0x04},
1332 };
1333 static const struct rate_s rate_1[] = { /* 320x240 */
1334 {125, 0x02, 0x81, 0x02},
1335 {100, 0x02, 0xc1, 0x04},
1336 {75, 0x03, 0xc1, 0x04},
1337 {60, 0x04, 0xc1, 0x04},
1338 {50, 0x02, 0x41, 0x04},
1339 {40, 0x03, 0x41, 0x04},
1340 {30, 0x04, 0x41, 0x04},
1341 };
1342
1343 if (gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv == 0) {
1344 r = rate_0;
1345 i = ARRAY_SIZE(rate_0);
1346 } else {
1347 r = rate_1;
1348 i = ARRAY_SIZE(rate_1);
1349 }
1350 while (--i > 0) {
1351 if (sd->frame_rate >= r->fps)
1352 break;
1353 r++;
1354 }
1355
1356 sccb_reg_write(gspca_dev, 0x11, r->r11);
1357 sccb_reg_write(gspca_dev, 0x0d, r->r0d);
1358 ov534_reg_write(gspca_dev, 0xe5, r->re5);
1359
1360 PDEBUG(D_PROBE, "frame_rate: %d", r->fps);
1361}
1362
1363static void setbrightness_77(struct gspca_dev *gspca_dev)
1364{
1365 struct sd *sd = (struct sd *) gspca_dev;
1366
1367 sccb_reg_write(gspca_dev, 0x9B, sd->brightness);
1368}
1369
1370static void setcontrast_77(struct gspca_dev *gspca_dev)
758{ 1371{
759 struct sd *sd = (struct sd *) gspca_dev; 1372 struct sd *sd = (struct sd *) gspca_dev;
760 int fr = sd->frame_rate;
761 1373
762 switch (fr) { 1374 sccb_reg_write(gspca_dev, 0x9C, sd->contrast);
763 case 50: 1375}
764 sccb_reg_write(gspca_dev, 0x11, 0x01); 1376
765 sccb_reg_write(gspca_dev, 0x0d, 0x41); 1377static void setgain(struct gspca_dev *gspca_dev)
766 ov534_reg_write(gspca_dev, 0xe5, 0x02); 1378{
1379 struct sd *sd = (struct sd *) gspca_dev;
1380 u8 val;
1381
1382 val = sd->gain;
1383 switch (val & 0x30) {
1384 case 0x00:
1385 val &= 0x0f;
767 break; 1386 break;
768 case 40: 1387 case 0x10:
769 sccb_reg_write(gspca_dev, 0x11, 0x02); 1388 val &= 0x0f;
770 sccb_reg_write(gspca_dev, 0x0d, 0xc1); 1389 val |= 0x30;
771 ov534_reg_write(gspca_dev, 0xe5, 0x04);
772 break; 1390 break;
773/* case 30: */ 1391 case 0x20:
774 default: 1392 val &= 0x0f;
775 fr = 30; 1393 val |= 0x70;
776 sccb_reg_write(gspca_dev, 0x11, 0x04);
777 sccb_reg_write(gspca_dev, 0x0d, 0x81);
778 ov534_reg_write(gspca_dev, 0xe5, 0x02);
779 break; 1394 break;
780 case 15: 1395 default:
781 sccb_reg_write(gspca_dev, 0x11, 0x03); 1396/* case 0x30: */
782 sccb_reg_write(gspca_dev, 0x0d, 0x41); 1397 val &= 0x0f;
783 ov534_reg_write(gspca_dev, 0xe5, 0x04); 1398 val |= 0xf0;
784 break; 1399 break;
785 } 1400 }
1401 sccb_reg_write(gspca_dev, 0x00, val);
1402}
1403
1404static void setexposure_77(struct gspca_dev *gspca_dev)
1405{
1406 struct sd *sd = (struct sd *) gspca_dev;
1407 u8 val;
1408
1409 val = sd->exposure;
1410 sccb_reg_write(gspca_dev, 0x08, val >> 7);
1411 sccb_reg_write(gspca_dev, 0x10, val << 1);
1412}
1413
1414static void setredblc(struct gspca_dev *gspca_dev)
1415{
1416 struct sd *sd = (struct sd *) gspca_dev;
1417
1418 sccb_reg_write(gspca_dev, 0x43, sd->redblc);
1419}
1420
1421static void setblueblc(struct gspca_dev *gspca_dev)
1422{
1423 struct sd *sd = (struct sd *) gspca_dev;
1424
1425 sccb_reg_write(gspca_dev, 0x42, sd->blueblc);
1426}
1427
1428static void sethue(struct gspca_dev *gspca_dev)
1429{
1430 struct sd *sd = (struct sd *) gspca_dev;
1431
1432 sccb_reg_write(gspca_dev, 0x01, sd->hue);
1433}
1434
1435static void setautogain_77(struct gspca_dev *gspca_dev)
1436{
1437 struct sd *sd = (struct sd *) gspca_dev;
1438
1439 if (sd->autogain) {
1440 sccb_reg_write(gspca_dev, 0x13, 0xf7); /* AGC,AEC,AWB ON */
1441 sccb_reg_write(gspca_dev, 0x64,
1442 sccb_reg_read(gspca_dev, 0x64) | 0x03);
1443 } else {
1444 sccb_reg_write(gspca_dev, 0x13, 0xf0); /* AGC,AEC,AWB OFF */
1445 sccb_reg_write(gspca_dev, 0x64,
1446 sccb_reg_read(gspca_dev, 0x64) & 0xfc);
1447 }
1448}
1449
1450static void setawb(struct gspca_dev *gspca_dev)
1451{
1452 struct sd *sd = (struct sd *) gspca_dev;
1453
1454 if (sd->awb)
1455 sccb_reg_write(gspca_dev, 0x63, 0xe0); /* AWB on */
1456 else
1457 sccb_reg_write(gspca_dev, 0x63, 0xaa); /* AWB off */
1458}
1459
1460static void setsharpness_77(struct gspca_dev *gspca_dev)
1461{
1462 struct sd *sd = (struct sd *) gspca_dev;
1463 u8 val;
1464
1465 val = sd->sharpness;
1466 sccb_reg_write(gspca_dev, 0x91, val); /* vga noise */
1467 sccb_reg_write(gspca_dev, 0x8e, val); /* qvga noise */
1468}
1469
1470static void sethflip(struct gspca_dev *gspca_dev)
1471{
1472 struct sd *sd = (struct sd *) gspca_dev;
1473
1474 if (sd->hflip == 0)
1475 sccb_reg_write(gspca_dev, 0x0c,
1476 sccb_reg_read(gspca_dev, 0x0c) | 0x40);
1477 else
1478 sccb_reg_write(gspca_dev, 0x0c,
1479 sccb_reg_read(gspca_dev, 0x0c) & 0xbf);
1480}
1481
1482static void setvflip(struct gspca_dev *gspca_dev)
1483{
1484 struct sd *sd = (struct sd *) gspca_dev;
1485
1486 if (sd->vflip == 0)
1487 sccb_reg_write(gspca_dev, 0x0c,
1488 sccb_reg_read(gspca_dev, 0x0c) | 0x80);
1489 else
1490 sccb_reg_write(gspca_dev, 0x0c,
1491 sccb_reg_read(gspca_dev, 0x0c) & 0x7f);
1492}
1493
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 u8 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);
786 1610
787 sd->frame_rate = fr; 1611 val = sccb_reg_read(gspca_dev, 0x42); /* com17 */
788 PDEBUG(D_PROBE, "frame_rate: %d", fr); 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);
789} 1618}
790 1619
791/* this function is called at probe time */ 1620/* this function is called at probe time */
@@ -800,17 +1629,60 @@ static int sd_config(struct gspca_dev *gspca_dev,
800 cam = &gspca_dev->cam; 1629 cam = &gspca_dev->cam;
801 1630
802 if (sd->sensor == SENSOR_OV772X) { 1631 if (sd->sensor == SENSOR_OV772X) {
803 cam->cam_mode = vga_yuyv_mode; 1632 cam->cam_mode = ov772x_mode;
804 cam->nmodes = ARRAY_SIZE(vga_yuyv_mode); 1633 cam->nmodes = ARRAY_SIZE(ov772x_mode);
805 1634
806 cam->bulk = 1; 1635 cam->bulk = 1;
807 cam->bulk_size = 16384; 1636 cam->bulk_size = 16384;
808 cam->bulk_nurbs = 2; 1637 cam->bulk_nurbs = 2;
809 } else { /* ov965x */ 1638 } else { /* ov965x */
810 cam->cam_mode = vga_jpeg_mode; 1639 cam->cam_mode = ov965x_mode;
811 cam->nmodes = ARRAY_SIZE(vga_jpeg_mode); 1640 cam->nmodes = ARRAY_SIZE(ov965x_mode);
812 } 1641 }
813 1642
1643 sd->frame_rate = 30;
1644
1645 if (sd->sensor == SENSOR_OV772X) {
1646 sd->brightness = BRIGHTNESS_77_DEF;
1647 sd->contrast = CONTRAST_77_DEF;
1648 sd->gain = GAIN_DEF;
1649 sd->exposure = EXPO_77_DEF;
1650 sd->redblc = RED_BALANCE_DEF;
1651 sd->blueblc = BLUE_BALANCE_DEF;
1652 sd->hue = HUE_DEF;
1653#if AUTOGAIN_77_DEF != 0
1654 sd->autogain = AUTOGAIN_77_DEF;
1655#else
1656 gspca_dev->ctrl_inac |= (1 << AWB_77_IDX);
1657#endif
1658#if AWB_DEF != 0
1659 sd->awb = AWB_DEF
1660#endif
1661#if SHARPNESS_77_DEF != 0
1662 sd->sharpness = SHARPNESS_77_DEF;
1663#endif
1664#if HFLIP_DEF != 0
1665 sd->hflip = HFLIP_DEF;
1666#endif
1667#if VFLIP_DEF != 0
1668 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
1677#if EXPO_96_DEF != 0
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 }
814 return 0; 1686 return 0;
815} 1687}
816 1688
@@ -847,14 +1719,14 @@ static int sd_init(struct gspca_dev *gspca_dev)
847 /* initialize */ 1719 /* initialize */
848 switch (sd->sensor) { 1720 switch (sd->sensor) {
849 case SENSOR_OV772X: 1721 case SENSOR_OV772X:
850 reg_w_array(gspca_dev, bridge_init_ov722x, 1722 reg_w_array(gspca_dev, bridge_init_ov772x,
851 ARRAY_SIZE(bridge_init_ov722x)); 1723 ARRAY_SIZE(bridge_init_ov772x));
852 ov534_set_led(gspca_dev, 1); 1724 ov534_set_led(gspca_dev, 1);
853 sccb_w_array(gspca_dev, sensor_init_ov722x, 1725 sccb_w_array(gspca_dev, sensor_init_ov772x,
854 ARRAY_SIZE(sensor_init_ov722x)); 1726 ARRAY_SIZE(sensor_init_ov772x));
855 ov534_reg_write(gspca_dev, 0xe0, 0x09); 1727 ov534_reg_write(gspca_dev, 0xe0, 0x09);
856 ov534_set_led(gspca_dev, 0); 1728 ov534_set_led(gspca_dev, 0);
857 ov534_set_frame_rate(gspca_dev); 1729 set_frame_rate(gspca_dev);
858 break; 1730 break;
859 default: 1731 default:
860/* case SENSOR_OV965X: */ 1732/* case SENSOR_OV965X: */
@@ -875,60 +1747,115 @@ static int sd_init(struct gspca_dev *gspca_dev)
875 return 0; 1747 return 0;
876} 1748}
877 1749
878static int sd_start(struct gspca_dev *gspca_dev) 1750static int sd_start_ov772x(struct gspca_dev *gspca_dev)
879{ 1751{
880 struct sd *sd = (struct sd *) gspca_dev;
881 int mode; 1752 int mode;
882 1753
883 switch (sd->sensor) { 1754 mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
884 case SENSOR_OV772X: 1755 if (mode != 0) { /* 320x240 */
885 ov534_set_led(gspca_dev, 1); 1756 reg_w_array(gspca_dev, bridge_start_ov772x_qvga,
886 ov534_reg_write(gspca_dev, 0xe0, 0x00); 1757 ARRAY_SIZE(bridge_start_ov772x_qvga));
887 break; 1758 sccb_w_array(gspca_dev, sensor_start_ov772x_qvga,
888 default: 1759 ARRAY_SIZE(sensor_start_ov772x_qvga));
889/* case SENSOR_OV965X: */ 1760 } else { /* 640x480 */
890 1761 reg_w_array(gspca_dev, bridge_start_ov772x_vga,
891 sccb_w_array(gspca_dev, sensor_start_ov965x, 1762 ARRAY_SIZE(bridge_start_ov772x_vga));
892 ARRAY_SIZE(sensor_start_ov965x)); 1763 sccb_w_array(gspca_dev, sensor_start_ov772x_vga,
893 reg_w_array(gspca_dev, bridge_start_ov965x, 1764 ARRAY_SIZE(sensor_start_ov772x_vga));
894 ARRAY_SIZE(bridge_start_ov965x));
895 mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
896 if (mode != 0) { /* 320x240 */
897 reg_w_array(gspca_dev, bridge_start_ov965x_cif,
898 ARRAY_SIZE(bridge_start_ov965x_cif));
899 sccb_w_array(gspca_dev, sensor_start_ov965x_cif,
900 ARRAY_SIZE(sensor_start_ov965x_cif));
901 } else { /* 640x480 */
902 reg_w_array(gspca_dev, bridge_start_ov965x_vga,
903 ARRAY_SIZE(bridge_start_ov965x_vga));
904 sccb_w_array(gspca_dev, sensor_start_ov965x_vga,
905 ARRAY_SIZE(sensor_start_ov965x_vga));
906 }
907 sccb_w_array(gspca_dev, sensor_start_ov965x_2,
908 ARRAY_SIZE(sensor_start_ov965x_2));
909 ov534_reg_write(gspca_dev, 0xe0, 0x00);
910 ov534_reg_write(gspca_dev, 0xe0, 0x00);
911 ov534_set_led(gspca_dev, 1);
912 } 1765 }
1766 set_frame_rate(gspca_dev);
1767
1768 setautogain_77(gspca_dev);
1769 setawb(gspca_dev);
1770 setgain(gspca_dev);
1771 setredblc(gspca_dev);
1772 setblueblc(gspca_dev);
1773 sethue(gspca_dev);
1774 setexposure_77(gspca_dev);
1775 setbrightness_77(gspca_dev);
1776 setcontrast_77(gspca_dev);
1777 setsharpness_77(gspca_dev);
1778 setvflip(gspca_dev);
1779 sethflip(gspca_dev);
1780
1781 ov534_set_led(gspca_dev, 1);
1782 ov534_reg_write(gspca_dev, 0xe0, 0x00);
913 return 0; 1783 return 0;
914} 1784}
915 1785
916static void sd_stopN(struct gspca_dev *gspca_dev) 1786static int sd_start_ov965x(struct gspca_dev *gspca_dev)
917{ 1787{
918 struct sd *sd = (struct sd *) gspca_dev; 1788 int mode;
919 1789
920 switch (sd->sensor) { 1790 mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
921 case SENSOR_OV772X: 1791 switch (mode) {
922 ov534_reg_write(gspca_dev, 0xe0, 0x09);
923 ov534_set_led(gspca_dev, 0);
924 break;
925 default: 1792 default:
926/* case SENSOR_OV965X: */ 1793/* case 4: * 320x240 */
927 ov534_reg_write(gspca_dev, 0xe0, 0x01); 1794 sccb_w_array(gspca_dev, sensor_start_ov965x_1_vga,
928 ov534_set_led(gspca_dev, 0); 1795 ARRAY_SIZE(sensor_start_ov965x_1_vga));
929 ov534_reg_write(gspca_dev, 0xe0, 0x00); 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));
930 break; 1832 break;
931 } 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{
1850 ov534_reg_write(gspca_dev, 0xe0, 0x09);
1851 ov534_set_led(gspca_dev, 0);
1852}
1853
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);
932} 1859}
933 1860
934/* Values for bmHeaderInfo (Video and Still Image Payload Headers, 2.4.3.3) */ 1861/* Values for bmHeaderInfo (Video and Still Image Payload Headers, 2.4.3.3) */
@@ -941,8 +1868,8 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
941#define UVC_STREAM_EOF (1 << 1) 1868#define UVC_STREAM_EOF (1 << 1)
942#define UVC_STREAM_FID (1 << 0) 1869#define UVC_STREAM_FID (1 << 0)
943 1870
944static void sd_pkt_scan(struct gspca_dev *gspca_dev, struct gspca_frame *frame, 1871static void sd_pkt_scan(struct gspca_dev *gspca_dev,
945 __u8 *data, int len) 1872 u8 *data, int len)
946{ 1873{
947 struct sd *sd = (struct sd *) gspca_dev; 1874 struct sd *sd = (struct sd *) gspca_dev;
948 __u32 this_pts; 1875 __u32 this_pts;
@@ -983,32 +1910,30 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, struct gspca_frame *frame,
983 /* If PTS or FID has changed, start a new frame. */ 1910 /* If PTS or FID has changed, start a new frame. */
984 if (this_pts != sd->last_pts || this_fid != sd->last_fid) { 1911 if (this_pts != sd->last_pts || this_fid != sd->last_fid) {
985 if (gspca_dev->last_packet_type == INTER_PACKET) 1912 if (gspca_dev->last_packet_type == INTER_PACKET)
986 frame = gspca_frame_add(gspca_dev, 1913 gspca_frame_add(gspca_dev, LAST_PACKET,
987 LAST_PACKET, frame, 1914 NULL, 0);
988 NULL, 0);
989 sd->last_pts = this_pts; 1915 sd->last_pts = this_pts;
990 sd->last_fid = this_fid; 1916 sd->last_fid = this_fid;
991 gspca_frame_add(gspca_dev, FIRST_PACKET, frame, 1917 gspca_frame_add(gspca_dev, FIRST_PACKET,
992 data + 12, len - 12); 1918 data + 12, len - 12);
993 /* If this packet is marked as EOF, end the frame */ 1919 /* If this packet is marked as EOF, end the frame */
994 } else if (data[1] & UVC_STREAM_EOF) { 1920 } else if (data[1] & UVC_STREAM_EOF) {
995 sd->last_pts = 0; 1921 sd->last_pts = 0;
996 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, 1922 gspca_frame_add(gspca_dev, LAST_PACKET,
997 data + 12, len - 12); 1923 data + 12, len - 12);
998 } else { 1924 } else {
999 1925
1000 /* Add the data from this payload */ 1926 /* Add the data from this payload */
1001 gspca_frame_add(gspca_dev, INTER_PACKET, frame, 1927 gspca_frame_add(gspca_dev, INTER_PACKET,
1002 data + 12, len - 12); 1928 data + 12, len - 12);
1003 } 1929 }
1004 1930
1005
1006 /* Done this payload */ 1931 /* Done this payload */
1007 goto scan_next; 1932 goto scan_next;
1008 1933
1009discard: 1934discard:
1010 /* Discard data until a new frame starts. */ 1935 /* Discard data until a new frame starts. */
1011 gspca_frame_add(gspca_dev, DISCARD_PACKET, frame, NULL, 0); 1936 gspca_dev->last_packet_type = DISCARD_PACKET;
1012 1937
1013scan_next: 1938scan_next:
1014 remaining_len -= len; 1939 remaining_len -= len;
@@ -1016,6 +1941,291 @@ scan_next:
1016 } while (remaining_len > 0); 1941 } while (remaining_len > 0);
1017} 1942}
1018 1943
1944/* controls */
1945static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val)
1946{
1947 struct sd *sd = (struct sd *) gspca_dev;
1948
1949 sd->gain = val;
1950 if (gspca_dev->streaming)
1951 setgain(gspca_dev);
1952 return 0;
1953}
1954
1955static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val)
1956{
1957 struct sd *sd = (struct sd *) gspca_dev;
1958
1959 *val = sd->gain;
1960 return 0;
1961}
1962
1963static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val)
1964{
1965 struct sd *sd = (struct sd *) gspca_dev;
1966
1967 sd->exposure = val;
1968 if (gspca_dev->streaming) {
1969 if (sd->sensor == SENSOR_OV772X)
1970 setexposure_77(gspca_dev);
1971 else
1972 setexposure_96(gspca_dev);
1973 }
1974 return 0;
1975}
1976
1977static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val)
1978{
1979 struct sd *sd = (struct sd *) gspca_dev;
1980
1981 *val = sd->exposure;
1982 return 0;
1983}
1984
1985static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
1986{
1987 struct sd *sd = (struct sd *) gspca_dev;
1988
1989 sd->brightness = val;
1990 if (gspca_dev->streaming) {
1991 if (sd->sensor == SENSOR_OV772X)
1992 setbrightness_77(gspca_dev);
1993 else
1994 setbrightness_96(gspca_dev);
1995 }
1996 return 0;
1997}
1998
1999static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
2000{
2001 struct sd *sd = (struct sd *) gspca_dev;
2002
2003 *val = sd->brightness;
2004 return 0;
2005}
2006
2007static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
2008{
2009 struct sd *sd = (struct sd *) gspca_dev;
2010
2011 sd->contrast = val;
2012 if (gspca_dev->streaming) {
2013 if (sd->sensor == SENSOR_OV772X)
2014 setcontrast_77(gspca_dev);
2015 else
2016 setcontrast_96(gspca_dev);
2017 }
2018 return 0;
2019}
2020
2021static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
2022{
2023 struct sd *sd = (struct sd *) gspca_dev;
2024
2025 *val = sd->contrast;
2026 return 0;
2027}
2028
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)
2065{
2066 struct sd *sd = (struct sd *) gspca_dev;
2067
2068 sd->redblc = val;
2069 if (gspca_dev->streaming)
2070 setredblc(gspca_dev);
2071 return 0;
2072}
2073
2074static int sd_getredblc(struct gspca_dev *gspca_dev, __s32 *val)
2075{
2076 struct sd *sd = (struct sd *) gspca_dev;
2077
2078 *val = sd->redblc;
2079 return 0;
2080}
2081
2082static int sd_setblueblc(struct gspca_dev *gspca_dev, __s32 val)
2083{
2084 struct sd *sd = (struct sd *) gspca_dev;
2085
2086 sd->blueblc = val;
2087 if (gspca_dev->streaming)
2088 setblueblc(gspca_dev);
2089 return 0;
2090}
2091
2092static int sd_getblueblc(struct gspca_dev *gspca_dev, __s32 *val)
2093{
2094 struct sd *sd = (struct sd *) gspca_dev;
2095
2096 *val = sd->blueblc;
2097 return 0;
2098}
2099
2100static int sd_sethue(struct gspca_dev *gspca_dev, __s32 val)
2101{
2102 struct sd *sd = (struct sd *) gspca_dev;
2103
2104 sd->hue = val;
2105 if (gspca_dev->streaming)
2106 sethue(gspca_dev);
2107 return 0;
2108}
2109
2110static int sd_gethue(struct gspca_dev *gspca_dev, __s32 *val)
2111{
2112 struct sd *sd = (struct sd *) gspca_dev;
2113
2114 *val = sd->hue;
2115 return 0;
2116}
2117
2118static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
2119{
2120 struct sd *sd = (struct sd *) gspca_dev;
2121
2122 sd->autogain = val;
2123
2124 if (gspca_dev->streaming) {
2125 if (sd->sensor == SENSOR_OV772X) {
2126
2127 /* the auto white balance control works only
2128 * when auto gain is set */
2129 if (val)
2130 gspca_dev->ctrl_inac &= ~(1 << AWB_77_IDX);
2131 else
2132 gspca_dev->ctrl_inac |= (1 << AWB_77_IDX);
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 }
2142 return 0;
2143}
2144
2145static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
2146{
2147 struct sd *sd = (struct sd *) gspca_dev;
2148
2149 *val = sd->autogain;
2150 return 0;
2151}
2152
2153static int sd_setawb(struct gspca_dev *gspca_dev, __s32 val)
2154{
2155 struct sd *sd = (struct sd *) gspca_dev;
2156
2157 sd->awb = val;
2158 if (gspca_dev->streaming)
2159 setawb(gspca_dev);
2160 return 0;
2161}
2162
2163static int sd_getawb(struct gspca_dev *gspca_dev, __s32 *val)
2164{
2165 struct sd *sd = (struct sd *) gspca_dev;
2166
2167 *val = sd->awb;
2168 return 0;
2169}
2170
2171static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val)
2172{
2173 struct sd *sd = (struct sd *) gspca_dev;
2174
2175 sd->sharpness = val;
2176 if (gspca_dev->streaming) {
2177 if (sd->sensor == SENSOR_OV772X)
2178 setsharpness_77(gspca_dev);
2179 else
2180 setsharpness_96(gspca_dev);
2181 }
2182 return 0;
2183}
2184
2185static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val)
2186{
2187 struct sd *sd = (struct sd *) gspca_dev;
2188
2189 *val = sd->sharpness;
2190 return 0;
2191}
2192
2193static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val)
2194{
2195 struct sd *sd = (struct sd *) gspca_dev;
2196
2197 sd->hflip = val;
2198 if (gspca_dev->streaming)
2199 sethflip(gspca_dev);
2200 return 0;
2201}
2202
2203static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val)
2204{
2205 struct sd *sd = (struct sd *) gspca_dev;
2206
2207 *val = sd->hflip;
2208 return 0;
2209}
2210
2211static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val)
2212{
2213 struct sd *sd = (struct sd *) gspca_dev;
2214
2215 sd->vflip = val;
2216 if (gspca_dev->streaming)
2217 setvflip(gspca_dev);
2218 return 0;
2219}
2220
2221static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val)
2222{
2223 struct sd *sd = (struct sd *) gspca_dev;
2224
2225 *val = sd->vflip;
2226 return 0;
2227}
2228
1019/* get stream parameters (framerate) */ 2229/* get stream parameters (framerate) */
1020static int sd_get_streamparm(struct gspca_dev *gspca_dev, 2230static int sd_get_streamparm(struct gspca_dev *gspca_dev,
1021 struct v4l2_streamparm *parm) 2231 struct v4l2_streamparm *parm)
@@ -1047,7 +2257,8 @@ static int sd_set_streamparm(struct gspca_dev *gspca_dev,
1047 2257
1048 /* Set requested framerate */ 2258 /* Set requested framerate */
1049 sd->frame_rate = tpf->denominator / tpf->numerator; 2259 sd->frame_rate = tpf->denominator / tpf->numerator;
1050 ov534_set_frame_rate(gspca_dev); 2260 if (gspca_dev->streaming && sd->sensor == SENSOR_OV772X)
2261 set_frame_rate(gspca_dev);
1051 2262
1052 /* Return the actual framerate */ 2263 /* Return the actual framerate */
1053 tpf->numerator = 1; 2264 tpf->numerator = 1;
@@ -1056,20 +2267,53 @@ static int sd_set_streamparm(struct gspca_dev *gspca_dev,
1056 return 0; 2267 return 0;
1057} 2268}
1058 2269
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
1059/* sub-driver description */ 2291/* sub-driver description */
1060static const struct sd_desc sd_desc = { 2292static const struct sd_desc sd_desc_ov772x = {
1061 .name = MODULE_NAME, 2293 .name = MODULE_NAME,
1062 .ctrls = sd_ctrls, 2294 .ctrls = sd_ctrls_ov772x,
1063 .nctrls = ARRAY_SIZE(sd_ctrls), 2295 .nctrls = ARRAY_SIZE(sd_ctrls_ov772x),
1064 .config = sd_config, 2296 .config = sd_config,
1065 .init = sd_init, 2297 .init = sd_init,
1066 .start = sd_start, 2298 .start = sd_start_ov772x,
1067 .stopN = sd_stopN, 2299 .stopN = sd_stopN_ov772x,
1068 .pkt_scan = sd_pkt_scan, 2300 .pkt_scan = sd_pkt_scan,
1069 .get_streamparm = sd_get_streamparm, 2301 .get_streamparm = sd_get_streamparm,
1070 .set_streamparm = sd_set_streamparm, 2302 .set_streamparm = sd_set_streamparm,
1071}; 2303};
1072 2304
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
1073/* -- module initialisation -- */ 2317/* -- module initialisation -- */
1074static const __devinitdata struct usb_device_id device_table[] = { 2318static const __devinitdata struct usb_device_id device_table[] = {
1075 {USB_DEVICE(0x06f8, 0x3003), .driver_info = SENSOR_OV965X}, 2319 {USB_DEVICE(0x06f8, 0x3003), .driver_info = SENSOR_OV965X},
@@ -1082,8 +2326,12 @@ MODULE_DEVICE_TABLE(usb, device_table);
1082/* -- device connect -- */ 2326/* -- device connect -- */
1083static int sd_probe(struct usb_interface *intf, const struct usb_device_id *id) 2327static int sd_probe(struct usb_interface *intf, const struct usb_device_id *id)
1084{ 2328{
1085 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), 2329 return gspca_dev_probe(intf, id,
1086 THIS_MODULE); 2330 id->driver_info == SENSOR_OV772X
2331 ? &sd_desc_ov772x
2332 : &sd_desc_ov965x,
2333 sizeof(struct sd),
2334 THIS_MODULE);
1087} 2335}
1088 2336
1089static struct usb_driver sd_driver = { 2337static struct usb_driver sd_driver = {
@@ -1101,6 +2349,7 @@ static struct usb_driver sd_driver = {
1101static int __init sd_mod_init(void) 2349static int __init sd_mod_init(void)
1102{ 2350{
1103 int ret; 2351 int ret;
2352
1104 ret = usb_register(&sd_driver); 2353 ret = usb_register(&sd_driver);
1105 if (ret < 0) 2354 if (ret < 0)
1106 return ret; 2355 return ret;
diff --git a/drivers/media/video/gspca/pac207.c b/drivers/media/video/gspca/pac207.c
index 96659433d248..4706a823add0 100644
--- a/drivers/media/video/gspca/pac207.c
+++ b/drivers/media/video/gspca/pac207.c
@@ -337,14 +337,13 @@ static void pac207_do_auto_gain(struct gspca_dev *gspca_dev)
337} 337}
338 338
339static void sd_pkt_scan(struct gspca_dev *gspca_dev, 339static void sd_pkt_scan(struct gspca_dev *gspca_dev,
340 struct gspca_frame *frame, 340 u8 *data,
341 __u8 *data,
342 int len) 341 int len)
343{ 342{
344 struct sd *sd = (struct sd *) gspca_dev; 343 struct sd *sd = (struct sd *) gspca_dev;
345 unsigned char *sof; 344 unsigned char *sof;
346 345
347 sof = pac_find_sof(gspca_dev, data, len); 346 sof = pac_find_sof(&sd->sof_read, data, len);
348 if (sof) { 347 if (sof) {
349 int n; 348 int n;
350 349
@@ -354,10 +353,10 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
354 n -= sizeof pac_sof_marker; 353 n -= sizeof pac_sof_marker;
355 else 354 else
356 n = 0; 355 n = 0;
357 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, 356 gspca_frame_add(gspca_dev, LAST_PACKET,
358 data, n); 357 data, n);
359 sd->header_read = 0; 358 sd->header_read = 0;
360 gspca_frame_add(gspca_dev, FIRST_PACKET, frame, NULL, 0); 359 gspca_frame_add(gspca_dev, FIRST_PACKET, NULL, 0);
361 len -= sof - data; 360 len -= sof - data;
362 data = sof; 361 data = sof;
363 } 362 }
@@ -381,7 +380,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
381 sd->header_read = 11; 380 sd->header_read = 11;
382 } 381 }
383 382
384 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); 383 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
385} 384}
386 385
387static void setbrightness(struct gspca_dev *gspca_dev) 386static void setbrightness(struct gspca_dev *gspca_dev)
diff --git a/drivers/media/video/gspca/pac7302.c b/drivers/media/video/gspca/pac7302.c
new file mode 100644
index 000000000000..74acceea8094
--- /dev/null
+++ b/drivers/media/video/gspca/pac7302.c
@@ -0,0 +1,1272 @@
1/*
2 * Pixart PAC7302 library
3 * Copyright (C) 2005 Thomas Kaiser thomas@kaiser-linux.li
4 *
5 * V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
6 *
7 * Separated from Pixart PAC7311 library by Márton Németh <nm127@freemail.hu>
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 * 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 02111-1307 USA
22 */
23
24/* 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
30 Register page 1:
31
32 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)
38 -/0x80 JPEG compression ratio ? Best not touched
39
40 Register page 3/4:
41
42 Address Description
43 0x02 Clock divider 2-63, fps =~ 60 / val. Must be a multiple of 3 on
44 the 7302, so one of 3, 6, 9, ..., except when between 6 and 12?
45 -/0x0f Master gain 1-245, low value = high gain
46 0x10/- Master gain 0-31
47 -/0x10 Another gain 0-15, limited influence (1-2x gain I guess)
48 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
53 The registers are accessed in the following functions:
54
55 Page | Register | Function
56 -----+------------+---------------------------------------------------
57 0 | 0x0f..0x20 | setcolors()
58 0 | 0xa2..0xab | setbrightcont()
59 0 | 0xc5 | setredbalance()
60 0 | 0xc6 | setwhitebalance()
61 0 | 0xc7 | setbluebalance()
62 0 | 0xdc | setbrightcont(), setcolors()
63 3 | 0x02 | setexposure()
64 3 | 0x10 | setgain()
65 3 | 0x11 | setcolors(), setgain(), setexposure(), sethvflip()
66 3 | 0x21 | sethvflip()
67*/
68
69#define MODULE_NAME "pac7302"
70
71#include <media/v4l2-chip-ident.h>
72#include "gspca.h"
73
74MODULE_AUTHOR("Thomas Kaiser thomas@kaiser-linux.li");
75MODULE_DESCRIPTION("Pixart PAC7302");
76MODULE_LICENSE("GPL");
77
78/* specific webcam descriptor for pac7302 */
79struct sd {
80 struct gspca_dev gspca_dev; /* !! must be the first item */
81
82 unsigned char brightness;
83 unsigned char contrast;
84 unsigned char colors;
85 unsigned char white_balance;
86 unsigned char red_balance;
87 unsigned char blue_balance;
88 unsigned char gain;
89 unsigned char exposure;
90 unsigned char autogain;
91 __u8 hflip;
92 __u8 vflip;
93
94 u8 sof_read;
95 u8 autogain_ignore_frames;
96
97 atomic_t avg_lum;
98};
99
100/* V4L2 controls supported by the driver */
101static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
102static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
103static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
104static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
105static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
106static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
107static int sd_setwhitebalance(struct gspca_dev *gspca_dev, __s32 val);
108static int sd_getwhitebalance(struct gspca_dev *gspca_dev, __s32 *val);
109static int sd_setredbalance(struct gspca_dev *gspca_dev, __s32 val);
110static int sd_getredbalance(struct gspca_dev *gspca_dev, __s32 *val);
111static int sd_setbluebalance(struct gspca_dev *gspca_dev, __s32 val);
112static int sd_getbluebalance(struct gspca_dev *gspca_dev, __s32 *val);
113static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
114static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
115static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val);
116static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val);
117static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val);
118static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val);
119static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val);
120static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val);
121static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val);
122static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val);
123
124static struct ctrl sd_ctrls[] = {
125/* This control is pac7302 only */
126 {
127 {
128 .id = V4L2_CID_BRIGHTNESS,
129 .type = V4L2_CTRL_TYPE_INTEGER,
130 .name = "Brightness",
131 .minimum = 0,
132#define BRIGHTNESS_MAX 0x20
133 .maximum = BRIGHTNESS_MAX,
134 .step = 1,
135#define BRIGHTNESS_DEF 0x10
136 .default_value = BRIGHTNESS_DEF,
137 },
138 .set = sd_setbrightness,
139 .get = sd_getbrightness,
140 },
141/* This control is for both the 7302 and the 7311 */
142 {
143 {
144 .id = V4L2_CID_CONTRAST,
145 .type = V4L2_CTRL_TYPE_INTEGER,
146 .name = "Contrast",
147 .minimum = 0,
148#define CONTRAST_MAX 255
149 .maximum = CONTRAST_MAX,
150 .step = 1,
151#define CONTRAST_DEF 127
152 .default_value = CONTRAST_DEF,
153 },
154 .set = sd_setcontrast,
155 .get = sd_getcontrast,
156 },
157/* This control is pac7302 only */
158 {
159 {
160 .id = V4L2_CID_SATURATION,
161 .type = V4L2_CTRL_TYPE_INTEGER,
162 .name = "Saturation",
163 .minimum = 0,
164#define COLOR_MAX 255
165 .maximum = COLOR_MAX,
166 .step = 1,
167#define COLOR_DEF 127
168 .default_value = COLOR_DEF,
169 },
170 .set = sd_setcolors,
171 .get = sd_getcolors,
172 },
173 {
174 {
175 .id = V4L2_CID_WHITE_BALANCE_TEMPERATURE,
176 .type = V4L2_CTRL_TYPE_INTEGER,
177 .name = "White Balance",
178 .minimum = 0,
179 .maximum = 255,
180 .step = 1,
181#define WHITEBALANCE_DEF 4
182 .default_value = WHITEBALANCE_DEF,
183 },
184 .set = sd_setwhitebalance,
185 .get = sd_getwhitebalance,
186 },
187 {
188 {
189 .id = V4L2_CID_RED_BALANCE,
190 .type = V4L2_CTRL_TYPE_INTEGER,
191 .name = "Red",
192 .minimum = 0,
193 .maximum = 3,
194 .step = 1,
195#define REDBALANCE_DEF 1
196 .default_value = REDBALANCE_DEF,
197 },
198 .set = sd_setredbalance,
199 .get = sd_getredbalance,
200 },
201 {
202 {
203 .id = V4L2_CID_BLUE_BALANCE,
204 .type = V4L2_CTRL_TYPE_INTEGER,
205 .name = "Blue",
206 .minimum = 0,
207 .maximum = 3,
208 .step = 1,
209#define BLUEBALANCE_DEF 1
210 .default_value = BLUEBALANCE_DEF,
211 },
212 .set = sd_setbluebalance,
213 .get = sd_getbluebalance,
214 },
215/* All controls below are for both the 7302 and the 7311 */
216 {
217 {
218 .id = V4L2_CID_GAIN,
219 .type = V4L2_CTRL_TYPE_INTEGER,
220 .name = "Gain",
221 .minimum = 0,
222#define GAIN_MAX 255
223 .maximum = GAIN_MAX,
224 .step = 1,
225#define GAIN_DEF 127
226#define GAIN_KNEE 255 /* Gain seems to cause little noise on the pac73xx */
227 .default_value = GAIN_DEF,
228 },
229 .set = sd_setgain,
230 .get = sd_getgain,
231 },
232 {
233 {
234 .id = V4L2_CID_EXPOSURE,
235 .type = V4L2_CTRL_TYPE_INTEGER,
236 .name = "Exposure",
237 .minimum = 0,
238#define EXPOSURE_MAX 255
239 .maximum = EXPOSURE_MAX,
240 .step = 1,
241#define EXPOSURE_DEF 16 /* 32 ms / 30 fps */
242#define EXPOSURE_KNEE 50 /* 100 ms / 10 fps */
243 .default_value = EXPOSURE_DEF,
244 },
245 .set = sd_setexposure,
246 .get = sd_getexposure,
247 },
248 {
249 {
250 .id = V4L2_CID_AUTOGAIN,
251 .type = V4L2_CTRL_TYPE_BOOLEAN,
252 .name = "Auto Gain",
253 .minimum = 0,
254 .maximum = 1,
255 .step = 1,
256#define AUTOGAIN_DEF 1
257 .default_value = AUTOGAIN_DEF,
258 },
259 .set = sd_setautogain,
260 .get = sd_getautogain,
261 },
262 {
263 {
264 .id = V4L2_CID_HFLIP,
265 .type = V4L2_CTRL_TYPE_BOOLEAN,
266 .name = "Mirror",
267 .minimum = 0,
268 .maximum = 1,
269 .step = 1,
270#define HFLIP_DEF 0
271 .default_value = HFLIP_DEF,
272 },
273 .set = sd_sethflip,
274 .get = sd_gethflip,
275 },
276 {
277 {
278 .id = V4L2_CID_VFLIP,
279 .type = V4L2_CTRL_TYPE_BOOLEAN,
280 .name = "Vflip",
281 .minimum = 0,
282 .maximum = 1,
283 .step = 1,
284#define VFLIP_DEF 0
285 .default_value = VFLIP_DEF,
286 },
287 .set = sd_setvflip,
288 .get = sd_getvflip,
289 },
290};
291
292static const struct v4l2_pix_format vga_mode[] = {
293 {640, 480, V4L2_PIX_FMT_PJPG, V4L2_FIELD_NONE,
294 .bytesperline = 640,
295 .sizeimage = 640 * 480 * 3 / 8 + 590,
296 .colorspace = V4L2_COLORSPACE_JPEG,
297 .priv = 0},
298};
299
300#define LOAD_PAGE3 255
301#define LOAD_PAGE4 254
302#define END_OF_SEQUENCE 0
303
304/* pac 7302 */
305static const __u8 init_7302[] = {
306/* index,value */
307 0xff, 0x01, /* page 1 */
308 0x78, 0x00, /* deactivate */
309 0xff, 0x01,
310 0x78, 0x40, /* led off */
311};
312static const __u8 start_7302[] = {
313/* index, len, [value]* */
314 0xff, 1, 0x00, /* page 0 */
315 0x00, 12, 0x01, 0x40, 0x40, 0x40, 0x01, 0xe0, 0x02, 0x80,
316 0x00, 0x00, 0x00, 0x00,
317 0x0d, 24, 0x03, 0x01, 0x00, 0xb5, 0x07, 0xcb, 0x00, 0x00,
318 0x07, 0xc8, 0x00, 0xea, 0x07, 0xcf, 0x07, 0xf7,
319 0x07, 0x7e, 0x01, 0x0b, 0x00, 0x00, 0x00, 0x11,
320 0x26, 2, 0xaa, 0xaa,
321 0x2e, 1, 0x31,
322 0x38, 1, 0x01,
323 0x3a, 3, 0x14, 0xff, 0x5a,
324 0x43, 11, 0x00, 0x0a, 0x18, 0x11, 0x01, 0x2c, 0x88, 0x11,
325 0x00, 0x54, 0x11,
326 0x55, 1, 0x00,
327 0x62, 4, 0x10, 0x1e, 0x1e, 0x18,
328 0x6b, 1, 0x00,
329 0x6e, 3, 0x08, 0x06, 0x00,
330 0x72, 3, 0x00, 0xff, 0x00,
331 0x7d, 23, 0x01, 0x01, 0x58, 0x46, 0x50, 0x3c, 0x50, 0x3c,
332 0x54, 0x46, 0x54, 0x56, 0x52, 0x50, 0x52, 0x50,
333 0x56, 0x64, 0xa4, 0x00, 0xda, 0x00, 0x00,
334 0xa2, 10, 0x22, 0x2c, 0x3c, 0x54, 0x69, 0x7c, 0x9c, 0xb9,
335 0xd2, 0xeb,
336 0xaf, 1, 0x02,
337 0xb5, 2, 0x08, 0x08,
338 0xb8, 2, 0x08, 0x88,
339 0xc4, 4, 0xae, 0x01, 0x04, 0x01,
340 0xcc, 1, 0x00,
341 0xd1, 11, 0x01, 0x30, 0x49, 0x5e, 0x6f, 0x7f, 0x8e, 0xa9,
342 0xc1, 0xd7, 0xec,
343 0xdc, 1, 0x01,
344 0xff, 1, 0x01, /* page 1 */
345 0x12, 3, 0x02, 0x00, 0x01,
346 0x3e, 2, 0x00, 0x00,
347 0x76, 5, 0x01, 0x20, 0x40, 0x00, 0xf2,
348 0x7c, 1, 0x00,
349 0x7f, 10, 0x4b, 0x0f, 0x01, 0x2c, 0x02, 0x58, 0x03, 0x20,
350 0x02, 0x00,
351 0x96, 5, 0x01, 0x10, 0x04, 0x01, 0x04,
352 0xc8, 14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00,
353 0x07, 0x00, 0x01, 0x07, 0x04, 0x01,
354 0xd8, 1, 0x01,
355 0xdb, 2, 0x00, 0x01,
356 0xde, 7, 0x00, 0x01, 0x04, 0x04, 0x00, 0x00, 0x00,
357 0xe6, 4, 0x00, 0x00, 0x00, 0x01,
358 0xeb, 1, 0x00,
359 0xff, 1, 0x02, /* page 2 */
360 0x22, 1, 0x00,
361 0xff, 1, 0x03, /* page 3 */
362 0, LOAD_PAGE3, /* load the page 3 */
363 0x11, 1, 0x01,
364 0xff, 1, 0x02, /* page 2 */
365 0x13, 1, 0x00,
366 0x22, 4, 0x1f, 0xa4, 0xf0, 0x96,
367 0x27, 2, 0x14, 0x0c,
368 0x2a, 5, 0xc8, 0x00, 0x18, 0x12, 0x22,
369 0x64, 8, 0x00, 0x00, 0xf0, 0x01, 0x14, 0x44, 0x44, 0x44,
370 0x6e, 1, 0x08,
371 0xff, 1, 0x01, /* page 1 */
372 0x78, 1, 0x00,
373 0, END_OF_SEQUENCE /* end of sequence */
374};
375
376#define SKIP 0xaa
377/* page 3 - the value SKIP says skip the index - see reg_w_page() */
378static const __u8 page3_7302[] = {
379 0x90, 0x40, 0x03, 0x50, 0xc2, 0x01, 0x14, 0x16,
380 0x14, 0x12, 0x00, 0x00, 0x00, 0x02, 0x33, 0x00,
381 0x0f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
382 0x00, 0x00, 0x00, 0x47, 0x01, 0xb3, 0x01, 0x00,
383 0x00, 0x08, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x21,
384 0x00, 0x00, 0x00, 0x54, 0xf4, 0x02, 0x52, 0x54,
385 0xa4, 0xb8, 0xe0, 0x2a, 0xf6, 0x00, 0x00, 0x00,
386 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
387 0x00, 0xfc, 0x00, 0xf2, 0x1f, 0x04, 0x00, 0x00,
388 0x00, 0x00, 0x00, 0xc0, 0xc0, 0x10, 0x00, 0x00,
389 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
390 0x00, 0x40, 0xff, 0x03, 0x19, 0x00, 0x00, 0x00,
391 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
392 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0xc8, 0xc8,
393 0xc8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50,
394 0x08, 0x10, 0x24, 0x40, 0x00, 0x00, 0x00, 0x00,
395 0x01, 0x00, 0x02, 0x47, 0x00, 0x00, 0x00, 0x00,
396 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
397 0x00, 0x02, 0xfa, 0x00, 0x64, 0x5a, 0x28, 0x00,
398 0x00
399};
400
401static int reg_w_buf(struct gspca_dev *gspca_dev,
402 __u8 index,
403 const char *buffer, int len)
404{
405 int ret;
406
407 memcpy(gspca_dev->usb_buf, buffer, len);
408 ret = usb_control_msg(gspca_dev->dev,
409 usb_sndctrlpipe(gspca_dev->dev, 0),
410 1, /* request */
411 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
412 0, /* value */
413 index, gspca_dev->usb_buf, len,
414 500);
415 if (ret < 0)
416 PDEBUG(D_ERR, "reg_w_buf(): "
417 "Failed to write registers to index 0x%x, error %i",
418 index, ret);
419 return ret;
420}
421
422
423static int reg_w(struct gspca_dev *gspca_dev,
424 __u8 index,
425 __u8 value)
426{
427 int ret;
428
429 gspca_dev->usb_buf[0] = value;
430 ret = usb_control_msg(gspca_dev->dev,
431 usb_sndctrlpipe(gspca_dev->dev, 0),
432 0, /* request */
433 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
434 0, index, gspca_dev->usb_buf, 1,
435 500);
436 if (ret < 0)
437 PDEBUG(D_ERR, "reg_w(): "
438 "Failed to write register to index 0x%x, value 0x%x, error %i",
439 index, value, ret);
440 return ret;
441}
442
443static int reg_w_seq(struct gspca_dev *gspca_dev,
444 const __u8 *seq, int len)
445{
446 int ret = 0;
447 while (--len >= 0) {
448 if (0 <= ret)
449 ret = reg_w(gspca_dev, seq[0], seq[1]);
450 seq += 2;
451 }
452 return ret;
453}
454
455/* load the beginning of a page */
456static int reg_w_page(struct gspca_dev *gspca_dev,
457 const __u8 *page, int len)
458{
459 int index;
460 int ret = 0;
461
462 for (index = 0; index < len; index++) {
463 if (page[index] == SKIP) /* skip this index */
464 continue;
465 gspca_dev->usb_buf[0] = page[index];
466 ret = usb_control_msg(gspca_dev->dev,
467 usb_sndctrlpipe(gspca_dev->dev, 0),
468 0, /* request */
469 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
470 0, index, gspca_dev->usb_buf, 1,
471 500);
472 if (ret < 0) {
473 PDEBUG(D_ERR, "reg_w_page(): "
474 "Failed to write register to index 0x%x, "
475 "value 0x%x, error %i",
476 index, page[index], ret);
477 break;
478 }
479 }
480 return ret;
481}
482
483/* output a variable sequence */
484static int reg_w_var(struct gspca_dev *gspca_dev,
485 const __u8 *seq,
486 const __u8 *page3, unsigned int page3_len,
487 const __u8 *page4, unsigned int page4_len)
488{
489 int index, len;
490 int ret = 0;
491
492 for (;;) {
493 index = *seq++;
494 len = *seq++;
495 switch (len) {
496 case END_OF_SEQUENCE:
497 return ret;
498 case LOAD_PAGE4:
499 ret = reg_w_page(gspca_dev, page4, page4_len);
500 break;
501 case LOAD_PAGE3:
502 ret = reg_w_page(gspca_dev, page3, page3_len);
503 break;
504 default:
505 if (len > USB_BUF_SZ) {
506 PDEBUG(D_ERR|D_STREAM,
507 "Incorrect variable sequence");
508 return -EINVAL;
509 }
510 while (len > 0) {
511 if (len < 8) {
512 ret = reg_w_buf(gspca_dev,
513 index, seq, len);
514 if (ret < 0)
515 return ret;
516 seq += len;
517 break;
518 }
519 ret = reg_w_buf(gspca_dev, index, seq, 8);
520 seq += 8;
521 index += 8;
522 len -= 8;
523 }
524 }
525 if (ret < 0)
526 return ret;
527 }
528 /* not reached */
529}
530
531/* this function is called at probe time for pac7302 */
532static int sd_config(struct gspca_dev *gspca_dev,
533 const struct usb_device_id *id)
534{
535 struct sd *sd = (struct sd *) gspca_dev;
536 struct cam *cam;
537
538 cam = &gspca_dev->cam;
539
540 PDEBUG(D_CONF, "Find Sensor PAC7302");
541 cam->cam_mode = vga_mode; /* only 640x480 */
542 cam->nmodes = ARRAY_SIZE(vga_mode);
543
544 sd->brightness = BRIGHTNESS_DEF;
545 sd->contrast = CONTRAST_DEF;
546 sd->colors = COLOR_DEF;
547 sd->white_balance = WHITEBALANCE_DEF;
548 sd->red_balance = REDBALANCE_DEF;
549 sd->blue_balance = BLUEBALANCE_DEF;
550 sd->gain = GAIN_DEF;
551 sd->exposure = EXPOSURE_DEF;
552 sd->autogain = AUTOGAIN_DEF;
553 sd->hflip = HFLIP_DEF;
554 sd->vflip = VFLIP_DEF;
555 return 0;
556}
557
558/* This function is used by pac7302 only */
559static int setbrightcont(struct gspca_dev *gspca_dev)
560{
561 struct sd *sd = (struct sd *) gspca_dev;
562 int i, v;
563 int ret;
564 static const __u8 max[10] =
565 {0x29, 0x33, 0x42, 0x5a, 0x6e, 0x80, 0x9f, 0xbb,
566 0xd4, 0xec};
567 static const __u8 delta[10] =
568 {0x35, 0x33, 0x33, 0x2f, 0x2a, 0x25, 0x1e, 0x17,
569 0x11, 0x0b};
570
571 ret = reg_w(gspca_dev, 0xff, 0x00); /* page 0 */
572 for (i = 0; i < 10; i++) {
573 v = max[i];
574 v += (sd->brightness - BRIGHTNESS_MAX)
575 * 150 / BRIGHTNESS_MAX; /* 200 ? */
576 v -= delta[i] * sd->contrast / CONTRAST_MAX;
577 if (v < 0)
578 v = 0;
579 else if (v > 0xff)
580 v = 0xff;
581 if (0 <= ret)
582 ret = reg_w(gspca_dev, 0xa2 + i, v);
583 }
584 if (0 <= ret)
585 ret = reg_w(gspca_dev, 0xdc, 0x01);
586 return ret;
587}
588
589/* This function is used by pac7302 only */
590static int setcolors(struct gspca_dev *gspca_dev)
591{
592 struct sd *sd = (struct sd *) gspca_dev;
593 int i, v;
594 int ret;
595 static const int a[9] =
596 {217, -212, 0, -101, 170, -67, -38, -315, 355};
597 static const int b[9] =
598 {19, 106, 0, 19, 106, 1, 19, 106, 1};
599
600 ret = reg_w(gspca_dev, 0xff, 0x03); /* page 3 */
601 if (0 <= ret)
602 ret = reg_w(gspca_dev, 0x11, 0x01);
603 if (0 <= ret)
604 ret = reg_w(gspca_dev, 0xff, 0x00); /* page 0 */
605 for (i = 0; i < 9; i++) {
606 v = a[i] * sd->colors / COLOR_MAX + b[i];
607 if (0 <= ret)
608 ret = reg_w(gspca_dev, 0x0f + 2 * i, (v >> 8) & 0x07);
609 if (0 <= ret)
610 ret = reg_w(gspca_dev, 0x0f + 2 * i + 1, v);
611 }
612 if (0 <= ret)
613 ret = reg_w(gspca_dev, 0xdc, 0x01);
614 PDEBUG(D_CONF|D_STREAM, "color: %i", sd->colors);
615 return ret;
616}
617
618static int setwhitebalance(struct gspca_dev *gspca_dev)
619{
620 struct sd *sd = (struct sd *) gspca_dev;
621 int ret;
622
623 ret = reg_w(gspca_dev, 0xff, 0x00); /* page 0 */
624 if (0 <= ret)
625 ret = reg_w(gspca_dev, 0xc6, sd->white_balance);
626
627 if (0 <= ret)
628 ret = reg_w(gspca_dev, 0xdc, 0x01);
629 PDEBUG(D_CONF|D_STREAM, "white_balance: %i", sd->white_balance);
630 return ret;
631}
632
633static int setredbalance(struct gspca_dev *gspca_dev)
634{
635 struct sd *sd = (struct sd *) gspca_dev;
636 int ret;
637
638 ret = reg_w(gspca_dev, 0xff, 0x00); /* page 0 */
639 if (0 <= ret)
640 ret = reg_w(gspca_dev, 0xc5, sd->red_balance);
641
642 if (0 <= ret)
643 ret = reg_w(gspca_dev, 0xdc, 0x01);
644 PDEBUG(D_CONF|D_STREAM, "red_balance: %i", sd->red_balance);
645 return ret;
646}
647
648static int setbluebalance(struct gspca_dev *gspca_dev)
649{
650 struct sd *sd = (struct sd *) gspca_dev;
651 int ret;
652
653 ret = reg_w(gspca_dev, 0xff, 0x00); /* page 0 */
654 if (0 <= ret)
655 ret = reg_w(gspca_dev, 0xc7, sd->blue_balance);
656
657 if (0 <= ret)
658 ret = reg_w(gspca_dev, 0xdc, 0x01);
659 PDEBUG(D_CONF|D_STREAM, "blue_balance: %i", sd->blue_balance);
660 return ret;
661}
662
663static int setgain(struct gspca_dev *gspca_dev)
664{
665 struct sd *sd = (struct sd *) gspca_dev;
666 int ret;
667
668 ret = reg_w(gspca_dev, 0xff, 0x03); /* page 3 */
669 if (0 <= ret)
670 ret = reg_w(gspca_dev, 0x10, sd->gain >> 3);
671
672 /* load registers to sensor (Bit 0, auto clear) */
673 if (0 <= ret)
674 ret = reg_w(gspca_dev, 0x11, 0x01);
675 return ret;
676}
677
678static int setexposure(struct gspca_dev *gspca_dev)
679{
680 struct sd *sd = (struct sd *) gspca_dev;
681 int ret;
682 __u8 reg;
683
684 /* register 2 of frame 3/4 contains the clock divider configuring the
685 no fps according to the formula: 60 / reg. sd->exposure is the
686 desired exposure time in ms. */
687 reg = 120 * sd->exposure / 1000;
688 if (reg < 2)
689 reg = 2;
690 else if (reg > 63)
691 reg = 63;
692
693 /* On the pac7302 reg2 MUST be a multiple of 3, so round it to
694 the nearest multiple of 3, except when between 6 and 12? */
695 if (reg < 6 || reg > 12)
696 reg = ((reg + 1) / 3) * 3;
697 ret = reg_w(gspca_dev, 0xff, 0x03); /* page 3 */
698 if (0 <= ret)
699 ret = reg_w(gspca_dev, 0x02, reg);
700
701 /* load registers to sensor (Bit 0, auto clear) */
702 if (0 <= ret)
703 ret = reg_w(gspca_dev, 0x11, 0x01);
704 return ret;
705}
706
707static int sethvflip(struct gspca_dev *gspca_dev)
708{
709 struct sd *sd = (struct sd *) gspca_dev;
710 int ret;
711 __u8 data;
712
713 ret = reg_w(gspca_dev, 0xff, 0x03); /* page 3 */
714 data = (sd->hflip ? 0x08 : 0x00) | (sd->vflip ? 0x04 : 0x00);
715 if (0 <= ret)
716 ret = reg_w(gspca_dev, 0x21, data);
717 /* load registers to sensor (Bit 0, auto clear) */
718 if (0 <= ret)
719 ret = reg_w(gspca_dev, 0x11, 0x01);
720 return ret;
721}
722
723/* this function is called at probe and resume time for pac7302 */
724static int sd_init(struct gspca_dev *gspca_dev)
725{
726 return reg_w_seq(gspca_dev, init_7302, sizeof(init_7302)/2);
727}
728
729static int sd_start(struct gspca_dev *gspca_dev)
730{
731 struct sd *sd = (struct sd *) gspca_dev;
732 int ret = 0;
733
734 sd->sof_read = 0;
735
736 ret = reg_w_var(gspca_dev, start_7302,
737 page3_7302, sizeof(page3_7302),
738 NULL, 0);
739 if (0 <= ret)
740 ret = setbrightcont(gspca_dev);
741 if (0 <= ret)
742 ret = setcolors(gspca_dev);
743 if (0 <= ret)
744 ret = setwhitebalance(gspca_dev);
745 if (0 <= ret)
746 ret = setredbalance(gspca_dev);
747 if (0 <= ret)
748 ret = setbluebalance(gspca_dev);
749 if (0 <= ret)
750 ret = setgain(gspca_dev);
751 if (0 <= ret)
752 ret = setexposure(gspca_dev);
753 if (0 <= ret)
754 ret = sethvflip(gspca_dev);
755
756 /* only resolution 640x480 is supported for pac7302 */
757
758 sd->sof_read = 0;
759 sd->autogain_ignore_frames = 0;
760 atomic_set(&sd->avg_lum, -1);
761
762 /* start stream */
763 if (0 <= ret)
764 ret = reg_w(gspca_dev, 0xff, 0x01);
765 if (0 <= ret)
766 ret = reg_w(gspca_dev, 0x78, 0x01);
767
768 return ret;
769}
770
771static void sd_stopN(struct gspca_dev *gspca_dev)
772{
773 int ret;
774
775 /* stop stream */
776 ret = reg_w(gspca_dev, 0xff, 0x01);
777 if (0 <= ret)
778 ret = reg_w(gspca_dev, 0x78, 0x00);
779}
780
781/* called on streamoff with alt 0 and on disconnect for pac7302 */
782static void sd_stop0(struct gspca_dev *gspca_dev)
783{
784 int ret;
785
786 if (!gspca_dev->present)
787 return;
788 ret = reg_w(gspca_dev, 0xff, 0x01);
789 if (0 <= ret)
790 ret = reg_w(gspca_dev, 0x78, 0x40);
791}
792
793/* Include pac common sof detection functions */
794#include "pac_common.h"
795
796static void do_autogain(struct gspca_dev *gspca_dev)
797{
798 struct sd *sd = (struct sd *) gspca_dev;
799 int avg_lum = atomic_read(&sd->avg_lum);
800 int desired_lum, deadzone;
801
802 if (avg_lum == -1)
803 return;
804
805 desired_lum = 270 + sd->brightness * 4;
806 /* Hack hack, with the 7202 the first exposure step is
807 pretty large, so if we're about to make the first
808 exposure increase make the deadzone large to avoid
809 oscilating */
810 if (desired_lum > avg_lum && sd->gain == GAIN_DEF &&
811 sd->exposure > EXPOSURE_DEF &&
812 sd->exposure < 42)
813 deadzone = 90;
814 else
815 deadzone = 30;
816
817 if (sd->autogain_ignore_frames > 0)
818 sd->autogain_ignore_frames--;
819 else if (gspca_auto_gain_n_exposure(gspca_dev, avg_lum, desired_lum,
820 deadzone, GAIN_KNEE, EXPOSURE_KNEE))
821 sd->autogain_ignore_frames = PAC_AUTOGAIN_IGNORE_FRAMES;
822}
823
824/* JPEG header, part 1 */
825static const unsigned char pac_jpeg_header1[] = {
826 0xff, 0xd8, /* SOI: Start of Image */
827
828 0xff, 0xc0, /* SOF0: Start of Frame (Baseline DCT) */
829 0x00, 0x11, /* length = 17 bytes (including this length field) */
830 0x08 /* Precision: 8 */
831 /* 2 bytes is placed here: number of image lines */
832 /* 2 bytes is placed here: samples per line */
833};
834
835/* JPEG header, continued */
836static const unsigned char pac_jpeg_header2[] = {
837 0x03, /* Number of image components: 3 */
838 0x01, 0x21, 0x00, /* ID=1, Subsampling 1x1, Quantization table: 0 */
839 0x02, 0x11, 0x01, /* ID=2, Subsampling 2x1, Quantization table: 1 */
840 0x03, 0x11, 0x01, /* ID=3, Subsampling 2x1, Quantization table: 1 */
841
842 0xff, 0xda, /* SOS: Start Of Scan */
843 0x00, 0x0c, /* length = 12 bytes (including this length field) */
844 0x03, /* number of components: 3 */
845 0x01, 0x00, /* selector 1, table 0x00 */
846 0x02, 0x11, /* selector 2, table 0x11 */
847 0x03, 0x11, /* selector 3, table 0x11 */
848 0x00, 0x3f, /* Spectral selection: 0 .. 63 */
849 0x00 /* Successive approximation: 0 */
850};
851
852static void pac_start_frame(struct gspca_dev *gspca_dev,
853 struct gspca_frame *frame,
854 __u16 lines, __u16 samples_per_line)
855{
856 unsigned char tmpbuf[4];
857
858 gspca_frame_add(gspca_dev, FIRST_PACKET,
859 pac_jpeg_header1, sizeof(pac_jpeg_header1));
860
861 tmpbuf[0] = lines >> 8;
862 tmpbuf[1] = lines & 0xff;
863 tmpbuf[2] = samples_per_line >> 8;
864 tmpbuf[3] = samples_per_line & 0xff;
865
866 gspca_frame_add(gspca_dev, INTER_PACKET,
867 tmpbuf, sizeof(tmpbuf));
868 gspca_frame_add(gspca_dev, INTER_PACKET,
869 pac_jpeg_header2, sizeof(pac_jpeg_header2));
870}
871
872/* this function is run at interrupt level */
873static void sd_pkt_scan(struct gspca_dev *gspca_dev,
874 u8 *data, /* isoc packet */
875 int len) /* iso packet length */
876{
877 struct sd *sd = (struct sd *) gspca_dev;
878 struct gspca_frame *frame;
879 unsigned char *sof;
880
881 sof = pac_find_sof(&sd->sof_read, data, len);
882 if (sof) {
883 int n, lum_offset, footer_length;
884
885 frame = gspca_get_i_frame(gspca_dev);
886 if (frame == NULL) {
887 gspca_dev->last_packet_type = DISCARD_PACKET;
888 return;
889 }
890
891 /* 6 bytes after the FF D9 EOF marker a number of lumination
892 bytes are send corresponding to different parts of the
893 image, the 14th and 15th byte after the EOF seem to
894 correspond to the center of the image */
895 lum_offset = 61 + sizeof pac_sof_marker;
896 footer_length = 74;
897
898 /* Finish decoding current frame */
899 n = (sof - data) - (footer_length + sizeof pac_sof_marker);
900 if (n < 0) {
901 frame->data_end += n;
902 n = 0;
903 }
904 gspca_frame_add(gspca_dev, INTER_PACKET,
905 data, n);
906 if (gspca_dev->last_packet_type != DISCARD_PACKET &&
907 frame->data_end[-2] == 0xff &&
908 frame->data_end[-1] == 0xd9)
909 gspca_frame_add(gspca_dev, LAST_PACKET,
910 NULL, 0);
911
912 n = sof - data;
913 len -= n;
914 data = sof;
915
916 /* Get average lumination */
917 if (gspca_dev->last_packet_type == LAST_PACKET &&
918 n >= lum_offset)
919 atomic_set(&sd->avg_lum, data[-lum_offset] +
920 data[-lum_offset + 1]);
921 else
922 atomic_set(&sd->avg_lum, -1);
923
924 /* Start the new frame with the jpeg header */
925 /* The PAC7302 has the image rotated 90 degrees */
926 pac_start_frame(gspca_dev, frame,
927 gspca_dev->width, gspca_dev->height);
928 }
929 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
930}
931
932static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
933{
934 struct sd *sd = (struct sd *) gspca_dev;
935
936 sd->brightness = val;
937 if (gspca_dev->streaming)
938 setbrightcont(gspca_dev);
939 return 0;
940}
941
942static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
943{
944 struct sd *sd = (struct sd *) gspca_dev;
945
946 *val = sd->brightness;
947 return 0;
948}
949
950static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
951{
952 struct sd *sd = (struct sd *) gspca_dev;
953
954 sd->contrast = val;
955 if (gspca_dev->streaming) {
956 setbrightcont(gspca_dev);
957 }
958 return 0;
959}
960
961static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
962{
963 struct sd *sd = (struct sd *) gspca_dev;
964
965 *val = sd->contrast;
966 return 0;
967}
968
969static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
970{
971 struct sd *sd = (struct sd *) gspca_dev;
972
973 sd->colors = val;
974 if (gspca_dev->streaming)
975 setcolors(gspca_dev);
976 return 0;
977}
978
979static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
980{
981 struct sd *sd = (struct sd *) gspca_dev;
982
983 *val = sd->colors;
984 return 0;
985}
986
987static int sd_setwhitebalance(struct gspca_dev *gspca_dev, __s32 val)
988{
989 struct sd *sd = (struct sd *) gspca_dev;
990 int ret = 0;
991
992 sd->white_balance = val;
993 if (gspca_dev->streaming)
994 ret = setwhitebalance(gspca_dev);
995 if (0 <= ret)
996 ret = 0;
997 return ret;
998}
999
1000static int sd_getwhitebalance(struct gspca_dev *gspca_dev, __s32 *val)
1001{
1002 struct sd *sd = (struct sd *) gspca_dev;
1003
1004 *val = sd->white_balance;
1005 return 0;
1006}
1007
1008static int sd_setredbalance(struct gspca_dev *gspca_dev, __s32 val)
1009{
1010 struct sd *sd = (struct sd *) gspca_dev;
1011 int ret = 0;
1012
1013 sd->red_balance = val;
1014 if (gspca_dev->streaming)
1015 ret = setredbalance(gspca_dev);
1016 if (0 <= ret)
1017 ret = 0;
1018 return ret;
1019}
1020
1021static int sd_getredbalance(struct gspca_dev *gspca_dev, __s32 *val)
1022{
1023 struct sd *sd = (struct sd *) gspca_dev;
1024
1025 *val = sd->red_balance;
1026 return 0;
1027}
1028
1029static int sd_setbluebalance(struct gspca_dev *gspca_dev, __s32 val)
1030{
1031 struct sd *sd = (struct sd *) gspca_dev;
1032 int ret = 0;
1033
1034 sd->blue_balance = val;
1035 if (gspca_dev->streaming)
1036 ret = setbluebalance(gspca_dev);
1037 if (0 <= ret)
1038 ret = 0;
1039 return ret;
1040}
1041
1042static int sd_getbluebalance(struct gspca_dev *gspca_dev, __s32 *val)
1043{
1044 struct sd *sd = (struct sd *) gspca_dev;
1045
1046 *val = sd->blue_balance;
1047 return 0;
1048}
1049
1050static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val)
1051{
1052 struct sd *sd = (struct sd *) gspca_dev;
1053
1054 sd->gain = val;
1055 if (gspca_dev->streaming)
1056 setgain(gspca_dev);
1057 return 0;
1058}
1059
1060static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val)
1061{
1062 struct sd *sd = (struct sd *) gspca_dev;
1063
1064 *val = sd->gain;
1065 return 0;
1066}
1067
1068static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val)
1069{
1070 struct sd *sd = (struct sd *) gspca_dev;
1071
1072 sd->exposure = val;
1073 if (gspca_dev->streaming)
1074 setexposure(gspca_dev);
1075 return 0;
1076}
1077
1078static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val)
1079{
1080 struct sd *sd = (struct sd *) gspca_dev;
1081
1082 *val = sd->exposure;
1083 return 0;
1084}
1085
1086static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
1087{
1088 struct sd *sd = (struct sd *) gspca_dev;
1089
1090 sd->autogain = val;
1091 /* when switching to autogain set defaults to make sure
1092 we are on a valid point of the autogain gain /
1093 exposure knee graph, and give this change time to
1094 take effect before doing autogain. */
1095 if (sd->autogain) {
1096 sd->exposure = EXPOSURE_DEF;
1097 sd->gain = GAIN_DEF;
1098 if (gspca_dev->streaming) {
1099 sd->autogain_ignore_frames =
1100 PAC_AUTOGAIN_IGNORE_FRAMES;
1101 setexposure(gspca_dev);
1102 setgain(gspca_dev);
1103 }
1104 }
1105
1106 return 0;
1107}
1108
1109static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
1110{
1111 struct sd *sd = (struct sd *) gspca_dev;
1112
1113 *val = sd->autogain;
1114 return 0;
1115}
1116
1117static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val)
1118{
1119 struct sd *sd = (struct sd *) gspca_dev;
1120
1121 sd->hflip = val;
1122 if (gspca_dev->streaming)
1123 sethvflip(gspca_dev);
1124 return 0;
1125}
1126
1127static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val)
1128{
1129 struct sd *sd = (struct sd *) gspca_dev;
1130
1131 *val = sd->hflip;
1132 return 0;
1133}
1134
1135static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val)
1136{
1137 struct sd *sd = (struct sd *) gspca_dev;
1138
1139 sd->vflip = val;
1140 if (gspca_dev->streaming)
1141 sethvflip(gspca_dev);
1142 return 0;
1143}
1144
1145static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val)
1146{
1147 struct sd *sd = (struct sd *) gspca_dev;
1148
1149 *val = sd->vflip;
1150 return 0;
1151}
1152
1153#ifdef CONFIG_VIDEO_ADV_DEBUG
1154static int sd_dbg_s_register(struct gspca_dev *gspca_dev,
1155 struct v4l2_dbg_register *reg)
1156{
1157 int ret = -EINVAL;
1158 __u8 index;
1159 __u8 value;
1160
1161 /* reg->reg: bit0..15: reserved for register index (wIndex is 16bit
1162 long on the USB bus)
1163 */
1164 if (reg->match.type == V4L2_CHIP_MATCH_HOST &&
1165 reg->match.addr == 0 &&
1166 (reg->reg < 0x000000ff) &&
1167 (reg->val <= 0x000000ff)
1168 ) {
1169 /* Currently writing to page 0 is only supported. */
1170 /* reg_w() only supports 8bit index */
1171 index = reg->reg & 0x000000ff;
1172 value = reg->val & 0x000000ff;
1173
1174 /* Note that there shall be no access to other page
1175 by any other function between the page swith and
1176 the actual register write */
1177 ret = reg_w(gspca_dev, 0xff, 0x00); /* page 0 */
1178 if (0 <= ret)
1179 ret = reg_w(gspca_dev, index, value);
1180
1181 if (0 <= ret)
1182 ret = reg_w(gspca_dev, 0xdc, 0x01);
1183 }
1184 return ret;
1185}
1186
1187static int sd_chip_ident(struct gspca_dev *gspca_dev,
1188 struct v4l2_dbg_chip_ident *chip)
1189{
1190 int ret = -EINVAL;
1191
1192 if (chip->match.type == V4L2_CHIP_MATCH_HOST &&
1193 chip->match.addr == 0) {
1194 chip->revision = 0;
1195 chip->ident = V4L2_IDENT_UNKNOWN;
1196 ret = 0;
1197 }
1198 return ret;
1199}
1200#endif
1201
1202/* sub-driver description for pac7302 */
1203static struct sd_desc sd_desc = {
1204 .name = MODULE_NAME,
1205 .ctrls = sd_ctrls,
1206 .nctrls = ARRAY_SIZE(sd_ctrls),
1207 .config = sd_config,
1208 .init = sd_init,
1209 .start = sd_start,
1210 .stopN = sd_stopN,
1211 .stop0 = sd_stop0,
1212 .pkt_scan = sd_pkt_scan,
1213 .dq_callback = do_autogain,
1214#ifdef CONFIG_VIDEO_ADV_DEBUG
1215 .set_register = sd_dbg_s_register,
1216 .get_chip_ident = sd_chip_ident,
1217#endif
1218};
1219
1220/* -- module initialisation -- */
1221static __devinitdata struct usb_device_id device_table[] = {
1222 {USB_DEVICE(0x06f8, 0x3009)},
1223 {USB_DEVICE(0x093a, 0x2620)},
1224 {USB_DEVICE(0x093a, 0x2621)},
1225 {USB_DEVICE(0x093a, 0x2622)},
1226 {USB_DEVICE(0x093a, 0x2624)},
1227 {USB_DEVICE(0x093a, 0x2626)},
1228 {USB_DEVICE(0x093a, 0x2628)},
1229 {USB_DEVICE(0x093a, 0x2629)},
1230 {USB_DEVICE(0x093a, 0x262a)},
1231 {USB_DEVICE(0x093a, 0x262c)},
1232 {}
1233};
1234MODULE_DEVICE_TABLE(usb, device_table);
1235
1236/* -- device connect -- */
1237static int sd_probe(struct usb_interface *intf,
1238 const struct usb_device_id *id)
1239{
1240 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1241 THIS_MODULE);
1242}
1243
1244static struct usb_driver sd_driver = {
1245 .name = MODULE_NAME,
1246 .id_table = device_table,
1247 .probe = sd_probe,
1248 .disconnect = gspca_disconnect,
1249#ifdef CONFIG_PM
1250 .suspend = gspca_suspend,
1251 .resume = gspca_resume,
1252#endif
1253};
1254
1255/* -- module insert / remove -- */
1256static int __init sd_mod_init(void)
1257{
1258 int ret;
1259 ret = usb_register(&sd_driver);
1260 if (ret < 0)
1261 return ret;
1262 PDEBUG(D_PROBE, "registered");
1263 return 0;
1264}
1265static void __exit sd_mod_exit(void)
1266{
1267 usb_deregister(&sd_driver);
1268 PDEBUG(D_PROBE, "deregistered");
1269}
1270
1271module_init(sd_mod_init);
1272module_exit(sd_mod_exit);
diff --git a/drivers/media/video/gspca/pac7311.c b/drivers/media/video/gspca/pac7311.c
index 052714484e83..e5697a6345e8 100644
--- a/drivers/media/video/gspca/pac7311.c
+++ b/drivers/media/video/gspca/pac7311.c
@@ -57,23 +57,17 @@ MODULE_AUTHOR("Thomas Kaiser thomas@kaiser-linux.li");
57MODULE_DESCRIPTION("Pixart PAC7311"); 57MODULE_DESCRIPTION("Pixart PAC7311");
58MODULE_LICENSE("GPL"); 58MODULE_LICENSE("GPL");
59 59
60/* specific webcam descriptor */ 60/* specific webcam descriptor for pac7311 */
61struct sd { 61struct sd {
62 struct gspca_dev gspca_dev; /* !! must be the first item */ 62 struct gspca_dev gspca_dev; /* !! must be the first item */
63 63
64 unsigned char brightness;
65 unsigned char contrast; 64 unsigned char contrast;
66 unsigned char colors;
67 unsigned char gain; 65 unsigned char gain;
68 unsigned char exposure; 66 unsigned char exposure;
69 unsigned char autogain; 67 unsigned char autogain;
70 __u8 hflip; 68 __u8 hflip;
71 __u8 vflip; 69 __u8 vflip;
72 70
73 __u8 sensor;
74#define SENSOR_PAC7302 0
75#define SENSOR_PAC7311 1
76
77 u8 sof_read; 71 u8 sof_read;
78 u8 autogain_ignore_frames; 72 u8 autogain_ignore_frames;
79 73
@@ -81,12 +75,8 @@ struct sd {
81}; 75};
82 76
83/* V4L2 controls supported by the driver */ 77/* V4L2 controls supported by the driver */
84static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
85static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
86static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val); 78static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
87static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); 79static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
88static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
89static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
90static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val); 80static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
91static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val); 81static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
92static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val); 82static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val);
@@ -99,23 +89,6 @@ static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val);
99static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val); 89static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val);
100 90
101static struct ctrl sd_ctrls[] = { 91static struct ctrl sd_ctrls[] = {
102/* This control is pac7302 only */
103#define BRIGHTNESS_IDX 0
104 {
105 {
106 .id = V4L2_CID_BRIGHTNESS,
107 .type = V4L2_CTRL_TYPE_INTEGER,
108 .name = "Brightness",
109 .minimum = 0,
110#define BRIGHTNESS_MAX 0x20
111 .maximum = BRIGHTNESS_MAX,
112 .step = 1,
113#define BRIGHTNESS_DEF 0x10
114 .default_value = BRIGHTNESS_DEF,
115 },
116 .set = sd_setbrightness,
117 .get = sd_getbrightness,
118 },
119/* This control is for both the 7302 and the 7311 */ 92/* This control is for both the 7302 and the 7311 */
120 { 93 {
121 { 94 {
@@ -132,23 +105,6 @@ static struct ctrl sd_ctrls[] = {
132 .set = sd_setcontrast, 105 .set = sd_setcontrast,
133 .get = sd_getcontrast, 106 .get = sd_getcontrast,
134 }, 107 },
135/* This control is pac7302 only */
136#define SATURATION_IDX 2
137 {
138 {
139 .id = V4L2_CID_SATURATION,
140 .type = V4L2_CTRL_TYPE_INTEGER,
141 .name = "Saturation",
142 .minimum = 0,
143#define COLOR_MAX 255
144 .maximum = COLOR_MAX,
145 .step = 1,
146#define COLOR_DEF 127
147 .default_value = COLOR_DEF,
148 },
149 .set = sd_setcolors,
150 .get = sd_getcolors,
151 },
152/* All controls below are for both the 7302 and the 7311 */ 108/* All controls below are for both the 7302 and the 7311 */
153 { 109 {
154 { 110 {
@@ -244,101 +200,9 @@ static const struct v4l2_pix_format vga_mode[] = {
244 .priv = 0}, 200 .priv = 0},
245}; 201};
246 202
247/* pac 7302 */ 203#define LOAD_PAGE3 255
248static const __u8 init_7302[] = { 204#define LOAD_PAGE4 254
249/* index,value */ 205#define END_OF_SEQUENCE 0
250 0xff, 0x01, /* page 1 */
251 0x78, 0x00, /* deactivate */
252 0xff, 0x01,
253 0x78, 0x40, /* led off */
254};
255static const __u8 start_7302[] = {
256/* index, len, [value]* */
257 0xff, 1, 0x00, /* page 0 */
258 0x00, 12, 0x01, 0x40, 0x40, 0x40, 0x01, 0xe0, 0x02, 0x80,
259 0x00, 0x00, 0x00, 0x00,
260 0x0d, 24, 0x03, 0x01, 0x00, 0xb5, 0x07, 0xcb, 0x00, 0x00,
261 0x07, 0xc8, 0x00, 0xea, 0x07, 0xcf, 0x07, 0xf7,
262 0x07, 0x7e, 0x01, 0x0b, 0x00, 0x00, 0x00, 0x11,
263 0x26, 2, 0xaa, 0xaa,
264 0x2e, 1, 0x31,
265 0x38, 1, 0x01,
266 0x3a, 3, 0x14, 0xff, 0x5a,
267 0x43, 11, 0x00, 0x0a, 0x18, 0x11, 0x01, 0x2c, 0x88, 0x11,
268 0x00, 0x54, 0x11,
269 0x55, 1, 0x00,
270 0x62, 4, 0x10, 0x1e, 0x1e, 0x18,
271 0x6b, 1, 0x00,
272 0x6e, 3, 0x08, 0x06, 0x00,
273 0x72, 3, 0x00, 0xff, 0x00,
274 0x7d, 23, 0x01, 0x01, 0x58, 0x46, 0x50, 0x3c, 0x50, 0x3c,
275 0x54, 0x46, 0x54, 0x56, 0x52, 0x50, 0x52, 0x50,
276 0x56, 0x64, 0xa4, 0x00, 0xda, 0x00, 0x00,
277 0xa2, 10, 0x22, 0x2c, 0x3c, 0x54, 0x69, 0x7c, 0x9c, 0xb9,
278 0xd2, 0xeb,
279 0xaf, 1, 0x02,
280 0xb5, 2, 0x08, 0x08,
281 0xb8, 2, 0x08, 0x88,
282 0xc4, 4, 0xae, 0x01, 0x04, 0x01,
283 0xcc, 1, 0x00,
284 0xd1, 11, 0x01, 0x30, 0x49, 0x5e, 0x6f, 0x7f, 0x8e, 0xa9,
285 0xc1, 0xd7, 0xec,
286 0xdc, 1, 0x01,
287 0xff, 1, 0x01, /* page 1 */
288 0x12, 3, 0x02, 0x00, 0x01,
289 0x3e, 2, 0x00, 0x00,
290 0x76, 5, 0x01, 0x20, 0x40, 0x00, 0xf2,
291 0x7c, 1, 0x00,
292 0x7f, 10, 0x4b, 0x0f, 0x01, 0x2c, 0x02, 0x58, 0x03, 0x20,
293 0x02, 0x00,
294 0x96, 5, 0x01, 0x10, 0x04, 0x01, 0x04,
295 0xc8, 14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00,
296 0x07, 0x00, 0x01, 0x07, 0x04, 0x01,
297 0xd8, 1, 0x01,
298 0xdb, 2, 0x00, 0x01,
299 0xde, 7, 0x00, 0x01, 0x04, 0x04, 0x00, 0x00, 0x00,
300 0xe6, 4, 0x00, 0x00, 0x00, 0x01,
301 0xeb, 1, 0x00,
302 0xff, 1, 0x02, /* page 2 */
303 0x22, 1, 0x00,
304 0xff, 1, 0x03, /* page 3 */
305 0x00, 255, /* load the page 3 */
306 0x11, 1, 0x01,
307 0xff, 1, 0x02, /* page 2 */
308 0x13, 1, 0x00,
309 0x22, 4, 0x1f, 0xa4, 0xf0, 0x96,
310 0x27, 2, 0x14, 0x0c,
311 0x2a, 5, 0xc8, 0x00, 0x18, 0x12, 0x22,
312 0x64, 8, 0x00, 0x00, 0xf0, 0x01, 0x14, 0x44, 0x44, 0x44,
313 0x6e, 1, 0x08,
314 0xff, 1, 0x01, /* page 1 */
315 0x78, 1, 0x00,
316 0, 0 /* end of sequence */
317};
318
319/* page 3 - the value 0xaa says skip the index - see reg_w_page() */
320static const __u8 page3_7302[] = {
321 0x90, 0x40, 0x03, 0x50, 0xc2, 0x01, 0x14, 0x16,
322 0x14, 0x12, 0x00, 0x00, 0x00, 0x02, 0x33, 0x00,
323 0x0f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
324 0x00, 0x00, 0x00, 0x47, 0x01, 0xb3, 0x01, 0x00,
325 0x00, 0x08, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x21,
326 0x00, 0x00, 0x00, 0x54, 0xf4, 0x02, 0x52, 0x54,
327 0xa4, 0xb8, 0xe0, 0x2a, 0xf6, 0x00, 0x00, 0x00,
328 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
329 0x00, 0xfc, 0x00, 0xf2, 0x1f, 0x04, 0x00, 0x00,
330 0x00, 0x00, 0x00, 0xc0, 0xc0, 0x10, 0x00, 0x00,
331 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
332 0x00, 0x40, 0xff, 0x03, 0x19, 0x00, 0x00, 0x00,
333 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
334 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0xc8, 0xc8,
335 0xc8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50,
336 0x08, 0x10, 0x24, 0x40, 0x00, 0x00, 0x00, 0x00,
337 0x01, 0x00, 0x02, 0x47, 0x00, 0x00, 0x00, 0x00,
338 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
339 0x00, 0x02, 0xfa, 0x00, 0x64, 0x5a, 0x28, 0x00,
340 0x00
341};
342 206
343/* pac 7311 */ 207/* pac 7311 */
344static const __u8 init_7311[] = { 208static const __u8 init_7311[] = {
@@ -378,119 +242,154 @@ static const __u8 start_7311[] = {
378 0xf0, 13, 0x01, 0x00, 0x00, 0x00, 0x22, 0x00, 0x20, 0x00, 242 0xf0, 13, 0x01, 0x00, 0x00, 0x00, 0x22, 0x00, 0x20, 0x00,
379 0x3f, 0x00, 0x0a, 0x01, 0x00, 243 0x3f, 0x00, 0x0a, 0x01, 0x00,
380 0xff, 1, 0x04, /* page 4 */ 244 0xff, 1, 0x04, /* page 4 */
381 0x00, 254, /* load the page 4 */ 245 0, LOAD_PAGE4, /* load the page 4 */
382 0x11, 1, 0x01, 246 0x11, 1, 0x01,
383 0, 0 /* end of sequence */ 247 0, END_OF_SEQUENCE /* end of sequence */
384}; 248};
385 249
386/* page 4 - the value 0xaa says skip the index - see reg_w_page() */ 250#define SKIP 0xaa
251/* page 4 - the value SKIP says skip the index - see reg_w_page() */
387static const __u8 page4_7311[] = { 252static const __u8 page4_7311[] = {
388 0xaa, 0xaa, 0x04, 0x54, 0x07, 0x2b, 0x09, 0x0f, 253 SKIP, SKIP, 0x04, 0x54, 0x07, 0x2b, 0x09, 0x0f,
389 0x09, 0x00, 0xaa, 0xaa, 0x07, 0x00, 0x00, 0x62, 254 0x09, 0x00, SKIP, SKIP, 0x07, 0x00, 0x00, 0x62,
390 0x08, 0xaa, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 255 0x08, SKIP, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
391 0x00, 0x00, 0x00, 0x03, 0xa0, 0x01, 0xf4, 0xaa, 256 0x00, 0x00, 0x00, 0x03, 0xa0, 0x01, 0xf4, SKIP,
392 0xaa, 0x00, 0x08, 0xaa, 0x03, 0xaa, 0x00, 0x68, 257 SKIP, 0x00, 0x08, SKIP, 0x03, SKIP, 0x00, 0x68,
393 0xca, 0x10, 0x06, 0x78, 0x00, 0x00, 0x00, 0x00, 258 0xca, 0x10, 0x06, 0x78, 0x00, 0x00, 0x00, 0x00,
394 0x23, 0x28, 0x04, 0x11, 0x00, 0x00 259 0x23, 0x28, 0x04, 0x11, 0x00, 0x00
395}; 260};
396 261
397static void reg_w_buf(struct gspca_dev *gspca_dev, 262static int reg_w_buf(struct gspca_dev *gspca_dev,
398 __u8 index, 263 __u8 index,
399 const char *buffer, int len) 264 const char *buffer, int len)
400{ 265{
266 int ret;
267
401 memcpy(gspca_dev->usb_buf, buffer, len); 268 memcpy(gspca_dev->usb_buf, buffer, len);
402 usb_control_msg(gspca_dev->dev, 269 ret = usb_control_msg(gspca_dev->dev,
403 usb_sndctrlpipe(gspca_dev->dev, 0), 270 usb_sndctrlpipe(gspca_dev->dev, 0),
404 1, /* request */ 271 1, /* request */
405 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 272 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
406 0, /* value */ 273 0, /* value */
407 index, gspca_dev->usb_buf, len, 274 index, gspca_dev->usb_buf, len,
408 500); 275 500);
276 if (ret < 0)
277 PDEBUG(D_ERR, "reg_w_buf(): "
278 "Failed to write registers to index 0x%x, error %i",
279 index, ret);
280 return ret;
409} 281}
410 282
411 283
412static void reg_w(struct gspca_dev *gspca_dev, 284static int reg_w(struct gspca_dev *gspca_dev,
413 __u8 index, 285 __u8 index,
414 __u8 value) 286 __u8 value)
415{ 287{
288 int ret;
289
416 gspca_dev->usb_buf[0] = value; 290 gspca_dev->usb_buf[0] = value;
417 usb_control_msg(gspca_dev->dev, 291 ret = usb_control_msg(gspca_dev->dev,
418 usb_sndctrlpipe(gspca_dev->dev, 0), 292 usb_sndctrlpipe(gspca_dev->dev, 0),
419 0, /* request */ 293 0, /* request */
420 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 294 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
421 0, index, gspca_dev->usb_buf, 1, 295 0, index, gspca_dev->usb_buf, 1,
422 500); 296 500);
297 if (ret < 0)
298 PDEBUG(D_ERR, "reg_w(): "
299 "Failed to write register to index 0x%x, value 0x%x, error %i",
300 index, value, ret);
301 return ret;
423} 302}
424 303
425static void reg_w_seq(struct gspca_dev *gspca_dev, 304static int reg_w_seq(struct gspca_dev *gspca_dev,
426 const __u8 *seq, int len) 305 const __u8 *seq, int len)
427{ 306{
307 int ret = 0;
428 while (--len >= 0) { 308 while (--len >= 0) {
429 reg_w(gspca_dev, seq[0], seq[1]); 309 if (0 <= ret)
310 ret = reg_w(gspca_dev, seq[0], seq[1]);
430 seq += 2; 311 seq += 2;
431 } 312 }
313 return ret;
432} 314}
433 315
434/* load the beginning of a page */ 316/* load the beginning of a page */
435static void reg_w_page(struct gspca_dev *gspca_dev, 317static int reg_w_page(struct gspca_dev *gspca_dev,
436 const __u8 *page, int len) 318 const __u8 *page, int len)
437{ 319{
438 int index; 320 int index;
321 int ret = 0;
439 322
440 for (index = 0; index < len; index++) { 323 for (index = 0; index < len; index++) {
441 if (page[index] == 0xaa) /* skip this index */ 324 if (page[index] == SKIP) /* skip this index */
442 continue; 325 continue;
443 gspca_dev->usb_buf[0] = page[index]; 326 gspca_dev->usb_buf[0] = page[index];
444 usb_control_msg(gspca_dev->dev, 327 ret = usb_control_msg(gspca_dev->dev,
445 usb_sndctrlpipe(gspca_dev->dev, 0), 328 usb_sndctrlpipe(gspca_dev->dev, 0),
446 0, /* request */ 329 0, /* request */
447 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 330 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
448 0, index, gspca_dev->usb_buf, 1, 331 0, index, gspca_dev->usb_buf, 1,
449 500); 332 500);
333 if (ret < 0) {
334 PDEBUG(D_ERR, "reg_w_page(): "
335 "Failed to write register to index 0x%x, "
336 "value 0x%x, error %i",
337 index, page[index], ret);
338 break;
339 }
450 } 340 }
341 return ret;
451} 342}
452 343
453/* output a variable sequence */ 344/* output a variable sequence */
454static void reg_w_var(struct gspca_dev *gspca_dev, 345static int reg_w_var(struct gspca_dev *gspca_dev,
455 const __u8 *seq) 346 const __u8 *seq,
347 const __u8 *page3, unsigned int page3_len,
348 const __u8 *page4, unsigned int page4_len)
456{ 349{
457 int index, len; 350 int index, len;
351 int ret = 0;
458 352
459 for (;;) { 353 for (;;) {
460 index = *seq++; 354 index = *seq++;
461 len = *seq++; 355 len = *seq++;
462 switch (len) { 356 switch (len) {
463 case 0: 357 case END_OF_SEQUENCE:
464 return; 358 return ret;
465 case 254: 359 case LOAD_PAGE4:
466 reg_w_page(gspca_dev, page4_7311, sizeof page4_7311); 360 ret = reg_w_page(gspca_dev, page4, page4_len);
467 break; 361 break;
468 case 255: 362 case LOAD_PAGE3:
469 reg_w_page(gspca_dev, page3_7302, sizeof page3_7302); 363 ret = reg_w_page(gspca_dev, page3, page3_len);
470 break; 364 break;
471 default: 365 default:
472 if (len > 64) { 366 if (len > USB_BUF_SZ) {
473 PDEBUG(D_ERR|D_STREAM, 367 PDEBUG(D_ERR|D_STREAM,
474 "Incorrect variable sequence"); 368 "Incorrect variable sequence");
475 return; 369 return -EINVAL;
476 } 370 }
477 while (len > 0) { 371 while (len > 0) {
478 if (len < 8) { 372 if (len < 8) {
479 reg_w_buf(gspca_dev, index, seq, len); 373 ret = reg_w_buf(gspca_dev,
374 index, seq, len);
375 if (ret < 0)
376 return ret;
480 seq += len; 377 seq += len;
481 break; 378 break;
482 } 379 }
483 reg_w_buf(gspca_dev, index, seq, 8); 380 ret = reg_w_buf(gspca_dev, index, seq, 8);
484 seq += 8; 381 seq += 8;
485 index += 8; 382 index += 8;
486 len -= 8; 383 len -= 8;
487 } 384 }
488 } 385 }
386 if (ret < 0)
387 return ret;
489 } 388 }
490 /* not reached */ 389 /* not reached */
491} 390}
492 391
493/* this function is called at probe time */ 392/* this function is called at probe time for pac7311 */
494static int sd_config(struct gspca_dev *gspca_dev, 393static int sd_config(struct gspca_dev *gspca_dev,
495 const struct usb_device_id *id) 394 const struct usb_device_id *id)
496{ 395{
@@ -499,22 +398,11 @@ static int sd_config(struct gspca_dev *gspca_dev,
499 398
500 cam = &gspca_dev->cam; 399 cam = &gspca_dev->cam;
501 400
502 sd->sensor = id->driver_info; 401 PDEBUG(D_CONF, "Find Sensor PAC7311");
503 if (sd->sensor == SENSOR_PAC7302) { 402 cam->cam_mode = vga_mode;
504 PDEBUG(D_CONF, "Find Sensor PAC7302"); 403 cam->nmodes = ARRAY_SIZE(vga_mode);
505 cam->cam_mode = &vga_mode[2]; /* only 640x480 */
506 cam->nmodes = 1;
507 } else {
508 PDEBUG(D_CONF, "Find Sensor PAC7311");
509 cam->cam_mode = vga_mode;
510 cam->nmodes = ARRAY_SIZE(vga_mode);
511 gspca_dev->ctrl_dis = (1 << BRIGHTNESS_IDX)
512 | (1 << SATURATION_IDX);
513 }
514 404
515 sd->brightness = BRIGHTNESS_DEF;
516 sd->contrast = CONTRAST_DEF; 405 sd->contrast = CONTRAST_DEF;
517 sd->colors = COLOR_DEF;
518 sd->gain = GAIN_DEF; 406 sd->gain = GAIN_DEF;
519 sd->exposure = EXPOSURE_DEF; 407 sd->exposure = EXPOSURE_DEF;
520 sd->autogain = AUTOGAIN_DEF; 408 sd->autogain = AUTOGAIN_DEF;
@@ -523,91 +411,47 @@ static int sd_config(struct gspca_dev *gspca_dev,
523 return 0; 411 return 0;
524} 412}
525 413
526/* This function is used by pac7302 only */
527static void setbrightcont(struct gspca_dev *gspca_dev)
528{
529 struct sd *sd = (struct sd *) gspca_dev;
530 int i, v;
531 static const __u8 max[10] =
532 {0x29, 0x33, 0x42, 0x5a, 0x6e, 0x80, 0x9f, 0xbb,
533 0xd4, 0xec};
534 static const __u8 delta[10] =
535 {0x35, 0x33, 0x33, 0x2f, 0x2a, 0x25, 0x1e, 0x17,
536 0x11, 0x0b};
537
538 reg_w(gspca_dev, 0xff, 0x00); /* page 0 */
539 for (i = 0; i < 10; i++) {
540 v = max[i];
541 v += (sd->brightness - BRIGHTNESS_MAX)
542 * 150 / BRIGHTNESS_MAX; /* 200 ? */
543 v -= delta[i] * sd->contrast / CONTRAST_MAX;
544 if (v < 0)
545 v = 0;
546 else if (v > 0xff)
547 v = 0xff;
548 reg_w(gspca_dev, 0xa2 + i, v);
549 }
550 reg_w(gspca_dev, 0xdc, 0x01);
551}
552
553/* This function is used by pac7311 only */ 414/* This function is used by pac7311 only */
554static void setcontrast(struct gspca_dev *gspca_dev) 415static int setcontrast(struct gspca_dev *gspca_dev)
555{ 416{
556 struct sd *sd = (struct sd *) gspca_dev; 417 struct sd *sd = (struct sd *) gspca_dev;
418 int ret;
557 419
558 reg_w(gspca_dev, 0xff, 0x04); 420 ret = reg_w(gspca_dev, 0xff, 0x04);
559 reg_w(gspca_dev, 0x10, sd->contrast >> 4); 421 if (0 <= ret)
422 ret = reg_w(gspca_dev, 0x10, sd->contrast >> 4);
560 /* load registers to sensor (Bit 0, auto clear) */ 423 /* load registers to sensor (Bit 0, auto clear) */
561 reg_w(gspca_dev, 0x11, 0x01); 424 if (0 <= ret)
425 ret = reg_w(gspca_dev, 0x11, 0x01);
426 return ret;
562} 427}
563 428
564/* This function is used by pac7302 only */ 429static int setgain(struct gspca_dev *gspca_dev)
565static void setcolors(struct gspca_dev *gspca_dev)
566{ 430{
567 struct sd *sd = (struct sd *) gspca_dev; 431 struct sd *sd = (struct sd *) gspca_dev;
568 int i, v; 432 int gain = GAIN_MAX - sd->gain;
569 static const int a[9] = 433 int ret;
570 {217, -212, 0, -101, 170, -67, -38, -315, 355};
571 static const int b[9] =
572 {19, 106, 0, 19, 106, 1, 19, 106, 1};
573
574 reg_w(gspca_dev, 0xff, 0x03); /* page 3 */
575 reg_w(gspca_dev, 0x11, 0x01);
576 reg_w(gspca_dev, 0xff, 0x00); /* page 0 */
577 reg_w(gspca_dev, 0xff, 0x00); /* page 0 */
578 for (i = 0; i < 9; i++) {
579 v = a[i] * sd->colors / COLOR_MAX + b[i];
580 reg_w(gspca_dev, 0x0f + 2 * i, (v >> 8) & 0x07);
581 reg_w(gspca_dev, 0x0f + 2 * i + 1, v);
582 }
583 reg_w(gspca_dev, 0xdc, 0x01);
584 PDEBUG(D_CONF|D_STREAM, "color: %i", sd->colors);
585}
586 434
587static void setgain(struct gspca_dev *gspca_dev) 435 if (gain < 1)
588{ 436 gain = 1;
589 struct sd *sd = (struct sd *) gspca_dev; 437 else if (gain > 245)
438 gain = 245;
439 ret = reg_w(gspca_dev, 0xff, 0x04); /* page 4 */
440 if (0 <= ret)
441 ret = reg_w(gspca_dev, 0x0e, 0x00);
442 if (0 <= ret)
443 ret = reg_w(gspca_dev, 0x0f, gain);
590 444
591 if (sd->sensor == SENSOR_PAC7302) {
592 reg_w(gspca_dev, 0xff, 0x03); /* page 3 */
593 reg_w(gspca_dev, 0x10, sd->gain >> 3);
594 } else {
595 int gain = GAIN_MAX - sd->gain;
596 if (gain < 1)
597 gain = 1;
598 else if (gain > 245)
599 gain = 245;
600 reg_w(gspca_dev, 0xff, 0x04); /* page 4 */
601 reg_w(gspca_dev, 0x0e, 0x00);
602 reg_w(gspca_dev, 0x0f, gain);
603 }
604 /* load registers to sensor (Bit 0, auto clear) */ 445 /* load registers to sensor (Bit 0, auto clear) */
605 reg_w(gspca_dev, 0x11, 0x01); 446 if (0 <= ret)
447 ret = reg_w(gspca_dev, 0x11, 0x01);
448 return ret;
606} 449}
607 450
608static void setexposure(struct gspca_dev *gspca_dev) 451static int setexposure(struct gspca_dev *gspca_dev)
609{ 452{
610 struct sd *sd = (struct sd *) gspca_dev; 453 struct sd *sd = (struct sd *) gspca_dev;
454 int ret;
611 __u8 reg; 455 __u8 reg;
612 456
613 /* register 2 of frame 3/4 contains the clock divider configuring the 457 /* register 2 of frame 3/4 contains the clock divider configuring the
@@ -619,97 +463,94 @@ static void setexposure(struct gspca_dev *gspca_dev)
619 else if (reg > 63) 463 else if (reg > 63)
620 reg = 63; 464 reg = 63;
621 465
622 if (sd->sensor == SENSOR_PAC7302) { 466 ret = reg_w(gspca_dev, 0xff, 0x04); /* page 4 */
623 /* On the pac7302 reg2 MUST be a multiple of 3, so round it to 467 if (0 <= ret)
624 the nearest multiple of 3, except when between 6 and 12? */ 468 ret = reg_w(gspca_dev, 0x02, reg);
625 if (reg < 6 || reg > 12) 469 /* Page 1 register 8 must always be 0x08 except when not in
626 reg = ((reg + 1) / 3) * 3; 470 640x480 mode and Page3/4 reg 2 <= 3 then it must be 9 */
627 reg_w(gspca_dev, 0xff, 0x03); /* page 3 */ 471 if (0 <= ret)
628 reg_w(gspca_dev, 0x02, reg); 472 ret = reg_w(gspca_dev, 0xff, 0x01);
473 if (gspca_dev->cam.cam_mode[(int)gspca_dev->curr_mode].priv &&
474 reg <= 3) {
475 if (0 <= ret)
476 ret = reg_w(gspca_dev, 0x08, 0x09);
629 } else { 477 } else {
630 reg_w(gspca_dev, 0xff, 0x04); /* page 4 */ 478 if (0 <= ret)
631 reg_w(gspca_dev, 0x02, reg); 479 ret = reg_w(gspca_dev, 0x08, 0x08);
632 /* Page 1 register 8 must always be 0x08 except when not in
633 640x480 mode and Page3/4 reg 2 <= 3 then it must be 9 */
634 reg_w(gspca_dev, 0xff, 0x01);
635 if (gspca_dev->cam.cam_mode[(int)gspca_dev->curr_mode].priv &&
636 reg <= 3)
637 reg_w(gspca_dev, 0x08, 0x09);
638 else
639 reg_w(gspca_dev, 0x08, 0x08);
640 } 480 }
481
641 /* load registers to sensor (Bit 0, auto clear) */ 482 /* load registers to sensor (Bit 0, auto clear) */
642 reg_w(gspca_dev, 0x11, 0x01); 483 if (0 <= ret)
484 ret = reg_w(gspca_dev, 0x11, 0x01);
485 return ret;
643} 486}
644 487
645static void sethvflip(struct gspca_dev *gspca_dev) 488static int sethvflip(struct gspca_dev *gspca_dev)
646{ 489{
647 struct sd *sd = (struct sd *) gspca_dev; 490 struct sd *sd = (struct sd *) gspca_dev;
491 int ret;
648 __u8 data; 492 __u8 data;
649 493
650 if (sd->sensor == SENSOR_PAC7302) { 494 ret = reg_w(gspca_dev, 0xff, 0x04); /* page 4 */
651 reg_w(gspca_dev, 0xff, 0x03); /* page 3 */ 495 data = (sd->hflip ? 0x04 : 0x00) | (sd->vflip ? 0x08 : 0x00);
652 data = (sd->hflip ? 0x08 : 0x00) 496 if (0 <= ret)
653 | (sd->vflip ? 0x04 : 0x00); 497 ret = reg_w(gspca_dev, 0x21, data);
654 } else {
655 reg_w(gspca_dev, 0xff, 0x04); /* page 4 */
656 data = (sd->hflip ? 0x04 : 0x00)
657 | (sd->vflip ? 0x08 : 0x00);
658 }
659 reg_w(gspca_dev, 0x21, data);
660 /* load registers to sensor (Bit 0, auto clear) */ 498 /* load registers to sensor (Bit 0, auto clear) */
661 reg_w(gspca_dev, 0x11, 0x01); 499 if (0 <= ret)
500 ret = reg_w(gspca_dev, 0x11, 0x01);
501 return ret;
662} 502}
663 503
664/* this function is called at probe and resume time */ 504/* this function is called at probe and resume time for pac7311 */
665static int sd_init(struct gspca_dev *gspca_dev) 505static int sd_init(struct gspca_dev *gspca_dev)
666{ 506{
667 struct sd *sd = (struct sd *) gspca_dev; 507 return reg_w_seq(gspca_dev, init_7311, sizeof(init_7311)/2);
668
669 if (sd->sensor == SENSOR_PAC7302)
670 reg_w_seq(gspca_dev, init_7302, sizeof init_7302);
671 else
672 reg_w_seq(gspca_dev, init_7311, sizeof init_7311);
673
674 return 0;
675} 508}
676 509
677static int sd_start(struct gspca_dev *gspca_dev) 510static int sd_start(struct gspca_dev *gspca_dev)
678{ 511{
679 struct sd *sd = (struct sd *) gspca_dev; 512 struct sd *sd = (struct sd *) gspca_dev;
513 int ret;
680 514
681 sd->sof_read = 0; 515 sd->sof_read = 0;
682 516
683 if (sd->sensor == SENSOR_PAC7302) { 517 ret = reg_w_var(gspca_dev, start_7311,
684 reg_w_var(gspca_dev, start_7302); 518 NULL, 0,
685 setbrightcont(gspca_dev); 519 page4_7311, sizeof(page4_7311));
686 setcolors(gspca_dev); 520 if (0 <= ret)
687 } else { 521 ret = setcontrast(gspca_dev);
688 reg_w_var(gspca_dev, start_7311); 522 if (0 <= ret)
689 setcontrast(gspca_dev); 523 ret = setgain(gspca_dev);
690 } 524 if (0 <= ret)
691 setgain(gspca_dev); 525 ret = setexposure(gspca_dev);
692 setexposure(gspca_dev); 526 if (0 <= ret)
693 sethvflip(gspca_dev); 527 ret = sethvflip(gspca_dev);
694 528
695 /* set correct resolution */ 529 /* set correct resolution */
696 switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) { 530 switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) {
697 case 2: /* 160x120 pac7311 */ 531 case 2: /* 160x120 pac7311 */
698 reg_w(gspca_dev, 0xff, 0x01); 532 if (0 <= ret)
699 reg_w(gspca_dev, 0x17, 0x20); 533 ret = reg_w(gspca_dev, 0xff, 0x01);
700 reg_w(gspca_dev, 0x87, 0x10); 534 if (0 <= ret)
535 ret = reg_w(gspca_dev, 0x17, 0x20);
536 if (0 <= ret)
537 ret = reg_w(gspca_dev, 0x87, 0x10);
701 break; 538 break;
702 case 1: /* 320x240 pac7311 */ 539 case 1: /* 320x240 pac7311 */
703 reg_w(gspca_dev, 0xff, 0x01); 540 if (0 <= ret)
704 reg_w(gspca_dev, 0x17, 0x30); 541 ret = reg_w(gspca_dev, 0xff, 0x01);
705 reg_w(gspca_dev, 0x87, 0x11); 542 if (0 <= ret)
543 ret = reg_w(gspca_dev, 0x17, 0x30);
544 if (0 <= ret)
545 ret = reg_w(gspca_dev, 0x87, 0x11);
706 break; 546 break;
707 case 0: /* 640x480 */ 547 case 0: /* 640x480 */
708 if (sd->sensor == SENSOR_PAC7302) 548 if (0 <= ret)
709 break; 549 ret = reg_w(gspca_dev, 0xff, 0x01);
710 reg_w(gspca_dev, 0xff, 0x01); 550 if (0 <= ret)
711 reg_w(gspca_dev, 0x17, 0x00); 551 ret = reg_w(gspca_dev, 0x17, 0x00);
712 reg_w(gspca_dev, 0x87, 0x12); 552 if (0 <= ret)
553 ret = reg_w(gspca_dev, 0x87, 0x12);
713 break; 554 break;
714 } 555 }
715 556
@@ -718,47 +559,42 @@ static int sd_start(struct gspca_dev *gspca_dev)
718 atomic_set(&sd->avg_lum, -1); 559 atomic_set(&sd->avg_lum, -1);
719 560
720 /* start stream */ 561 /* start stream */
721 reg_w(gspca_dev, 0xff, 0x01); 562 if (0 <= ret)
722 if (sd->sensor == SENSOR_PAC7302) 563 ret = reg_w(gspca_dev, 0xff, 0x01);
723 reg_w(gspca_dev, 0x78, 0x01); 564 if (0 <= ret)
724 else 565 ret = reg_w(gspca_dev, 0x78, 0x05);
725 reg_w(gspca_dev, 0x78, 0x05); 566
726 return 0; 567 return ret;
727} 568}
728 569
729static void sd_stopN(struct gspca_dev *gspca_dev) 570static void sd_stopN(struct gspca_dev *gspca_dev)
730{ 571{
731 struct sd *sd = (struct sd *) gspca_dev; 572 int ret;
732
733 if (sd->sensor == SENSOR_PAC7302) {
734 reg_w(gspca_dev, 0xff, 0x01);
735 reg_w(gspca_dev, 0x78, 0x00);
736 reg_w(gspca_dev, 0x78, 0x00);
737 return;
738 }
739 reg_w(gspca_dev, 0xff, 0x04);
740 reg_w(gspca_dev, 0x27, 0x80);
741 reg_w(gspca_dev, 0x28, 0xca);
742 reg_w(gspca_dev, 0x29, 0x53);
743 reg_w(gspca_dev, 0x2a, 0x0e);
744 reg_w(gspca_dev, 0xff, 0x01);
745 reg_w(gspca_dev, 0x3e, 0x20);
746 reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */
747 reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */
748 reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */
749}
750 573
751/* called on streamoff with alt 0 and on disconnect */ 574 ret = reg_w(gspca_dev, 0xff, 0x04);
575 if (0 <= ret)
576 ret = reg_w(gspca_dev, 0x27, 0x80);
577 if (0 <= ret)
578 ret = reg_w(gspca_dev, 0x28, 0xca);
579 if (0 <= ret)
580 ret = reg_w(gspca_dev, 0x29, 0x53);
581 if (0 <= ret)
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}
594
595/* called on streamoff with alt 0 and on disconnect for 7311 */
752static void sd_stop0(struct gspca_dev *gspca_dev) 596static void sd_stop0(struct gspca_dev *gspca_dev)
753{ 597{
754 struct sd *sd = (struct sd *) gspca_dev;
755
756 if (!gspca_dev->present)
757 return;
758 if (sd->sensor == SENSOR_PAC7302) {
759 reg_w(gspca_dev, 0xff, 0x01);
760 reg_w(gspca_dev, 0x78, 0x40);
761 }
762} 598}
763 599
764/* Include pac common sof detection functions */ 600/* Include pac common sof detection functions */
@@ -773,22 +609,8 @@ static void do_autogain(struct gspca_dev *gspca_dev)
773 if (avg_lum == -1) 609 if (avg_lum == -1)
774 return; 610 return;
775 611
776 if (sd->sensor == SENSOR_PAC7302) { 612 desired_lum = 200;
777 desired_lum = 270 + sd->brightness * 4; 613 deadzone = 20;
778 /* Hack hack, with the 7202 the first exposure step is
779 pretty large, so if we're about to make the first
780 exposure increase make the deadzone large to avoid
781 oscilating */
782 if (desired_lum > avg_lum && sd->gain == GAIN_DEF &&
783 sd->exposure > EXPOSURE_DEF &&
784 sd->exposure < 42)
785 deadzone = 90;
786 else
787 deadzone = 30;
788 } else {
789 desired_lum = 200;
790 deadzone = 20;
791 }
792 614
793 if (sd->autogain_ignore_frames > 0) 615 if (sd->autogain_ignore_frames > 0)
794 sd->autogain_ignore_frames--; 616 sd->autogain_ignore_frames--;
@@ -797,53 +619,92 @@ static void do_autogain(struct gspca_dev *gspca_dev)
797 sd->autogain_ignore_frames = PAC_AUTOGAIN_IGNORE_FRAMES; 619 sd->autogain_ignore_frames = PAC_AUTOGAIN_IGNORE_FRAMES;
798} 620}
799 621
800static const unsigned char pac7311_jpeg_header1[] = { 622/* JPEG header, part 1 */
801 0xff, 0xd8, 0xff, 0xc0, 0x00, 0x11, 0x08 623static const unsigned char pac_jpeg_header1[] = {
624 0xff, 0xd8, /* SOI: Start of Image */
625
626 0xff, 0xc0, /* SOF0: Start of Frame (Baseline DCT) */
627 0x00, 0x11, /* length = 17 bytes (including this length field) */
628 0x08 /* Precision: 8 */
629 /* 2 bytes is placed here: number of image lines */
630 /* 2 bytes is placed here: samples per line */
802}; 631};
803 632
804static const unsigned char pac7311_jpeg_header2[] = { 633/* JPEG header, continued */
805 0x03, 0x01, 0x21, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01, 0xff, 0xda, 634static const unsigned char pac_jpeg_header2[] = {
806 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00 635 0x03, /* Number of image components: 3 */
636 0x01, 0x21, 0x00, /* ID=1, Subsampling 1x1, Quantization table: 0 */
637 0x02, 0x11, 0x01, /* ID=2, Subsampling 2x1, Quantization table: 1 */
638 0x03, 0x11, 0x01, /* ID=3, Subsampling 2x1, Quantization table: 1 */
639
640 0xff, 0xda, /* SOS: Start Of Scan */
641 0x00, 0x0c, /* length = 12 bytes (including this length field) */
642 0x03, /* number of components: 3 */
643 0x01, 0x00, /* selector 1, table 0x00 */
644 0x02, 0x11, /* selector 2, table 0x11 */
645 0x03, 0x11, /* selector 3, table 0x11 */
646 0x00, 0x3f, /* Spectral selection: 0 .. 63 */
647 0x00 /* Successive approximation: 0 */
807}; 648};
808 649
650static void pac_start_frame(struct gspca_dev *gspca_dev,
651 struct gspca_frame *frame,
652 __u16 lines, __u16 samples_per_line)
653{
654 unsigned char tmpbuf[4];
655
656 gspca_frame_add(gspca_dev, FIRST_PACKET,
657 pac_jpeg_header1, sizeof(pac_jpeg_header1));
658
659 tmpbuf[0] = lines >> 8;
660 tmpbuf[1] = lines & 0xff;
661 tmpbuf[2] = samples_per_line >> 8;
662 tmpbuf[3] = samples_per_line & 0xff;
663
664 gspca_frame_add(gspca_dev, INTER_PACKET,
665 tmpbuf, sizeof(tmpbuf));
666 gspca_frame_add(gspca_dev, INTER_PACKET,
667 pac_jpeg_header2, sizeof(pac_jpeg_header2));
668}
669
809/* this function is run at interrupt level */ 670/* this function is run at interrupt level */
810static void sd_pkt_scan(struct gspca_dev *gspca_dev, 671static void sd_pkt_scan(struct gspca_dev *gspca_dev,
811 struct gspca_frame *frame, /* target */ 672 u8 *data, /* isoc packet */
812 __u8 *data, /* isoc packet */
813 int len) /* iso packet length */ 673 int len) /* iso packet length */
814{ 674{
815 struct sd *sd = (struct sd *) gspca_dev; 675 struct sd *sd = (struct sd *) gspca_dev;
816 unsigned char *sof; 676 unsigned char *sof;
677 struct gspca_frame *frame;
817 678
818 sof = pac_find_sof(gspca_dev, data, len); 679 sof = pac_find_sof(&sd->sof_read, data, len);
819 if (sof) { 680 if (sof) {
820 unsigned char tmpbuf[4];
821 int n, lum_offset, footer_length; 681 int n, lum_offset, footer_length;
822 682
823 if (sd->sensor == SENSOR_PAC7302) { 683 frame = gspca_get_i_frame(gspca_dev);
824 /* 6 bytes after the FF D9 EOF marker a number of lumination 684 if (frame == NULL) {
825 bytes are send corresponding to different parts of the 685 gspca_dev->last_packet_type = DISCARD_PACKET;
826 image, the 14th and 15th byte after the EOF seem to 686 return;
827 correspond to the center of the image */
828 lum_offset = 61 + sizeof pac_sof_marker;
829 footer_length = 74;
830 } else {
831 lum_offset = 24 + sizeof pac_sof_marker;
832 footer_length = 26;
833 } 687 }
834 688
689 /* 6 bytes after the FF D9 EOF marker a number of lumination
690 bytes are send corresponding to different parts of the
691 image, the 14th and 15th byte after the EOF seem to
692 correspond to the center of the image */
693 lum_offset = 24 + sizeof pac_sof_marker;
694 footer_length = 26;
695
835 /* Finish decoding current frame */ 696 /* Finish decoding current frame */
836 n = (sof - data) - (footer_length + sizeof pac_sof_marker); 697 n = (sof - data) - (footer_length + sizeof pac_sof_marker);
837 if (n < 0) { 698 if (n < 0) {
838 frame->data_end += n; 699 frame->data_end += n;
839 n = 0; 700 n = 0;
840 } 701 }
841 frame = gspca_frame_add(gspca_dev, INTER_PACKET, frame, 702 gspca_frame_add(gspca_dev, INTER_PACKET,
842 data, n); 703 data, n);
843 if (gspca_dev->last_packet_type != DISCARD_PACKET && 704 if (gspca_dev->last_packet_type != DISCARD_PACKET &&
844 frame->data_end[-2] == 0xff && 705 frame->data_end[-2] == 0xff &&
845 frame->data_end[-1] == 0xd9) 706 frame->data_end[-1] == 0xd9)
846 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, 707 gspca_frame_add(gspca_dev, LAST_PACKET,
847 NULL, 0); 708 NULL, 0);
848 709
849 n = sof - data; 710 n = sof - data;
@@ -859,43 +720,10 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
859 atomic_set(&sd->avg_lum, -1); 720 atomic_set(&sd->avg_lum, -1);
860 721
861 /* Start the new frame with the jpeg header */ 722 /* Start the new frame with the jpeg header */
862 gspca_frame_add(gspca_dev, FIRST_PACKET, frame, 723 pac_start_frame(gspca_dev, frame,
863 pac7311_jpeg_header1, sizeof(pac7311_jpeg_header1)); 724 gspca_dev->height, gspca_dev->width);
864 if (sd->sensor == SENSOR_PAC7302) {
865 /* The PAC7302 has the image rotated 90 degrees */
866 tmpbuf[0] = gspca_dev->width >> 8;
867 tmpbuf[1] = gspca_dev->width & 0xff;
868 tmpbuf[2] = gspca_dev->height >> 8;
869 tmpbuf[3] = gspca_dev->height & 0xff;
870 } else {
871 tmpbuf[0] = gspca_dev->height >> 8;
872 tmpbuf[1] = gspca_dev->height & 0xff;
873 tmpbuf[2] = gspca_dev->width >> 8;
874 tmpbuf[3] = gspca_dev->width & 0xff;
875 }
876 gspca_frame_add(gspca_dev, INTER_PACKET, frame, tmpbuf, 4);
877 gspca_frame_add(gspca_dev, INTER_PACKET, frame,
878 pac7311_jpeg_header2, sizeof(pac7311_jpeg_header2));
879 } 725 }
880 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); 726 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
881}
882
883static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
884{
885 struct sd *sd = (struct sd *) gspca_dev;
886
887 sd->brightness = val;
888 if (gspca_dev->streaming)
889 setbrightcont(gspca_dev);
890 return 0;
891}
892
893static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
894{
895 struct sd *sd = (struct sd *) gspca_dev;
896
897 *val = sd->brightness;
898 return 0;
899} 727}
900 728
901static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val) 729static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
@@ -904,10 +732,7 @@ static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
904 732
905 sd->contrast = val; 733 sd->contrast = val;
906 if (gspca_dev->streaming) { 734 if (gspca_dev->streaming) {
907 if (sd->sensor == SENSOR_PAC7302) 735 setcontrast(gspca_dev);
908 setbrightcont(gspca_dev);
909 else
910 setcontrast(gspca_dev);
911 } 736 }
912 return 0; 737 return 0;
913} 738}
@@ -920,24 +745,6 @@ static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
920 return 0; 745 return 0;
921} 746}
922 747
923static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
924{
925 struct sd *sd = (struct sd *) gspca_dev;
926
927 sd->colors = val;
928 if (gspca_dev->streaming)
929 setcolors(gspca_dev);
930 return 0;
931}
932
933static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
934{
935 struct sd *sd = (struct sd *) gspca_dev;
936
937 *val = sd->colors;
938 return 0;
939}
940
941static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val) 748static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val)
942{ 749{
943 struct sd *sd = (struct sd *) gspca_dev; 750 struct sd *sd = (struct sd *) gspca_dev;
@@ -1041,7 +848,7 @@ static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val)
1041 return 0; 848 return 0;
1042} 849}
1043 850
1044/* sub-driver description */ 851/* sub-driver description for pac7311 */
1045static struct sd_desc sd_desc = { 852static struct sd_desc sd_desc = {
1046 .name = MODULE_NAME, 853 .name = MODULE_NAME,
1047 .ctrls = sd_ctrls, 854 .ctrls = sd_ctrls,
@@ -1057,21 +864,12 @@ static struct sd_desc sd_desc = {
1057 864
1058/* -- module initialisation -- */ 865/* -- module initialisation -- */
1059static __devinitdata struct usb_device_id device_table[] = { 866static __devinitdata struct usb_device_id device_table[] = {
1060 {USB_DEVICE(0x06f8, 0x3009), .driver_info = SENSOR_PAC7302}, 867 {USB_DEVICE(0x093a, 0x2600)},
1061 {USB_DEVICE(0x093a, 0x2600), .driver_info = SENSOR_PAC7311}, 868 {USB_DEVICE(0x093a, 0x2601)},
1062 {USB_DEVICE(0x093a, 0x2601), .driver_info = SENSOR_PAC7311}, 869 {USB_DEVICE(0x093a, 0x2603)},
1063 {USB_DEVICE(0x093a, 0x2603), .driver_info = SENSOR_PAC7311}, 870 {USB_DEVICE(0x093a, 0x2608)},
1064 {USB_DEVICE(0x093a, 0x2608), .driver_info = SENSOR_PAC7311}, 871 {USB_DEVICE(0x093a, 0x260e)},
1065 {USB_DEVICE(0x093a, 0x260e), .driver_info = SENSOR_PAC7311}, 872 {USB_DEVICE(0x093a, 0x260f)},
1066 {USB_DEVICE(0x093a, 0x260f), .driver_info = SENSOR_PAC7311},
1067 {USB_DEVICE(0x093a, 0x2620), .driver_info = SENSOR_PAC7302},
1068 {USB_DEVICE(0x093a, 0x2621), .driver_info = SENSOR_PAC7302},
1069 {USB_DEVICE(0x093a, 0x2622), .driver_info = SENSOR_PAC7302},
1070 {USB_DEVICE(0x093a, 0x2624), .driver_info = SENSOR_PAC7302},
1071 {USB_DEVICE(0x093a, 0x2626), .driver_info = SENSOR_PAC7302},
1072 {USB_DEVICE(0x093a, 0x2629), .driver_info = SENSOR_PAC7302},
1073 {USB_DEVICE(0x093a, 0x262a), .driver_info = SENSOR_PAC7302},
1074 {USB_DEVICE(0x093a, 0x262c), .driver_info = SENSOR_PAC7302},
1075 {} 873 {}
1076}; 874};
1077MODULE_DEVICE_TABLE(usb, device_table); 875MODULE_DEVICE_TABLE(usb, device_table);
diff --git a/drivers/media/video/gspca/pac_common.h b/drivers/media/video/gspca/pac_common.h
index 34d4b1494cd5..20f67d9b8c06 100644
--- a/drivers/media/video/gspca/pac_common.h
+++ b/drivers/media/video/gspca/pac_common.h
@@ -33,26 +33,101 @@
33static const unsigned char pac_sof_marker[5] = 33static const unsigned char pac_sof_marker[5] =
34 { 0xff, 0xff, 0x00, 0xff, 0x96 }; 34 { 0xff, 0xff, 0x00, 0xff, 0x96 };
35 35
36static unsigned char *pac_find_sof(struct gspca_dev *gspca_dev, 36/*
37 The following state machine finds the SOF marker sequence
38 0xff, 0xff, 0x00, 0xff, 0x96 in a byte stream.
39
40 +----------+
41 | 0: START |<---------------\
42 +----------+<-\ |
43 | \---/otherwise |
44 v 0xff |
45 +----------+ otherwise |
46 | 1 |--------------->*
47 | | ^
48 +----------+ |
49 | |
50 v 0xff |
51 +----------+<-\0xff |
52 /->| |--/ |
53 | | 2 |--------------->*
54 | | | otherwise ^
55 | +----------+ |
56 | | |
57 | v 0x00 |
58 | +----------+ |
59 | | 3 | |
60 | | |--------------->*
61 | +----------+ otherwise ^
62 | | |
63 0xff | v 0xff |
64 | +----------+ |
65 \--| 4 | |
66 | |----------------/
67 +----------+ otherwise
68 |
69 v 0x96
70 +----------+
71 | FOUND |
72 +----------+
73*/
74
75static unsigned char *pac_find_sof(u8 *sof_read,
37 unsigned char *m, int len) 76 unsigned char *m, int len)
38{ 77{
39 struct sd *sd = (struct sd *) gspca_dev;
40 int i; 78 int i;
41 79
42 /* Search for the SOF marker (fixed part) in the header */ 80 /* Search for the SOF marker (fixed part) in the header */
43 for (i = 0; i < len; i++) { 81 for (i = 0; i < len; i++) {
44 if (m[i] == pac_sof_marker[sd->sof_read]) { 82 switch (*sof_read) {
45 sd->sof_read++; 83 case 0:
46 if (sd->sof_read == sizeof(pac_sof_marker)) { 84 if (m[i] == 0xff)
85 *sof_read = 1;
86 break;
87 case 1:
88 if (m[i] == 0xff)
89 *sof_read = 2;
90 else
91 *sof_read = 0;
92 break;
93 case 2:
94 switch (m[i]) {
95 case 0x00:
96 *sof_read = 3;
97 break;
98 case 0xff:
99 /* stay in this state */
100 break;
101 default:
102 *sof_read = 0;
103 }
104 break;
105 case 3:
106 if (m[i] == 0xff)
107 *sof_read = 4;
108 else
109 *sof_read = 0;
110 break;
111 case 4:
112 switch (m[i]) {
113 case 0x96:
114 /* Pattern found */
47 PDEBUG(D_FRAM, 115 PDEBUG(D_FRAM,
48 "SOF found, bytes to analyze: %u." 116 "SOF found, bytes to analyze: %u."
49 " Frame starts at byte #%u", 117 " Frame starts at byte #%u",
50 len, i + 1); 118 len, i + 1);
51 sd->sof_read = 0; 119 *sof_read = 0;
52 return m + i + 1; 120 return m + i + 1;
121 break;
122 case 0xff:
123 *sof_read = 2;
124 break;
125 default:
126 *sof_read = 0;
53 } 127 }
54 } else { 128 break;
55 sd->sof_read = 0; 129 default:
130 *sof_read = 0;
56 } 131 }
57 } 132 }
58 133
diff --git a/drivers/media/video/gspca/sn9c20x.c b/drivers/media/video/gspca/sn9c20x.c
index cdad3db33367..b1944a7cbb0f 100644
--- a/drivers/media/video/gspca/sn9c20x.c
+++ b/drivers/media/video/gspca/sn9c20x.c
@@ -2342,7 +2342,6 @@ static void sd_dqcallback(struct gspca_dev *gspca_dev)
2342} 2342}
2343 2343
2344static void sd_pkt_scan(struct gspca_dev *gspca_dev, 2344static void sd_pkt_scan(struct gspca_dev *gspca_dev,
2345 struct gspca_frame *frame, /* target */
2346 u8 *data, /* isoc packet */ 2345 u8 *data, /* isoc packet */
2347 int len) /* iso packet length */ 2346 int len) /* iso packet length */
2348{ 2347{
@@ -2378,22 +2377,22 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
2378 avg_lum >>= 9; 2377 avg_lum >>= 9;
2379 atomic_set(&sd->avg_lum, avg_lum); 2378 atomic_set(&sd->avg_lum, avg_lum);
2380 gspca_frame_add(gspca_dev, LAST_PACKET, 2379 gspca_frame_add(gspca_dev, LAST_PACKET,
2381 frame, data, len); 2380 data, len);
2382 return; 2381 return;
2383 } 2382 }
2384 if (gspca_dev->last_packet_type == LAST_PACKET) { 2383 if (gspca_dev->last_packet_type == LAST_PACKET) {
2385 if (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv 2384 if (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv
2386 & MODE_JPEG) { 2385 & MODE_JPEG) {
2387 gspca_frame_add(gspca_dev, FIRST_PACKET, frame, 2386 gspca_frame_add(gspca_dev, FIRST_PACKET,
2388 sd->jpeg_hdr, JPEG_HDR_SZ); 2387 sd->jpeg_hdr, JPEG_HDR_SZ);
2389 gspca_frame_add(gspca_dev, INTER_PACKET, frame, 2388 gspca_frame_add(gspca_dev, INTER_PACKET,
2390 data, len); 2389 data, len);
2391 } else { 2390 } else {
2392 gspca_frame_add(gspca_dev, FIRST_PACKET, frame, 2391 gspca_frame_add(gspca_dev, FIRST_PACKET,
2393 data, len); 2392 data, len);
2394 } 2393 }
2395 } else { 2394 } else {
2396 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); 2395 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
2397 } 2396 }
2398} 2397}
2399 2398
diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/video/gspca/sonixb.c
index e39efb45fa1c..5be95bc65138 100644
--- a/drivers/media/video/gspca/sonixb.c
+++ b/drivers/media/video/gspca/sonixb.c
@@ -995,8 +995,7 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
995} 995}
996 996
997static void sd_pkt_scan(struct gspca_dev *gspca_dev, 997static void sd_pkt_scan(struct gspca_dev *gspca_dev,
998 struct gspca_frame *frame, /* target */ 998 u8 *data, /* isoc packet */
999 unsigned char *data, /* isoc packet */
1000 int len) /* iso packet length */ 999 int len) /* iso packet length */
1001{ 1000{
1002 int i; 1001 int i;
@@ -1054,12 +1053,12 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1054 pkt_type = DISCARD_PACKET; 1053 pkt_type = DISCARD_PACKET;
1055 } 1054 }
1056 1055
1057 frame = gspca_frame_add(gspca_dev, pkt_type, 1056 gspca_frame_add(gspca_dev, pkt_type,
1058 frame, data, 0); 1057 NULL, 0);
1059 data += i + fr_h_sz; 1058 data += i + fr_h_sz;
1060 len -= i + fr_h_sz; 1059 len -= i + fr_h_sz;
1061 gspca_frame_add(gspca_dev, FIRST_PACKET, 1060 gspca_frame_add(gspca_dev, FIRST_PACKET,
1062 frame, data, len); 1061 data, len);
1063 return; 1062 return;
1064 } 1063 }
1065 } 1064 }
@@ -1068,15 +1067,21 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1068 if (cam->cam_mode[gspca_dev->curr_mode].priv & MODE_RAW) { 1067 if (cam->cam_mode[gspca_dev->curr_mode].priv & MODE_RAW) {
1069 /* In raw mode we sometimes get some garbage after the frame 1068 /* In raw mode we sometimes get some garbage after the frame
1070 ignore this */ 1069 ignore this */
1071 int used = frame->data_end - frame->data; 1070 struct gspca_frame *frame;
1071 int used;
1072 int size = cam->cam_mode[gspca_dev->curr_mode].sizeimage; 1072 int size = cam->cam_mode[gspca_dev->curr_mode].sizeimage;
1073 1073
1074 frame = gspca_get_i_frame(gspca_dev);
1075 if (frame == NULL) {
1076 gspca_dev->last_packet_type = DISCARD_PACKET;
1077 return;
1078 }
1079 used = frame->data_end - frame->data;
1074 if (used + len > size) 1080 if (used + len > size)
1075 len = size - used; 1081 len = size - used;
1076 } 1082 }
1077 1083
1078 gspca_frame_add(gspca_dev, INTER_PACKET, 1084 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
1079 frame, data, len);
1080} 1085}
1081 1086
1082static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) 1087static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c
index 33f4d0a1f6fd..0bd36a00dd2a 100644
--- a/drivers/media/video/gspca/sonixj.c
+++ b/drivers/media/video/gspca/sonixj.c
@@ -1,8 +1,8 @@
1/* 1/*
2 * Sonix sn9c102p sn9c105 sn9c120 (jpeg) library 2 * Sonix sn9c102p sn9c105 sn9c120 (jpeg) subdriver
3 * Copyright (C) 2005 Michel Xhaard mxhaard@magic.fr
4 * 3 *
5 * V4L2 by Jean-Francois Moine <http://moinejf.free.fr> 4 * Copyright (C) 2009 Jean-Francois Moine <http://moinejf.free.fr>
5 * Copyright (C) 2005 Michel Xhaard mxhaard@magic.fr
6 * 6 *
7 * 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
8 * 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
@@ -72,8 +72,9 @@ struct sd {
72#define SENSOR_OV7630 5 72#define SENSOR_OV7630 5
73#define SENSOR_OV7648 6 73#define SENSOR_OV7648 6
74#define SENSOR_OV7660 7 74#define SENSOR_OV7660 7
75#define SENSOR_SP80708 8 75#define SENSOR_PO1030 8
76 u8 i2c_base; 76#define SENSOR_SP80708 9
77 u8 i2c_addr;
77 78
78 u8 *jpeg_hdr; 79 u8 *jpeg_hdr;
79}; 80};
@@ -250,7 +251,7 @@ static struct ctrl sd_ctrls[] = {
250 .minimum = 0, 251 .minimum = 0,
251 .maximum = 2, /* 0: 0, 1: 50Hz, 2:60Hz */ 252 .maximum = 2, /* 0: 0, 1: 50Hz, 2:60Hz */
252 .step = 1, 253 .step = 1,
253#define FREQ_DEF 2 254#define FREQ_DEF 1
254 .default_value = FREQ_DEF, 255 .default_value = FREQ_DEF,
255 }, 256 },
256 .set = sd_setfreq, 257 .set = sd_setfreq,
@@ -277,7 +278,9 @@ static __u32 ctrl_dis[] = {
277 (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX), 278 (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX),
278 /* SENSOR_OV7660 7 */ 279 /* SENSOR_OV7660 7 */
279 (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX) | 280 (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX) |
280 (1 << FREQ_IDX), /* SENSOR_SP80708 8 */ 281 (1 << FREQ_IDX), /* SENSOR_PO1030 8 */
282 (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX) |
283 (1 << FREQ_IDX), /* SENSOR_SP80708 9 */
281}; 284};
282 285
283static const struct v4l2_pix_format vga_mode[] = { 286static const struct v4l2_pix_format vga_mode[] = {
@@ -304,7 +307,7 @@ static const u8 sn_hv7131[0x1c] = {
304/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ 307/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
305 0x00, 0x03, 0x64, 0x00, 0x1a, 0x20, 0x20, 0x20, 308 0x00, 0x03, 0x64, 0x00, 0x1a, 0x20, 0x20, 0x20,
306/* reg8 reg9 rega regb regc regd rege regf */ 309/* reg8 reg9 rega regb regc regd rege regf */
307 0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10, 310 0x81, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
308/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */ 311/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
309 0x03, 0x00, 0x00, 0x01, 0x03, 0x28, 0x1e, 0x41, 312 0x03, 0x00, 0x00, 0x01, 0x03, 0x28, 0x1e, 0x41,
310/* reg18 reg19 reg1a reg1b */ 313/* reg18 reg19 reg1a reg1b */
@@ -315,7 +318,7 @@ static const u8 sn_mi0360[0x1c] = {
315/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ 318/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
316 0x00, 0x61, 0x44, 0x00, 0x1a, 0x20, 0x20, 0x20, 319 0x00, 0x61, 0x44, 0x00, 0x1a, 0x20, 0x20, 0x20,
317/* reg8 reg9 rega regb regc regd rege regf */ 320/* reg8 reg9 rega regb regc regd rege regf */
318 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10, 321 0x81, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
319/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */ 322/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
320 0x03, 0x00, 0x00, 0x02, 0x0a, 0x28, 0x1e, 0x61, 323 0x03, 0x00, 0x00, 0x02, 0x0a, 0x28, 0x1e, 0x61,
321/* reg18 reg19 reg1a reg1b */ 324/* reg18 reg19 reg1a reg1b */
@@ -337,7 +340,7 @@ static const u8 sn_mt9v111[0x1c] = {
337/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ 340/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
338 0x00, 0x61, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20, 341 0x00, 0x61, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20,
339/* reg8 reg9 rega regb regc regd rege regf */ 342/* reg8 reg9 rega regb regc regd rege regf */
340 0x81, 0x5c, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 343 0x81, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
341/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */ 344/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
342 0x03, 0x00, 0x00, 0x02, 0x1c, 0x28, 0x1e, 0x40, 345 0x03, 0x00, 0x00, 0x02, 0x1c, 0x28, 0x1e, 0x40,
343/* reg18 reg19 reg1a reg1b */ 346/* reg18 reg19 reg1a reg1b */
@@ -346,7 +349,7 @@ static const u8 sn_mt9v111[0x1c] = {
346 349
347static const u8 sn_om6802[0x1c] = { 350static const u8 sn_om6802[0x1c] = {
348/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ 351/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
349 0x00, 0x23, 0x72, 0x00, 0x1a, 0x34, 0x27, 0x20, 352 0x00, 0x23, 0x72, 0x00, 0x1a, 0x20, 0x20, 0x19,
350/* reg8 reg9 rega regb regc regd rege regf */ 353/* reg8 reg9 rega regb regc regd rege regf */
351 0x80, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 354 0x80, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
352/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */ 355/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
@@ -359,7 +362,7 @@ static const u8 sn_ov7630[0x1c] = {
359/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ 362/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
360 0x00, 0x21, 0x40, 0x00, 0x1a, 0x20, 0x1f, 0x20, 363 0x00, 0x21, 0x40, 0x00, 0x1a, 0x20, 0x1f, 0x20,
361/* reg8 reg9 rega regb regc regd rege regf */ 364/* reg8 reg9 rega regb regc regd rege regf */
362 0xa1, 0x21, 0x76, 0x21, 0x00, 0x00, 0x00, 0x10, 365 0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
363/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */ 366/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
364 0x03, 0x00, 0x04, 0x01, 0x0a, 0x28, 0x1e, 0xc2, 367 0x03, 0x00, 0x04, 0x01, 0x0a, 0x28, 0x1e, 0xc2,
365/* reg18 reg19 reg1a reg1b */ 368/* reg18 reg19 reg1a reg1b */
@@ -370,7 +373,7 @@ static const u8 sn_ov7648[0x1c] = {
370/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ 373/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
371 0x00, 0x63, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20, 374 0x00, 0x63, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20,
372/* reg8 reg9 rega regb regc regd rege regf */ 375/* reg8 reg9 rega regb regc regd rege regf */
373 0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 376 0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
374/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */ 377/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
375 0x03, 0x00, 0x00, 0x01, 0x00, 0x28, 0x1e, 0x00, 378 0x03, 0x00, 0x00, 0x01, 0x00, 0x28, 0x1e, 0x00,
376/* reg18 reg19 reg1a reg1b */ 379/* reg18 reg19 reg1a reg1b */
@@ -388,11 +391,22 @@ static const u8 sn_ov7660[0x1c] = {
388 0x07, 0x00, 0x00, 0x00 391 0x07, 0x00, 0x00, 0x00
389}; 392};
390 393
394static const u8 sn_po1030[0x1c] = {
395/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
396 0x00, 0x21, 0x62, 0x00, 0x1a, 0x20, 0x20, 0x20,
397/* reg8 reg9 rega regb regc regd rege regf */
398 0x81, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
399/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
400 0x03, 0x00, 0x00, 0x06, 0x06, 0x28, 0x1e, 0x00,
401/* reg18 reg19 reg1a reg1b */
402 0x07, 0x00, 0x00, 0x00
403};
404
391static const u8 sn_sp80708[0x1c] = { 405static const u8 sn_sp80708[0x1c] = {
392/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ 406/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
393 0x00, 0x63, 0x60, 0x00, 0x1a, 0x20, 0x20, 0x20, 407 0x00, 0x63, 0x60, 0x00, 0x1a, 0x20, 0x20, 0x20,
394/* reg8 reg9 rega regb regc regd rege regf */ 408/* reg8 reg9 rega regb regc regd rege regf */
395 0x81, 0x18, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 409 0x81, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
396/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */ 410/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
397 0x03, 0x00, 0x00, 0x03, 0x04, 0x28, 0x1e, 0x00, 411 0x03, 0x00, 0x00, 0x03, 0x04, 0x28, 0x1e, 0x00,
398/* reg18 reg19 reg1a reg1b */ 412/* reg18 reg19 reg1a reg1b */
@@ -409,6 +423,7 @@ static const u8 *sn_tb[] = {
409 sn_ov7630, 423 sn_ov7630,
410 sn_ov7648, 424 sn_ov7648,
411 sn_ov7660, 425 sn_ov7660,
426 sn_po1030,
412 sn_sp80708 427 sn_sp80708
413}; 428};
414 429
@@ -455,7 +470,7 @@ static const u8 hv7131r_sensor_init[][8] = {
455 470
456 {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10}, 471 {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
457 {0xa1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10}, 472 {0xa1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
458 {0xa1, 0x11, 0x21, 0xD0, 0x00, 0x00, 0x00, 0x10}, 473 {0xa1, 0x11, 0x21, 0xd0, 0x00, 0x00, 0x00, 0x10},
459 {0xa1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10}, 474 {0xa1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
460 {0xa1, 0x11, 0x23, 0x09, 0x00, 0x00, 0x00, 0x10}, 475 {0xa1, 0x11, 0x23, 0x09, 0x00, 0x00, 0x00, 0x10},
461 476
@@ -464,6 +479,8 @@ static const u8 hv7131r_sensor_init[][8] = {
464 {0xa1, 0x11, 0x21, 0xd0, 0x00, 0x00, 0x00, 0x10}, 479 {0xa1, 0x11, 0x21, 0xd0, 0x00, 0x00, 0x00, 0x10},
465 {0xa1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10}, 480 {0xa1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
466 {0xa1, 0x11, 0x23, 0x10, 0x00, 0x00, 0x00, 0x10}, 481 {0xa1, 0x11, 0x23, 0x10, 0x00, 0x00, 0x00, 0x10},
482 {0xa1, 0x11, 0x01, 0x18, 0x00, 0x00, 0x00, 0x10},
483 /* set sensor clock */
467 {} 484 {}
468}; 485};
469static const u8 mi0360_sensor_init[][8] = { 486static const u8 mi0360_sensor_init[][8] = {
@@ -545,7 +562,7 @@ static const u8 mo4000_sensor_init[][8] = {
545}; 562};
546static const u8 mt9v111_sensor_init[][8] = { 563static const u8 mt9v111_sensor_init[][8] = {
547 {0xb1, 0x5c, 0x0d, 0x00, 0x01, 0x00, 0x00, 0x10}, /* reset? */ 564 {0xb1, 0x5c, 0x0d, 0x00, 0x01, 0x00, 0x00, 0x10}, /* reset? */
548 /* delay 20 ms */ 565 {0xdd, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */
549 {0xb1, 0x5c, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x10}, 566 {0xb1, 0x5c, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x10},
550 {0xb1, 0x5c, 0x01, 0x00, 0x01, 0x00, 0x00, 0x10}, /* IFP select */ 567 {0xb1, 0x5c, 0x01, 0x00, 0x01, 0x00, 0x00, 0x10}, /* IFP select */
551 {0xb1, 0x5c, 0x08, 0x04, 0x80, 0x00, 0x00, 0x10}, /* output fmt ctrl */ 568 {0xb1, 0x5c, 0x08, 0x04, 0x80, 0x00, 0x00, 0x10}, /* output fmt ctrl */
@@ -572,7 +589,9 @@ static const u8 mt9v111_sensor_init[][8] = {
572 {0xb1, 0x5c, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x10}, /* digital zoom */ 589 {0xb1, 0x5c, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x10}, /* digital zoom */
573 {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10}, /* read mode */ 590 {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10}, /* read mode */
574 {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10}, 591 {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
575 /*******/ 592 {}
593};
594static const u8 mt9v111_sensor_param1[][8] = {
576 {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10}, 595 {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
577 {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10}, 596 {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
578 {0xb1, 0x5c, 0x09, 0x01, 0x2c, 0x00, 0x00, 0x10}, 597 {0xb1, 0x5c, 0x09, 0x01, 0x2c, 0x00, 0x00, 0x10},
@@ -585,14 +604,20 @@ static const u8 mt9v111_sensor_init[][8] = {
585 {0xb1, 0x5c, 0x35, 0x01, 0xc0, 0x00, 0x00, 0x10}, /* global gain */ 604 {0xb1, 0x5c, 0x35, 0x01, 0xc0, 0x00, 0x00, 0x10}, /* global gain */
586 {} 605 {}
587}; 606};
607static const u8 om6802_init0[2][8] = {
608/*fixme: variable*/
609 {0xa0, 0x34, 0x29, 0x0e, 0x00, 0x00, 0x00, 0x10},
610 {0xa0, 0x34, 0x23, 0xb0, 0x00, 0x00, 0x00, 0x10},
611};
588static const u8 om6802_sensor_init[][8] = { 612static const u8 om6802_sensor_init[][8] = {
589 {0xa0, 0x34, 0x90, 0x05, 0x00, 0x00, 0x00, 0x10}, 613 {0xa0, 0x34, 0xdf, 0x6d, 0x00, 0x00, 0x00, 0x10},
590 {0xa0, 0x34, 0x49, 0x85, 0x00, 0x00, 0x00, 0x10}, 614 /* factory mode */
591 {0xa0, 0x34, 0x5a, 0xc0, 0x00, 0x00, 0x00, 0x10},
592 {0xa0, 0x34, 0xdd, 0x18, 0x00, 0x00, 0x00, 0x10}, 615 {0xa0, 0x34, 0xdd, 0x18, 0x00, 0x00, 0x00, 0x10},
616 /* output raw RGB */
617 {0xa0, 0x34, 0x5a, 0xc0, 0x00, 0x00, 0x00, 0x10},
593/* {0xa0, 0x34, 0xfb, 0x11, 0x00, 0x00, 0x00, 0x10}, */ 618/* {0xa0, 0x34, 0xfb, 0x11, 0x00, 0x00, 0x00, 0x10}, */
594 {0xa0, 0x34, 0xf0, 0x04, 0x00, 0x00, 0x00, 0x10}, 619 {0xa0, 0x34, 0xf0, 0x04, 0x00, 0x00, 0x00, 0x10},
595 /* white balance & auto-exposure */ 620 /* auto-exposure speed (0) / white balance mode (auto RGB) */
596/* {0xa0, 0x34, 0xf1, 0x02, 0x00, 0x00, 0x00, 0x10}, 621/* {0xa0, 0x34, 0xf1, 0x02, 0x00, 0x00, 0x00, 0x10},
597 * set color mode */ 622 * set color mode */
598/* {0xa0, 0x34, 0xfe, 0x5b, 0x00, 0x00, 0x00, 0x10}, 623/* {0xa0, 0x34, 0xfe, 0x5b, 0x00, 0x00, 0x00, 0x10},
@@ -606,26 +631,29 @@ static const u8 om6802_sensor_init[][8] = {
606/* {0xa0, 0x34, 0xe8, 0x31, 0x00, 0x00, 0x00, 0x10}, 631/* {0xa0, 0x34, 0xe8, 0x31, 0x00, 0x00, 0x00, 0x10},
607 * preset gamma */ 632 * preset gamma */
608 {0xa0, 0x34, 0xe9, 0x0f, 0x00, 0x00, 0x00, 0x10}, 633 {0xa0, 0x34, 0xe9, 0x0f, 0x00, 0x00, 0x00, 0x10},
609 /* luminance mode (0x4f = AE) */ 634 /* luminance mode (0x4f -> AutoExpo on) */
610 {0xa0, 0x34, 0xe4, 0xff, 0x00, 0x00, 0x00, 0x10}, 635 {0xa0, 0x34, 0xe4, 0xff, 0x00, 0x00, 0x00, 0x10},
611 /* preset shutter */ 636 /* preset shutter */
612/* {0xa0, 0x34, 0xef, 0x00, 0x00, 0x00, 0x00, 0x10}, 637/* {0xa0, 0x34, 0xef, 0x00, 0x00, 0x00, 0x00, 0x10},
613 * auto frame rate */ 638 * auto frame rate */
614/* {0xa0, 0x34, 0xfb, 0xee, 0x00, 0x00, 0x00, 0x10}, */ 639/* {0xa0, 0x34, 0xfb, 0xee, 0x00, 0x00, 0x00, 0x10}, */
615 640 {0xa0, 0x34, 0x5d, 0x80, 0x00, 0x00, 0x00, 0x10},
616/* {0xa0, 0x34, 0x71, 0x84, 0x00, 0x00, 0x00, 0x10}, */ 641 {}
617/* {0xa0, 0x34, 0x72, 0x05, 0x00, 0x00, 0x00, 0x10}, */ 642};
618/* {0xa0, 0x34, 0x68, 0x80, 0x00, 0x00, 0x00, 0x10}, */ 643static const u8 om6802_sensor_param1[][8] = {
619/* {0xa0, 0x34, 0x69, 0x01, 0x00, 0x00, 0x00, 0x10}, */ 644 {0xa0, 0x34, 0x71, 0x84, 0x00, 0x00, 0x00, 0x10},
645 {0xa0, 0x34, 0x72, 0x05, 0x00, 0x00, 0x00, 0x10},
646 {0xa0, 0x34, 0x68, 0x80, 0x00, 0x00, 0x00, 0x10},
647 {0xa0, 0x34, 0x69, 0x01, 0x00, 0x00, 0x00, 0x10},
620 {} 648 {}
621}; 649};
622static const u8 ov7630_sensor_init[][8] = { 650static const u8 ov7630_sensor_init[][8] = {
623 {0xa1, 0x21, 0x76, 0x01, 0x00, 0x00, 0x00, 0x10}, 651 {0xa1, 0x21, 0x76, 0x01, 0x00, 0x00, 0x00, 0x10},
624 {0xa1, 0x21, 0x12, 0xc8, 0x00, 0x00, 0x00, 0x10}, 652 {0xa1, 0x21, 0x12, 0xc8, 0x00, 0x00, 0x00, 0x10},
625/* win: delay 20ms */ 653 {0xdd, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */
626 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10}, 654 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
627 {0xa1, 0x21, 0x12, 0xc8, 0x00, 0x00, 0x00, 0x10}, 655 {0xa1, 0x21, 0x12, 0xc8, 0x00, 0x00, 0x00, 0x10},
628/* win: delay 20ms */ 656 {0xdd, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */
629 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10}, 657 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
630/* win: i2c_r from 00 to 80 */ 658/* win: i2c_r from 00 to 80 */
631 {0xd1, 0x21, 0x03, 0x80, 0x10, 0x20, 0x80, 0x10}, 659 {0xd1, 0x21, 0x03, 0x80, 0x10, 0x20, 0x80, 0x10},
@@ -677,6 +705,7 @@ static const u8 ov7630_sensor_init[][8] = {
677static const u8 ov7648_sensor_init[][8] = { 705static const u8 ov7648_sensor_init[][8] = {
678 {0xa1, 0x21, 0x76, 0x00, 0x00, 0x00, 0x00, 0x10}, 706 {0xa1, 0x21, 0x76, 0x00, 0x00, 0x00, 0x00, 0x10},
679 {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset */ 707 {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset */
708 {0xdd, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */
680 {0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10}, 709 {0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
681 {0xd1, 0x21, 0x03, 0xa4, 0x30, 0x88, 0x00, 0x10}, 710 {0xd1, 0x21, 0x03, 0xa4, 0x30, 0x88, 0x00, 0x10},
682 {0xb1, 0x21, 0x11, 0x80, 0x08, 0x00, 0x00, 0x10}, 711 {0xb1, 0x21, 0x11, 0x80, 0x08, 0x00, 0x00, 0x10},
@@ -701,7 +730,9 @@ static const u8 ov7648_sensor_init[][8] = {
701/* {0xd1, 0x21, 0x25, 0x80, 0x32, 0xfe, 0xa0, 0x10}, jfm done */ 730/* {0xd1, 0x21, 0x25, 0x80, 0x32, 0xfe, 0xa0, 0x10}, jfm done */
702/* {0xd1, 0x21, 0x29, 0x00, 0x91, 0x00, 0x88, 0x10}, jfm done */ 731/* {0xd1, 0x21, 0x29, 0x00, 0x91, 0x00, 0x88, 0x10}, jfm done */
703/* {0xb1, 0x21, 0x2d, 0x85, 0x00, 0x00, 0x00, 0x10}, set by setfreq */ 732/* {0xb1, 0x21, 0x2d, 0x85, 0x00, 0x00, 0x00, 0x10}, set by setfreq */
704/*...*/ 733 {}
734};
735static const u8 ov7648_sensor_param1[][8] = {
705/* {0xa1, 0x21, 0x12, 0x08, 0x00, 0x00, 0x00, 0x10}, jfm done */ 736/* {0xa1, 0x21, 0x12, 0x08, 0x00, 0x00, 0x00, 0x10}, jfm done */
706/* {0xa1, 0x21, 0x75, 0x06, 0x00, 0x00, 0x00, 0x10}, * COMN 737/* {0xa1, 0x21, 0x75, 0x06, 0x00, 0x00, 0x00, 0x10}, * COMN
707 * set by setvflip */ 738 * set by setvflip */
@@ -723,7 +754,7 @@ static const u8 ov7648_sensor_init[][8] = {
723 754
724static const u8 ov7660_sensor_init[][8] = { 755static const u8 ov7660_sensor_init[][8] = {
725 {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset SCCB */ 756 {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset SCCB */
726/* (delay 20ms) */ 757 {0xdd, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */
727 {0xa1, 0x21, 0x12, 0x05, 0x00, 0x00, 0x00, 0x10}, 758 {0xa1, 0x21, 0x12, 0x05, 0x00, 0x00, 0x00, 0x10},
728 /* Outformat = rawRGB */ 759 /* Outformat = rawRGB */
729 {0xa1, 0x21, 0x13, 0xb8, 0x00, 0x00, 0x00, 0x10}, /* init COM8 */ 760 {0xa1, 0x21, 0x13, 0xb8, 0x00, 0x00, 0x00, 0x10}, /* init COM8 */
@@ -783,8 +814,11 @@ static const u8 ov7660_sensor_init[][8] = {
783 {0xc1, 0x21, 0x88, 0xaf, 0xc7, 0xdf, 0x00, 0x10}, /* gamma curve */ 814 {0xc1, 0x21, 0x88, 0xaf, 0xc7, 0xdf, 0x00, 0x10}, /* gamma curve */
784 {0xc1, 0x21, 0x8b, 0x99, 0x99, 0xcf, 0x00, 0x10}, /* reserved */ 815 {0xc1, 0x21, 0x8b, 0x99, 0x99, 0xcf, 0x00, 0x10}, /* reserved */
785 {0xb1, 0x21, 0x92, 0x00, 0x00, 0x00, 0x00, 0x10}, /* DM_LNL/H */ 816 {0xb1, 0x21, 0x92, 0x00, 0x00, 0x00, 0x00, 0x10}, /* DM_LNL/H */
817/* not in all ms-win traces*/
786 {0xa1, 0x21, 0xa1, 0x00, 0x00, 0x00, 0x00, 0x10}, 818 {0xa1, 0x21, 0xa1, 0x00, 0x00, 0x00, 0x00, 0x10},
787/****** (some exchanges in the win trace) ******/ 819 {}
820};
821static const u8 ov7660_sensor_param1[][8] = {
788 {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10}, /* MVFP */ 822 {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10}, /* MVFP */
789 /* bits[3..0]reserved */ 823 /* bits[3..0]reserved */
790 {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10}, 824 {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10},
@@ -797,6 +831,7 @@ static const u8 ov7660_sensor_init[][8] = {
797 {0xa1, 0x21, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x10}, /* GAIN */ 831 {0xa1, 0x21, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x10}, /* GAIN */
798/* {0xb1, 0x21, 0x01, 0x78, 0x78, 0x00, 0x00, 0x10}, * BLUE */ 832/* {0xb1, 0x21, 0x01, 0x78, 0x78, 0x00, 0x00, 0x10}, * BLUE */
799/****** (some exchanges in the win trace) ******/ 833/****** (some exchanges in the win trace) ******/
834/*fixme:param2*/
800 {0xa1, 0x21, 0x93, 0x00, 0x00, 0x00, 0x00, 0x10},/* dummy line hight */ 835 {0xa1, 0x21, 0x93, 0x00, 0x00, 0x00, 0x00, 0x10},/* dummy line hight */
801 {0xa1, 0x21, 0x92, 0x25, 0x00, 0x00, 0x00, 0x10}, /* dummy line low */ 836 {0xa1, 0x21, 0x92, 0x25, 0x00, 0x00, 0x00, 0x10}, /* dummy line low */
802 {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10}, /* EXHCH */ 837 {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10}, /* EXHCH */
@@ -804,6 +839,7 @@ static const u8 ov7660_sensor_init[][8] = {
804/* {0xa1, 0x21, 0x02, 0x90, 0x00, 0x00, 0x00, 0x10}, * RED */ 839/* {0xa1, 0x21, 0x02, 0x90, 0x00, 0x00, 0x00, 0x10}, * RED */
805/****** (some exchanges in the win trace) ******/ 840/****** (some exchanges in the win trace) ******/
806/******!! startsensor KO if changed !!****/ 841/******!! startsensor KO if changed !!****/
842/*fixme: param3*/
807 {0xa1, 0x21, 0x93, 0x01, 0x00, 0x00, 0x00, 0x10}, 843 {0xa1, 0x21, 0x93, 0x01, 0x00, 0x00, 0x00, 0x10},
808 {0xa1, 0x21, 0x92, 0xff, 0x00, 0x00, 0x00, 0x10}, 844 {0xa1, 0x21, 0x92, 0xff, 0x00, 0x00, 0x00, 0x10},
809 {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10}, 845 {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10},
@@ -811,6 +847,60 @@ static const u8 ov7660_sensor_init[][8] = {
811 {} 847 {}
812}; 848};
813 849
850static const u8 po1030_sensor_init[][8] = {
851/* the sensor registers are described in m5602/m5602_po1030.h */
852 {0xa1, 0x6e, 0x3f, 0x20, 0x00, 0x00, 0x00, 0x10}, /* sensor reset */
853 {0xdd, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */
854 {0xa1, 0x6e, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x10},
855 {0xa1, 0x6e, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x10},
856 {0xd1, 0x6e, 0x04, 0x02, 0xb1, 0x02, 0x39, 0x10},
857 {0xd1, 0x6e, 0x08, 0x00, 0x01, 0x00, 0x00, 0x10},
858 {0xd1, 0x6e, 0x0c, 0x02, 0x7f, 0x01, 0xe0, 0x10},
859 {0xd1, 0x6e, 0x12, 0x03, 0x02, 0x00, 0x03, 0x10},
860 {0xd1, 0x6e, 0x16, 0x85, 0x40, 0x4a, 0x40, 0x10}, /* r/g1/b/g2 gains */
861 {0xc1, 0x6e, 0x1a, 0x00, 0x80, 0x00, 0x00, 0x10},
862 {0xd1, 0x6e, 0x1d, 0x08, 0x03, 0x00, 0x00, 0x10},
863 {0xd1, 0x6e, 0x23, 0x00, 0xb0, 0x00, 0x94, 0x10},
864 {0xd1, 0x6e, 0x27, 0x58, 0x00, 0x00, 0x00, 0x10},
865 {0xb1, 0x6e, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10},
866 {0xd1, 0x6e, 0x2d, 0x14, 0x35, 0x61, 0x84, 0x10}, /* gamma corr */
867 {0xd1, 0x6e, 0x31, 0xa2, 0xbd, 0xd8, 0xff, 0x10},
868 {0xd1, 0x6e, 0x35, 0x06, 0x1e, 0x12, 0x02, 0x10}, /* color matrix */
869 {0xd1, 0x6e, 0x39, 0xaa, 0x53, 0x37, 0xd5, 0x10},
870 {0xa1, 0x6e, 0x3d, 0xf2, 0x00, 0x00, 0x00, 0x10},
871 {0xd1, 0x6e, 0x3e, 0x00, 0x00, 0x80, 0x03, 0x10},
872 {0xd1, 0x6e, 0x42, 0x03, 0x00, 0x00, 0x00, 0x10},
873 {0xc1, 0x6e, 0x46, 0x00, 0x80, 0x80, 0x00, 0x10},
874 {0xd1, 0x6e, 0x4b, 0x02, 0xef, 0x08, 0xcd, 0x10},
875 {0xd1, 0x6e, 0x4f, 0x00, 0xd0, 0x00, 0xa0, 0x10},
876 {0xd1, 0x6e, 0x53, 0x01, 0xaa, 0x01, 0x40, 0x10},
877 {0xd1, 0x6e, 0x5a, 0x50, 0x04, 0x30, 0x03, 0x10}, /* raw rgb bayer */
878 {0xa1, 0x6e, 0x5e, 0x00, 0x00, 0x00, 0x00, 0x10},
879 {0xd1, 0x6e, 0x5f, 0x10, 0x40, 0xff, 0x00, 0x10},
880
881 {0xd1, 0x6e, 0x63, 0x40, 0x40, 0x00, 0x00, 0x10},
882 {0xd1, 0x6e, 0x67, 0x00, 0x00, 0x00, 0x00, 0x10},
883 {0xd1, 0x6e, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x10},
884 {0xd1, 0x6e, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x10},
885 {0xc1, 0x6e, 0x73, 0x10, 0x80, 0xeb, 0x00, 0x10},
886 {}
887};
888static const u8 po1030_sensor_param1[][8] = {
889/* from ms-win traces - these values change with auto gain/expo/wb.. */
890 {0xa1, 0x6e, 0x1e, 0x03, 0x00, 0x00, 0x00, 0x10},
891 {0xa1, 0x6e, 0x1e, 0x03, 0x00, 0x00, 0x00, 0x10},
892/* mean values */
893 {0xc1, 0x6e, 0x1a, 0x02, 0xd4, 0xa4, 0x00, 0x10}, /* integlines */
894 {0xa1, 0x6e, 0x15, 0x04, 0x00, 0x00, 0x00, 0x10}, /* global gain */
895 {0xc1, 0x6e, 0x16, 0x40, 0x40, 0x40, 0x00, 0x10}, /* r/g1/b gains */
896
897 {0xa1, 0x6e, 0x1d, 0x08, 0x00, 0x00, 0x00, 0x10}, /* control1 */
898 {0xa1, 0x6e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x10}, /* frameheight */
899 {0xa1, 0x6e, 0x07, 0xd5, 0x00, 0x00, 0x00, 0x10},
900/* {0xc1, 0x6e, 0x16, 0x49, 0x40, 0x45, 0x00, 0x10}, */
901 {}
902};
903
814static const u8 sp80708_sensor_init[][8] = { 904static const u8 sp80708_sensor_init[][8] = {
815 {0xa1, 0x18, 0x06, 0xf9, 0x00, 0x00, 0x00, 0x10}, 905 {0xa1, 0x18, 0x06, 0xf9, 0x00, 0x00, 0x00, 0x10},
816 {0xa1, 0x18, 0x09, 0x1f, 0x00, 0x00, 0x00, 0x10}, 906 {0xa1, 0x18, 0x09, 0x1f, 0x00, 0x00, 0x00, 0x10},
@@ -883,7 +973,9 @@ static const u8 sp80708_sensor_init[][8] = {
883 {0xa1, 0x18, 0x67, 0x24, 0x00, 0x00, 0x00, 0x10}, 973 {0xa1, 0x18, 0x67, 0x24, 0x00, 0x00, 0x00, 0x10},
884 {0xa1, 0x18, 0x68, 0x08, 0x00, 0x00, 0x00, 0x10}, 974 {0xa1, 0x18, 0x68, 0x08, 0x00, 0x00, 0x00, 0x10},
885 {0xa1, 0x18, 0x2f, 0xc9, 0x00, 0x00, 0x00, 0x10}, 975 {0xa1, 0x18, 0x2f, 0xc9, 0x00, 0x00, 0x00, 0x10},
886 /********/ 976 {}
977};
978static const u8 sp80708_sensor_param1[][8] = {
887 {0xa1, 0x18, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x10}, 979 {0xa1, 0x18, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x10},
888 {0xa1, 0x18, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x10}, 980 {0xa1, 0x18, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x10},
889 {0xa1, 0x18, 0x03, 0x01, 0x00, 0x00, 0x00, 0x10}, 981 {0xa1, 0x18, 0x03, 0x01, 0x00, 0x00, 0x00, 0x10},
@@ -894,6 +986,19 @@ static const u8 sp80708_sensor_init[][8] = {
894 {} 986 {}
895}; 987};
896 988
989static const u8 (*sensor_init[10])[8] = {
990 hv7131r_sensor_init, /* HV7131R 0 */
991 mi0360_sensor_init, /* MI0360 1 */
992 mo4000_sensor_init, /* MO4000 2 */
993 mt9v111_sensor_init, /* MT9V111 3 */
994 om6802_sensor_init, /* OM6802 4 */
995 ov7630_sensor_init, /* OV7630 5 */
996 ov7648_sensor_init, /* OV7648 6 */
997 ov7660_sensor_init, /* OV7660 7 */
998 po1030_sensor_init, /* PO1030 8 */
999 sp80708_sensor_init, /* SP80708 9 */
1000};
1001
897/* read <len> bytes to gspca_dev->usb_buf */ 1002/* read <len> bytes to gspca_dev->usb_buf */
898static void reg_r(struct gspca_dev *gspca_dev, 1003static void reg_r(struct gspca_dev *gspca_dev,
899 u16 value, int len) 1004 u16 value, int len)
@@ -958,8 +1063,15 @@ static void i2c_w1(struct gspca_dev *gspca_dev, u8 reg, u8 val)
958 struct sd *sd = (struct sd *) gspca_dev; 1063 struct sd *sd = (struct sd *) gspca_dev;
959 1064
960 PDEBUG(D_USBO, "i2c_w2 [%02x] = %02x", reg, val); 1065 PDEBUG(D_USBO, "i2c_w2 [%02x] = %02x", reg, val);
961 gspca_dev->usb_buf[0] = 0x81 | (2 << 4); /* = a1 */ 1066 switch (sd->sensor) {
962 gspca_dev->usb_buf[1] = sd->i2c_base; 1067 case SENSOR_OM6802: /* i2c command = a0 (100 kHz) */
1068 gspca_dev->usb_buf[0] = 0x80 | (2 << 4);
1069 break;
1070 default: /* i2c command = a1 (400 kHz) */
1071 gspca_dev->usb_buf[0] = 0x81 | (2 << 4);
1072 break;
1073 }
1074 gspca_dev->usb_buf[1] = sd->i2c_addr;
963 gspca_dev->usb_buf[2] = reg; 1075 gspca_dev->usb_buf[2] = reg;
964 gspca_dev->usb_buf[3] = val; 1076 gspca_dev->usb_buf[3] = val;
965 gspca_dev->usb_buf[4] = 0; 1077 gspca_dev->usb_buf[4] = 0;
@@ -991,14 +1103,21 @@ static void i2c_w8(struct gspca_dev *gspca_dev,
991 msleep(2); 1103 msleep(2);
992} 1104}
993 1105
994/* read 5 bytes in gspca_dev->usb_buf */ 1106/* sensor read 'len' (1..5) bytes in gspca_dev->usb_buf */
995static void i2c_r5(struct gspca_dev *gspca_dev, u8 reg) 1107static void i2c_r(struct gspca_dev *gspca_dev, u8 reg, int len)
996{ 1108{
997 struct sd *sd = (struct sd *) gspca_dev; 1109 struct sd *sd = (struct sd *) gspca_dev;
998 u8 mode[8]; 1110 u8 mode[8];
999 1111
1000 mode[0] = 0x81 | 0x10; 1112 switch (sd->sensor) {
1001 mode[1] = sd->i2c_base; 1113 case SENSOR_OM6802: /* i2c command = 90 (100 kHz) */
1114 mode[0] = 0x80 | 0x10;
1115 break;
1116 default: /* i2c command = 91 (400 kHz) */
1117 mode[0] = 0x81 | 0x10;
1118 break;
1119 }
1120 mode[1] = sd->i2c_addr;
1002 mode[2] = reg; 1121 mode[2] = reg;
1003 mode[3] = 0; 1122 mode[3] = 0;
1004 mode[4] = 0; 1123 mode[4] = 0;
@@ -1007,33 +1126,43 @@ static void i2c_r5(struct gspca_dev *gspca_dev, u8 reg)
1007 mode[7] = 0x10; 1126 mode[7] = 0x10;
1008 i2c_w8(gspca_dev, mode); 1127 i2c_w8(gspca_dev, mode);
1009 msleep(2); 1128 msleep(2);
1010 mode[0] = 0x81 | (5 << 4) | 0x02; 1129 mode[0] = (mode[0] & 0x81) | (len << 4) | 0x02;
1011 mode[2] = 0; 1130 mode[2] = 0;
1012 i2c_w8(gspca_dev, mode); 1131 i2c_w8(gspca_dev, mode);
1013 msleep(2); 1132 msleep(2);
1014 reg_r(gspca_dev, 0x0a, 5); 1133 reg_r(gspca_dev, 0x0a, 5);
1015} 1134}
1016 1135
1017static int hv7131r_probe(struct gspca_dev *gspca_dev) 1136static void i2c_w_seq(struct gspca_dev *gspca_dev,
1137 const u8 (*data)[8])
1138{
1139 while ((*data)[0] != 0) {
1140 if ((*data)[0] != 0xdd)
1141 i2c_w8(gspca_dev, *data);
1142 else
1143 msleep((*data)[1]);
1144 data++;
1145 }
1146}
1147
1148static void hv7131r_probe(struct gspca_dev *gspca_dev)
1018{ 1149{
1019 i2c_w1(gspca_dev, 0x02, 0); /* sensor wakeup */ 1150 i2c_w1(gspca_dev, 0x02, 0); /* sensor wakeup */
1020 msleep(10); 1151 msleep(10);
1021 reg_w1(gspca_dev, 0x02, 0x66); /* Gpio on */ 1152 reg_w1(gspca_dev, 0x02, 0x66); /* Gpio on */
1022 msleep(10); 1153 msleep(10);
1023 i2c_r5(gspca_dev, 0); /* read sensor id */ 1154 i2c_r(gspca_dev, 0, 5); /* read sensor id */
1024 if (gspca_dev->usb_buf[0] == 0x02 1155 if (gspca_dev->usb_buf[0] == 0x02
1025 && gspca_dev->usb_buf[1] == 0x09 1156 && gspca_dev->usb_buf[1] == 0x09
1026 && gspca_dev->usb_buf[2] == 0x01 1157 && gspca_dev->usb_buf[2] == 0x01
1027 && gspca_dev->usb_buf[3] == 0x00 1158 && gspca_dev->usb_buf[3] == 0x00
1028 && gspca_dev->usb_buf[4] == 0x00) { 1159 && gspca_dev->usb_buf[4] == 0x00) {
1029 PDEBUG(D_PROBE, "Find Sensor sn9c102P HV7131R"); 1160 PDEBUG(D_PROBE, "Sensor sn9c102P HV7131R found");
1030 return 0; 1161 return;
1031 } 1162 }
1032 PDEBUG(D_PROBE, "Find Sensor 0x%02x 0x%02x 0x%02x", 1163 PDEBUG(D_PROBE, "Sensor 0x%02x 0x%02x 0x%02x - sn9c102P not found",
1033 gspca_dev->usb_buf[0], gspca_dev->usb_buf[1], 1164 gspca_dev->usb_buf[0], gspca_dev->usb_buf[1],
1034 gspca_dev->usb_buf[2]); 1165 gspca_dev->usb_buf[2]);
1035 PDEBUG(D_PROBE, "Sensor sn9c102P Not found");
1036 return -ENODEV;
1037} 1166}
1038 1167
1039static void mi0360_probe(struct gspca_dev *gspca_dev) 1168static void mi0360_probe(struct gspca_dev *gspca_dev)
@@ -1075,7 +1204,6 @@ static void mi0360_probe(struct gspca_dev *gspca_dev)
1075 case 0x823a: 1204 case 0x823a:
1076 PDEBUG(D_PROBE, "Sensor mt9v111"); 1205 PDEBUG(D_PROBE, "Sensor mt9v111");
1077 sd->sensor = SENSOR_MT9V111; 1206 sd->sensor = SENSOR_MT9V111;
1078 sd->i2c_base = 0x5c;
1079 break; 1207 break;
1080 case 0x8243: 1208 case 0x8243:
1081 PDEBUG(D_PROBE, "Sensor mi0360"); 1209 PDEBUG(D_PROBE, "Sensor mi0360");
@@ -1086,7 +1214,42 @@ static void mi0360_probe(struct gspca_dev *gspca_dev)
1086 } 1214 }
1087} 1215}
1088 1216
1089static int configure_gpio(struct gspca_dev *gspca_dev, 1217static void ov7648_probe(struct gspca_dev *gspca_dev)
1218{
1219 struct sd *sd = (struct sd *) gspca_dev;
1220
1221 /* check ov76xx */
1222 reg_w1(gspca_dev, 0x17, 0x62);
1223 reg_w1(gspca_dev, 0x01, 0x08);
1224 sd->i2c_addr = 0x21;
1225 i2c_r(gspca_dev, 0x0a, 2);
1226 if (gspca_dev->usb_buf[3] == 0x76) { /* ov76xx */
1227 PDEBUG(D_PROBE, "Sensor ov%02x%02x",
1228 gspca_dev->usb_buf[3], gspca_dev->usb_buf[4]);
1229 return;
1230 }
1231
1232 /* reset */
1233 reg_w1(gspca_dev, 0x01, 0x29);
1234 reg_w1(gspca_dev, 0x17, 0x42);
1235
1236 /* check po1030 */
1237 reg_w1(gspca_dev, 0x17, 0x62);
1238 reg_w1(gspca_dev, 0x01, 0x08);
1239 sd->i2c_addr = 0x6e;
1240 i2c_r(gspca_dev, 0x00, 2);
1241 if (gspca_dev->usb_buf[3] == 0x10 /* po1030 */
1242 && gspca_dev->usb_buf[4] == 0x30) {
1243 PDEBUG(D_PROBE, "Sensor po1030");
1244 sd->sensor = SENSOR_PO1030;
1245 return;
1246 }
1247
1248 PDEBUG(D_PROBE, "Unknown sensor %02x%02x",
1249 gspca_dev->usb_buf[3], gspca_dev->usb_buf[4]);
1250}
1251
1252static void bridge_init(struct gspca_dev *gspca_dev,
1090 const u8 *sn9c1xx) 1253 const u8 *sn9c1xx)
1091{ 1254{
1092 struct sd *sd = (struct sd *) gspca_dev; 1255 struct sd *sd = (struct sd *) gspca_dev;
@@ -1103,9 +1266,10 @@ static int configure_gpio(struct gspca_dev *gspca_dev,
1103 /* configure gpio */ 1266 /* configure gpio */
1104 reg_w(gspca_dev, 0x01, &sn9c1xx[1], 2); 1267 reg_w(gspca_dev, 0x01, &sn9c1xx[1], 2);
1105 reg_w(gspca_dev, 0x08, &sn9c1xx[8], 2); 1268 reg_w(gspca_dev, 0x08, &sn9c1xx[8], 2);
1106 reg_w(gspca_dev, 0x17, &sn9c1xx[0x17], 5); /* jfm len was 3 */ 1269 reg_w(gspca_dev, 0x17, &sn9c1xx[0x17], 5);
1107 switch (sd->sensor) { 1270 switch (sd->sensor) {
1108 case SENSOR_OV7660: 1271 case SENSOR_OV7660:
1272 case SENSOR_PO1030:
1109 case SENSOR_SP80708: 1273 case SENSOR_SP80708:
1110 reg9a = reg9a_spec; 1274 reg9a = reg9a_spec;
1111 break; 1275 break;
@@ -1115,7 +1279,7 @@ static int configure_gpio(struct gspca_dev *gspca_dev,
1115 } 1279 }
1116 reg_w(gspca_dev, 0x9a, reg9a, 6); 1280 reg_w(gspca_dev, 0x9a, reg9a, 6);
1117 1281
1118 reg_w(gspca_dev, 0xd4, regd4, sizeof regd4); /*fixme:jfm was 60 only*/ 1282 reg_w(gspca_dev, 0xd4, regd4, sizeof regd4);
1119 1283
1120 reg_w(gspca_dev, 0x03, &sn9c1xx[3], 0x0f); 1284 reg_w(gspca_dev, 0x03, &sn9c1xx[3], 0x0f);
1121 1285
@@ -1127,10 +1291,22 @@ static int configure_gpio(struct gspca_dev *gspca_dev,
1127 reg_w1(gspca_dev, 0x01, 0x40); 1291 reg_w1(gspca_dev, 0x01, 0x40);
1128 break; 1292 break;
1129 case SENSOR_OM6802: 1293 case SENSOR_OM6802:
1130 reg_w1(gspca_dev, 0x02, 0x71); 1294 msleep(10);
1131 reg_w1(gspca_dev, 0x01, 0x42); 1295 reg_w1(gspca_dev, 0x02, 0x73);
1296 reg_w1(gspca_dev, 0x17, 0x60);
1297 reg_w1(gspca_dev, 0x01, 0x22);
1298 msleep(100);
1299 reg_w1(gspca_dev, 0x01, 0x62);
1300 reg_w1(gspca_dev, 0x17, 0x64);
1132 reg_w1(gspca_dev, 0x17, 0x64); 1301 reg_w1(gspca_dev, 0x17, 0x64);
1133 reg_w1(gspca_dev, 0x01, 0x42); 1302 reg_w1(gspca_dev, 0x01, 0x42);
1303 msleep(10);
1304 reg_w1(gspca_dev, 0x01, 0x42);
1305 i2c_w8(gspca_dev, om6802_init0[0]);
1306 i2c_w8(gspca_dev, om6802_init0[1]);
1307 msleep(15);
1308 reg_w1(gspca_dev, 0x02, 0x71);
1309 msleep(150);
1134 break; 1310 break;
1135 case SENSOR_OV7630: 1311 case SENSOR_OV7630:
1136 reg_w1(gspca_dev, 0x01, 0x61); 1312 reg_w1(gspca_dev, 0x01, 0x61);
@@ -1144,7 +1320,14 @@ static int configure_gpio(struct gspca_dev *gspca_dev,
1144 reg_w1(gspca_dev, 0x01, 0x62); 1320 reg_w1(gspca_dev, 0x01, 0x62);
1145 reg_w1(gspca_dev, 0x01, 0x42); 1321 reg_w1(gspca_dev, 0x01, 0x42);
1146 break; 1322 break;
1323 case SENSOR_PO1030:
1324 reg_w1(gspca_dev, 0x01, 0x61);
1325 reg_w1(gspca_dev, 0x17, 0x20);
1326 reg_w1(gspca_dev, 0x01, 0x60);
1327 reg_w1(gspca_dev, 0x01, 0x40);
1328 break;
1147 case SENSOR_OV7660: 1329 case SENSOR_OV7660:
1330 /* fall thru */
1148 case SENSOR_SP80708: 1331 case SENSOR_SP80708:
1149 reg_w1(gspca_dev, 0x01, 0x63); 1332 reg_w1(gspca_dev, 0x01, 0x63);
1150 reg_w1(gspca_dev, 0x17, 0x20); 1333 reg_w1(gspca_dev, 0x17, 0x20);
@@ -1153,143 +1336,18 @@ static int configure_gpio(struct gspca_dev *gspca_dev,
1153 msleep(100); 1336 msleep(100);
1154 reg_w1(gspca_dev, 0x02, 0x62); 1337 reg_w1(gspca_dev, 0x02, 0x62);
1155 break; 1338 break;
1339 default:
1156/* case SENSOR_HV7131R: */ 1340/* case SENSOR_HV7131R: */
1157/* case SENSOR_MI0360: */ 1341/* case SENSOR_MI0360: */
1158/* case SENSOR_MO4000: */ 1342/* case SENSOR_MO4000: */
1159 default:
1160 reg_w1(gspca_dev, 0x01, 0x43); 1343 reg_w1(gspca_dev, 0x01, 0x43);
1161 reg_w1(gspca_dev, 0x17, 0x61); 1344 reg_w1(gspca_dev, 0x17, 0x61);
1162 reg_w1(gspca_dev, 0x01, 0x42); 1345 reg_w1(gspca_dev, 0x01, 0x42);
1163 if (sd->sensor == SENSOR_HV7131R) { 1346 if (sd->sensor == SENSOR_HV7131R
1164 if (hv7131r_probe(gspca_dev) < 0) 1347 && sd->bridge == BRIDGE_SN9C102P)
1165 return -ENODEV; 1348 hv7131r_probe(gspca_dev);
1166 }
1167 break; 1349 break;
1168 } 1350 }
1169 return 0;
1170}
1171
1172static void hv7131R_InitSensor(struct gspca_dev *gspca_dev)
1173{
1174 int i = 0;
1175 static const u8 SetSensorClk[] = /* 0x08 Mclk */
1176 { 0xa1, 0x11, 0x01, 0x18, 0x00, 0x00, 0x00, 0x10 };
1177
1178 while (hv7131r_sensor_init[i][0]) {
1179 i2c_w8(gspca_dev, hv7131r_sensor_init[i]);
1180 i++;
1181 }
1182 i2c_w8(gspca_dev, SetSensorClk);
1183}
1184
1185static void mi0360_InitSensor(struct gspca_dev *gspca_dev)
1186{
1187 int i = 0;
1188
1189 while (mi0360_sensor_init[i][0]) {
1190 i2c_w8(gspca_dev, mi0360_sensor_init[i]);
1191 i++;
1192 }
1193}
1194
1195static void mo4000_InitSensor(struct gspca_dev *gspca_dev)
1196{
1197 int i = 0;
1198
1199 while (mo4000_sensor_init[i][0]) {
1200 i2c_w8(gspca_dev, mo4000_sensor_init[i]);
1201 i++;
1202 }
1203}
1204
1205static void mt9v111_InitSensor(struct gspca_dev *gspca_dev)
1206{
1207 int i = 0;
1208
1209 i2c_w8(gspca_dev, mt9v111_sensor_init[i]);
1210 i++;
1211 msleep(20);
1212 while (mt9v111_sensor_init[i][0]) {
1213 i2c_w8(gspca_dev, mt9v111_sensor_init[i]);
1214 i++;
1215 }
1216}
1217
1218static void om6802_InitSensor(struct gspca_dev *gspca_dev)
1219{
1220 int i = 0;
1221
1222 while (om6802_sensor_init[i][0]) {
1223 i2c_w8(gspca_dev, om6802_sensor_init[i]);
1224 i++;
1225 }
1226}
1227
1228static void ov7630_InitSensor(struct gspca_dev *gspca_dev)
1229{
1230 int i = 0;
1231
1232 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 76 01 */
1233 i++;
1234 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 c8 (RGB+SRST) */
1235 i++;
1236 msleep(20);
1237 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 48 */
1238 i++;
1239 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 c8 */
1240 i++;
1241 msleep(20);
1242 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 48 */
1243 i++;
1244/*jfm:win i2c_r from 00 to 80*/
1245
1246 while (ov7630_sensor_init[i][0]) {
1247 i2c_w8(gspca_dev, ov7630_sensor_init[i]);
1248 i++;
1249 }
1250}
1251
1252static void ov7648_InitSensor(struct gspca_dev *gspca_dev)
1253{
1254 int i = 0;
1255
1256 i2c_w8(gspca_dev, ov7648_sensor_init[i]);
1257 i++;
1258/* win: dble reset */
1259 i2c_w8(gspca_dev, ov7648_sensor_init[i]); /* reset */
1260 i++;
1261 msleep(20);
1262/* win: i2c reg read 00..7f */
1263 while (ov7648_sensor_init[i][0]) {
1264 i2c_w8(gspca_dev, ov7648_sensor_init[i]);
1265 i++;
1266 }
1267}
1268
1269static void ov7660_InitSensor(struct gspca_dev *gspca_dev)
1270{
1271 int i = 0;
1272
1273 i2c_w8(gspca_dev, ov7660_sensor_init[i]); /* reset SCCB */
1274 i++;
1275 msleep(20);
1276 while (ov7660_sensor_init[i][0]) {
1277 i2c_w8(gspca_dev, ov7660_sensor_init[i]);
1278 i++;
1279 }
1280}
1281
1282static void sp80708_InitSensor(struct gspca_dev *gspca_dev)
1283{
1284 int i = 0;
1285
1286 i2c_w8(gspca_dev, sp80708_sensor_init[i]); /* reset SCCB */
1287 i++;
1288 msleep(20);
1289 while (sp80708_sensor_init[i][0]) {
1290 i2c_w8(gspca_dev, sp80708_sensor_init[i]);
1291 i++;
1292 }
1293} 1351}
1294 1352
1295/* this function is called at probe time */ 1353/* this function is called at probe time */
@@ -1305,8 +1363,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
1305 cam->npkt = 24; /* 24 packets per ISOC message */ 1363 cam->npkt = 24; /* 24 packets per ISOC message */
1306 1364
1307 sd->bridge = id->driver_info >> 16; 1365 sd->bridge = id->driver_info >> 16;
1308 sd->sensor = id->driver_info >> 8; 1366 sd->sensor = id->driver_info;
1309 sd->i2c_base = id->driver_info;
1310 1367
1311 sd->brightness = BRIGHTNESS_DEF; 1368 sd->brightness = BRIGHTNESS_DEF;
1312 sd->contrast = CONTRAST_DEF; 1369 sd->contrast = CONTRAST_DEF;
@@ -1322,7 +1379,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
1322 sd->quality = QUALITY_DEF; 1379 sd->quality = QUALITY_DEF;
1323 sd->jpegqual = 80; 1380 sd->jpegqual = 80;
1324 1381
1325 gspca_dev->ctrl_dis = ctrl_dis[sd->sensor];
1326 return 0; 1382 return 0;
1327} 1383}
1328 1384
@@ -1330,6 +1386,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
1330static int sd_init(struct gspca_dev *gspca_dev) 1386static int sd_init(struct gspca_dev *gspca_dev)
1331{ 1387{
1332 struct sd *sd = (struct sd *) gspca_dev; 1388 struct sd *sd = (struct sd *) gspca_dev;
1389 const u8 *sn9c1xx;
1333 u8 regGpio[] = { 0x29, 0x74 }; 1390 u8 regGpio[] = { 0x29, 0x74 };
1334 u8 regF1; 1391 u8 regF1;
1335 1392
@@ -1356,8 +1413,14 @@ static int sd_init(struct gspca_dev *gspca_dev)
1356 case BRIDGE_SN9C120: 1413 case BRIDGE_SN9C120:
1357 if (regF1 != 0x12) 1414 if (regF1 != 0x12)
1358 return -ENODEV; 1415 return -ENODEV;
1359 if (sd->sensor == SENSOR_MI0360) 1416 switch (sd->sensor) {
1417 case SENSOR_MI0360:
1360 mi0360_probe(gspca_dev); 1418 mi0360_probe(gspca_dev);
1419 break;
1420 case SENSOR_OV7648:
1421 ov7648_probe(gspca_dev);
1422 break;
1423 }
1361 regGpio[1] = 0x70; 1424 regGpio[1] = 0x70;
1362 reg_w(gspca_dev, 0x01, regGpio, 2); 1425 reg_w(gspca_dev, 0x01, regGpio, 2);
1363 break; 1426 break;
@@ -1372,6 +1435,12 @@ static int sd_init(struct gspca_dev *gspca_dev)
1372 1435
1373 reg_w1(gspca_dev, 0xf1, 0x01); 1436 reg_w1(gspca_dev, 0xf1, 0x01);
1374 1437
1438 /* set the i2c address */
1439 sn9c1xx = sn_tb[sd->sensor];
1440 sd->i2c_addr = sn9c1xx[9];
1441
1442 gspca_dev->ctrl_dis = ctrl_dis[sd->sensor];
1443
1375 return 0; 1444 return 0;
1376} 1445}
1377 1446
@@ -1383,7 +1452,7 @@ static u32 setexposure(struct gspca_dev *gspca_dev,
1383 switch (sd->sensor) { 1452 switch (sd->sensor) {
1384 case SENSOR_HV7131R: { 1453 case SENSOR_HV7131R: {
1385 u8 Expodoit[] = 1454 u8 Expodoit[] =
1386 { 0xc1, 0x11, 0x25, 0x07, 0x27, 0xc0, 0x00, 0x16 }; 1455 { 0xc1, 0x11, 0x25, 0x00, 0x00, 0x00, 0x00, 0x16 };
1387 1456
1388 Expodoit[3] = expo >> 16; 1457 Expodoit[3] = expo >> 16;
1389 Expodoit[4] = expo >> 8; 1458 Expodoit[4] = expo >> 8;
@@ -1393,7 +1462,7 @@ static u32 setexposure(struct gspca_dev *gspca_dev,
1393 } 1462 }
1394 case SENSOR_MI0360: { 1463 case SENSOR_MI0360: {
1395 u8 expoMi[] = /* exposure 0x0635 -> 4 fp/s 0x10 */ 1464 u8 expoMi[] = /* exposure 0x0635 -> 4 fp/s 0x10 */
1396 { 0xb1, 0x5d, 0x09, 0x06, 0x35, 0x00, 0x00, 0x16 }; 1465 { 0xb1, 0x5d, 0x09, 0x00, 0x00, 0x00, 0x00, 0x16 };
1397 static const u8 doit[] = /* update sensor */ 1466 static const u8 doit[] = /* update sensor */
1398 { 0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10 }; 1467 { 0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10 };
1399 static const u8 sensorgo[] = /* sensor on */ 1468 static const u8 sensorgo[] = /* sensor on */
@@ -1412,9 +1481,9 @@ static u32 setexposure(struct gspca_dev *gspca_dev,
1412 } 1481 }
1413 case SENSOR_MO4000: { 1482 case SENSOR_MO4000: {
1414 u8 expoMof[] = 1483 u8 expoMof[] =
1415 { 0xa1, 0x21, 0x0f, 0x20, 0x00, 0x00, 0x00, 0x10 }; 1484 { 0xa1, 0x21, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x10 };
1416 u8 expoMo10[] = 1485 u8 expoMo10[] =
1417 { 0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10 }; 1486 { 0xa1, 0x21, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10 };
1418 static const u8 gainMo[] = 1487 static const u8 gainMo[] =
1419 { 0xa1, 0x21, 0x00, 0x10, 0x00, 0x00, 0x00, 0x1d }; 1488 { 0xa1, 0x21, 0x00, 0x10, 0x00, 0x00, 0x00, 0x1d };
1420 1489
@@ -1450,6 +1519,7 @@ static u32 setexposure(struct gspca_dev *gspca_dev,
1450 case SENSOR_OM6802: { 1519 case SENSOR_OM6802: {
1451 u8 gainOm[] = 1520 u8 gainOm[] =
1452 { 0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10 }; 1521 { 0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10 };
1522 /* preset AGC - works when AutoExpo = off */
1453 1523
1454 if (expo > 0x03ff) 1524 if (expo > 0x03ff)
1455 expo = 0x03ff; 1525 expo = 0x03ff;
@@ -1457,7 +1527,7 @@ static u32 setexposure(struct gspca_dev *gspca_dev,
1457 expo = 0x0001; 1527 expo = 0x0001;
1458 gainOm[3] = expo >> 2; 1528 gainOm[3] = expo >> 2;
1459 i2c_w8(gspca_dev, gainOm); 1529 i2c_w8(gspca_dev, gainOm);
1460 reg_w1(gspca_dev, 0x96, (expo >> 5) & 0x1f); 1530 reg_w1(gspca_dev, 0x96, expo >> 5);
1461 PDEBUG(D_FRAM, "set exposure %d", gainOm[3]); 1531 PDEBUG(D_FRAM, "set exposure %d", gainOm[3]);
1462 break; 1532 break;
1463 } 1533 }
@@ -1489,7 +1559,7 @@ static void setbrightness(struct gspca_dev *gspca_dev)
1489 case SENSOR_MT9V111: 1559 case SENSOR_MT9V111:
1490 expo = sd->brightness >> 8; 1560 expo = sd->brightness >> 8;
1491 sd->exposure = setexposure(gspca_dev, expo); 1561 sd->exposure = setexposure(gspca_dev, expo);
1492 break; 1562 return; /* don't set the Y offset */
1493 case SENSOR_OM6802: 1563 case SENSOR_OM6802:
1494 expo = sd->brightness >> 6; 1564 expo = sd->brightness >> 6;
1495 sd->exposure = setexposure(gspca_dev, expo); 1565 sd->exposure = setexposure(gspca_dev, expo);
@@ -1497,8 +1567,7 @@ static void setbrightness(struct gspca_dev *gspca_dev)
1497 break; 1567 break;
1498 } 1568 }
1499 1569
1500 if (sd->sensor != SENSOR_MT9V111) 1570 reg_w1(gspca_dev, 0x96, k2); /* color matrix Y offset */
1501 reg_w1(gspca_dev, 0x96, k2); /* color matrix Y offset */
1502} 1571}
1503 1572
1504static void setcontrast(struct gspca_dev *gspca_dev) 1573static void setcontrast(struct gspca_dev *gspca_dev)
@@ -1526,6 +1595,7 @@ static void setcolors(struct gspca_dev *gspca_dev)
1526 -24, -38, 64, /* UR UG UB */ 1595 -24, -38, 64, /* UR UG UB */
1527 62, -51, -9 /* VR VG VB */ 1596 62, -51, -9 /* VR VG VB */
1528 }; 1597 };
1598
1529 for (i = 0; i < 6; i++) { 1599 for (i = 0; i < 6; i++) {
1530 v = uv[i] * sd->colors / COLOR_DEF; 1600 v = uv[i] * sd->colors / COLOR_DEF;
1531 reg8a[i * 2] = v; 1601 reg8a[i * 2] = v;
@@ -1605,6 +1675,8 @@ static void setvflip(struct sd *sd)
1605{ 1675{
1606 u8 comn; 1676 u8 comn;
1607 1677
1678 if (sd->gspca_dev.ctrl_dis & (1 << VFLIP_IDX))
1679 return;
1608 if (sd->sensor == SENSOR_OV7630) { 1680 if (sd->sensor == SENSOR_OV7630) {
1609 comn = 0x02; 1681 comn = 0x02;
1610 if (!sd->vflip) 1682 if (!sd->vflip)
@@ -1726,8 +1798,9 @@ static int sd_start(struct gspca_dev *gspca_dev)
1726{ 1798{
1727 struct sd *sd = (struct sd *) gspca_dev; 1799 struct sd *sd = (struct sd *) gspca_dev;
1728 int i; 1800 int i;
1729 u8 reg1, reg17; 1801 u8 reg1, reg2, reg17;
1730 const u8 *sn9c1xx; 1802 const u8 *sn9c1xx;
1803 const u8 (*init)[8];
1731 int mode; 1804 int mode;
1732 static const u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f }; 1805 static const u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f };
1733 static const u8 CA[] = { 0x28, 0xd8, 0x14, 0xec }; 1806 static const u8 CA[] = { 0x28, 0xd8, 0x14, 0xec };
@@ -1743,8 +1816,26 @@ static int sd_start(struct gspca_dev *gspca_dev)
1743 0x21); /* JPEG 422 */ 1816 0x21); /* JPEG 422 */
1744 jpeg_set_qual(sd->jpeg_hdr, sd->quality); 1817 jpeg_set_qual(sd->jpeg_hdr, sd->quality);
1745 1818
1746 sn9c1xx = sn_tb[(int) sd->sensor]; 1819 /* initialize the bridge */
1747 configure_gpio(gspca_dev, sn9c1xx); 1820 sn9c1xx = sn_tb[sd->sensor];
1821 bridge_init(gspca_dev, sn9c1xx);
1822
1823 /* initialize the sensor */
1824 i2c_w_seq(gspca_dev, sensor_init[sd->sensor]);
1825
1826 switch (sd->sensor) {
1827 case SENSOR_OM6802:
1828 reg2 = 0x71;
1829 break;
1830 case SENSOR_SP80708:
1831 reg2 = 0x62;
1832 break;
1833 default:
1834 reg2 = 0x40;
1835 break;
1836 }
1837 reg_w1(gspca_dev, 0x02, reg2);
1838 reg_w1(gspca_dev, 0x02, reg2);
1748 1839
1749 reg_w1(gspca_dev, 0x15, sn9c1xx[0x15]); 1840 reg_w1(gspca_dev, 0x15, sn9c1xx[0x15]);
1750 reg_w1(gspca_dev, 0x16, sn9c1xx[0x16]); 1841 reg_w1(gspca_dev, 0x16, sn9c1xx[0x16]);
@@ -1771,6 +1862,9 @@ static int sd_start(struct gspca_dev *gspca_dev)
1771 case SENSOR_OV7660: 1862 case SENSOR_OV7660:
1772 reg17 = 0xa0; 1863 reg17 = 0xa0;
1773 break; 1864 break;
1865 case SENSOR_PO1030:
1866 reg17 = 0xa0;
1867 break;
1774 default: 1868 default:
1775 reg17 = 0x60; 1869 reg17 = 0x60;
1776 break; 1870 break;
@@ -1791,6 +1885,10 @@ static int sd_start(struct gspca_dev *gspca_dev)
1791 reg_w1(gspca_dev, 0x9a, 0x07); 1885 reg_w1(gspca_dev, 0x9a, 0x07);
1792 reg_w1(gspca_dev, 0x99, 0x59); 1886 reg_w1(gspca_dev, 0x99, 0x59);
1793 break; 1887 break;
1888 case SENSOR_OM6802:
1889 reg_w1(gspca_dev, 0x9a, 0x08);
1890 reg_w1(gspca_dev, 0x99, 0x10);
1891 break;
1794 case SENSOR_OV7648: 1892 case SENSOR_OV7648:
1795 reg_w1(gspca_dev, 0x9a, 0x0a); 1893 reg_w1(gspca_dev, 0x9a, 0x0a);
1796 reg_w1(gspca_dev, 0x99, 0x60); 1894 reg_w1(gspca_dev, 0x99, 0x60);
@@ -1806,21 +1904,20 @@ static int sd_start(struct gspca_dev *gspca_dev)
1806 break; 1904 break;
1807 } 1905 }
1808 1906
1809 mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; 1907 reg_w(gspca_dev, 0x84, reg84, sizeof reg84);
1908 reg_w1(gspca_dev, 0x05, sn9c1xx[5]); /* red */
1909 reg_w1(gspca_dev, 0x07, sn9c1xx[7]); /* green */
1910 reg_w1(gspca_dev, 0x06, sn9c1xx[6]); /* blue */
1911
1912 init = NULL;
1913 mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
1810 if (mode) 1914 if (mode)
1811 reg1 = 0x46; /* 320x240: clk 48Mhz, video trf enable */ 1915 reg1 = 0x46; /* 320x240: clk 48Mhz, video trf enable */
1812 else 1916 else
1813 reg1 = 0x06; /* 640x480: clk 24Mhz, video trf enable */ 1917 reg1 = 0x06; /* 640x480: clk 24Mhz, video trf enable */
1814 reg17 = 0x61; /* 0x:20: enable sensor clock */ 1918 reg17 = 0x61; /* 0x:20: enable sensor clock */
1815 switch (sd->sensor) { 1919 switch (sd->sensor) {
1816 case SENSOR_HV7131R:
1817 hv7131R_InitSensor(gspca_dev);
1818 break;
1819 case SENSOR_MI0360:
1820 mi0360_InitSensor(gspca_dev);
1821 break;
1822 case SENSOR_MO4000: 1920 case SENSOR_MO4000:
1823 mo4000_InitSensor(gspca_dev);
1824 if (mode) { 1921 if (mode) {
1825/* reg1 = 0x46; * 320 clk 48Mhz 60fp/s */ 1922/* reg1 = 0x46; * 320 clk 48Mhz 60fp/s */
1826 reg1 = 0x06; /* clk 24Mz */ 1923 reg1 = 0x06; /* clk 24Mz */
@@ -1830,7 +1927,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
1830 } 1927 }
1831 break; 1928 break;
1832 case SENSOR_MT9V111: 1929 case SENSOR_MT9V111:
1833 mt9v111_InitSensor(gspca_dev); 1930 init = mt9v111_sensor_param1;
1834 if (mode) { 1931 if (mode) {
1835 reg1 = 0x04; /* 320 clk 48Mhz */ 1932 reg1 = 0x04; /* 320 clk 48Mhz */
1836 } else { 1933 } else {
@@ -1839,22 +1936,21 @@ static int sd_start(struct gspca_dev *gspca_dev)
1839 } 1936 }
1840 break; 1937 break;
1841 case SENSOR_OM6802: 1938 case SENSOR_OM6802:
1842 om6802_InitSensor(gspca_dev); 1939 init = om6802_sensor_param1;
1843 reg17 = 0x64; /* 640 MCKSIZE */ 1940 reg17 = 0x64; /* 640 MCKSIZE */
1844 break; 1941 break;
1845 case SENSOR_OV7630: 1942 case SENSOR_OV7630:
1846 ov7630_InitSensor(gspca_dev);
1847 setvflip(sd); 1943 setvflip(sd);
1848 reg17 = 0xe2; 1944 reg17 = 0xe2;
1849 reg1 = 0x44; 1945 reg1 = 0x44;
1850 break; 1946 break;
1851 case SENSOR_OV7648: 1947 case SENSOR_OV7648:
1852 ov7648_InitSensor(gspca_dev); 1948 init = ov7648_sensor_param1;
1853 reg17 = 0x21; 1949 reg17 = 0x21;
1854/* reg1 = 0x42; * 42 - 46? */ 1950/* reg1 = 0x42; * 42 - 46? */
1855 break; 1951 break;
1856 case SENSOR_OV7660: 1952 case SENSOR_OV7660:
1857 ov7660_InitSensor(gspca_dev); 1953 init = ov7660_sensor_param1;
1858 if (sd->bridge == BRIDGE_SN9C120) { 1954 if (sd->bridge == BRIDGE_SN9C120) {
1859 if (mode) { /* 320x240 - 160x120 */ 1955 if (mode) { /* 320x240 - 160x120 */
1860 reg17 = 0xa2; 1956 reg17 = 0xa2;
@@ -1866,9 +1962,14 @@ static int sd_start(struct gspca_dev *gspca_dev)
1866 * inverse power down */ 1962 * inverse power down */
1867 } 1963 }
1868 break; 1964 break;
1965 case SENSOR_PO1030:
1966 init = po1030_sensor_param1;
1967 reg17 = 0xa2;
1968 reg1 = 0x44;
1969 break;
1869 default: 1970 default:
1870/* case SENSOR_SP80708: */ 1971/* case SENSOR_SP80708: */
1871 sp80708_InitSensor(gspca_dev); 1972 init = sp80708_sensor_param1;
1872 if (mode) { 1973 if (mode) {
1873/*?? reg1 = 0x04; * 320 clk 48Mhz */ 1974/*?? reg1 = 0x04; * 320 clk 48Mhz */
1874 } else { 1975 } else {
@@ -1877,6 +1978,13 @@ static int sd_start(struct gspca_dev *gspca_dev)
1877 } 1978 }
1878 break; 1979 break;
1879 } 1980 }
1981
1982 /* more sensor initialization - param1 */
1983 if (init != NULL) {
1984 i2c_w_seq(gspca_dev, init);
1985/* init = NULL; */
1986 }
1987
1880 reg_w(gspca_dev, 0xc0, C0, 6); 1988 reg_w(gspca_dev, 0xc0, C0, 6);
1881 reg_w(gspca_dev, 0xca, CA, 4); 1989 reg_w(gspca_dev, 0xca, CA, 4);
1882 switch (sd->sensor) { 1990 switch (sd->sensor) {
@@ -1891,6 +1999,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
1891 break; 1999 break;
1892 } 2000 }
1893 2001
2002
1894 /* here change size mode 0 -> VGA; 1 -> CIF */ 2003 /* here change size mode 0 -> VGA; 1 -> CIF */
1895 sd->reg18 = sn9c1xx[0x18] | (mode << 4) | 0x40; 2004 sd->reg18 = sn9c1xx[0x18] | (mode << 4) | 0x40;
1896 reg_w1(gspca_dev, 0x18, sd->reg18); 2005 reg_w1(gspca_dev, 0x18, sd->reg18);
@@ -1898,6 +2007,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
1898 2007
1899 reg_w1(gspca_dev, 0x17, reg17); 2008 reg_w1(gspca_dev, 0x17, reg17);
1900 reg_w1(gspca_dev, 0x01, reg1); 2009 reg_w1(gspca_dev, 0x01, reg1);
2010
1901 switch (sd->sensor) { 2011 switch (sd->sensor) {
1902 case SENSOR_OV7630: 2012 case SENSOR_OV7630:
1903 setvflip(sd); 2013 setvflip(sd);
@@ -1937,14 +2047,11 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
1937 /* fall thru */ 2047 /* fall thru */
1938 case SENSOR_MT9V111: 2048 case SENSOR_MT9V111:
1939 case SENSOR_OV7630: 2049 case SENSOR_OV7630:
2050 case SENSOR_PO1030:
1940 data = 0x29; 2051 data = 0x29;
1941 break; 2052 break;
1942 default:
1943/* case SENSOR_MO4000: */
1944/* case SENSOR_OV7660: */
1945 break;
1946 } 2053 }
1947 sn9c1xx = sn_tb[(int) sd->sensor]; 2054 sn9c1xx = sn_tb[sd->sensor];
1948 reg_w1(gspca_dev, 0x01, sn9c1xx[1]); 2055 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
1949 reg_w1(gspca_dev, 0x17, sn9c1xx[0x17]); 2056 reg_w1(gspca_dev, 0x17, sn9c1xx[0x17]);
1950 reg_w1(gspca_dev, 0x01, sn9c1xx[1]); 2057 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
@@ -1987,11 +2094,19 @@ static void do_autogain(struct gspca_dev *gspca_dev)
1987 sd->exposure = setexposure(gspca_dev, 2094 sd->exposure = setexposure(gspca_dev,
1988 (unsigned int) (expotimes << 8)); 2095 (unsigned int) (expotimes << 8));
1989 break; 2096 break;
2097 case SENSOR_OM6802:
2098 expotimes = sd->exposure;
2099 expotimes += (luma_mean - delta) >> 2;
2100 if (expotimes < 0)
2101 expotimes = 0;
2102 sd->exposure = setexposure(gspca_dev,
2103 (unsigned int) expotimes);
2104 setredblue(gspca_dev);
2105 break;
1990 default: 2106 default:
1991/* case SENSOR_MO4000: */ 2107/* case SENSOR_MO4000: */
1992/* case SENSOR_MI0360: */ 2108/* case SENSOR_MI0360: */
1993/* case SENSOR_MT9V111: */ 2109/* case SENSOR_MT9V111: */
1994/* case SENSOR_OM6802: */
1995 expotimes = sd->exposure; 2110 expotimes = sd->exposure;
1996 expotimes += (luma_mean - delta) >> 6; 2111 expotimes += (luma_mean - delta) >> 6;
1997 if (expotimes < 0) 2112 if (expotimes < 0)
@@ -2007,7 +2122,6 @@ static void do_autogain(struct gspca_dev *gspca_dev)
2007/* scan the URB packets */ 2122/* scan the URB packets */
2008/* This function is run at interrupt level. */ 2123/* This function is run at interrupt level. */
2009static void sd_pkt_scan(struct gspca_dev *gspca_dev, 2124static void sd_pkt_scan(struct gspca_dev *gspca_dev,
2010 struct gspca_frame *frame, /* target */
2011 u8 *data, /* isoc packet */ 2125 u8 *data, /* isoc packet */
2012 int len) /* iso packet length */ 2126 int len) /* iso packet length */
2013{ 2127{
@@ -2019,7 +2133,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
2019 2133
2020 /* end of frame */ 2134 /* end of frame */
2021 gspca_frame_add(gspca_dev, LAST_PACKET, 2135 gspca_frame_add(gspca_dev, LAST_PACKET,
2022 frame, data, sof + 2); 2136 data, sof + 2);
2023 if (sd->ag_cnt < 0) 2137 if (sd->ag_cnt < 0)
2024 return; 2138 return;
2025/* w1 w2 w3 */ 2139/* w1 w2 w3 */
@@ -2042,10 +2156,10 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
2042 if (gspca_dev->last_packet_type == LAST_PACKET) { 2156 if (gspca_dev->last_packet_type == LAST_PACKET) {
2043 2157
2044 /* put the JPEG 422 header */ 2158 /* put the JPEG 422 header */
2045 gspca_frame_add(gspca_dev, FIRST_PACKET, frame, 2159 gspca_frame_add(gspca_dev, FIRST_PACKET,
2046 sd->jpeg_hdr, JPEG_HDR_SZ); 2160 sd->jpeg_hdr, JPEG_HDR_SZ);
2047 } 2161 }
2048 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); 2162 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
2049} 2163}
2050 2164
2051static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) 2165static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
@@ -2295,69 +2409,69 @@ static const struct sd_desc sd_desc = {
2295}; 2409};
2296 2410
2297/* -- module initialisation -- */ 2411/* -- module initialisation -- */
2298#define BSI(bridge, sensor, i2c_addr) \ 2412#define BS(bridge, sensor) \
2299 .driver_info = (BRIDGE_ ## bridge << 16) \ 2413 .driver_info = (BRIDGE_ ## bridge << 16) \
2300 | (SENSOR_ ## sensor << 8) \ 2414 | SENSOR_ ## sensor
2301 | (i2c_addr)
2302static const __devinitdata struct usb_device_id device_table[] = { 2415static const __devinitdata struct usb_device_id device_table[] = {
2303#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE 2416#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
2304 {USB_DEVICE(0x0458, 0x7025), BSI(SN9C120, MI0360, 0x5d)}, 2417 {USB_DEVICE(0x0458, 0x7025), BS(SN9C120, MI0360)},
2305 {USB_DEVICE(0x0458, 0x702e), BSI(SN9C120, OV7660, 0x21)}, 2418 {USB_DEVICE(0x0458, 0x702e), BS(SN9C120, OV7660)},
2306#endif 2419#endif
2307 {USB_DEVICE(0x045e, 0x00f5), BSI(SN9C105, OV7660, 0x21)}, 2420 {USB_DEVICE(0x045e, 0x00f5), BS(SN9C105, OV7660)},
2308 {USB_DEVICE(0x045e, 0x00f7), BSI(SN9C105, OV7660, 0x21)}, 2421 {USB_DEVICE(0x045e, 0x00f7), BS(SN9C105, OV7660)},
2309 {USB_DEVICE(0x0471, 0x0327), BSI(SN9C105, MI0360, 0x5d)}, 2422 {USB_DEVICE(0x0471, 0x0327), BS(SN9C105, MI0360)},
2310 {USB_DEVICE(0x0471, 0x0328), BSI(SN9C105, MI0360, 0x5d)}, 2423 {USB_DEVICE(0x0471, 0x0328), BS(SN9C105, MI0360)},
2311 {USB_DEVICE(0x0471, 0x0330), BSI(SN9C105, MI0360, 0x5d)}, 2424 {USB_DEVICE(0x0471, 0x0330), BS(SN9C105, MI0360)},
2312 {USB_DEVICE(0x06f8, 0x3004), BSI(SN9C105, OV7660, 0x21)}, 2425 {USB_DEVICE(0x06f8, 0x3004), BS(SN9C105, OV7660)},
2313 {USB_DEVICE(0x06f8, 0x3008), BSI(SN9C105, OV7660, 0x21)}, 2426 {USB_DEVICE(0x06f8, 0x3008), BS(SN9C105, OV7660)},
2314 {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, HV7131R, 0x11)}, 2427/* {USB_DEVICE(0x0c45, 0x603a), BS(SN9C102P, OV7648)}, */
2315/* bw600.inf: 2428 {USB_DEVICE(0x0c45, 0x6040), BS(SN9C102P, HV7131R)},
2316 {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, MI0360, 0x5d)}, */ 2429/* {USB_DEVICE(0x0c45, 0x607a), BS(SN9C102P, OV7648)}, */
2317/* {USB_DEVICE(0x0c45, 0x603a), BSI(SN9C102P, OV7648, 0x??)}, */ 2430/* {USB_DEVICE(0x0c45, 0x607b), BS(SN9C102P, OV7660)}, */
2318/* {USB_DEVICE(0x0c45, 0x607a), BSI(SN9C102P, OV7648, 0x??)}, */ 2431 {USB_DEVICE(0x0c45, 0x607c), BS(SN9C102P, HV7131R)},
2319 {USB_DEVICE(0x0c45, 0x607c), BSI(SN9C102P, HV7131R, 0x11)}, 2432/* {USB_DEVICE(0x0c45, 0x607e), BS(SN9C102P, OV7630)}, */
2320/* {USB_DEVICE(0x0c45, 0x607e), BSI(SN9C102P, OV7630, 0x??)}, */ 2433 {USB_DEVICE(0x0c45, 0x60c0), BS(SN9C105, MI0360)},
2321 {USB_DEVICE(0x0c45, 0x60c0), BSI(SN9C105, MI0360, 0x5d)}, 2434/* {USB_DEVICE(0x0c45, 0x60c2), BS(SN9C105, P1030xC)}, */
2322/* {USB_DEVICE(0x0c45, 0x60c8), BSI(SN9C105, OM6802, 0x??)}, */ 2435/* {USB_DEVICE(0x0c45, 0x60c8), BS(SN9C105, OM6802)}, */
2323/* {USB_DEVICE(0x0c45, 0x60cc), BSI(SN9C105, HV7131GP, 0x??)}, */ 2436/* {USB_DEVICE(0x0c45, 0x60cc), BS(SN9C105, HV7131GP)}, */
2324 {USB_DEVICE(0x0c45, 0x60ec), BSI(SN9C105, MO4000, 0x21)}, 2437 {USB_DEVICE(0x0c45, 0x60ec), BS(SN9C105, MO4000)},
2325/* {USB_DEVICE(0x0c45, 0x60ef), BSI(SN9C105, ICM105C, 0x??)}, */ 2438/* {USB_DEVICE(0x0c45, 0x60ef), BS(SN9C105, ICM105C)}, */
2326/* {USB_DEVICE(0x0c45, 0x60fa), BSI(SN9C105, OV7648, 0x??)}, */ 2439/* {USB_DEVICE(0x0c45, 0x60fa), BS(SN9C105, OV7648)}, */
2327 {USB_DEVICE(0x0c45, 0x60fb), BSI(SN9C105, OV7660, 0x21)}, 2440 {USB_DEVICE(0x0c45, 0x60fb), BS(SN9C105, OV7660)},
2328#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE 2441#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
2329 {USB_DEVICE(0x0c45, 0x60fc), BSI(SN9C105, HV7131R, 0x11)}, 2442 {USB_DEVICE(0x0c45, 0x60fc), BS(SN9C105, HV7131R)},
2330 {USB_DEVICE(0x0c45, 0x60fe), BSI(SN9C105, OV7630, 0x21)}, 2443 {USB_DEVICE(0x0c45, 0x60fe), BS(SN9C105, OV7630)},
2331#endif 2444#endif
2332 {USB_DEVICE(0x0c45, 0x6100), BSI(SN9C120, MI0360, 0x5d)}, /*sn9c128*/ 2445 {USB_DEVICE(0x0c45, 0x6100), BS(SN9C120, MI0360)}, /*sn9c128*/
2333/* {USB_DEVICE(0x0c45, 0x6102), BSI(SN9C120, PO2030N, ??)}, */ 2446/* {USB_DEVICE(0x0c45, 0x6102), BS(SN9C120, P1030xC)}, */
2334/* {USB_DEVICE(0x0c45, 0x6108), BSI(SN9C120, OM6802, 0x21)}, */ 2447/* {USB_DEVICE(0x0c45, 0x6108), BS(SN9C120, OM6802)}, */
2335 {USB_DEVICE(0x0c45, 0x610a), BSI(SN9C120, OV7648, 0x21)}, /*sn9c128*/ 2448 {USB_DEVICE(0x0c45, 0x610a), BS(SN9C120, OV7648)}, /*sn9c128*/
2336 {USB_DEVICE(0x0c45, 0x610b), BSI(SN9C120, OV7660, 0x21)}, /*sn9c128*/ 2449 {USB_DEVICE(0x0c45, 0x610b), BS(SN9C120, OV7660)}, /*sn9c128*/
2337 {USB_DEVICE(0x0c45, 0x610c), BSI(SN9C120, HV7131R, 0x11)}, /*sn9c128*/ 2450 {USB_DEVICE(0x0c45, 0x610c), BS(SN9C120, HV7131R)}, /*sn9c128*/
2338 {USB_DEVICE(0x0c45, 0x610e), BSI(SN9C120, OV7630, 0x21)}, /*sn9c128*/ 2451 {USB_DEVICE(0x0c45, 0x610e), BS(SN9C120, OV7630)}, /*sn9c128*/
2339/* {USB_DEVICE(0x0c45, 0x6122), BSI(SN9C110, ICM105C, 0x??)}, */ 2452/* {USB_DEVICE(0x0c45, 0x610f), BS(SN9C120, S5K53BEB)}, */
2340/* {USB_DEVICE(0x0c45, 0x6123), BSI(SN9C110, SanyoCCD, 0x??)}, */ 2453/* {USB_DEVICE(0x0c45, 0x6122), BS(SN9C110, ICM105C)}, */
2341 {USB_DEVICE(0x0c45, 0x6128), BSI(SN9C110, OM6802, 0x21)}, /*sn9c325?*/ 2454/* {USB_DEVICE(0x0c45, 0x6123), BS(SN9C110, SanyoCCD)}, */
2455 {USB_DEVICE(0x0c45, 0x6128), BS(SN9C120, OM6802)}, /*sn9c325?*/
2342/*bw600.inf:*/ 2456/*bw600.inf:*/
2343 {USB_DEVICE(0x0c45, 0x612a), BSI(SN9C120, OV7648, 0x21)}, /*sn9c110?*/ 2457 {USB_DEVICE(0x0c45, 0x612a), BS(SN9C120, OV7648)}, /*sn9c325?*/
2344 {USB_DEVICE(0x0c45, 0x612c), BSI(SN9C110, MO4000, 0x21)}, 2458 {USB_DEVICE(0x0c45, 0x612c), BS(SN9C110, MO4000)},
2345 {USB_DEVICE(0x0c45, 0x612e), BSI(SN9C110, OV7630, 0x21)}, 2459 {USB_DEVICE(0x0c45, 0x612e), BS(SN9C110, OV7630)},
2346/* {USB_DEVICE(0x0c45, 0x612f), BSI(SN9C110, ICM105C, 0x??)}, */ 2460/* {USB_DEVICE(0x0c45, 0x612f), BS(SN9C110, ICM105C)}, */
2347#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE 2461#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
2348 {USB_DEVICE(0x0c45, 0x6130), BSI(SN9C120, MI0360, 0x5d)}, 2462 {USB_DEVICE(0x0c45, 0x6130), BS(SN9C120, MI0360)},
2349#endif 2463#endif
2350/* {USB_DEVICE(0x0c45, 0x6132), BSI(SN9C120, OV7670, 0x21)}, */ 2464/* {USB_DEVICE(0x0c45, 0x6132), BS(SN9C120, OV7670)}, */
2351 {USB_DEVICE(0x0c45, 0x6138), BSI(SN9C120, MO4000, 0x21)}, 2465 {USB_DEVICE(0x0c45, 0x6138), BS(SN9C120, MO4000)},
2352 {USB_DEVICE(0x0c45, 0x613a), BSI(SN9C120, OV7648, 0x21)}, 2466 {USB_DEVICE(0x0c45, 0x613a), BS(SN9C120, OV7648)},
2353#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE 2467#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
2354 {USB_DEVICE(0x0c45, 0x613b), BSI(SN9C120, OV7660, 0x21)}, 2468 {USB_DEVICE(0x0c45, 0x613b), BS(SN9C120, OV7660)},
2355#endif 2469#endif
2356 {USB_DEVICE(0x0c45, 0x613c), BSI(SN9C120, HV7131R, 0x11)}, 2470 {USB_DEVICE(0x0c45, 0x613c), BS(SN9C120, HV7131R)},
2357 {USB_DEVICE(0x0c45, 0x613e), BSI(SN9C120, OV7630, 0x21)}, 2471 {USB_DEVICE(0x0c45, 0x613e), BS(SN9C120, OV7630)},
2358/* {USB_DEVICE(0x0c45, 0x6142), BSI(SN9C120, PO2030N, ??)}, *sn9c120b*/ 2472/* {USB_DEVICE(0x0c45, 0x6142), BS(SN9C120, PO2030N)}, *sn9c120b*/
2359 {USB_DEVICE(0x0c45, 0x6143), BSI(SN9C120, SP80708, 0x18)}, /*sn9c120b*/ 2473 {USB_DEVICE(0x0c45, 0x6143), BS(SN9C120, SP80708)}, /*sn9c120b*/
2360 {USB_DEVICE(0x0c45, 0x6148), BSI(SN9C120, OM6802, 0x21)}, /*sn9c120b*/ 2474 {USB_DEVICE(0x0c45, 0x6148), BS(SN9C120, OM6802)}, /*sn9c120b*/
2361 {} 2475 {}
2362}; 2476};
2363MODULE_DEVICE_TABLE(usb, device_table); 2477MODULE_DEVICE_TABLE(usb, device_table);
diff --git a/drivers/media/video/gspca/spca500.c b/drivers/media/video/gspca/spca500.c
index 7dbd5eea6cc0..fe46868a87f2 100644
--- a/drivers/media/video/gspca/spca500.c
+++ b/drivers/media/video/gspca/spca500.c
@@ -899,8 +899,7 @@ static void sd_stop0(struct gspca_dev *gspca_dev)
899} 899}
900 900
901static void sd_pkt_scan(struct gspca_dev *gspca_dev, 901static void sd_pkt_scan(struct gspca_dev *gspca_dev,
902 struct gspca_frame *frame, /* target */ 902 u8 *data, /* isoc packet */
903 __u8 *data, /* isoc packet */
904 int len) /* iso packet length */ 903 int len) /* iso packet length */
905{ 904{
906 struct sd *sd = (struct sd *) gspca_dev; 905 struct sd *sd = (struct sd *) gspca_dev;
@@ -913,11 +912,11 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
913/* gspca_dev->last_packet_type = DISCARD_PACKET; */ 912/* gspca_dev->last_packet_type = DISCARD_PACKET; */
914 return; 913 return;
915 } 914 }
916 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, 915 gspca_frame_add(gspca_dev, LAST_PACKET,
917 ffd9, 2); 916 ffd9, 2);
918 917
919 /* put the JPEG header in the new frame */ 918 /* put the JPEG header in the new frame */
920 gspca_frame_add(gspca_dev, FIRST_PACKET, frame, 919 gspca_frame_add(gspca_dev, FIRST_PACKET,
921 sd->jpeg_hdr, JPEG_HDR_SZ); 920 sd->jpeg_hdr, JPEG_HDR_SZ);
922 921
923 data += SPCA500_OFFSET_DATA; 922 data += SPCA500_OFFSET_DATA;
@@ -931,7 +930,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
931 i = 0; 930 i = 0;
932 do { 931 do {
933 if (data[i] == 0xff) { 932 if (data[i] == 0xff) {
934 gspca_frame_add(gspca_dev, INTER_PACKET, frame, 933 gspca_frame_add(gspca_dev, INTER_PACKET,
935 data, i + 1); 934 data, i + 1);
936 len -= i; 935 len -= i;
937 data += i; 936 data += i;
@@ -940,7 +939,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
940 } 939 }
941 i++; 940 i++;
942 } while (i < len); 941 } while (i < len);
943 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); 942 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
944} 943}
945 944
946static void setbrightness(struct gspca_dev *gspca_dev) 945static void setbrightness(struct gspca_dev *gspca_dev)
diff --git a/drivers/media/video/gspca/spca501.c b/drivers/media/video/gspca/spca501.c
index 66f9f0056146..6761a3048a98 100644
--- a/drivers/media/video/gspca/spca501.c
+++ b/drivers/media/video/gspca/spca501.c
@@ -2032,20 +2032,15 @@ static void sd_stop0(struct gspca_dev *gspca_dev)
2032} 2032}
2033 2033
2034static void sd_pkt_scan(struct gspca_dev *gspca_dev, 2034static void sd_pkt_scan(struct gspca_dev *gspca_dev,
2035 struct gspca_frame *frame, /* target */ 2035 u8 *data, /* isoc packet */
2036 __u8 *data, /* isoc packet */
2037 int len) /* iso packet length */ 2036 int len) /* iso packet length */
2038{ 2037{
2039 switch (data[0]) { 2038 switch (data[0]) {
2040 case 0: /* start of frame */ 2039 case 0: /* start of frame */
2041 frame = gspca_frame_add(gspca_dev, 2040 gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
2042 LAST_PACKET,
2043 frame,
2044 data, 0);
2045 data += SPCA501_OFFSET_DATA; 2041 data += SPCA501_OFFSET_DATA;
2046 len -= SPCA501_OFFSET_DATA; 2042 len -= SPCA501_OFFSET_DATA;
2047 gspca_frame_add(gspca_dev, FIRST_PACKET, frame, 2043 gspca_frame_add(gspca_dev, FIRST_PACKET, data, len);
2048 data, len);
2049 return; 2044 return;
2050 case 0xff: /* drop */ 2045 case 0xff: /* drop */
2051/* gspca_dev->last_packet_type = DISCARD_PACKET; */ 2046/* gspca_dev->last_packet_type = DISCARD_PACKET; */
@@ -2053,8 +2048,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
2053 } 2048 }
2054 data++; 2049 data++;
2055 len--; 2050 len--;
2056 gspca_frame_add(gspca_dev, INTER_PACKET, frame, 2051 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
2057 data, len);
2058} 2052}
2059 2053
2060static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) 2054static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
diff --git a/drivers/media/video/gspca/spca505.c b/drivers/media/video/gspca/spca505.c
index ea8c9fe2e961..0f9232ff1281 100644
--- a/drivers/media/video/gspca/spca505.c
+++ b/drivers/media/video/gspca/spca505.c
@@ -739,26 +739,22 @@ static void sd_stop0(struct gspca_dev *gspca_dev)
739} 739}
740 740
741static void sd_pkt_scan(struct gspca_dev *gspca_dev, 741static void sd_pkt_scan(struct gspca_dev *gspca_dev,
742 struct gspca_frame *frame, /* target */
743 u8 *data, /* isoc packet */ 742 u8 *data, /* isoc packet */
744 int len) /* iso packet length */ 743 int len) /* iso packet length */
745{ 744{
746 switch (data[0]) { 745 switch (data[0]) {
747 case 0: /* start of frame */ 746 case 0: /* start of frame */
748 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, 747 gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
749 data, 0);
750 data += SPCA50X_OFFSET_DATA; 748 data += SPCA50X_OFFSET_DATA;
751 len -= SPCA50X_OFFSET_DATA; 749 len -= SPCA50X_OFFSET_DATA;
752 gspca_frame_add(gspca_dev, FIRST_PACKET, frame, 750 gspca_frame_add(gspca_dev, FIRST_PACKET, data, len);
753 data, len);
754 break; 751 break;
755 case 0xff: /* drop */ 752 case 0xff: /* drop */
756 break; 753 break;
757 default: 754 default:
758 data += 1; 755 data += 1;
759 len -= 1; 756 len -= 1;
760 gspca_frame_add(gspca_dev, INTER_PACKET, frame, 757 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
761 data, len);
762 break; 758 break;
763 } 759 }
764} 760}
diff --git a/drivers/media/video/gspca/spca506.c b/drivers/media/video/gspca/spca506.c
index a199298a6419..ab28cc23e415 100644
--- a/drivers/media/video/gspca/spca506.c
+++ b/drivers/media/video/gspca/spca506.c
@@ -543,18 +543,15 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
543} 543}
544 544
545static void sd_pkt_scan(struct gspca_dev *gspca_dev, 545static void sd_pkt_scan(struct gspca_dev *gspca_dev,
546 struct gspca_frame *frame, /* target */ 546 u8 *data, /* isoc packet */
547 __u8 *data, /* isoc packet */
548 int len) /* iso packet length */ 547 int len) /* iso packet length */
549{ 548{
550 switch (data[0]) { 549 switch (data[0]) {
551 case 0: /* start of frame */ 550 case 0: /* start of frame */
552 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, 551 gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
553 data, 0);
554 data += SPCA50X_OFFSET_DATA; 552 data += SPCA50X_OFFSET_DATA;
555 len -= SPCA50X_OFFSET_DATA; 553 len -= SPCA50X_OFFSET_DATA;
556 gspca_frame_add(gspca_dev, FIRST_PACKET, frame, 554 gspca_frame_add(gspca_dev, FIRST_PACKET, data, len);
557 data, len);
558 break; 555 break;
559 case 0xff: /* drop */ 556 case 0xff: /* drop */
560/* gspca_dev->last_packet_type = DISCARD_PACKET; */ 557/* gspca_dev->last_packet_type = DISCARD_PACKET; */
@@ -562,8 +559,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
562 default: 559 default:
563 data += 1; 560 data += 1;
564 len -= 1; 561 len -= 1;
565 gspca_frame_add(gspca_dev, INTER_PACKET, frame, 562 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
566 data, len);
567 break; 563 break;
568 } 564 }
569} 565}
diff --git a/drivers/media/video/gspca/spca508.c b/drivers/media/video/gspca/spca508.c
index 9696c4caf5c9..4d8e6cf75d55 100644
--- a/drivers/media/video/gspca/spca508.c
+++ b/drivers/media/video/gspca/spca508.c
@@ -1447,26 +1447,22 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
1447} 1447}
1448 1448
1449static void sd_pkt_scan(struct gspca_dev *gspca_dev, 1449static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1450 struct gspca_frame *frame, /* target */
1451 u8 *data, /* isoc packet */ 1450 u8 *data, /* isoc packet */
1452 int len) /* iso packet length */ 1451 int len) /* iso packet length */
1453{ 1452{
1454 switch (data[0]) { 1453 switch (data[0]) {
1455 case 0: /* start of frame */ 1454 case 0: /* start of frame */
1456 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, 1455 gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
1457 data, 0);
1458 data += SPCA508_OFFSET_DATA; 1456 data += SPCA508_OFFSET_DATA;
1459 len -= SPCA508_OFFSET_DATA; 1457 len -= SPCA508_OFFSET_DATA;
1460 gspca_frame_add(gspca_dev, FIRST_PACKET, frame, 1458 gspca_frame_add(gspca_dev, FIRST_PACKET, data, len);
1461 data, len);
1462 break; 1459 break;
1463 case 0xff: /* drop */ 1460 case 0xff: /* drop */
1464 break; 1461 break;
1465 default: 1462 default:
1466 data += 1; 1463 data += 1;
1467 len -= 1; 1464 len -= 1;
1468 gspca_frame_add(gspca_dev, INTER_PACKET, frame, 1465 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
1469 data, len);
1470 break; 1466 break;
1471 } 1467 }
1472} 1468}
diff --git a/drivers/media/video/gspca/spca561.c b/drivers/media/video/gspca/spca561.c
index 27e82b35f3e7..58c2f0039af1 100644
--- a/drivers/media/video/gspca/spca561.c
+++ b/drivers/media/video/gspca/spca561.c
@@ -779,8 +779,7 @@ static void do_autogain(struct gspca_dev *gspca_dev)
779} 779}
780 780
781static void sd_pkt_scan(struct gspca_dev *gspca_dev, 781static void sd_pkt_scan(struct gspca_dev *gspca_dev,
782 struct gspca_frame *frame, /* target */ 782 u8 *data, /* isoc packet */
783 __u8 *data, /* isoc packet */
784 int len) /* iso packet length */ 783 int len) /* iso packet length */
785{ 784{
786 struct sd *sd = (struct sd *) gspca_dev; 785 struct sd *sd = (struct sd *) gspca_dev;
@@ -788,12 +787,10 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
788 len--; 787 len--;
789 switch (*data++) { /* sequence number */ 788 switch (*data++) { /* sequence number */
790 case 0: /* start of frame */ 789 case 0: /* start of frame */
791 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, 790 gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
792 data, 0);
793 if (data[1] & 0x10) { 791 if (data[1] & 0x10) {
794 /* compressed bayer */ 792 /* compressed bayer */
795 gspca_frame_add(gspca_dev, FIRST_PACKET, 793 gspca_frame_add(gspca_dev, FIRST_PACKET, data, len);
796 frame, data, len);
797 } else { 794 } else {
798 /* raw bayer (with a header, which we skip) */ 795 /* raw bayer (with a header, which we skip) */
799 if (sd->chip_revision == Rev012A) { 796 if (sd->chip_revision == Rev012A) {
@@ -803,14 +800,13 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
803 data += 16; 800 data += 16;
804 len -= 16; 801 len -= 16;
805 } 802 }
806 gspca_frame_add(gspca_dev, FIRST_PACKET, 803 gspca_frame_add(gspca_dev, FIRST_PACKET, data, len);
807 frame, data, len);
808 } 804 }
809 return; 805 return;
810 case 0xff: /* drop (empty mpackets) */ 806 case 0xff: /* drop (empty mpackets) */
811 return; 807 return;
812 } 808 }
813 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); 809 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
814} 810}
815 811
816/* rev 72a only */ 812/* rev 72a only */
diff --git a/drivers/media/video/gspca/sq905.c b/drivers/media/video/gspca/sq905.c
index 715a68f0156e..1fcaca6a87f7 100644
--- a/drivers/media/video/gspca/sq905.c
+++ b/drivers/media/video/gspca/sq905.c
@@ -168,18 +168,22 @@ static int sq905_ack_frame(struct gspca_dev *gspca_dev)
168 * request and read a block of data - see warning on sq905_command. 168 * request and read a block of data - see warning on sq905_command.
169 */ 169 */
170static int 170static int
171sq905_read_data(struct gspca_dev *gspca_dev, u8 *data, int size) 171sq905_read_data(struct gspca_dev *gspca_dev, u8 *data, int size, int need_lock)
172{ 172{
173 int ret; 173 int ret;
174 int act_len; 174 int act_len;
175 175
176 gspca_dev->usb_buf[0] = '\0'; 176 gspca_dev->usb_buf[0] = '\0';
177 if (need_lock)
178 mutex_lock(&gspca_dev->usb_lock);
177 ret = usb_control_msg(gspca_dev->dev, 179 ret = usb_control_msg(gspca_dev->dev,
178 usb_sndctrlpipe(gspca_dev->dev, 0), 180 usb_sndctrlpipe(gspca_dev->dev, 0),
179 USB_REQ_SYNCH_FRAME, /* request */ 181 USB_REQ_SYNCH_FRAME, /* request */
180 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 182 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
181 SQ905_BULK_READ, size, gspca_dev->usb_buf, 183 SQ905_BULK_READ, size, gspca_dev->usb_buf,
182 1, SQ905_CMD_TIMEOUT); 184 1, SQ905_CMD_TIMEOUT);
185 if (need_lock)
186 mutex_unlock(&gspca_dev->usb_lock);
183 if (ret < 0) { 187 if (ret < 0) {
184 PDEBUG(D_ERR, "%s: usb_control_msg failed (%d)", __func__, ret); 188 PDEBUG(D_ERR, "%s: usb_control_msg failed (%d)", __func__, ret);
185 return ret; 189 return ret;
@@ -210,11 +214,9 @@ static void sq905_dostream(struct work_struct *work)
210{ 214{
211 struct sd *dev = container_of(work, struct sd, work_struct); 215 struct sd *dev = container_of(work, struct sd, work_struct);
212 struct gspca_dev *gspca_dev = &dev->gspca_dev; 216 struct gspca_dev *gspca_dev = &dev->gspca_dev;
213 struct gspca_frame *frame;
214 int bytes_left; /* bytes remaining in current frame. */ 217 int bytes_left; /* bytes remaining in current frame. */
215 int data_len; /* size to use for the next read. */ 218 int data_len; /* size to use for the next read. */
216 int header_read; /* true if we have already read the frame header. */ 219 int header_read; /* true if we have already read the frame header. */
217 int discarding; /* true if we failed to get space for frame. */
218 int packet_type; 220 int packet_type;
219 int frame_sz; 221 int frame_sz;
220 int ret; 222 int ret;
@@ -222,7 +224,6 @@ static void sq905_dostream(struct work_struct *work)
222 u8 *buffer; 224 u8 *buffer;
223 225
224 buffer = kmalloc(SQ905_MAX_TRANSFER, GFP_KERNEL | GFP_DMA); 226 buffer = kmalloc(SQ905_MAX_TRANSFER, GFP_KERNEL | GFP_DMA);
225 mutex_lock(&gspca_dev->usb_lock);
226 if (!buffer) { 227 if (!buffer) {
227 PDEBUG(D_ERR, "Couldn't allocate USB buffer"); 228 PDEBUG(D_ERR, "Couldn't allocate USB buffer");
228 goto quit_stream; 229 goto quit_stream;
@@ -232,28 +233,22 @@ static void sq905_dostream(struct work_struct *work)
232 + FRAME_HEADER_LEN; 233 + FRAME_HEADER_LEN;
233 234
234 while (gspca_dev->present && gspca_dev->streaming) { 235 while (gspca_dev->present && gspca_dev->streaming) {
235 /* Need a short delay to ensure streaming flag was set by
236 * gspca and to make sure gspca can grab the mutex. */
237 mutex_unlock(&gspca_dev->usb_lock);
238 msleep(1);
239
240 /* request some data and then read it until we have 236 /* request some data and then read it until we have
241 * a complete frame. */ 237 * a complete frame. */
242 bytes_left = frame_sz; 238 bytes_left = frame_sz;
243 header_read = 0; 239 header_read = 0;
244 discarding = 0;
245 240
246 while (bytes_left > 0) { 241 /* Note we do not check for gspca_dev->streaming here, as
242 we must finish reading an entire frame, otherwise the
243 next time we stream we start reading in the middle of a
244 frame. */
245 while (bytes_left > 0 && gspca_dev->present) {
247 data_len = bytes_left > SQ905_MAX_TRANSFER ? 246 data_len = bytes_left > SQ905_MAX_TRANSFER ?
248 SQ905_MAX_TRANSFER : bytes_left; 247 SQ905_MAX_TRANSFER : bytes_left;
249 mutex_lock(&gspca_dev->usb_lock); 248 ret = sq905_read_data(gspca_dev, buffer, data_len, 1);
250 if (!gspca_dev->present)
251 goto quit_stream;
252 ret = sq905_read_data(gspca_dev, buffer, data_len);
253 if (ret < 0) 249 if (ret < 0)
254 goto quit_stream; 250 goto quit_stream;
255 mutex_unlock(&gspca_dev->usb_lock); 251 PDEBUG(D_PACK,
256 PDEBUG(D_STREAM,
257 "Got %d bytes out of %d for frame", 252 "Got %d bytes out of %d for frame",
258 data_len, bytes_left); 253 data_len, bytes_left);
259 bytes_left -= data_len; 254 bytes_left -= data_len;
@@ -270,34 +265,30 @@ static void sq905_dostream(struct work_struct *work)
270 } else { 265 } else {
271 packet_type = INTER_PACKET; 266 packet_type = INTER_PACKET;
272 } 267 }
273 frame = gspca_get_i_frame(gspca_dev); 268 gspca_frame_add(gspca_dev, packet_type,
274 if (frame && !discarding) { 269 data, data_len);
275 frame = gspca_frame_add(gspca_dev, packet_type, 270 /* If entire frame fits in one packet we still
276 frame, data, data_len); 271 need to add a LAST_PACKET */
277 /* If entire frame fits in one packet we still 272 if (packet_type == FIRST_PACKET &&
278 need to add a LAST_PACKET */ 273 bytes_left == 0)
279 if (packet_type == FIRST_PACKET && 274 gspca_frame_add(gspca_dev, LAST_PACKET,
280 bytes_left == 0) 275 NULL, 0);
281 frame = gspca_frame_add(gspca_dev, 276 }
282 LAST_PACKET, 277 if (gspca_dev->present) {
283 frame, data, 0); 278 /* acknowledge the frame */
284 } else { 279 mutex_lock(&gspca_dev->usb_lock);
285 discarding = 1; 280 ret = sq905_ack_frame(gspca_dev);
286 } 281 mutex_unlock(&gspca_dev->usb_lock);
282 if (ret < 0)
283 goto quit_stream;
287 } 284 }
288 /* acknowledge the frame */
289 mutex_lock(&gspca_dev->usb_lock);
290 if (!gspca_dev->present)
291 goto quit_stream;
292 ret = sq905_ack_frame(gspca_dev);
293 if (ret < 0)
294 goto quit_stream;
295 } 285 }
296quit_stream: 286quit_stream:
297 /* the usb_lock is already acquired */ 287 if (gspca_dev->present) {
298 if (gspca_dev->present) 288 mutex_lock(&gspca_dev->usb_lock);
299 sq905_command(gspca_dev, SQ905_CLEAR); 289 sq905_command(gspca_dev, SQ905_CLEAR);
300 mutex_unlock(&gspca_dev->usb_lock); 290 mutex_unlock(&gspca_dev->usb_lock);
291 }
301 kfree(buffer); 292 kfree(buffer);
302} 293}
303 294
@@ -346,7 +337,7 @@ static int sd_init(struct gspca_dev *gspca_dev)
346 ret = sq905_command(gspca_dev, SQ905_ID); 337 ret = sq905_command(gspca_dev, SQ905_ID);
347 if (ret < 0) 338 if (ret < 0)
348 return ret; 339 return ret;
349 ret = sq905_read_data(gspca_dev, gspca_dev->usb_buf, 4); 340 ret = sq905_read_data(gspca_dev, gspca_dev->usb_buf, 4, 0);
350 if (ret < 0) 341 if (ret < 0)
351 return ret; 342 return ret;
352 /* usb_buf is allocated with kmalloc so is aligned. 343 /* usb_buf is allocated with kmalloc so is aligned.
diff --git a/drivers/media/video/gspca/sq905c.c b/drivers/media/video/gspca/sq905c.c
index 916892505432..d70b156872d6 100644
--- a/drivers/media/video/gspca/sq905c.c
+++ b/drivers/media/video/gspca/sq905c.c
@@ -115,11 +115,9 @@ static void sq905c_dostream(struct work_struct *work)
115{ 115{
116 struct sd *dev = container_of(work, struct sd, work_struct); 116 struct sd *dev = container_of(work, struct sd, work_struct);
117 struct gspca_dev *gspca_dev = &dev->gspca_dev; 117 struct gspca_dev *gspca_dev = &dev->gspca_dev;
118 struct gspca_frame *frame;
119 int bytes_left; /* bytes remaining in current frame. */ 118 int bytes_left; /* bytes remaining in current frame. */
120 int data_len; /* size to use for the next read. */ 119 int data_len; /* size to use for the next read. */
121 int act_len; 120 int act_len;
122 int discarding = 0; /* true if we failed to get space for frame. */
123 int packet_type; 121 int packet_type;
124 int ret; 122 int ret;
125 u8 *buffer; 123 u8 *buffer;
@@ -131,8 +129,6 @@ static void sq905c_dostream(struct work_struct *work)
131 } 129 }
132 130
133 while (gspca_dev->present && gspca_dev->streaming) { 131 while (gspca_dev->present && gspca_dev->streaming) {
134 if (!gspca_dev->present)
135 goto quit_stream;
136 /* Request the header, which tells the size to download */ 132 /* Request the header, which tells the size to download */
137 ret = usb_bulk_msg(gspca_dev->dev, 133 ret = usb_bulk_msg(gspca_dev->dev,
138 usb_rcvbulkpipe(gspca_dev->dev, 0x81), 134 usb_rcvbulkpipe(gspca_dev->dev, 0x81),
@@ -149,17 +145,11 @@ static void sq905c_dostream(struct work_struct *work)
149 PDEBUG(D_STREAM, "bytes_left = 0x%x", bytes_left); 145 PDEBUG(D_STREAM, "bytes_left = 0x%x", bytes_left);
150 /* We keep the header. It has other information, too. */ 146 /* We keep the header. It has other information, too. */
151 packet_type = FIRST_PACKET; 147 packet_type = FIRST_PACKET;
152 frame = gspca_get_i_frame(gspca_dev); 148 gspca_frame_add(gspca_dev, packet_type,
153 if (frame && !discarding) { 149 buffer, FRAME_HEADER_LEN);
154 gspca_frame_add(gspca_dev, packet_type, 150 while (bytes_left > 0 && gspca_dev->present) {
155 frame, buffer, FRAME_HEADER_LEN);
156 } else
157 discarding = 1;
158 while (bytes_left > 0) {
159 data_len = bytes_left > SQ905C_MAX_TRANSFER ? 151 data_len = bytes_left > SQ905C_MAX_TRANSFER ?
160 SQ905C_MAX_TRANSFER : bytes_left; 152 SQ905C_MAX_TRANSFER : bytes_left;
161 if (!gspca_dev->present)
162 goto quit_stream;
163 ret = usb_bulk_msg(gspca_dev->dev, 153 ret = usb_bulk_msg(gspca_dev->dev,
164 usb_rcvbulkpipe(gspca_dev->dev, 0x81), 154 usb_rcvbulkpipe(gspca_dev->dev, 0x81),
165 buffer, data_len, &act_len, 155 buffer, data_len, &act_len,
@@ -174,19 +164,16 @@ static void sq905c_dostream(struct work_struct *work)
174 packet_type = LAST_PACKET; 164 packet_type = LAST_PACKET;
175 else 165 else
176 packet_type = INTER_PACKET; 166 packet_type = INTER_PACKET;
177 frame = gspca_get_i_frame(gspca_dev); 167 gspca_frame_add(gspca_dev, packet_type,
178 if (frame && !discarding) 168 buffer, data_len);
179 gspca_frame_add(gspca_dev, packet_type,
180 frame, buffer, data_len);
181 else
182 discarding = 1;
183 } 169 }
184 } 170 }
185quit_stream: 171quit_stream:
186 mutex_lock(&gspca_dev->usb_lock); 172 if (gspca_dev->present) {
187 if (gspca_dev->present) 173 mutex_lock(&gspca_dev->usb_lock);
188 sq905c_command(gspca_dev, SQ905C_CLEAR, 0); 174 sq905c_command(gspca_dev, SQ905C_CLEAR, 0);
189 mutex_unlock(&gspca_dev->usb_lock); 175 mutex_unlock(&gspca_dev->usb_lock);
176 }
190 kfree(buffer); 177 kfree(buffer);
191} 178}
192 179
diff --git a/drivers/media/video/gspca/stk014.c b/drivers/media/video/gspca/stk014.c
index 47628964801e..8e23320d7ab7 100644
--- a/drivers/media/video/gspca/stk014.c
+++ b/drivers/media/video/gspca/stk014.c
@@ -418,8 +418,7 @@ static void sd_stop0(struct gspca_dev *gspca_dev)
418} 418}
419 419
420static void sd_pkt_scan(struct gspca_dev *gspca_dev, 420static void sd_pkt_scan(struct gspca_dev *gspca_dev,
421 struct gspca_frame *frame, /* target */ 421 u8 *data, /* isoc packet */
422 __u8 *data, /* isoc packet */
423 int len) /* iso packet length */ 422 int len) /* iso packet length */
424{ 423{
425 struct sd *sd = (struct sd *) gspca_dev; 424 struct sd *sd = (struct sd *) gspca_dev;
@@ -435,11 +434,11 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
435 * (without ending - ff d9) 434 * (without ending - ff d9)
436 */ 435 */
437 if (data[0] == 0xff && data[1] == 0xfe) { 436 if (data[0] == 0xff && data[1] == 0xfe) {
438 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, 437 gspca_frame_add(gspca_dev, LAST_PACKET,
439 ffd9, 2); 438 ffd9, 2);
440 439
441 /* put the JPEG 411 header */ 440 /* put the JPEG 411 header */
442 gspca_frame_add(gspca_dev, FIRST_PACKET, frame, 441 gspca_frame_add(gspca_dev, FIRST_PACKET,
443 sd->jpeg_hdr, JPEG_HDR_SZ); 442 sd->jpeg_hdr, JPEG_HDR_SZ);
444 443
445 /* beginning of the frame */ 444 /* beginning of the frame */
@@ -447,7 +446,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
447 data += STKHDRSZ; 446 data += STKHDRSZ;
448 len -= STKHDRSZ; 447 len -= STKHDRSZ;
449 } 448 }
450 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); 449 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
451} 450}
452 451
453static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) 452static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
diff --git a/drivers/media/video/gspca/stv0680.c b/drivers/media/video/gspca/stv0680.c
new file mode 100644
index 000000000000..2a69d7ccb50d
--- /dev/null
+++ b/drivers/media/video/gspca/stv0680.c
@@ -0,0 +1,364 @@
1/*
2 * STV0680 USB Camera Driver
3 *
4 * Copyright (C) 2009 Hans de Goede <hdgoede@redhat.com>
5 *
6 * This module is adapted from the in kernel v4l1 stv680 driver:
7 *
8 * STV0680 USB Camera Driver, by Kevin Sisson (kjsisson@bellsouth.net)
9 *
10 * Thanks to STMicroelectronics for information on the usb commands, and
11 * to Steve Miller at STM for his help and encouragement while I was
12 * writing this driver.
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 *
28 */
29
30#define MODULE_NAME "stv0680"
31
32#include "gspca.h"
33
34MODULE_AUTHOR("Hans de Goede <hdgoede@redhat.com>");
35MODULE_DESCRIPTION("STV0680 USB Camera Driver");
36MODULE_LICENSE("GPL");
37
38/* specific webcam descriptor */
39struct sd {
40 struct gspca_dev gspca_dev; /* !! must be the first item */
41 struct v4l2_pix_format mode;
42 u8 orig_mode;
43 u8 video_mode;
44 u8 current_mode;
45};
46
47/* V4L2 controls supported by the driver */
48static struct ctrl sd_ctrls[] = {
49};
50
51static int stv_sndctrl(struct gspca_dev *gspca_dev, int set, u8 req, u16 val,
52 int size)
53{
54 int ret = -1;
55 u8 req_type = 0;
56
57 switch (set) {
58 case 0: /* 0xc1 */
59 req_type = USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT;
60 break;
61 case 1: /* 0x41 */
62 req_type = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT;
63 break;
64 case 2: /* 0x80 */
65 req_type = USB_DIR_IN | USB_RECIP_DEVICE;
66 break;
67 case 3: /* 0x40 */
68 req_type = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE;
69 break;
70 }
71
72 ret = usb_control_msg(gspca_dev->dev,
73 usb_rcvctrlpipe(gspca_dev->dev, 0),
74 req, req_type,
75 val, 0, gspca_dev->usb_buf, size, 500);
76
77 if ((ret < 0) && (req != 0x0a))
78 PDEBUG(D_ERR,
79 "usb_control_msg error %i, request = 0x%x, error = %i",
80 set, req, ret);
81
82 return ret;
83}
84
85static int stv0680_handle_error(struct gspca_dev *gspca_dev, int ret)
86{
87 stv_sndctrl(gspca_dev, 0, 0x80, 0, 0x02); /* Get Last Error */
88 PDEBUG(D_ERR, "last error: %i, command = 0x%x",
89 gspca_dev->usb_buf[0], gspca_dev->usb_buf[1]);
90 return ret;
91}
92
93static int stv0680_get_video_mode(struct gspca_dev *gspca_dev)
94{
95 /* Note not sure if this init of usb_buf is really necessary */
96 memset(gspca_dev->usb_buf, 0, 8);
97 gspca_dev->usb_buf[0] = 0x0f;
98
99 if (stv_sndctrl(gspca_dev, 0, 0x87, 0, 0x08) != 0x08) {
100 PDEBUG(D_ERR, "Get_Camera_Mode failed");
101 return stv0680_handle_error(gspca_dev, -EIO);
102 }
103
104 return gspca_dev->usb_buf[0]; /* 01 = VGA, 03 = QVGA, 00 = CIF */
105}
106
107static int stv0680_set_video_mode(struct gspca_dev *gspca_dev, u8 mode)
108{
109 struct sd *sd = (struct sd *) gspca_dev;
110
111 if (sd->current_mode == mode)
112 return 0;
113
114 memset(gspca_dev->usb_buf, 0, 8);
115 gspca_dev->usb_buf[0] = mode;
116
117 if (stv_sndctrl(gspca_dev, 3, 0x07, 0x0100, 0x08) != 0x08) {
118 PDEBUG(D_ERR, "Set_Camera_Mode failed");
119 return stv0680_handle_error(gspca_dev, -EIO);
120 }
121
122 /* Verify we got what we've asked for */
123 if (stv0680_get_video_mode(gspca_dev) != mode) {
124 PDEBUG(D_ERR, "Error setting camera video mode!");
125 return -EIO;
126 }
127
128 sd->current_mode = mode;
129
130 return 0;
131}
132
133/* this function is called at probe time */
134static int sd_config(struct gspca_dev *gspca_dev,
135 const struct usb_device_id *id)
136{
137 int ret;
138 struct sd *sd = (struct sd *) gspca_dev;
139 struct cam *cam = &gspca_dev->cam;
140
141 /* ping camera to be sure STV0680 is present */
142 if (stv_sndctrl(gspca_dev, 0, 0x88, 0x5678, 0x02) != 0x02 ||
143 gspca_dev->usb_buf[0] != 0x56 || gspca_dev->usb_buf[1] != 0x78) {
144 PDEBUG(D_ERR, "STV(e): camera ping failed!!");
145 return stv0680_handle_error(gspca_dev, -ENODEV);
146 }
147
148 /* get camera descriptor */
149 if (stv_sndctrl(gspca_dev, 2, 0x06, 0x0200, 0x09) != 0x09)
150 return stv0680_handle_error(gspca_dev, -ENODEV);
151
152 if (stv_sndctrl(gspca_dev, 2, 0x06, 0x0200, 0x22) != 0x22 ||
153 gspca_dev->usb_buf[7] != 0xa0 || gspca_dev->usb_buf[8] != 0x23) {
154 PDEBUG(D_ERR, "Could not get descriptor 0200.");
155 return stv0680_handle_error(gspca_dev, -ENODEV);
156 }
157 if (stv_sndctrl(gspca_dev, 0, 0x8a, 0, 0x02) != 0x02)
158 return stv0680_handle_error(gspca_dev, -ENODEV);
159 if (stv_sndctrl(gspca_dev, 0, 0x8b, 0, 0x24) != 0x24)
160 return stv0680_handle_error(gspca_dev, -ENODEV);
161 if (stv_sndctrl(gspca_dev, 0, 0x85, 0, 0x10) != 0x10)
162 return stv0680_handle_error(gspca_dev, -ENODEV);
163
164 if (!(gspca_dev->usb_buf[7] & 0x09)) {
165 PDEBUG(D_ERR, "Camera supports neither CIF nor QVGA mode");
166 return -ENODEV;
167 }
168 if (gspca_dev->usb_buf[7] & 0x01)
169 PDEBUG(D_PROBE, "Camera supports CIF mode");
170 if (gspca_dev->usb_buf[7] & 0x02)
171 PDEBUG(D_PROBE, "Camera supports VGA mode");
172 if (gspca_dev->usb_buf[7] & 0x08)
173 PDEBUG(D_PROBE, "Camera supports QVGA mode");
174
175 if (gspca_dev->usb_buf[7] & 0x01)
176 sd->video_mode = 0x00; /* CIF */
177 else
178 sd->video_mode = 0x03; /* QVGA */
179
180 /* FW rev, ASIC rev, sensor ID */
181 PDEBUG(D_PROBE, "Firmware rev is %i.%i",
182 gspca_dev->usb_buf[0], gspca_dev->usb_buf[1]);
183 PDEBUG(D_PROBE, "ASIC rev is %i.%i",
184 gspca_dev->usb_buf[2], gspca_dev->usb_buf[3]);
185 PDEBUG(D_PROBE, "Sensor ID is %i",
186 (gspca_dev->usb_buf[4]*16) + (gspca_dev->usb_buf[5]>>4));
187
188
189 ret = stv0680_get_video_mode(gspca_dev);
190 if (ret < 0)
191 return ret;
192 sd->current_mode = sd->orig_mode = ret;
193
194 ret = stv0680_set_video_mode(gspca_dev, sd->video_mode);
195 if (ret < 0)
196 return ret;
197
198 /* Get mode details */
199 if (stv_sndctrl(gspca_dev, 0, 0x8f, 0, 0x10) != 0x10)
200 return stv0680_handle_error(gspca_dev, -EIO);
201
202 cam->bulk = 1;
203 cam->bulk_nurbs = 1; /* The cam cannot handle more */
204 cam->bulk_size = (gspca_dev->usb_buf[0] << 24) |
205 (gspca_dev->usb_buf[1] << 16) |
206 (gspca_dev->usb_buf[2] << 8) |
207 (gspca_dev->usb_buf[3]);
208 sd->mode.width = (gspca_dev->usb_buf[4] << 8) |
209 (gspca_dev->usb_buf[5]); /* 322, 356, 644 */
210 sd->mode.height = (gspca_dev->usb_buf[6] << 8) |
211 (gspca_dev->usb_buf[7]); /* 242, 292, 484 */
212 sd->mode.pixelformat = V4L2_PIX_FMT_STV0680;
213 sd->mode.field = V4L2_FIELD_NONE;
214 sd->mode.bytesperline = sd->mode.width;
215 sd->mode.sizeimage = cam->bulk_size;
216 sd->mode.colorspace = V4L2_COLORSPACE_SRGB;
217
218 /* origGain = gspca_dev->usb_buf[12]; */
219
220 cam->cam_mode = &sd->mode;
221 cam->nmodes = 1;
222
223
224 ret = stv0680_set_video_mode(gspca_dev, sd->orig_mode);
225 if (ret < 0)
226 return ret;
227
228 if (stv_sndctrl(gspca_dev, 2, 0x06, 0x0100, 0x12) != 0x12 ||
229 gspca_dev->usb_buf[8] != 0x53 || gspca_dev->usb_buf[9] != 0x05) {
230 PDEBUG(D_ERR, "Could not get descriptor 0100.");
231 return stv0680_handle_error(gspca_dev, -EIO);
232 }
233
234 return 0;
235}
236
237/* this function is called at probe and resume time */
238static int sd_init(struct gspca_dev *gspca_dev)
239{
240 return 0;
241}
242
243/* -- start the camera -- */
244static int sd_start(struct gspca_dev *gspca_dev)
245{
246 int ret;
247 struct sd *sd = (struct sd *) gspca_dev;
248
249 ret = stv0680_set_video_mode(gspca_dev, sd->video_mode);
250 if (ret < 0)
251 return ret;
252
253 if (stv_sndctrl(gspca_dev, 0, 0x85, 0, 0x10) != 0x10)
254 return stv0680_handle_error(gspca_dev, -EIO);
255
256 /* Start stream at:
257 0x0000 = CIF (352x288)
258 0x0100 = VGA (640x480)
259 0x0300 = QVGA (320x240) */
260 if (stv_sndctrl(gspca_dev, 1, 0x09, sd->video_mode << 8, 0x0) != 0x0)
261 return stv0680_handle_error(gspca_dev, -EIO);
262
263 return 0;
264}
265
266static void sd_stopN(struct gspca_dev *gspca_dev)
267{
268 /* This is a high priority command; it stops all lower order cmds */
269 if (stv_sndctrl(gspca_dev, 1, 0x04, 0x0000, 0x0) != 0x0)
270 stv0680_handle_error(gspca_dev, -EIO);
271}
272
273static void sd_stop0(struct gspca_dev *gspca_dev)
274{
275 struct sd *sd = (struct sd *) gspca_dev;
276
277 if (!sd->gspca_dev.present)
278 return;
279
280 stv0680_set_video_mode(gspca_dev, sd->orig_mode);
281}
282
283static void sd_pkt_scan(struct gspca_dev *gspca_dev,
284 u8 *data,
285 int len)
286{
287 struct sd *sd = (struct sd *) gspca_dev;
288
289 /* Every now and then the camera sends a 16 byte packet, no idea
290 what it contains, but it is not image data, when this
291 happens the frame received before this packet is corrupt,
292 so discard it. */
293 if (len != sd->mode.sizeimage) {
294 gspca_dev->last_packet_type = DISCARD_PACKET;
295 return;
296 }
297
298 /* Finish the previous frame, we do this upon reception of the next
299 packet, even though it is already complete so that the strange 16
300 byte packets send after a corrupt frame can discard it. */
301 gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
302
303 /* Store the just received frame */
304 gspca_frame_add(gspca_dev, FIRST_PACKET, data, len);
305}
306
307/* sub-driver description */
308static const struct sd_desc sd_desc = {
309 .name = MODULE_NAME,
310 .ctrls = sd_ctrls,
311 .nctrls = ARRAY_SIZE(sd_ctrls),
312 .config = sd_config,
313 .init = sd_init,
314 .start = sd_start,
315 .stopN = sd_stopN,
316 .stop0 = sd_stop0,
317 .pkt_scan = sd_pkt_scan,
318};
319
320/* -- module initialisation -- */
321static const __devinitdata struct usb_device_id device_table[] = {
322 {USB_DEVICE(0x0553, 0x0202)},
323 {USB_DEVICE(0x041e, 0x4007)},
324 {}
325};
326MODULE_DEVICE_TABLE(usb, device_table);
327
328/* -- device connect -- */
329static int sd_probe(struct usb_interface *intf,
330 const struct usb_device_id *id)
331{
332 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
333 THIS_MODULE);
334}
335
336static struct usb_driver sd_driver = {
337 .name = MODULE_NAME,
338 .id_table = device_table,
339 .probe = sd_probe,
340 .disconnect = gspca_disconnect,
341#ifdef CONFIG_PM
342 .suspend = gspca_suspend,
343 .resume = gspca_resume,
344#endif
345};
346
347/* -- module insert / remove -- */
348static int __init sd_mod_init(void)
349{
350 int ret;
351 ret = usb_register(&sd_driver);
352 if (ret < 0)
353 return ret;
354 PDEBUG(D_PROBE, "registered");
355 return 0;
356}
357static void __exit sd_mod_exit(void)
358{
359 usb_deregister(&sd_driver);
360 PDEBUG(D_PROBE, "deregistered");
361}
362
363module_init(sd_mod_init);
364module_exit(sd_mod_exit);
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx.c b/drivers/media/video/gspca/stv06xx/stv06xx.c
index bfae63f5584c..5d0241bb1611 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx.c
+++ b/drivers/media/video/gspca/stv06xx/stv06xx.c
@@ -312,8 +312,7 @@ out:
312 * The 0005 and 0100 chunks seem to appear only in compressed stream. 312 * The 0005 and 0100 chunks seem to appear only in compressed stream.
313 */ 313 */
314static void stv06xx_pkt_scan(struct gspca_dev *gspca_dev, 314static void stv06xx_pkt_scan(struct gspca_dev *gspca_dev,
315 struct gspca_frame *frame, /* target */ 315 u8 *data, /* isoc packet */
316 __u8 *data, /* isoc packet */
317 int len) /* iso packet length */ 316 int len) /* iso packet length */
318{ 317{
319 struct sd *sd = (struct sd *) gspca_dev; 318 struct sd *sd = (struct sd *) gspca_dev;
@@ -366,7 +365,7 @@ frame_data:
366 sd->to_skip -= skip; 365 sd->to_skip -= skip;
367 } 366 }
368 367
369 gspca_frame_add(gspca_dev, INTER_PACKET, frame, 368 gspca_frame_add(gspca_dev, INTER_PACKET,
370 data, chunk_len); 369 data, chunk_len);
371 break; 370 break;
372 371
@@ -378,7 +377,7 @@ frame_data:
378 377
379 /* Create a new frame, chunk length should be zero */ 378 /* Create a new frame, chunk length should be zero */
380 gspca_frame_add(gspca_dev, FIRST_PACKET, 379 gspca_frame_add(gspca_dev, FIRST_PACKET,
381 frame, data, 0); 380 NULL, 0);
382 381
383 if (sd->bridge == BRIDGE_ST6422) 382 if (sd->bridge == BRIDGE_ST6422)
384 sd->to_skip = gspca_dev->width * 4; 383 sd->to_skip = gspca_dev->width * 4;
@@ -394,8 +393,8 @@ frame_data:
394 PDEBUG(D_PACK, "End of frame detected"); 393 PDEBUG(D_PACK, "End of frame detected");
395 394
396 /* Complete the last frame (if any) */ 395 /* Complete the last frame (if any) */
397 frame = gspca_frame_add(gspca_dev, LAST_PACKET, 396 gspca_frame_add(gspca_dev, LAST_PACKET,
398 frame, data, 0); 397 NULL, 0);
399 398
400 if (chunk_len) 399 if (chunk_len)
401 PDEBUG(D_ERR, "Chunk length is " 400 PDEBUG(D_ERR, "Chunk length is "
diff --git a/drivers/media/video/gspca/sunplus.c b/drivers/media/video/gspca/sunplus.c
index 1a9af2ebdbef..72bf3b4f0a31 100644
--- a/drivers/media/video/gspca/sunplus.c
+++ b/drivers/media/video/gspca/sunplus.c
@@ -1116,7 +1116,6 @@ static void sd_stop0(struct gspca_dev *gspca_dev)
1116} 1116}
1117 1117
1118static void sd_pkt_scan(struct gspca_dev *gspca_dev, 1118static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1119 struct gspca_frame *frame, /* target */
1120 u8 *data, /* isoc packet */ 1119 u8 *data, /* isoc packet */
1121 int len) /* iso packet length */ 1120 int len) /* iso packet length */
1122{ 1121{
@@ -1186,11 +1185,11 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1186 break; 1185 break;
1187 } 1186 }
1188 if (sof) { /* start of frame */ 1187 if (sof) { /* start of frame */
1189 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, 1188 gspca_frame_add(gspca_dev, LAST_PACKET,
1190 ffd9, 2); 1189 ffd9, 2);
1191 1190
1192 /* put the JPEG header in the new frame */ 1191 /* put the JPEG header in the new frame */
1193 gspca_frame_add(gspca_dev, FIRST_PACKET, frame, 1192 gspca_frame_add(gspca_dev, FIRST_PACKET,
1194 sd->jpeg_hdr, JPEG_HDR_SZ); 1193 sd->jpeg_hdr, JPEG_HDR_SZ);
1195 } 1194 }
1196 1195
@@ -1198,7 +1197,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1198 i = 0; 1197 i = 0;
1199 do { 1198 do {
1200 if (data[i] == 0xff) { 1199 if (data[i] == 0xff) {
1201 gspca_frame_add(gspca_dev, INTER_PACKET, frame, 1200 gspca_frame_add(gspca_dev, INTER_PACKET,
1202 data, i + 1); 1201 data, i + 1);
1203 len -= i; 1202 len -= i;
1204 data += i; 1203 data += i;
@@ -1207,7 +1206,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1207 } 1206 }
1208 i++; 1207 i++;
1209 } while (i < len); 1208 } while (i < len);
1210 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); 1209 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
1211} 1210}
1212 1211
1213static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) 1212static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
diff --git a/drivers/media/video/gspca/t613.c b/drivers/media/video/gspca/t613.c
index 1d321c30d22f..55ef6a744427 100644
--- a/drivers/media/video/gspca/t613.c
+++ b/drivers/media/video/gspca/t613.c
@@ -938,7 +938,6 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
938} 938}
939 939
940static void sd_pkt_scan(struct gspca_dev *gspca_dev, 940static void sd_pkt_scan(struct gspca_dev *gspca_dev,
941 struct gspca_frame *frame, /* target */
942 u8 *data, /* isoc packet */ 941 u8 *data, /* isoc packet */
943 int len) /* iso packet length */ 942 int len) /* iso packet length */
944{ 943{
@@ -956,9 +955,9 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
956 /* extra bytes....., could be processed too but would be 955 /* extra bytes....., could be processed too but would be
957 * a waste of time, right now leave the application and 956 * a waste of time, right now leave the application and
958 * libjpeg do it for ourserlves.. */ 957 * libjpeg do it for ourserlves.. */
959 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, 958 gspca_frame_add(gspca_dev, LAST_PACKET,
960 ffd9, 2); 959 ffd9, 2);
961 gspca_frame_add(gspca_dev, FIRST_PACKET, frame, data, len); 960 gspca_frame_add(gspca_dev, FIRST_PACKET, data, len);
962 return; 961 return;
963 } 962 }
964 963
@@ -967,7 +966,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
967 * other's do not include it... */ 966 * other's do not include it... */
968 len -= 2; 967 len -= 2;
969 } 968 }
970 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); 969 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
971} 970}
972 971
973static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) 972static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
diff --git a/drivers/media/video/gspca/tv8532.c b/drivers/media/video/gspca/tv8532.c
index 4b44dde9f8b8..b74a3b6489c7 100644
--- a/drivers/media/video/gspca/tv8532.c
+++ b/drivers/media/video/gspca/tv8532.c
@@ -398,8 +398,7 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
398} 398}
399 399
400static void sd_pkt_scan(struct gspca_dev *gspca_dev, 400static void sd_pkt_scan(struct gspca_dev *gspca_dev,
401 struct gspca_frame *frame, /* target */ 401 u8 *data, /* isoc packet */
402 __u8 *data, /* isoc packet */
403 int len) /* iso packet length */ 402 int len) /* iso packet length */
404{ 403{
405 struct sd *sd = (struct sd *) gspca_dev; 404 struct sd *sd = (struct sd *) gspca_dev;
@@ -424,9 +423,9 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
424 * - 4 bytes 423 * - 4 bytes
425 */ 424 */
426 gspca_frame_add(gspca_dev, packet_type0, 425 gspca_frame_add(gspca_dev, packet_type0,
427 frame, data + 2, gspca_dev->width); 426 data + 2, gspca_dev->width);
428 gspca_frame_add(gspca_dev, packet_type1, 427 gspca_frame_add(gspca_dev, packet_type1,
429 frame, data + gspca_dev->width + 5, gspca_dev->width); 428 data + gspca_dev->width + 5, gspca_dev->width);
430} 429}
431 430
432static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) 431static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
diff --git a/drivers/media/video/gspca/vc032x.c b/drivers/media/video/gspca/vc032x.c
index 589042f6adbe..c090efcd8045 100644
--- a/drivers/media/video/gspca/vc032x.c
+++ b/drivers/media/video/gspca/vc032x.c
@@ -2987,7 +2987,6 @@ static void sd_stop0(struct gspca_dev *gspca_dev)
2987} 2987}
2988 2988
2989static void sd_pkt_scan(struct gspca_dev *gspca_dev, 2989static void sd_pkt_scan(struct gspca_dev *gspca_dev,
2990 struct gspca_frame *frame, /* target */
2991 u8 *data, /* isoc packet */ 2990 u8 *data, /* isoc packet */
2992 int len) /* iso pkt length */ 2991 int len) /* iso pkt length */
2993{ 2992{
@@ -2996,21 +2995,25 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
2996 if (data[0] == 0xff && data[1] == 0xd8) { 2995 if (data[0] == 0xff && data[1] == 0xd8) {
2997 PDEBUG(D_PACK, 2996 PDEBUG(D_PACK,
2998 "vc032x header packet found len %d", len); 2997 "vc032x header packet found len %d", len);
2999 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, 2998 gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
3000 data, 0);
3001 data += sd->image_offset; 2999 data += sd->image_offset;
3002 len -= sd->image_offset; 3000 len -= sd->image_offset;
3003 gspca_frame_add(gspca_dev, FIRST_PACKET, frame, 3001 gspca_frame_add(gspca_dev, FIRST_PACKET, data, len);
3004 data, len);
3005 return; 3002 return;
3006 } 3003 }
3007 3004
3008 /* The vc0321 sends some additional data after sending the complete 3005 /* The vc0321 sends some additional data after sending the complete
3009 * frame, we ignore this. */ 3006 * frame, we ignore this. */
3010 if (sd->bridge == BRIDGE_VC0321 3007 if (sd->bridge == BRIDGE_VC0321) {
3011 && len > frame->v4l2_buf.length - (frame->data_end - frame->data)) 3008 struct gspca_frame *frame;
3012 len = frame->v4l2_buf.length - (frame->data_end - frame->data); 3009 int l;
3013 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); 3010
3011 frame = gspca_get_i_frame(gspca_dev);
3012 l = frame->data_end - frame->data;
3013 if (len > frame->v4l2_buf.length - l)
3014 len = frame->v4l2_buf.length - l;
3015 }
3016 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
3014} 3017}
3015 3018
3016static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val) 3019static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val)
@@ -3092,6 +3095,8 @@ static int sd_querymenu(struct gspca_dev *gspca_dev,
3092 3095
3093 switch (menu->id) { 3096 switch (menu->id) {
3094 case V4L2_CID_POWER_LINE_FREQUENCY: 3097 case V4L2_CID_POWER_LINE_FREQUENCY:
3098 if (menu->index >= ARRAY_SIZE(freq_nm))
3099 break;
3095 strcpy((char *) menu->name, freq_nm[menu->index]); 3100 strcpy((char *) menu->name, freq_nm[menu->index]);
3096 return 0; 3101 return 0;
3097 } 3102 }
diff --git a/drivers/media/video/gspca/w996Xcf.c b/drivers/media/video/gspca/w996Xcf.c
new file mode 100644
index 000000000000..2fffe203bed8
--- /dev/null
+++ b/drivers/media/video/gspca/w996Xcf.c
@@ -0,0 +1,609 @@
1/**
2 *
3 * GSPCA sub driver for W996[78]CF JPEG USB Dual Mode Camera Chip.
4 *
5 * Copyright (C) 2009 Hans de Goede <hdegoede@redhat.com>
6 *
7 * This module is adapted from the in kernel v4l1 w9968cf driver:
8 *
9 * Copyright (C) 2002-2004 by Luca Risolia <luca.risolia@studio.unibo.it>
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 *
25 */
26
27/* Note this is not a stand alone driver, it gets included in ov519.c, this
28 is a bit of a hack, but it needs the driver code for a lot of different
29 ov sensors which is already present in ov519.c (the old v4l1 driver used
30 the ovchipcam framework). When we have the time we really should move
31 the sensor drivers to v4l2 sub drivers, and properly split of this
32 driver from ov519.c */
33
34/* The CONEX_CAM define for jpeg.h needs renaming, now its used here too */
35#define CONEX_CAM
36#include "jpeg.h"
37
38#define W9968CF_I2C_BUS_DELAY 4 /* delay in us for I2C bit r/w operations */
39
40#define Y_QUANTABLE (sd->jpeg_hdr + JPEG_QT0_OFFSET)
41#define UV_QUANTABLE (sd->jpeg_hdr + JPEG_QT1_OFFSET)
42
43static const struct v4l2_pix_format w9968cf_vga_mode[] = {
44 {160, 120, V4L2_PIX_FMT_UYVY, V4L2_FIELD_NONE,
45 .bytesperline = 160 * 2,
46 .sizeimage = 160 * 120 * 2,
47 .colorspace = V4L2_COLORSPACE_JPEG},
48 {176, 144, V4L2_PIX_FMT_UYVY, V4L2_FIELD_NONE,
49 .bytesperline = 176 * 2,
50 .sizeimage = 176 * 144 * 2,
51 .colorspace = V4L2_COLORSPACE_JPEG},
52 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
53 .bytesperline = 320 * 2,
54 .sizeimage = 320 * 240 * 2,
55 .colorspace = V4L2_COLORSPACE_JPEG},
56 {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
57 .bytesperline = 352 * 2,
58 .sizeimage = 352 * 288 * 2,
59 .colorspace = V4L2_COLORSPACE_JPEG},
60 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
61 .bytesperline = 640 * 2,
62 .sizeimage = 640 * 480 * 2,
63 .colorspace = V4L2_COLORSPACE_JPEG},
64};
65
66static int reg_w(struct sd *sd, __u16 index, __u16 value);
67
68/*--------------------------------------------------------------------------
69 Write 64-bit data to the fast serial bus registers.
70 Return 0 on success, -1 otherwise.
71 --------------------------------------------------------------------------*/
72static int w9968cf_write_fsb(struct sd *sd, u16* data)
73{
74 struct usb_device* udev = sd->gspca_dev.dev;
75 u16 value;
76 int ret;
77
78 value = *data++;
79 memcpy(sd->gspca_dev.usb_buf, data, 6);
80
81 ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0,
82 USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE,
83 value, 0x06, sd->gspca_dev.usb_buf, 6, 500);
84 if (ret < 0) {
85 PDEBUG(D_ERR, "Write FSB registers failed (%d)", ret);
86 return ret;
87 }
88
89 return 0;
90}
91
92/*--------------------------------------------------------------------------
93 Write data to the serial bus control register.
94 Return 0 on success, a negative number otherwise.
95 --------------------------------------------------------------------------*/
96static int w9968cf_write_sb(struct sd *sd, u16 value)
97{
98 int ret;
99
100 /* We don't use reg_w here, as that would cause all writes when
101 bitbanging i2c to be logged, making the logs impossible to read */
102 ret = usb_control_msg(sd->gspca_dev.dev,
103 usb_sndctrlpipe(sd->gspca_dev.dev, 0),
104 0,
105 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
106 value, 0x01, NULL, 0, 500);
107
108 udelay(W9968CF_I2C_BUS_DELAY);
109
110 if (ret < 0) {
111 PDEBUG(D_ERR, "Write SB reg [01] %04x failed", value);
112 return ret;
113 }
114
115 return 0;
116}
117
118/*--------------------------------------------------------------------------
119 Read data from the serial bus control register.
120 Return 0 on success, a negative number otherwise.
121 --------------------------------------------------------------------------*/
122static int w9968cf_read_sb(struct sd *sd)
123{
124 int ret;
125
126 /* We don't use reg_r here, as the w9968cf is special and has 16
127 bit registers instead of 8 bit */
128 ret = usb_control_msg(sd->gspca_dev.dev,
129 usb_rcvctrlpipe(sd->gspca_dev.dev, 0),
130 1,
131 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
132 0, 0x01, sd->gspca_dev.usb_buf, 2, 500);
133 if (ret >= 0)
134 ret = sd->gspca_dev.usb_buf[0] |
135 (sd->gspca_dev.usb_buf[1] << 8);
136 else
137 PDEBUG(D_ERR, "Read SB reg [01] failed");
138
139 udelay(W9968CF_I2C_BUS_DELAY);
140
141 return ret;
142}
143
144/*--------------------------------------------------------------------------
145 Upload quantization tables for the JPEG compression.
146 This function is called by w9968cf_start_transfer().
147 Return 0 on success, a negative number otherwise.
148 --------------------------------------------------------------------------*/
149static int w9968cf_upload_quantizationtables(struct sd *sd)
150{
151 u16 a, b;
152 int ret = 0, i, j;
153
154 ret += reg_w(sd, 0x39, 0x0010); /* JPEG clock enable */
155
156 for (i = 0, j = 0; i < 32; i++, j += 2) {
157 a = Y_QUANTABLE[j] | ((unsigned)(Y_QUANTABLE[j+1]) << 8);
158 b = UV_QUANTABLE[j] | ((unsigned)(UV_QUANTABLE[j+1]) << 8);
159 ret += reg_w(sd, 0x40+i, a);
160 ret += reg_w(sd, 0x60+i, b);
161 }
162 ret += reg_w(sd, 0x39, 0x0012); /* JPEG encoder enable */
163
164 return ret;
165}
166
167/****************************************************************************
168 * Low-level I2C I/O functions. *
169 * The adapter supports the following I2C transfer functions: *
170 * i2c_adap_fastwrite_byte_data() (at 400 kHz bit frequency only) *
171 * i2c_adap_read_byte_data() *
172 * i2c_adap_read_byte() *
173 ****************************************************************************/
174
175static int w9968cf_smbus_start(struct sd *sd)
176{
177 int ret = 0;
178
179 ret += w9968cf_write_sb(sd, 0x0011); /* SDE=1, SDA=0, SCL=1 */
180 ret += w9968cf_write_sb(sd, 0x0010); /* SDE=1, SDA=0, SCL=0 */
181
182 return ret;
183}
184
185static int w9968cf_smbus_stop(struct sd *sd)
186{
187 int ret = 0;
188
189 ret += w9968cf_write_sb(sd, 0x0010); /* SDE=1, SDA=0, SCL=0 */
190 ret += w9968cf_write_sb(sd, 0x0011); /* SDE=1, SDA=0, SCL=1 */
191 ret += w9968cf_write_sb(sd, 0x0013); /* SDE=1, SDA=1, SCL=1 */
192
193 return ret;
194}
195
196static int w9968cf_smbus_write_byte(struct sd *sd, u8 v)
197{
198 u8 bit;
199 int ret = 0, sda;
200
201 for (bit = 0 ; bit < 8 ; bit++) {
202 sda = (v & 0x80) ? 2 : 0;
203 v <<= 1;
204 /* SDE=1, SDA=sda, SCL=0 */
205 ret += w9968cf_write_sb(sd, 0x10 | sda);
206 /* SDE=1, SDA=sda, SCL=1 */
207 ret += w9968cf_write_sb(sd, 0x11 | sda);
208 /* SDE=1, SDA=sda, SCL=0 */
209 ret += w9968cf_write_sb(sd, 0x10 | sda);
210 }
211
212 return ret;
213}
214
215static int w9968cf_smbus_read_byte(struct sd *sd, u8* v)
216{
217 u8 bit;
218 int ret = 0;
219
220 /* No need to ensure SDA is high as we are always called after
221 read_ack which ends with SDA high */
222 *v = 0;
223 for (bit = 0 ; bit < 8 ; bit++) {
224 *v <<= 1;
225 /* SDE=1, SDA=1, SCL=1 */
226 ret += w9968cf_write_sb(sd, 0x0013);
227 *v |= (w9968cf_read_sb(sd) & 0x0008) ? 1 : 0;
228 /* SDE=1, SDA=1, SCL=0 */
229 ret += w9968cf_write_sb(sd, 0x0012);
230 }
231
232 return ret;
233}
234
235static int w9968cf_smbus_write_nack(struct sd *sd)
236{
237 int ret = 0;
238
239 /* No need to ensure SDA is high as we are always called after
240 read_byte which ends with SDA high */
241 ret += w9968cf_write_sb(sd, 0x0013); /* SDE=1, SDA=1, SCL=1 */
242 ret += w9968cf_write_sb(sd, 0x0012); /* SDE=1, SDA=1, SCL=0 */
243
244 return ret;
245}
246
247static int w9968cf_smbus_read_ack(struct sd *sd)
248{
249 int ret = 0, sda;
250
251 /* Ensure SDA is high before raising clock to avoid a spurious stop */
252 ret += w9968cf_write_sb(sd, 0x0012); /* SDE=1, SDA=1, SCL=0 */
253 ret += w9968cf_write_sb(sd, 0x0013); /* SDE=1, SDA=1, SCL=1 */
254 sda = w9968cf_read_sb(sd);
255 ret += w9968cf_write_sb(sd, 0x0012); /* SDE=1, SDA=1, SCL=0 */
256 if (sda < 0)
257 ret += sda;
258 else if (sda & 0x08) {
259 PDEBUG(D_USBI, "Did not receive i2c ACK");
260 ret += -1;
261 }
262
263 return ret;
264}
265
266/* SMBus protocol: S Addr Wr [A] Subaddr [A] Value [A] P */
267static int w9968cf_i2c_w(struct sd *sd, u8 reg, u8 value)
268{
269 u16* data = (u16 *)sd->gspca_dev.usb_buf;
270 int ret = 0;
271
272 data[0] = 0x082f | ((sd->sensor_addr & 0x80) ? 0x1500 : 0x0);
273 data[0] |= (sd->sensor_addr & 0x40) ? 0x4000 : 0x0;
274 data[1] = 0x2082 | ((sd->sensor_addr & 0x40) ? 0x0005 : 0x0);
275 data[1] |= (sd->sensor_addr & 0x20) ? 0x0150 : 0x0;
276 data[1] |= (sd->sensor_addr & 0x10) ? 0x5400 : 0x0;
277 data[2] = 0x8208 | ((sd->sensor_addr & 0x08) ? 0x0015 : 0x0);
278 data[2] |= (sd->sensor_addr & 0x04) ? 0x0540 : 0x0;
279 data[2] |= (sd->sensor_addr & 0x02) ? 0x5000 : 0x0;
280 data[3] = 0x1d20 | ((sd->sensor_addr & 0x02) ? 0x0001 : 0x0);
281 data[3] |= (sd->sensor_addr & 0x01) ? 0x0054 : 0x0;
282
283 ret += w9968cf_write_fsb(sd, data);
284
285 data[0] = 0x8208 | ((reg & 0x80) ? 0x0015 : 0x0);
286 data[0] |= (reg & 0x40) ? 0x0540 : 0x0;
287 data[0] |= (reg & 0x20) ? 0x5000 : 0x0;
288 data[1] = 0x0820 | ((reg & 0x20) ? 0x0001 : 0x0);
289 data[1] |= (reg & 0x10) ? 0x0054 : 0x0;
290 data[1] |= (reg & 0x08) ? 0x1500 : 0x0;
291 data[1] |= (reg & 0x04) ? 0x4000 : 0x0;
292 data[2] = 0x2082 | ((reg & 0x04) ? 0x0005 : 0x0);
293 data[2] |= (reg & 0x02) ? 0x0150 : 0x0;
294 data[2] |= (reg & 0x01) ? 0x5400 : 0x0;
295 data[3] = 0x001d;
296
297 ret += w9968cf_write_fsb(sd, data);
298
299 data[0] = 0x8208 | ((value & 0x80) ? 0x0015 : 0x0);
300 data[0] |= (value & 0x40) ? 0x0540 : 0x0;
301 data[0] |= (value & 0x20) ? 0x5000 : 0x0;
302 data[1] = 0x0820 | ((value & 0x20) ? 0x0001 : 0x0);
303 data[1] |= (value & 0x10) ? 0x0054 : 0x0;
304 data[1] |= (value & 0x08) ? 0x1500 : 0x0;
305 data[1] |= (value & 0x04) ? 0x4000 : 0x0;
306 data[2] = 0x2082 | ((value & 0x04) ? 0x0005 : 0x0);
307 data[2] |= (value & 0x02) ? 0x0150 : 0x0;
308 data[2] |= (value & 0x01) ? 0x5400 : 0x0;
309 data[3] = 0xfe1d;
310
311 ret += w9968cf_write_fsb(sd, data);
312
313 if (!ret)
314 PDEBUG(D_USBO, "i2c 0x%02x -> [0x%02x]", value, reg);
315 else
316 PDEBUG(D_ERR, "i2c 0x%02x -> [0x%02x] failed", value, reg);
317
318 return ret;
319}
320
321/* SMBus protocol: S Addr Wr [A] Subaddr [A] P S Addr+1 Rd [A] [Value] NA P */
322static int w9968cf_i2c_r(struct sd *sd, u8 reg)
323{
324 int ret = 0;
325 u8 value;
326
327 /* Fast serial bus data control disable */
328 ret += w9968cf_write_sb(sd, 0x0013); /* don't change ! */
329
330 ret += w9968cf_smbus_start(sd);
331 ret += w9968cf_smbus_write_byte(sd, sd->sensor_addr);
332 ret += w9968cf_smbus_read_ack(sd);
333 ret += w9968cf_smbus_write_byte(sd, reg);
334 ret += w9968cf_smbus_read_ack(sd);
335 ret += w9968cf_smbus_stop(sd);
336 ret += w9968cf_smbus_start(sd);
337 ret += w9968cf_smbus_write_byte(sd, sd->sensor_addr + 1);
338 ret += w9968cf_smbus_read_ack(sd);
339 ret += w9968cf_smbus_read_byte(sd, &value);
340 /* signal we don't want to read anymore, the v4l1 driver used to
341 send an ack here which is very wrong! (and then fixed
342 the issues this gave by retrying reads) */
343 ret += w9968cf_smbus_write_nack(sd);
344 ret += w9968cf_smbus_stop(sd);
345
346 /* Fast serial bus data control re-enable */
347 ret += w9968cf_write_sb(sd, 0x0030);
348
349 if (!ret) {
350 ret = value;
351 PDEBUG(D_USBI, "i2c [0x%02X] -> 0x%02X", reg, value);
352 } else
353 PDEBUG(D_ERR, "i2c read [0x%02x] failed", reg);
354
355 return ret;
356}
357
358
359/*--------------------------------------------------------------------------
360 Turn on the LED on some webcams. A beep should be heard too.
361 Return 0 on success, a negative number otherwise.
362 --------------------------------------------------------------------------*/
363static int w9968cf_configure(struct sd *sd)
364{
365 int ret = 0;
366
367 ret += reg_w(sd, 0x00, 0xff00); /* power-down */
368 ret += reg_w(sd, 0x00, 0xbf17); /* reset everything */
369 ret += reg_w(sd, 0x00, 0xbf10); /* normal operation */
370 ret += reg_w(sd, 0x01, 0x0010); /* serial bus, SDS high */
371 ret += reg_w(sd, 0x01, 0x0000); /* serial bus, SDS low */
372 ret += reg_w(sd, 0x01, 0x0010); /* ..high 'beep-beep' */
373 ret += reg_w(sd, 0x01, 0x0030); /* Set sda scl to FSB mode */
374
375 if (ret)
376 PDEBUG(D_ERR, "Couldn't turn on the LED");
377
378 sd->stopped = 1;
379
380 return ret;
381}
382
383static int w9968cf_init(struct sd *sd)
384{
385 int ret = 0;
386 unsigned long hw_bufsize = sd->sif ? (352 * 288 * 2) : (640 * 480 * 2),
387 y0 = 0x0000,
388 u0 = y0 + hw_bufsize/2,
389 v0 = u0 + hw_bufsize/4,
390 y1 = v0 + hw_bufsize/4,
391 u1 = y1 + hw_bufsize/2,
392 v1 = u1 + hw_bufsize/4;
393
394 ret += reg_w(sd, 0x00, 0xff00); /* power off */
395 ret += reg_w(sd, 0x00, 0xbf10); /* power on */
396
397 ret += reg_w(sd, 0x03, 0x405d); /* DRAM timings */
398 ret += reg_w(sd, 0x04, 0x0030); /* SDRAM timings */
399
400 ret += reg_w(sd, 0x20, y0 & 0xffff); /* Y buf.0, low */
401 ret += reg_w(sd, 0x21, y0 >> 16); /* Y buf.0, high */
402 ret += reg_w(sd, 0x24, u0 & 0xffff); /* U buf.0, low */
403 ret += reg_w(sd, 0x25, u0 >> 16); /* U buf.0, high */
404 ret += reg_w(sd, 0x28, v0 & 0xffff); /* V buf.0, low */
405 ret += reg_w(sd, 0x29, v0 >> 16); /* V buf.0, high */
406
407 ret += reg_w(sd, 0x22, y1 & 0xffff); /* Y buf.1, low */
408 ret += reg_w(sd, 0x23, y1 >> 16); /* Y buf.1, high */
409 ret += reg_w(sd, 0x26, u1 & 0xffff); /* U buf.1, low */
410 ret += reg_w(sd, 0x27, u1 >> 16); /* U buf.1, high */
411 ret += reg_w(sd, 0x2a, v1 & 0xffff); /* V buf.1, low */
412 ret += reg_w(sd, 0x2b, v1 >> 16); /* V buf.1, high */
413
414 ret += reg_w(sd, 0x32, y1 & 0xffff); /* JPEG buf 0 low */
415 ret += reg_w(sd, 0x33, y1 >> 16); /* JPEG buf 0 high */
416
417 ret += reg_w(sd, 0x34, y1 & 0xffff); /* JPEG buf 1 low */
418 ret += reg_w(sd, 0x35, y1 >> 16); /* JPEG bug 1 high */
419
420 ret += reg_w(sd, 0x36, 0x0000);/* JPEG restart interval */
421 ret += reg_w(sd, 0x37, 0x0804);/*JPEG VLE FIFO threshold*/
422 ret += reg_w(sd, 0x38, 0x0000);/* disable hw up-scaling */
423 ret += reg_w(sd, 0x3f, 0x0000); /* JPEG/MCTL test data */
424
425 return ret;
426}
427
428static int w9968cf_set_crop_window(struct sd *sd)
429{
430 int ret = 0, start_cropx, start_cropy, x, y, fw, fh, cw, ch,
431 max_width, max_height;
432
433 if (sd->sif) {
434 max_width = 352;
435 max_height = 288;
436 } else {
437 max_width = 640;
438 max_height = 480;
439 }
440
441 if (sd->sensor == SEN_OV7620) {
442 /* Sigh, this is dependend on the clock / framerate changes
443 made by the frequency control, sick. */
444 if (sd->freq == 1) {
445 start_cropx = 277;
446 start_cropy = 37;
447 } else {
448 start_cropx = 105;
449 start_cropy = 37;
450 }
451 } else {
452 start_cropx = 320;
453 start_cropy = 35;
454 }
455
456 /* Work around to avoid FP arithmetics */
457 #define SC(x) ((x) << 10)
458
459 /* Scaling factors */
460 fw = SC(sd->gspca_dev.width) / max_width;
461 fh = SC(sd->gspca_dev.height) / max_height;
462
463 cw = (fw >= fh) ? max_width : SC(sd->gspca_dev.width)/fh;
464 ch = (fw >= fh) ? SC(sd->gspca_dev.height)/fw : max_height;
465
466 sd->sensor_width = max_width;
467 sd->sensor_height = max_height;
468
469 x = (max_width - cw) / 2;
470 y = (max_height - ch) / 2;
471
472 ret += reg_w(sd, 0x10, start_cropx + x);
473 ret += reg_w(sd, 0x11, start_cropy + y);
474 ret += reg_w(sd, 0x12, start_cropx + x + cw);
475 ret += reg_w(sd, 0x13, start_cropy + y + ch);
476
477 return ret;
478}
479
480static int w9968cf_mode_init_regs(struct sd *sd)
481{
482 int ret = 0, val, vs_polarity, hs_polarity;
483
484 ret += w9968cf_set_crop_window(sd);
485
486 ret += reg_w(sd, 0x14, sd->gspca_dev.width);
487 ret += reg_w(sd, 0x15, sd->gspca_dev.height);
488
489 /* JPEG width & height */
490 ret += reg_w(sd, 0x30, sd->gspca_dev.width);
491 ret += reg_w(sd, 0x31, sd->gspca_dev.height);
492
493 /* Y & UV frame buffer strides (in WORD) */
494 if (w9968cf_vga_mode[sd->gspca_dev.curr_mode].pixelformat ==
495 V4L2_PIX_FMT_JPEG) {
496 ret += reg_w(sd, 0x2c, sd->gspca_dev.width/2);
497 ret += reg_w(sd, 0x2d, sd->gspca_dev.width/4);
498 } else
499 ret += reg_w(sd, 0x2c, sd->gspca_dev.width);
500
501 ret += reg_w(sd, 0x00, 0xbf17); /* reset everything */
502 ret += reg_w(sd, 0x00, 0xbf10); /* normal operation */
503
504 /* Transfer size in WORDS (for UYVY format only) */
505 val = sd->gspca_dev.width * sd->gspca_dev.height;
506 ret += reg_w(sd, 0x3d, val & 0xffff); /* low bits */
507 ret += reg_w(sd, 0x3e, val >> 16); /* high bits */
508
509 if (w9968cf_vga_mode[sd->gspca_dev.curr_mode].pixelformat ==
510 V4L2_PIX_FMT_JPEG) {
511 /* We may get called multiple times (usb isoc bw negotiat.) */
512 if (!sd->jpeg_hdr)
513 sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL);
514 if (!sd->jpeg_hdr)
515 return -ENOMEM;
516
517 jpeg_define(sd->jpeg_hdr, sd->gspca_dev.height,
518 sd->gspca_dev.width, 0x22); /* JPEG 420 */
519 jpeg_set_qual(sd->jpeg_hdr, sd->quality);
520 ret += w9968cf_upload_quantizationtables(sd);
521 }
522
523 /* Video Capture Control Register */
524 if (sd->sensor == SEN_OV7620) {
525 /* Seems to work around a bug in the image sensor */
526 vs_polarity = 1;
527 hs_polarity = 1;
528 } else {
529 vs_polarity = 1;
530 hs_polarity = 0;
531 }
532
533 val = (vs_polarity << 12) | (hs_polarity << 11);
534
535 /* NOTE: We may not have enough memory to do double buffering while
536 doing compression (amount of memory differs per model cam).
537 So we use the second image buffer also as jpeg stream buffer
538 (see w9968cf_init), and disable double buffering. */
539 if (w9968cf_vga_mode[sd->gspca_dev.curr_mode].pixelformat ==
540 V4L2_PIX_FMT_JPEG) {
541 /* val |= 0x0002; YUV422P */
542 val |= 0x0003; /* YUV420P */
543 } else
544 val |= 0x0080; /* Enable HW double buffering */
545
546 /* val |= 0x0020; enable clamping */
547 /* val |= 0x0008; enable (1-2-1) filter */
548 /* val |= 0x000c; enable (2-3-6-3-2) filter */
549
550 val |= 0x8000; /* capt. enable */
551
552 ret += reg_w(sd, 0x16, val);
553
554 sd->gspca_dev.empty_packet = 0;
555
556 return ret;
557}
558
559static void w9968cf_stop0(struct sd *sd)
560{
561 if (sd->gspca_dev.present) {
562 reg_w(sd, 0x39, 0x0000); /* disable JPEG encoder */
563 reg_w(sd, 0x16, 0x0000); /* stop video capture */
564 }
565
566 kfree(sd->jpeg_hdr);
567 sd->jpeg_hdr = NULL;
568}
569
570/* The w9968cf docs say that a 0 sized packet means EOF (and also SOF
571 for the next frame). This seems to simply not be true when operating
572 in JPEG mode, in this case there may be empty packets within the
573 frame. So in JPEG mode use the JPEG SOI marker to detect SOF.
574
575 Note to make things even more interesting the w9968cf sends *PLANAR* jpeg,
576 to be precise it sends: SOI, SOF, DRI, SOS, Y-data, SOS, U-data, SOS,
577 V-data, EOI. */
578static void w9968cf_pkt_scan(struct gspca_dev *gspca_dev,
579 u8 *data, /* isoc packet */
580 int len) /* iso packet length */
581{
582 struct sd *sd = (struct sd *) gspca_dev;
583
584 if (w9968cf_vga_mode[gspca_dev->curr_mode].pixelformat ==
585 V4L2_PIX_FMT_JPEG) {
586 if (len >= 2 &&
587 data[0] == 0xff &&
588 data[1] == 0xd8) {
589 gspca_frame_add(gspca_dev, LAST_PACKET,
590 NULL, 0);
591 gspca_frame_add(gspca_dev, FIRST_PACKET,
592 sd->jpeg_hdr, JPEG_HDR_SZ);
593 /* Strip the ff d8, our own header (which adds
594 huffman and quantization tables) already has this */
595 len -= 2;
596 data += 2;
597 }
598 } else {
599 /* In UYVY mode an empty packet signals EOF */
600 if (gspca_dev->empty_packet) {
601 gspca_frame_add(gspca_dev, LAST_PACKET,
602 NULL, 0);
603 gspca_frame_add(gspca_dev, FIRST_PACKET,
604 NULL, 0);
605 gspca_dev->empty_packet = 0;
606 }
607 }
608 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
609}
diff --git a/drivers/media/video/gspca/zc3xx.c b/drivers/media/video/gspca/zc3xx.c
index 49c3c1226e0e..69e5dc4fc9de 100644
--- a/drivers/media/video/gspca/zc3xx.c
+++ b/drivers/media/video/gspca/zc3xx.c
@@ -61,17 +61,18 @@ struct sd {
61#define SENSOR_HV7131C 6 61#define SENSOR_HV7131C 6
62#define SENSOR_ICM105A 7 62#define SENSOR_ICM105A 7
63#define SENSOR_MC501CB 8 63#define SENSOR_MC501CB 8
64#define SENSOR_OV7620 9 64#define SENSOR_MI0360SOC 9
65/*#define SENSOR_OV7648 9 - same values */ 65#define SENSOR_OV7620 10
66#define SENSOR_OV7630C 10 66/*#define SENSOR_OV7648 10 - same values */
67#define SENSOR_PAS106 11 67#define SENSOR_OV7630C 11
68#define SENSOR_PAS202B 12 68#define SENSOR_PAS106 12
69#define SENSOR_PB0330 13 69#define SENSOR_PAS202B 13
70#define SENSOR_PO2030 14 70#define SENSOR_PB0330 14 /* (MI0360) */
71#define SENSOR_TAS5130CK 15 71#define SENSOR_PO2030 15
72#define SENSOR_TAS5130CXX 16 72#define SENSOR_TAS5130CK 16
73#define SENSOR_TAS5130C_VF0250 17 73#define SENSOR_TAS5130CXX 17
74#define SENSOR_MAX 18 74#define SENSOR_TAS5130C_VF0250 18
75#define SENSOR_MAX 19
75 unsigned short chip_revision; 76 unsigned short chip_revision;
76 77
77 u8 *jpeg_hdr; 78 u8 *jpeg_hdr;
@@ -420,9 +421,7 @@ static const struct usb_action adcm2700_NoFliker[] = {
420 {0xaa, 0xfe, 0x0010}, /* 00,fe,10,aa */ 421 {0xaa, 0xfe, 0x0010}, /* 00,fe,10,aa */
421 {} 422 {}
422}; 423};
423static const struct usb_action cs2102_Initial[] = { 424static const struct usb_action cs2102_Initial[] = { /* 320x240 */
424 {0xa1, 0x01, 0x0008},
425 {0xa1, 0x01, 0x0008},
426 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, 425 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
427 {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT}, 426 {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT},
428 {0xa0, 0x00, ZC3XX_R010_CMOSSENSORSELECT}, 427 {0xa0, 0x00, ZC3XX_R010_CMOSSENSORSELECT},
@@ -471,88 +470,10 @@ static const struct usb_action cs2102_Initial[] = {
471 {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, 470 {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
472 {0xa0, 0x68, ZC3XX_R18D_YTARGET}, 471 {0xa0, 0x68, ZC3XX_R18D_YTARGET},
473 {0xa0, 0x00, 0x01ad}, 472 {0xa0, 0x00, 0x01ad},
474 {0xa1, 0x01, 0x0002},
475 {0xa1, 0x01, 0x0008},
476 {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* 00 */
477 {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */
478 {0xa1, 0x01, 0x01c8},
479 {0xa1, 0x01, 0x01c9},
480 {0xa1, 0x01, 0x01ca},
481 {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */
482 {0xa0, 0x24, ZC3XX_R120_GAMMA00}, /* gamma 5 */
483 {0xa0, 0x44, ZC3XX_R121_GAMMA01},
484 {0xa0, 0x64, ZC3XX_R122_GAMMA02},
485 {0xa0, 0x84, ZC3XX_R123_GAMMA03},
486 {0xa0, 0x9d, ZC3XX_R124_GAMMA04},
487 {0xa0, 0xb2, ZC3XX_R125_GAMMA05},
488 {0xa0, 0xc4, ZC3XX_R126_GAMMA06},
489 {0xa0, 0xd3, ZC3XX_R127_GAMMA07},
490 {0xa0, 0xe0, ZC3XX_R128_GAMMA08},
491 {0xa0, 0xeb, ZC3XX_R129_GAMMA09},
492 {0xa0, 0xf4, ZC3XX_R12A_GAMMA0A},
493 {0xa0, 0xfb, ZC3XX_R12B_GAMMA0B},
494 {0xa0, 0xff, ZC3XX_R12C_GAMMA0C},
495 {0xa0, 0xff, ZC3XX_R12D_GAMMA0D},
496 {0xa0, 0xff, ZC3XX_R12E_GAMMA0E},
497 {0xa0, 0xff, ZC3XX_R12F_GAMMA0F},
498 {0xa0, 0x18, ZC3XX_R130_GAMMA10},
499 {0xa0, 0x20, ZC3XX_R131_GAMMA11},
500 {0xa0, 0x20, ZC3XX_R132_GAMMA12},
501 {0xa0, 0x1c, ZC3XX_R133_GAMMA13},
502 {0xa0, 0x16, ZC3XX_R134_GAMMA14},
503 {0xa0, 0x13, ZC3XX_R135_GAMMA15},
504 {0xa0, 0x10, ZC3XX_R136_GAMMA16},
505 {0xa0, 0x0e, ZC3XX_R137_GAMMA17},
506 {0xa0, 0x0b, ZC3XX_R138_GAMMA18},
507 {0xa0, 0x09, ZC3XX_R139_GAMMA19},
508 {0xa0, 0x07, ZC3XX_R13A_GAMMA1A},
509 {0xa0, 0x06, ZC3XX_R13B_GAMMA1B},
510 {0xa0, 0x00, ZC3XX_R13C_GAMMA1C},
511 {0xa0, 0x00, ZC3XX_R13D_GAMMA1D},
512 {0xa0, 0x00, ZC3XX_R13E_GAMMA1E},
513 {0xa0, 0x01, ZC3XX_R13F_GAMMA1F},
514 {0xa0, 0x58, ZC3XX_R10A_RGB00}, /* matrix */
515 {0xa0, 0xf4, ZC3XX_R10B_RGB01},
516 {0xa0, 0xf4, ZC3XX_R10C_RGB02},
517 {0xa0, 0xf4, ZC3XX_R10D_RGB10},
518 {0xa0, 0x58, ZC3XX_R10E_RGB11},
519 {0xa0, 0xf4, ZC3XX_R10F_RGB12},
520 {0xa0, 0xf4, ZC3XX_R110_RGB20},
521 {0xa0, 0xf4, ZC3XX_R111_RGB21},
522 {0xa0, 0x58, ZC3XX_R112_RGB22},
523 {0xa1, 0x01, 0x0180},
524 {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
525 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
526 {0xaa, 0x23, 0x0001},
527 {0xaa, 0x24, 0x0055},
528 {0xaa, 0x25, 0x00cc},
529 {0xaa, 0x21, 0x003f},
530 {0xa0, 0x02, ZC3XX_R190_EXPOSURELIMITHIGH},
531 {0xa0, 0xab, ZC3XX_R191_EXPOSURELIMITMID},
532 {0xa0, 0x98, ZC3XX_R192_EXPOSURELIMITLOW},
533 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
534 {0xa0, 0x30, ZC3XX_R196_ANTIFLICKERMID},
535 {0xa0, 0xd4, ZC3XX_R197_ANTIFLICKERLOW},
536 {0xa0, 0x10, ZC3XX_R18C_AEFREEZE},
537 {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE},
538 {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF},
539 {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP},
540 {0xa0, 0x39, ZC3XX_R01D_HSYNC_0},
541 {0xa0, 0x70, ZC3XX_R01E_HSYNC_1},
542 {0xa0, 0xb0, ZC3XX_R01F_HSYNC_2},
543 {0xa0, 0xff, ZC3XX_R020_HSYNC_3},
544 {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE},
545 {0xa1, 0x01, 0x0180},
546 {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
547 {0xa0, 0x40, ZC3XX_R116_RGAIN},
548 {0xa0, 0x40, ZC3XX_R117_GGAIN},
549 {0xa0, 0x40, ZC3XX_R118_BGAIN},
550 {} 473 {}
551}; 474};
552 475
553static const struct usb_action cs2102_InitialScale[] = { 476static const struct usb_action cs2102_InitialScale[] = { /* 640x480 */
554 {0xa1, 0x01, 0x0008},
555 {0xa1, 0x01, 0x0008},
556 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, 477 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
557 {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT}, 478 {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT},
558 {0xa0, 0x00, ZC3XX_R010_CMOSSENSORSELECT}, 479 {0xa0, 0x00, ZC3XX_R010_CMOSSENSORSELECT},
@@ -601,57 +522,75 @@ static const struct usb_action cs2102_InitialScale[] = {
601 {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, 522 {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
602 {0xa0, 0x68, ZC3XX_R18D_YTARGET}, 523 {0xa0, 0x68, ZC3XX_R18D_YTARGET},
603 {0xa0, 0x00, 0x01ad}, 524 {0xa0, 0x00, 0x01ad},
604 {0xa1, 0x01, 0x0002}, 525 {}
605 {0xa1, 0x01, 0x0008}, 526};
606 {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* 00 */ 527static const struct usb_action cs2102_50HZ[] = {
607 {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */ 528 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
608 {0xa1, 0x01, 0x01c8}, 529 {0xaa, 0x23, 0x0001},
609 {0xa1, 0x01, 0x01c9}, 530 {0xaa, 0x24, 0x005f},
610 {0xa1, 0x01, 0x01ca}, 531 {0xaa, 0x25, 0x0090},
611 {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */ 532 {0xaa, 0x21, 0x00dd},
612 {0xa0, 0x24, ZC3XX_R120_GAMMA00}, /* gamma 5 */ 533 {0xa0, 0x02, ZC3XX_R190_EXPOSURELIMITHIGH},
613 {0xa0, 0x44, ZC3XX_R121_GAMMA01}, 534 {0xa0, 0xbf, ZC3XX_R191_EXPOSURELIMITMID},
614 {0xa0, 0x64, ZC3XX_R122_GAMMA02}, 535 {0xa0, 0x20, ZC3XX_R192_EXPOSURELIMITLOW},
615 {0xa0, 0x84, ZC3XX_R123_GAMMA03}, 536 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
616 {0xa0, 0x9d, ZC3XX_R124_GAMMA04}, 537 {0xa0, 0x3a, ZC3XX_R196_ANTIFLICKERMID},
617 {0xa0, 0xb2, ZC3XX_R125_GAMMA05}, 538 {0xa0, 0x98, ZC3XX_R197_ANTIFLICKERLOW},
618 {0xa0, 0xc4, ZC3XX_R126_GAMMA06}, 539 {0xa0, 0x10, ZC3XX_R18C_AEFREEZE},
619 {0xa0, 0xd3, ZC3XX_R127_GAMMA07}, 540 {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE},
620 {0xa0, 0xe0, ZC3XX_R128_GAMMA08}, 541 {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF},
621 {0xa0, 0xeb, ZC3XX_R129_GAMMA09}, 542 {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP},
622 {0xa0, 0xf4, ZC3XX_R12A_GAMMA0A}, 543 {0xa0, 0xdd, ZC3XX_R01D_HSYNC_0},
623 {0xa0, 0xfb, ZC3XX_R12B_GAMMA0B}, 544 {0xa0, 0xe4, ZC3XX_R01E_HSYNC_1},
624 {0xa0, 0xff, ZC3XX_R12C_GAMMA0C}, 545 {0xa0, 0xf0, ZC3XX_R01F_HSYNC_2},
625 {0xa0, 0xff, ZC3XX_R12D_GAMMA0D}, 546 {0xa0, 0xff, ZC3XX_R020_HSYNC_3},
626 {0xa0, 0xff, ZC3XX_R12E_GAMMA0E}, 547 {}
627 {0xa0, 0xff, ZC3XX_R12F_GAMMA0F}, 548};
628 {0xa0, 0x18, ZC3XX_R130_GAMMA10}, 549static const struct usb_action cs2102_50HZScale[] = {
629 {0xa0, 0x20, ZC3XX_R131_GAMMA11}, 550 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
630 {0xa0, 0x20, ZC3XX_R132_GAMMA12}, 551 {0xaa, 0x23, 0x0000},
631 {0xa0, 0x1c, ZC3XX_R133_GAMMA13}, 552 {0xaa, 0x24, 0x00af},
632 {0xa0, 0x16, ZC3XX_R134_GAMMA14}, 553 {0xaa, 0x25, 0x00c8},
633 {0xa0, 0x13, ZC3XX_R135_GAMMA15}, 554 {0xaa, 0x21, 0x0068},
634 {0xa0, 0x10, ZC3XX_R136_GAMMA16}, 555 {0xa0, 0x01, ZC3XX_R190_EXPOSURELIMITHIGH},
635 {0xa0, 0x0e, ZC3XX_R137_GAMMA17}, 556 {0xa0, 0x5f, ZC3XX_R191_EXPOSURELIMITMID},
636 {0xa0, 0x0b, ZC3XX_R138_GAMMA18}, 557 {0xa0, 0x90, ZC3XX_R192_EXPOSURELIMITLOW},
637 {0xa0, 0x09, ZC3XX_R139_GAMMA19}, 558 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
638 {0xa0, 0x07, ZC3XX_R13A_GAMMA1A}, 559 {0xa0, 0x1d, ZC3XX_R196_ANTIFLICKERMID},
639 {0xa0, 0x06, ZC3XX_R13B_GAMMA1B}, 560 {0xa0, 0x4c, ZC3XX_R197_ANTIFLICKERLOW},
640 {0xa0, 0x00, ZC3XX_R13C_GAMMA1C}, 561 {0xa0, 0x10, ZC3XX_R18C_AEFREEZE},
641 {0xa0, 0x00, ZC3XX_R13D_GAMMA1D}, 562 {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE},
642 {0xa0, 0x00, ZC3XX_R13E_GAMMA1E}, 563 {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF},
643 {0xa0, 0x01, ZC3XX_R13F_GAMMA1F}, 564 {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP},
644 {0xa0, 0x58, ZC3XX_R10A_RGB00}, /* matrix */ 565 {0xa0, 0x68, ZC3XX_R01D_HSYNC_0},
645 {0xa0, 0xf4, ZC3XX_R10B_RGB01}, 566 {0xa0, 0xe3, ZC3XX_R01E_HSYNC_1},
646 {0xa0, 0xf4, ZC3XX_R10C_RGB02}, 567 {0xa0, 0xf0, ZC3XX_R01F_HSYNC_2},
647 {0xa0, 0xf4, ZC3XX_R10D_RGB10}, 568 {0xa0, 0xff, ZC3XX_R020_HSYNC_3},
648 {0xa0, 0x58, ZC3XX_R10E_RGB11}, 569 {}
649 {0xa0, 0xf4, ZC3XX_R10F_RGB12}, 570};
650 {0xa0, 0xf4, ZC3XX_R110_RGB20}, 571static const struct usb_action cs2102_60HZ[] = {
651 {0xa0, 0xf4, ZC3XX_R111_RGB21}, 572 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
652 {0xa0, 0x58, ZC3XX_R112_RGB22}, 573 {0xaa, 0x23, 0x0001},
653 {0xa1, 0x01, 0x0180}, 574 {0xaa, 0x24, 0x0055},
654 {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE}, 575 {0xaa, 0x25, 0x00cc},
576 {0xaa, 0x21, 0x003f},
577 {0xa0, 0x02, ZC3XX_R190_EXPOSURELIMITHIGH},
578 {0xa0, 0xab, ZC3XX_R191_EXPOSURELIMITMID},
579 {0xa0, 0x98, ZC3XX_R192_EXPOSURELIMITLOW},
580 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
581 {0xa0, 0x30, ZC3XX_R196_ANTIFLICKERMID},
582 {0xa0, 0xd4, ZC3XX_R197_ANTIFLICKERLOW},
583 {0xa0, 0x10, ZC3XX_R18C_AEFREEZE},
584 {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE},
585 {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF},
586 {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP},
587 {0xa0, 0x39, ZC3XX_R01D_HSYNC_0},
588 {0xa0, 0x70, ZC3XX_R01E_HSYNC_1},
589 {0xa0, 0xb0, ZC3XX_R01F_HSYNC_2},
590 {0xa0, 0xff, ZC3XX_R020_HSYNC_3},
591 {}
592};
593static const struct usb_action cs2102_60HZScale[] = {
655 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, 594 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
656 {0xaa, 0x23, 0x0000}, 595 {0xaa, 0x23, 0x0000},
657 {0xaa, 0x24, 0x00aa}, 596 {0xaa, 0x24, 0x00aa},
@@ -671,162 +610,50 @@ static const struct usb_action cs2102_InitialScale[] = {
671 {0xa0, 0xa5, ZC3XX_R01E_HSYNC_1}, 610 {0xa0, 0xa5, ZC3XX_R01E_HSYNC_1},
672 {0xa0, 0xf0, ZC3XX_R01F_HSYNC_2}, 611 {0xa0, 0xf0, ZC3XX_R01F_HSYNC_2},
673 {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, 612 {0xa0, 0xff, ZC3XX_R020_HSYNC_3},
674 {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE},
675 {0xa1, 0x01, 0x0180},
676 {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
677 {0xa0, 0x40, ZC3XX_R116_RGAIN},
678 {0xa0, 0x40, ZC3XX_R117_GGAIN},
679 {0xa0, 0x40, ZC3XX_R118_BGAIN},
680 {}
681};
682static const struct usb_action cs2102_50HZ[] = {
683 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
684 {0xaa, 0x0f, 0x008c}, /* 00,0f,8c,aa */
685 {0xaa, 0x03, 0x0005}, /* 00,03,05,aa */
686 {0xaa, 0x04, 0x00ac}, /* 00,04,ac,aa */
687 {0xaa, 0x10, 0x0005}, /* 00,10,05,aa */
688 {0xaa, 0x11, 0x00ac}, /* 00,11,ac,aa */
689 {0xaa, 0x1b, 0x0000}, /* 00,1b,00,aa */
690 {0xaa, 0x1c, 0x0005}, /* 00,1c,05,aa */
691 {0xaa, 0x1d, 0x00ac}, /* 00,1d,ac,aa */
692 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
693 {0xa0, 0x3f, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,3f,cc */
694 {0xa0, 0xf0, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,f0,cc */
695 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
696 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
697 {0xa0, 0x42, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,42,cc */
698 {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */
699 {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */
700 {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,10,cc */
701 {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc */
702 {0xa0, 0x8c, ZC3XX_R01D_HSYNC_0}, /* 00,1d,8c,cc */
703 {0xa0, 0xb0, ZC3XX_R01E_HSYNC_1}, /* 00,1e,b0,cc */
704 {0xa0, 0xd0, ZC3XX_R01F_HSYNC_2}, /* 00,1f,d0,cc */
705 {}
706};
707static const struct usb_action cs2102_50HZScale[] = {
708 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
709 {0xaa, 0x0f, 0x0093}, /* 00,0f,93,aa */
710 {0xaa, 0x03, 0x0005}, /* 00,03,05,aa */
711 {0xaa, 0x04, 0x00a1}, /* 00,04,a1,aa */
712 {0xaa, 0x10, 0x0005}, /* 00,10,05,aa */
713 {0xaa, 0x11, 0x00a1}, /* 00,11,a1,aa */
714 {0xaa, 0x1b, 0x0000}, /* 00,1b,00,aa */
715 {0xaa, 0x1c, 0x0005}, /* 00,1c,05,aa */
716 {0xaa, 0x1d, 0x00a1}, /* 00,1d,a1,aa */
717 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
718 {0xa0, 0x3f, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,3f,cc */
719 {0xa0, 0xf7, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,f7,cc */
720 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
721 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
722 {0xa0, 0x83, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,83,cc */
723 {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */
724 {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */
725 {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,10,cc */
726 {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc */
727 {0xa0, 0x93, ZC3XX_R01D_HSYNC_0}, /* 00,1d,93,cc */
728 {0xa0, 0xb0, ZC3XX_R01E_HSYNC_1}, /* 00,1e,b0,cc */
729 {0xa0, 0xd0, ZC3XX_R01F_HSYNC_2}, /* 00,1f,d0,cc */
730 {}
731};
732static const struct usb_action cs2102_60HZ[] = {
733 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
734 {0xaa, 0x0f, 0x005d}, /* 00,0f,5d,aa */
735 {0xaa, 0x03, 0x0005}, /* 00,03,05,aa */
736 {0xaa, 0x04, 0x00aa}, /* 00,04,aa,aa */
737 {0xaa, 0x10, 0x0005}, /* 00,10,05,aa */
738 {0xaa, 0x11, 0x00aa}, /* 00,11,aa,aa */
739 {0xaa, 0x1b, 0x0000}, /* 00,1b,00,aa */
740 {0xaa, 0x1c, 0x0005}, /* 00,1c,05,aa */
741 {0xaa, 0x1d, 0x00aa}, /* 00,1d,aa,aa */
742 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
743 {0xa0, 0x3f, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,3f,cc */
744 {0xa0, 0xe4, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,e4,cc */
745 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
746 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
747 {0xa0, 0x3a, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,3a,cc */
748 {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */
749 {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */
750 {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,10,cc */
751 {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc */
752 {0xa0, 0x5d, ZC3XX_R01D_HSYNC_0}, /* 00,1d,5d,cc */
753 {0xa0, 0x90, ZC3XX_R01E_HSYNC_1}, /* 00,1e,90,cc */
754 {0xa0, 0xd0, 0x00c8}, /* 00,c8,d0,cc */
755 {}
756};
757static const struct usb_action cs2102_60HZScale[] = {
758 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
759 {0xaa, 0x0f, 0x00b7}, /* 00,0f,b7,aa */
760 {0xaa, 0x03, 0x0005}, /* 00,03,05,aa */
761 {0xaa, 0x04, 0x00be}, /* 00,04,be,aa */
762 {0xaa, 0x10, 0x0005}, /* 00,10,05,aa */
763 {0xaa, 0x11, 0x00be}, /* 00,11,be,aa */
764 {0xaa, 0x1b, 0x0000}, /* 00,1b,00,aa */
765 {0xaa, 0x1c, 0x0005}, /* 00,1c,05,aa */
766 {0xaa, 0x1d, 0x00be}, /* 00,1d,be,aa */
767 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
768 {0xa0, 0x3f, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,3f,cc */
769 {0xa0, 0xfc, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,fc,cc */
770 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
771 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
772 {0xa0, 0x69, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,69,cc */
773 {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */
774 {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */
775 {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,10,cc */
776 {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc */
777 {0xa0, 0xb7, ZC3XX_R01D_HSYNC_0}, /* 00,1d,b7,cc */
778 {0xa0, 0xd0, ZC3XX_R01E_HSYNC_1}, /* 00,1e,d0,cc */
779 {0xa0, 0xe8, ZC3XX_R01F_HSYNC_2}, /* 00,1f,e8,cc */
780 {} 613 {}
781}; 614};
782static const struct usb_action cs2102_NoFliker[] = { 615static const struct usb_action cs2102_NoFliker[] = {
783 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ 616 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
784 {0xaa, 0x0f, 0x0059}, /* 00,0f,59,aa */ 617 {0xaa, 0x23, 0x0001},
785 {0xaa, 0x03, 0x0005}, /* 00,03,05,aa */ 618 {0xaa, 0x24, 0x005f},
786 {0xaa, 0x04, 0x0080}, /* 00,04,80,aa */ 619 {0xaa, 0x25, 0x0000},
787 {0xaa, 0x10, 0x0005}, /* 00,10,05,aa */ 620 {0xaa, 0x21, 0x0001},
788 {0xaa, 0x11, 0x0080}, /* 00,11,80,aa */ 621 {0xa0, 0x02, ZC3XX_R190_EXPOSURELIMITHIGH},
789 {0xaa, 0x1b, 0x0000}, /* 00,1b,00,aa */ 622 {0xa0, 0xbf, ZC3XX_R191_EXPOSURELIMITMID},
790 {0xaa, 0x1c, 0x0005}, /* 00,1c,05,aa */ 623 {0xa0, 0x00, ZC3XX_R192_EXPOSURELIMITLOW},
791 {0xaa, 0x1d, 0x0080}, /* 00,1d,80,aa */ 624 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
792 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ 625 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
793 {0xa0, 0x3f, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,3f,cc */ 626 {0xa0, 0x80, ZC3XX_R197_ANTIFLICKERLOW},
794 {0xa0, 0xf0, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,f0,cc */ 627 {0xa0, 0x10, ZC3XX_R18C_AEFREEZE},
795 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ 628 {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE},
796 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ 629 {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF},
797 {0xa0, 0x10, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,10,cc */ 630 {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP},
798 {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ 631 {0xa0, 0x01, ZC3XX_R01D_HSYNC_0},
799 {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ 632 {0xa0, 0x40, ZC3XX_R01E_HSYNC_1},
800 {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,00,cc */ 633 {0xa0, 0xa0, ZC3XX_R01F_HSYNC_2},
801 {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,00,cc */ 634 {0xa0, 0xff, ZC3XX_R020_HSYNC_3},
802 {0xa0, 0x59, ZC3XX_R01D_HSYNC_0}, /* 00,1d,59,cc */
803 {0xa0, 0x90, ZC3XX_R01E_HSYNC_1}, /* 00,1e,90,cc */
804 {0xa0, 0xc8, ZC3XX_R01F_HSYNC_2}, /* 00,1f,c8,cc */
805 {} 635 {}
806}; 636};
807static const struct usb_action cs2102_NoFlikerScale[] = { 637static const struct usb_action cs2102_NoFlikerScale[] = {
808 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ 638 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
809 {0xaa, 0x0f, 0x0059}, /* 00,0f,59,aa */ 639 {0xaa, 0x23, 0x0000},
810 {0xaa, 0x03, 0x0005}, /* 00,03,05,aa */ 640 {0xaa, 0x24, 0x00af},
811 {0xaa, 0x04, 0x0080}, /* 00,04,80,aa */ 641 {0xaa, 0x25, 0x0080},
812 {0xaa, 0x10, 0x0005}, /* 00,10,05,aa */ 642 {0xaa, 0x21, 0x0001},
813 {0xaa, 0x11, 0x0080}, /* 00,11,80,aa */ 643 {0xa0, 0x01, ZC3XX_R190_EXPOSURELIMITHIGH},
814 {0xaa, 0x1b, 0x0000}, /* 00,1b,00,aa */ 644 {0xa0, 0x5f, ZC3XX_R191_EXPOSURELIMITMID},
815 {0xaa, 0x1c, 0x0005}, /* 00,1c,05,aa */ 645 {0xa0, 0x80, ZC3XX_R192_EXPOSURELIMITLOW},
816 {0xaa, 0x1d, 0x0080}, /* 00,1d,80,aa */ 646 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
817 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ 647 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
818 {0xa0, 0x3f, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,3f,cc */ 648 {0xa0, 0x80, ZC3XX_R197_ANTIFLICKERLOW},
819 {0xa0, 0xf0, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,f0,cc */ 649 {0xa0, 0x10, ZC3XX_R18C_AEFREEZE},
820 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ 650 {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE},
821 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ 651 {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF},
822 {0xa0, 0x10, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,10,cc */ 652 {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP},
823 {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ 653 {0xa0, 0x01, ZC3XX_R01D_HSYNC_0},
824 {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ 654 {0xa0, 0x40, ZC3XX_R01E_HSYNC_1},
825 {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,00,cc */ 655 {0xa0, 0xa0, ZC3XX_R01F_HSYNC_2},
826 {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,00,cc */ 656 {0xa0, 0xff, ZC3XX_R020_HSYNC_3},
827 {0xa0, 0x59, ZC3XX_R01D_HSYNC_0}, /* 00,1d,59,cc */
828 {0xa0, 0x90, ZC3XX_R01E_HSYNC_1}, /* 00,1e,90,cc */
829 {0xa0, 0xc8, ZC3XX_R01F_HSYNC_2}, /* 00,1f,c8,cc */
830 {} 657 {}
831}; 658};
832 659
@@ -4409,170 +4236,80 @@ static const struct usb_action pas202b_NoFlikerScale[] = {
4409 {} 4236 {}
4410}; 4237};
4411 4238
4412static const struct usb_action pb03303x_Initial[] = { 4239/* mi0360soc and pb0330 from vm30x.inf for 0ac8:301b and 0ac8:303b 07/02/13 */
4240static const struct usb_action mi0360soc_Initial[] = { /* 640x480 */
4413 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, 4241 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
4414 {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, 4242 {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
4415 {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, 4243 {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT},
4416 {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT}, 4244 {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT},
4417 {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, 4245 {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH},
4418 {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, 4246 {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW},
4419 {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, 4247 {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH},
4420 {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, 4248 {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW},
4421 {0xa0, 0xdc, ZC3XX_R08B_I2CDEVICEADDR}, /* 8b -> dc */ 4249 {0xa0, 0xdc, ZC3XX_R08B_I2CDEVICEADDR},
4422 {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, 4250 {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING},
4423 {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, 4251 {0xa0, 0x07, ZC3XX_R012_VIDEOCONTROLFUNC}, /*jfm: was 03*/
4424 {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, 4252/* {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, */
4425 {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, 4253 {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW},
4426 {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, 4254 {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW},
4427 {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, 4255 {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW},
4428 {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, 4256 {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW},
4429 {0xa0, 0xdc, ZC3XX_R08B_I2CDEVICEADDR}, 4257 {0xa0, 0xdc, ZC3XX_R08B_I2CDEVICEADDR},
4258 {0xdd, 0x00, 0x0200},
4430 {0xaa, 0x01, 0x0001}, 4259 {0xaa, 0x01, 0x0001},
4431 {0xaa, 0x06, 0x0000}, 4260 {0xaa, 0x06, 0x0000},
4432 {0xaa, 0x08, 0x0483}, 4261 {0xaa, 0x08, 0x0483},
4433 {0xaa, 0x01, 0x0004}, 4262 {0xaa, 0x01, 0x0004},
4434 {0xaa, 0x08, 0x0006}, 4263 {0xaa, 0x08, 0x0006},
4435 {0xaa, 0x02, 0x0011}, 4264 {0xaa, 0x02, 0x0011},
4436 {0xaa, 0x03, 0x01e7}, 4265 {0xaa, 0x03, 0x01e5}, /*jfm: was 01e7*/
4437 {0xaa, 0x04, 0x0287}, 4266 {0xaa, 0x04, 0x0285}, /*jfm: was 0287*/
4438 {0xaa, 0x07, 0x3002}, 4267 {0xaa, 0x07, 0x3002},
4439 {0xaa, 0x20, 0x1100}, 4268 {0xaa, 0x20, 0x5100}, /*jfm: was 1100*/
4440 {0xaa, 0x35, 0x0050}, 4269 {0xaa, 0x35, 0x507f}, /*jfm: was 0050*/
4441 {0xaa, 0x30, 0x0005}, 4270 {0xaa, 0x30, 0x0005},
4442 {0xaa, 0x31, 0x0000}, 4271 {0xaa, 0x31, 0x0000},
4443 {0xaa, 0x58, 0x0078}, 4272 {0xaa, 0x58, 0x0078},
4444 {0xaa, 0x62, 0x0411}, 4273 {0xaa, 0x62, 0x0411},
4445 {0xaa, 0x2b, 0x0028}, 4274 {0xaa, 0x2b, 0x0028},
4446 {0xaa, 0x2c, 0x0030}, 4275 {0xaa, 0x2c, 0x007f}, /*jfm: was 0030*/
4447 {0xaa, 0x2d, 0x0030}, 4276 {0xaa, 0x2d, 0x007f}, /*jfm: was 0030*/
4448 {0xaa, 0x2e, 0x0028}, 4277 {0xaa, 0x2e, 0x007f}, /*jfm: was 0030*/
4449 {0xa0, 0x10, ZC3XX_R087_EXPTIMEMID}, 4278 {0xa0, 0x10, ZC3XX_R087_EXPTIMEMID},
4450 {0xa0, 0x37, ZC3XX_R101_SENSORCORRECTION}, 4279 {0xa0, 0xb7, ZC3XX_R101_SENSORCORRECTION}, /*jfm: was 37*/
4451 {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, 4280 {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC},
4452 {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, 4281 {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE},
4453 {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, 4282 {0xa0, 0x06, ZC3XX_R189_AWBSTATUS},
4454 {0xa0, 0x00, 0x01ad}, 4283 {0xa0, 0x09, 0x01ad}, /*jfm: was 00*/
4455 {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, 4284 {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE},
4456 {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, 4285 {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05},
4457 {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, 4286 {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE},
4458 {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, 4287 {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
4459 {0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN}, 4288 {0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN},
4460 {0xa0, 0x78, ZC3XX_R18D_YTARGET}, 4289 {0xa0, 0x6c, ZC3XX_R18D_YTARGET}, /* jfm: was 78 */
4461 {0xa0, 0x61, ZC3XX_R116_RGAIN}, 4290 {0xa0, 0x61, ZC3XX_R116_RGAIN},
4462 {0xa0, 0x65, ZC3XX_R118_BGAIN}, 4291 {0xa0, 0x65, ZC3XX_R118_BGAIN},
4463
4464 {0xa1, 0x01, 0x0002},
4465 {0xa0, 0x09, 0x01ad},
4466 {0xa0, 0x15, 0x01ae},
4467 {0xa0, 0x0d, 0x003a},
4468 {0xa0, 0x02, 0x003b},
4469 {0xa0, 0x00, 0x0038},
4470 {0xa0, 0x50, ZC3XX_R10A_RGB00}, /* matrix */
4471 {0xa0, 0xf8, ZC3XX_R10B_RGB01},
4472 {0xa0, 0xf8, ZC3XX_R10C_RGB02},
4473 {0xa0, 0xf8, ZC3XX_R10D_RGB10},
4474 {0xa0, 0x50, ZC3XX_R10E_RGB11},
4475 {0xa0, 0xf8, ZC3XX_R10F_RGB12},
4476 {0xa0, 0xf8, ZC3XX_R110_RGB20},
4477 {0xa0, 0xf8, ZC3XX_R111_RGB21},
4478 {0xa0, 0x50, ZC3XX_R112_RGB22},
4479
4480 {0xa1, 0x01, 0x0008},
4481 {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
4482 {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00},
4483 {0xa1, 0x01, 0x01c8},
4484 {0xa1, 0x01, 0x01c9},
4485 {0xa1, 0x01, 0x01ca},
4486 {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */
4487 {0xa0, 0x13, ZC3XX_R120_GAMMA00}, /* gamma 4 */
4488 {0xa0, 0x38, ZC3XX_R121_GAMMA01},
4489 {0xa0, 0x59, ZC3XX_R122_GAMMA02},
4490 {0xa0, 0x79, ZC3XX_R123_GAMMA03},
4491 {0xa0, 0x92, ZC3XX_R124_GAMMA04},
4492 {0xa0, 0xa7, ZC3XX_R125_GAMMA05},
4493 {0xa0, 0xb9, ZC3XX_R126_GAMMA06},
4494 {0xa0, 0xc8, ZC3XX_R127_GAMMA07},
4495 {0xa0, 0xd4, ZC3XX_R128_GAMMA08},
4496 {0xa0, 0xdf, ZC3XX_R129_GAMMA09},
4497 {0xa0, 0xe7, ZC3XX_R12A_GAMMA0A},
4498 {0xa0, 0xee, ZC3XX_R12B_GAMMA0B},
4499 {0xa0, 0xf4, ZC3XX_R12C_GAMMA0C},
4500 {0xa0, 0xf9, ZC3XX_R12D_GAMMA0D},
4501 {0xa0, 0xfc, ZC3XX_R12E_GAMMA0E},
4502 {0xa0, 0xff, ZC3XX_R12F_GAMMA0F},
4503 {0xa0, 0x26, ZC3XX_R130_GAMMA10},
4504 {0xa0, 0x22, ZC3XX_R131_GAMMA11},
4505 {0xa0, 0x20, ZC3XX_R132_GAMMA12},
4506 {0xa0, 0x1c, ZC3XX_R133_GAMMA13},
4507 {0xa0, 0x16, ZC3XX_R134_GAMMA14},
4508 {0xa0, 0x13, ZC3XX_R135_GAMMA15},
4509 {0xa0, 0x10, ZC3XX_R136_GAMMA16},
4510 {0xa0, 0x0d, ZC3XX_R137_GAMMA17},
4511 {0xa0, 0x0b, ZC3XX_R138_GAMMA18},
4512 {0xa0, 0x09, ZC3XX_R139_GAMMA19},
4513 {0xa0, 0x07, ZC3XX_R13A_GAMMA1A},
4514 {0xa0, 0x06, ZC3XX_R13B_GAMMA1B},
4515 {0xa0, 0x05, ZC3XX_R13C_GAMMA1C},
4516 {0xa0, 0x04, ZC3XX_R13D_GAMMA1D},
4517 {0xa0, 0x03, ZC3XX_R13E_GAMMA1E},
4518 {0xa0, 0x02, ZC3XX_R13F_GAMMA1F},
4519 {0xa0, 0x50, ZC3XX_R10A_RGB00}, /* matrix */
4520 {0xa0, 0xf8, ZC3XX_R10B_RGB01},
4521 {0xa0, 0xf8, ZC3XX_R10C_RGB02},
4522 {0xa0, 0xf8, ZC3XX_R10D_RGB10},
4523 {0xa0, 0x50, ZC3XX_R10E_RGB11},
4524 {0xa0, 0xf8, ZC3XX_R10F_RGB12},
4525 {0xa0, 0xf8, ZC3XX_R110_RGB20},
4526 {0xa0, 0xf8, ZC3XX_R111_RGB21},
4527 {0xa0, 0x50, ZC3XX_R112_RGB22},
4528
4529 {0xa1, 0x01, 0x0180},
4530 {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
4531 {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
4532 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
4533 {0xaa, 0x05, 0x0009},
4534 {0xaa, 0x09, 0x0134},
4535 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
4536 {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID},
4537 {0xa0, 0xec, ZC3XX_R192_EXPOSURELIMITLOW},
4538 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
4539 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
4540 {0xa0, 0x9c, ZC3XX_R197_ANTIFLICKERLOW},
4541 {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE},
4542 {0xa0, 0x1c, ZC3XX_R18F_AEUNFREEZE},
4543 {0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF},
4544 {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP},
4545 {0xa0, 0xd7, ZC3XX_R01D_HSYNC_0},
4546 {0xa0, 0xf4, ZC3XX_R01E_HSYNC_1},
4547 {0xa0, 0xf9, ZC3XX_R01F_HSYNC_2},
4548 {0xa0, 0xff, ZC3XX_R020_HSYNC_3},
4549 {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
4550 {0xa0, 0x09, 0x01ad},
4551 {0xa0, 0x15, 0x01ae},
4552 {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE},
4553 {0xa1, 0x01, 0x0180},
4554 {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
4555 {} 4292 {}
4556}; 4293};
4557 4294static const struct usb_action mi0360soc_InitialScale[] = { /* 320x240 */
4558static const struct usb_action pb03303x_InitialScale[] = {
4559 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, 4295 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
4560 {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, 4296 {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
4561 {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, 4297 {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT},
4562 {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT}, 4298 {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT},
4563 {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, 4299 {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH},
4564 {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, 4300 {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW},
4565 {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, 4301 {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH},
4566 {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, 4302 {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW},
4567 {0xa0, 0xdc, ZC3XX_R08B_I2CDEVICEADDR}, /* 8b -> dc */ 4303 {0xa0, 0xdc, ZC3XX_R08B_I2CDEVICEADDR},
4568 {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, 4304 {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING},
4569 {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, 4305 {0xa0, 0x07, ZC3XX_R012_VIDEOCONTROLFUNC}, /*jfm: was 03*/
4570 {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, 4306/* {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, */
4571 {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, 4307 {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW},
4572 {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, 4308 {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW},
4573 {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, 4309 {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW},
4574 {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, 4310 {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW},
4575 {0xa0, 0xdc, ZC3XX_R08B_I2CDEVICEADDR}, 4311 {0xa0, 0xdc, ZC3XX_R08B_I2CDEVICEADDR},
4312 {0xdd, 0x00, 0x0200},
4576 {0xaa, 0x01, 0x0001}, 4313 {0xaa, 0x01, 0x0001},
4577 {0xaa, 0x06, 0x0000}, 4314 {0xaa, 0x06, 0x0000},
4578 {0xaa, 0x08, 0x0483}, 4315 {0xaa, 0x08, 0x0483},
@@ -4582,111 +4319,111 @@ static const struct usb_action pb03303x_InitialScale[] = {
4582 {0xaa, 0x03, 0x01e7}, 4319 {0xaa, 0x03, 0x01e7},
4583 {0xaa, 0x04, 0x0287}, 4320 {0xaa, 0x04, 0x0287},
4584 {0xaa, 0x07, 0x3002}, 4321 {0xaa, 0x07, 0x3002},
4585 {0xaa, 0x20, 0x1100}, 4322 {0xaa, 0x20, 0x5100}, /*jfm: was 1100*/
4586 {0xaa, 0x35, 0x0050}, 4323 {0xaa, 0x35, 0x007f}, /*jfm: was 0050*/
4587 {0xaa, 0x30, 0x0005}, 4324 {0xaa, 0x30, 0x0005},
4588 {0xaa, 0x31, 0x0000}, 4325 {0xaa, 0x31, 0x0000},
4589 {0xaa, 0x58, 0x0078}, 4326 {0xaa, 0x58, 0x0078},
4590 {0xaa, 0x62, 0x0411}, 4327 {0xaa, 0x62, 0x0411},
4591 {0xaa, 0x2b, 0x0028}, 4328 {0xaa, 0x2b, 0x007f}, /*jfm: was 28*/
4592 {0xaa, 0x2c, 0x0030}, 4329 {0xaa, 0x2c, 0x007f}, /*jfm: was 30*/
4593 {0xaa, 0x2d, 0x0030}, 4330 {0xaa, 0x2d, 0x007f}, /*jfm: was 30*/
4594 {0xaa, 0x2e, 0x0028}, 4331 {0xaa, 0x2e, 0x007f}, /*jfm: was 28*/
4595 {0xa0, 0x10, ZC3XX_R087_EXPTIMEMID}, 4332 {0xa0, 0x10, ZC3XX_R087_EXPTIMEMID},
4596 {0xa0, 0x37, ZC3XX_R101_SENSORCORRECTION}, 4333 {0xa0, 0xb7, ZC3XX_R101_SENSORCORRECTION}, /*jfm: was 37*/
4597 {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, 4334 {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC},
4598 {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, 4335 {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE},
4599 {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, 4336 {0xa0, 0x06, ZC3XX_R189_AWBSTATUS},
4600 {0xa0, 0x00, 0x01ad}, 4337 {0xa0, 0x09, 0x01ad}, /*jfm: was 00*/
4601 {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, 4338 {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE},
4602 {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, 4339 {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05},
4603 {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, 4340 {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE},
4604 {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, 4341 {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
4605 {0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN}, 4342 {0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN},
4606 {0xa0, 0x78, ZC3XX_R18D_YTARGET}, 4343 {0xa0, 0x6c, ZC3XX_R18D_YTARGET}, /*jfm: was 78*/
4607 {0xa0, 0x61, ZC3XX_R116_RGAIN}, 4344 {0xa0, 0x61, ZC3XX_R116_RGAIN},
4608 {0xa0, 0x65, ZC3XX_R118_BGAIN}, 4345 {0xa0, 0x65, ZC3XX_R118_BGAIN},
4609 4346 {}
4610 {0xa1, 0x01, 0x0002}, 4347};
4611 4348static const struct usb_action mi360soc_AE50HZ[] = {
4612 {0xa0, 0x09, 0x01ad}, 4349 {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
4613 {0xa0, 0x15, 0x01ae}, 4350 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
4614 4351 {0xbb, 0x00, 0x0562},
4615 {0xa0, 0x0d, 0x003a}, 4352 {0xbb, 0x01, 0x09aa},
4616 {0xa0, 0x02, 0x003b}, 4353 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
4617 {0xa0, 0x00, 0x0038}, 4354 {0xa0, 0x03, ZC3XX_R191_EXPOSURELIMITMID},
4618 {0xa0, 0x50, ZC3XX_R10A_RGB00}, /* matrix */ 4355 {0xa0, 0x9b, ZC3XX_R192_EXPOSURELIMITLOW},
4619 {0xa0, 0xf8, ZC3XX_R10B_RGB01}, 4356 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
4620 {0xa0, 0xf8, ZC3XX_R10C_RGB02}, 4357 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
4621 {0xa0, 0xf8, ZC3XX_R10D_RGB10}, 4358 {0xa0, 0x47, ZC3XX_R197_ANTIFLICKERLOW},
4622 {0xa0, 0x50, ZC3XX_R10E_RGB11}, 4359 {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE},
4623 {0xa0, 0xf8, ZC3XX_R10F_RGB12}, 4360 {0xa0, 0x1c, ZC3XX_R18F_AEUNFREEZE},
4624 {0xa0, 0xf8, ZC3XX_R110_RGB20}, 4361 {0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF},
4625 {0xa0, 0xf8, ZC3XX_R111_RGB21}, 4362 {0xa0, 0x66, ZC3XX_R1AA_DIGITALGAINSTEP},
4626 {0xa0, 0x50, ZC3XX_R112_RGB22}, 4363 {0xa0, 0x62, ZC3XX_R01D_HSYNC_0},
4627 4364 {0xa0, 0x90, ZC3XX_R01E_HSYNC_1},
4628 {0xa1, 0x01, 0x0008}, 4365 {0xa0, 0xc8, ZC3XX_R01F_HSYNC_2},
4629 {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* clock ? */ 4366 {0xa0, 0xff, ZC3XX_R020_HSYNC_3},
4630 {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */ 4367 {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN},
4631 {0xa1, 0x01, 0x01c8}, 4368 {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
4632 {0xa1, 0x01, 0x01c9}, 4369 {}
4633 {0xa1, 0x01, 0x01ca}, 4370};
4634 {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */ 4371static const struct usb_action mi360soc_AE50HZScale[] = {
4635
4636 {0xa0, 0x13, ZC3XX_R120_GAMMA00}, /* gamma 4 */
4637 {0xa0, 0x38, ZC3XX_R121_GAMMA01},
4638 {0xa0, 0x59, ZC3XX_R122_GAMMA02},
4639 {0xa0, 0x79, ZC3XX_R123_GAMMA03},
4640 {0xa0, 0x92, ZC3XX_R124_GAMMA04},
4641 {0xa0, 0xa7, ZC3XX_R125_GAMMA05},
4642 {0xa0, 0xb9, ZC3XX_R126_GAMMA06},
4643 {0xa0, 0xc8, ZC3XX_R127_GAMMA07},
4644 {0xa0, 0xd4, ZC3XX_R128_GAMMA08},
4645 {0xa0, 0xdf, ZC3XX_R129_GAMMA09},
4646 {0xa0, 0xe7, ZC3XX_R12A_GAMMA0A},
4647 {0xa0, 0xee, ZC3XX_R12B_GAMMA0B},
4648 {0xa0, 0xf4, ZC3XX_R12C_GAMMA0C},
4649 {0xa0, 0xf9, ZC3XX_R12D_GAMMA0D},
4650 {0xa0, 0xfc, ZC3XX_R12E_GAMMA0E},
4651 {0xa0, 0xff, ZC3XX_R12F_GAMMA0F},
4652 {0xa0, 0x26, ZC3XX_R130_GAMMA10},
4653 {0xa0, 0x22, ZC3XX_R131_GAMMA11},
4654 {0xa0, 0x20, ZC3XX_R132_GAMMA12},
4655 {0xa0, 0x1c, ZC3XX_R133_GAMMA13},
4656 {0xa0, 0x16, ZC3XX_R134_GAMMA14},
4657 {0xa0, 0x13, ZC3XX_R135_GAMMA15},
4658 {0xa0, 0x10, ZC3XX_R136_GAMMA16},
4659 {0xa0, 0x0d, ZC3XX_R137_GAMMA17},
4660 {0xa0, 0x0b, ZC3XX_R138_GAMMA18},
4661 {0xa0, 0x09, ZC3XX_R139_GAMMA19},
4662 {0xa0, 0x07, ZC3XX_R13A_GAMMA1A},
4663 {0xa0, 0x06, ZC3XX_R13B_GAMMA1B},
4664 {0xa0, 0x05, ZC3XX_R13C_GAMMA1C},
4665 {0xa0, 0x04, ZC3XX_R13D_GAMMA1D},
4666 {0xa0, 0x03, ZC3XX_R13E_GAMMA1E},
4667 {0xa0, 0x02, ZC3XX_R13F_GAMMA1F},
4668 {0xa0, 0x50, ZC3XX_R10A_RGB00}, /* matrix */
4669 {0xa0, 0xf8, ZC3XX_R10B_RGB01},
4670 {0xa0, 0xf8, ZC3XX_R10C_RGB02},
4671 {0xa0, 0xf8, ZC3XX_R10D_RGB10},
4672 {0xa0, 0x50, ZC3XX_R10E_RGB11},
4673 {0xa0, 0xf8, ZC3XX_R10F_RGB12},
4674 {0xa0, 0xf8, ZC3XX_R110_RGB20},
4675 {0xa0, 0xf8, ZC3XX_R111_RGB21},
4676 {0xa0, 0x50, ZC3XX_R112_RGB22},
4677
4678 {0xa1, 0x01, 0x0180},
4679 {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE}, 4372 {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
4373 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
4374 {0xbb, 0x00, 0x0509},
4375 {0xbb, 0x01, 0x0934},
4376 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
4377 {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID},
4378 {0xa0, 0xd2, ZC3XX_R192_EXPOSURELIMITLOW},
4379 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
4380 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
4381 {0xa0, 0x9a, ZC3XX_R197_ANTIFLICKERLOW},
4382 {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE},
4383 {0xa0, 0x1c, ZC3XX_R18F_AEUNFREEZE},
4384 {0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF},
4385 {0xa0, 0x66, ZC3XX_R1AA_DIGITALGAINSTEP},
4386 {0xa0, 0xd7, ZC3XX_R01D_HSYNC_0},
4387 {0xa0, 0xf4, ZC3XX_R01E_HSYNC_1},
4388 {0xa0, 0xf9, ZC3XX_R01F_HSYNC_2},
4389 {0xa0, 0xff, ZC3XX_R020_HSYNC_3},
4390 {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
4391 {}
4392};
4393static const struct usb_action mi360soc_AE60HZ[] = {
4394 {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
4395 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
4396 {0xbb, 0x00, 0x053d},
4397 {0xbb, 0x01, 0x096e},
4398 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
4399 {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID},
4400 {0xa0, 0xdd, ZC3XX_R192_EXPOSURELIMITLOW},
4401 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
4402 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
4403 {0xa0, 0x3d, ZC3XX_R197_ANTIFLICKERLOW},
4404 {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE},
4405 {0xa0, 0x1c, ZC3XX_R18F_AEUNFREEZE},
4406 {0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF},
4407 {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP},
4408 {0xa0, 0x62, ZC3XX_R01D_HSYNC_0},
4409 {0xa0, 0x90, ZC3XX_R01E_HSYNC_1},
4410 {0xa0, 0xc8, ZC3XX_R01F_HSYNC_2},
4411 {0xa0, 0xff, ZC3XX_R020_HSYNC_3},
4412 {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN},
4413 {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
4414 {}
4415};
4416static const struct usb_action mi360soc_AE60HZScale[] = {
4680 {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE}, 4417 {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
4681 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, 4418 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
4682 {0xaa, 0x05, 0x0009}, 4419 {0xbb, 0x00, 0x0509},
4683 {0xaa, 0x09, 0x0134}, 4420 {0xbb, 0x01, 0x0983},
4684 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, 4421 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
4685 {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, 4422 {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID},
4686 {0xa0, 0xec, ZC3XX_R192_EXPOSURELIMITLOW}, 4423 {0xa0, 0x8f, ZC3XX_R192_EXPOSURELIMITLOW},
4687 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, 4424 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
4688 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, 4425 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
4689 {0xa0, 0x9c, ZC3XX_R197_ANTIFLICKERLOW}, 4426 {0xa0, 0x81, ZC3XX_R197_ANTIFLICKERLOW},
4690 {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE}, 4427 {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE},
4691 {0xa0, 0x1c, ZC3XX_R18F_AEUNFREEZE}, 4428 {0xa0, 0x1c, ZC3XX_R18F_AEUNFREEZE},
4692 {0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF}, 4429 {0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF},
@@ -4696,20 +4433,60 @@ static const struct usb_action pb03303x_InitialScale[] = {
4696 {0xa0, 0xf9, ZC3XX_R01F_HSYNC_2}, 4433 {0xa0, 0xf9, ZC3XX_R01F_HSYNC_2},
4697 {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, 4434 {0xa0, 0xff, ZC3XX_R020_HSYNC_3},
4698 {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, 4435 {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
4699 {0xa0, 0x09, 0x01ad}, 4436 {}
4700 {0xa0, 0x15, 0x01ae}, 4437};
4701 {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE}, 4438static const struct usb_action mi360soc_AENoFliker[] = {
4702 {0xa1, 0x01, 0x0180}, 4439 {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
4440 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
4441 {0xbb, 0x00, 0x0509},
4442 {0xbb, 0x01, 0x0960},
4443 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
4444 {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID},
4445 {0xa0, 0xf0, ZC3XX_R192_EXPOSURELIMITLOW},
4446 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
4447 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
4448 {0xa0, 0x04, ZC3XX_R197_ANTIFLICKERLOW},
4449 {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE},
4450 {0xa0, 0x1c, ZC3XX_R18F_AEUNFREEZE},
4451 {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF},
4452 {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP},
4453 {0xa0, 0x09, ZC3XX_R01D_HSYNC_0},
4454 {0xa0, 0x40, ZC3XX_R01E_HSYNC_1},
4455 {0xa0, 0x90, ZC3XX_R01F_HSYNC_2},
4456 {0xa0, 0xe0, ZC3XX_R020_HSYNC_3},
4457 {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN},
4703 {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, 4458 {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
4704 {} 4459 {}
4705}; 4460};
4706static const struct usb_action pb0330xx_Initial[] = { 4461static const struct usb_action mi360soc_AENoFlikerScale[] = {
4707 {0xa1, 0x01, 0x0008}, 4462 {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
4708 {0xa1, 0x01, 0x0008}, 4463 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
4464 {0xbb, 0x00, 0x0534},
4465 {0xbb, 0x02, 0x0960},
4466 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
4467 {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID},
4468 {0xa0, 0xf0, ZC3XX_R192_EXPOSURELIMITLOW},
4469 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
4470 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
4471 {0xa0, 0x04, ZC3XX_R197_ANTIFLICKERLOW},
4472 {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE},
4473 {0xa0, 0x1c, ZC3XX_R18F_AEUNFREEZE},
4474 {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF},
4475 {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP},
4476 {0xa0, 0x34, ZC3XX_R01D_HSYNC_0},
4477 {0xa0, 0x60, ZC3XX_R01E_HSYNC_1},
4478 {0xa0, 0x90, ZC3XX_R01F_HSYNC_2},
4479 {0xa0, 0xe0, ZC3XX_R020_HSYNC_3},
4480 {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN},
4481 {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
4482 {}
4483};
4484
4485static const struct usb_action pb0330_Initial[] = { /* 640x480 */
4709 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, 4486 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
4710 {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* 00 */ 4487 {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* 00 */
4711 {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, 4488 {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT},
4712 {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT}, 4489 {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT},
4713 {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, 4490 {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH},
4714 {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, 4491 {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW},
4715 {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, 4492 {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH},
@@ -4721,11 +4498,12 @@ static const struct usb_action pb0330xx_Initial[] = {
4721 {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, 4498 {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW},
4722 {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, 4499 {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW},
4723 {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, 4500 {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW},
4501 {0xdd, 0x00, 0x0200},
4724 {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, 4502 {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC},
4725 {0xaa, 0x01, 0x0006}, 4503 {0xaa, 0x01, 0x0006},
4726 {0xaa, 0x02, 0x0011}, 4504 {0xaa, 0x02, 0x0011},
4727 {0xaa, 0x03, 0x01e7}, 4505 {0xaa, 0x03, 0x01e5}, /*jfm: was 1e7*/
4728 {0xaa, 0x04, 0x0287}, 4506 {0xaa, 0x04, 0x0285}, /*jfm: was 0287*/
4729 {0xaa, 0x06, 0x0003}, 4507 {0xaa, 0x06, 0x0003},
4730 {0xaa, 0x07, 0x3002}, 4508 {0xaa, 0x07, 0x3002},
4731 {0xaa, 0x20, 0x1100}, 4509 {0xaa, 0x20, 0x1100},
@@ -4743,88 +4521,21 @@ static const struct usb_action pb0330xx_Initial[] = {
4743 {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, 4521 {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC},
4744 {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, 4522 {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE},
4745 {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, 4523 {0xa0, 0x06, ZC3XX_R189_AWBSTATUS},
4746 {0xa0, 0x00, 0x01ad}, 4524 {0xa0, 0x09, 0x01ad}, /*jfm: was 00 */
4525 {0xa0, 0x15, 0x01ae},
4747 {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, 4526 {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE},
4748 {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, 4527 {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05},
4749 {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, 4528 {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE},
4750 {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, 4529 {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
4751 {0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN}, 4530 {0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN},
4752 {0xa0, 0x6c, ZC3XX_R18D_YTARGET}, 4531 {0xa0, 0x78, ZC3XX_R18D_YTARGET}, /*jfm: was 6c*/
4753 {0xa1, 0x01, 0x0002},
4754 {0xa0, 0x09, 0x01ad},
4755 {0xa0, 0x15, 0x01ae},
4756 {0xa0, 0x00, ZC3XX_R092_I2CADDRESSSELECT},
4757 {0xa0, 0x02, ZC3XX_R090_I2CCOMMAND},
4758 {0xa1, 0x01, 0x0091},
4759 {0xa1, 0x01, 0x0095},
4760 {0xa1, 0x01, 0x0096},
4761 {0xa0, 0x50, ZC3XX_R10A_RGB00}, /* matrix */
4762 {0xa0, 0xf8, ZC3XX_R10B_RGB01},
4763 {0xa0, 0xf8, ZC3XX_R10C_RGB02},
4764 {0xa0, 0xf8, ZC3XX_R10D_RGB10},
4765 {0xa0, 0x50, ZC3XX_R10E_RGB11},
4766 {0xa0, 0xf8, ZC3XX_R10F_RGB12},
4767 {0xa0, 0xf8, ZC3XX_R110_RGB20},
4768 {0xa0, 0xf8, ZC3XX_R111_RGB21},
4769 {0xa0, 0x50, ZC3XX_R112_RGB22},
4770 {0xa1, 0x01, 0x0008},
4771 {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* clock ? */
4772 {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */
4773 {0xa1, 0x01, 0x01c8},
4774 {0xa1, 0x01, 0x01c9},
4775 {0xa1, 0x01, 0x01ca},
4776 {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */
4777
4778 {0xa0, 0x50, ZC3XX_R10A_RGB00}, /* matrix */
4779 {0xa0, 0xf8, ZC3XX_R10B_RGB01},
4780 {0xa0, 0xf8, ZC3XX_R10C_RGB02},
4781 {0xa0, 0xf8, ZC3XX_R10D_RGB10},
4782 {0xa0, 0x50, ZC3XX_R10E_RGB11},
4783 {0xa0, 0xf8, ZC3XX_R10F_RGB12},
4784 {0xa0, 0xf8, ZC3XX_R110_RGB20},
4785 {0xa0, 0xf8, ZC3XX_R111_RGB21},
4786 {0xa0, 0x50, ZC3XX_R112_RGB22},
4787 {0xa1, 0x01, 0x0180},
4788 {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
4789 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
4790 {0xaa, 0x05, 0x0066},
4791 {0xaa, 0x09, 0x02b2},
4792 {0xaa, 0x10, 0x0002},
4793
4794 {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN},
4795 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
4796 {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID},
4797 {0xa0, 0x8c, ZC3XX_R192_EXPOSURELIMITLOW},
4798 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
4799 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
4800 {0xa0, 0x8a, ZC3XX_R197_ANTIFLICKERLOW},
4801 {0xa0, 0x10, ZC3XX_R18C_AEFREEZE},
4802 {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE},
4803 {0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF},
4804 {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP},
4805 {0xa0, 0xd7, ZC3XX_R01D_HSYNC_0},
4806 {0xa0, 0xf0, ZC3XX_R01E_HSYNC_1},
4807 {0xa0, 0xf8, ZC3XX_R01F_HSYNC_2},
4808 {0xa0, 0xff, ZC3XX_R020_HSYNC_3},
4809 {0xa0, 0x09, 0x01ad},
4810 {0xa0, 0x15, 0x01ae},
4811 {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE},
4812 {0xa1, 0x01, 0x0180},
4813 {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
4814 {0xa1, 0x01, 0x0008},
4815 {0xa1, 0x01, 0x0007},
4816/* {0xa0, 0x30, 0x0007}, */
4817/* {0xa0, 0x00, 0x0007}, */
4818 {} 4532 {}
4819}; 4533};
4820 4534static const struct usb_action pb0330_InitialScale[] = { /* 320x240 */
4821static const struct usb_action pb0330xx_InitialScale[] = {
4822 {0xa1, 0x01, 0x0008},
4823 {0xa1, 0x01, 0x0008},
4824 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, 4535 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
4825 {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* 00 */ 4536 {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* 00 */
4826 {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, 4537 {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT},
4827 {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT}, /* 10 */ 4538 {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT},
4828 {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, 4539 {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH},
4829 {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, 4540 {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW},
4830 {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, 4541 {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH},
@@ -4836,6 +4547,7 @@ static const struct usb_action pb0330xx_InitialScale[] = {
4836 {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, 4547 {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW},
4837 {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, 4548 {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW},
4838 {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, 4549 {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW},
4550 {0xdd, 0x00, 0x0200},
4839 {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, 4551 {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC},
4840 {0xaa, 0x01, 0x0006}, 4552 {0xaa, 0x01, 0x0006},
4841 {0xaa, 0x02, 0x0011}, 4553 {0xaa, 0x02, 0x0011},
@@ -4858,53 +4570,43 @@ static const struct usb_action pb0330xx_InitialScale[] = {
4858 {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, 4570 {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC},
4859 {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, 4571 {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE},
4860 {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, 4572 {0xa0, 0x06, ZC3XX_R189_AWBSTATUS},
4861 {0xa0, 0x00, 0x01ad}, 4573 {0xa0, 0x09, 0x01ad},
4574 {0xa0, 0x15, 0x01ae},
4862 {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, 4575 {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE},
4863 {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, 4576 {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05},
4864 {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, 4577 {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE},
4865 {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, 4578 {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
4866 {0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN}, 4579 {0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN},
4867 {0xa0, 0x6c, ZC3XX_R18D_YTARGET}, 4580 {0xa0, 0x78, ZC3XX_R18D_YTARGET}, /*jfm: was 6c*/
4868 {0xa1, 0x01, 0x0002}, 4581 {}
4869 {0xa0, 0x09, 0x01ad}, 4582};
4870 {0xa0, 0x15, 0x01ae}, 4583static const struct usb_action pb0330_50HZ[] = {
4871 {0xa0, 0x00, ZC3XX_R092_I2CADDRESSSELECT},
4872 {0xa0, 0x02, ZC3XX_R090_I2CCOMMAND},
4873 {0xa1, 0x01, 0x0091},
4874 {0xa1, 0x01, 0x0095},
4875 {0xa1, 0x01, 0x0096},
4876 {0xa0, 0x50, ZC3XX_R10A_RGB00}, /* matrix */
4877 {0xa0, 0xf8, ZC3XX_R10B_RGB01},
4878 {0xa0, 0xf8, ZC3XX_R10C_RGB02},
4879 {0xa0, 0xf8, ZC3XX_R10D_RGB10},
4880 {0xa0, 0x50, ZC3XX_R10E_RGB11},
4881 {0xa0, 0xf8, ZC3XX_R10F_RGB12},
4882 {0xa0, 0xf8, ZC3XX_R110_RGB20},
4883 {0xa0, 0xf8, ZC3XX_R111_RGB21},
4884 {0xa0, 0x50, ZC3XX_R112_RGB22},
4885 {0xa1, 0x01, 0x0008},
4886 {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* clock ? */
4887 {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */
4888 {0xa1, 0x01, 0x01c8},
4889 {0xa1, 0x01, 0x01c9},
4890 {0xa1, 0x01, 0x01ca},
4891 {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */
4892
4893 {0xa0, 0x50, ZC3XX_R10A_RGB00}, /* matrix */
4894 {0xa0, 0xf8, ZC3XX_R10B_RGB01},
4895 {0xa0, 0xf8, ZC3XX_R10C_RGB02},
4896 {0xa0, 0xf8, ZC3XX_R10D_RGB10},
4897 {0xa0, 0x50, ZC3XX_R10E_RGB11},
4898 {0xa0, 0xf8, ZC3XX_R10F_RGB12},
4899 {0xa0, 0xf8, ZC3XX_R110_RGB20},
4900 {0xa0, 0xf8, ZC3XX_R111_RGB21},
4901 {0xa0, 0x50, ZC3XX_R112_RGB22},
4902 {0xa1, 0x01, 0x0180},
4903 {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
4904 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, 4584 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
4905 {0xaa, 0x05, 0x0066}, 4585 {0xbb, 0x00, 0x055c},
4906 {0xaa, 0x09, 0x02b2}, 4586 {0xbb, 0x01, 0x09aa},
4907 {0xaa, 0x10, 0x0002}, 4587 {0xbb, 0x00, 0x1001},
4588 {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN},
4589 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
4590 {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID},
4591 {0xa0, 0xc4, ZC3XX_R192_EXPOSURELIMITLOW},
4592 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
4593 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
4594 {0xa0, 0x47, ZC3XX_R197_ANTIFLICKERLOW},
4595 {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE},
4596 {0xa0, 0x1a, ZC3XX_R18F_AEUNFREEZE},
4597 {0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF},
4598 {0xa0, 0x66, ZC3XX_R1AA_DIGITALGAINSTEP},
4599 {0xa0, 0x5c, ZC3XX_R01D_HSYNC_0},
4600 {0xa0, 0x90, ZC3XX_R01E_HSYNC_1},
4601 {0xa0, 0xc8, ZC3XX_R01F_HSYNC_2},
4602 {0xa0, 0xff, ZC3XX_R020_HSYNC_3},
4603 {}
4604};
4605static const struct usb_action pb0330_50HZScale[] = {
4606 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
4607 {0xbb, 0x00, 0x0566},
4608 {0xbb, 0x02, 0x09b2},
4609 {0xbb, 0x00, 0x1002},
4908 {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN}, 4610 {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN},
4909 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, 4611 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
4910 {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, 4612 {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID},
@@ -4912,124 +4614,102 @@ static const struct usb_action pb0330xx_InitialScale[] = {
4912 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, 4614 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
4913 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, 4615 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
4914 {0xa0, 0x8a, ZC3XX_R197_ANTIFLICKERLOW}, 4616 {0xa0, 0x8a, ZC3XX_R197_ANTIFLICKERLOW},
4915 {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, 4617 {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE},
4916 {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, 4618 {0xa0, 0x1a, ZC3XX_R18F_AEUNFREEZE},
4917 {0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF}, 4619 {0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF},
4918 {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, 4620 {0xa0, 0x66, ZC3XX_R1AA_DIGITALGAINSTEP},
4919 {0xa0, 0xd7, ZC3XX_R01D_HSYNC_0}, 4621 {0xa0, 0xd7, ZC3XX_R01D_HSYNC_0},
4920 {0xa0, 0xf0, ZC3XX_R01E_HSYNC_1}, 4622 {0xa0, 0xf0, ZC3XX_R01E_HSYNC_1},
4921 {0xa0, 0xf8, ZC3XX_R01F_HSYNC_2}, 4623 {0xa0, 0xf8, ZC3XX_R01F_HSYNC_2},
4922 {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, 4624 {0xa0, 0xff, ZC3XX_R020_HSYNC_3},
4923 {0xa0, 0x09, 0x01ad},
4924 {0xa0, 0x15, 0x01ae},
4925 {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE},
4926 {0xa1, 0x01, 0x0180},
4927 {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
4928 {0xa1, 0x01, 0x0008},
4929 {0xa1, 0x01, 0x0007},
4930/* {0xa0, 0x30, 0x0007}, */
4931/* {0xa0, 0x00, 0x0007}, */
4932 {}
4933};
4934static const struct usb_action pb0330_50HZ[] = {
4935 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
4936 {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,07,cc */
4937 {0xa0, 0xee, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,ee,cc */
4938 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
4939 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
4940 {0xa0, 0x46, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,46,cc */
4941 {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */
4942 {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */
4943 {0xa0, 0x0c, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,0c,cc */
4944 {0xa0, 0x26, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,26,cc */
4945 {0xa0, 0x68, ZC3XX_R01D_HSYNC_0}, /* 00,1d,68,cc */
4946 {0xa0, 0x90, ZC3XX_R01E_HSYNC_1}, /* 00,1e,90,cc */
4947 {0xa0, 0xc8, ZC3XX_R01F_HSYNC_2}, /* 00,1f,c8,cc */
4948 {}
4949};
4950static const struct usb_action pb0330_50HZScale[] = {
4951 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
4952 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
4953 {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,07,cc */
4954 {0xa0, 0xa0, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,a0,cc */
4955 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
4956 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
4957 {0xa0, 0x7a, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,7a,cc */
4958 {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */
4959 {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */
4960 {0xa0, 0x0c, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,0c,cc */
4961 {0xa0, 0x26, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,26,cc */
4962 {0xa0, 0xe5, ZC3XX_R01D_HSYNC_0}, /* 00,1d,e5,cc */
4963 {0xa0, 0xf0, ZC3XX_R01E_HSYNC_1}, /* 00,1e,f0,cc */
4964 {0xa0, 0xf8, ZC3XX_R01F_HSYNC_2}, /* 00,1f,f8,cc */
4965 {} 4625 {}
4966}; 4626};
4967static const struct usb_action pb0330_60HZ[] = { 4627static const struct usb_action pb0330_60HZ[] = {
4968 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ 4628 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
4969 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ 4629 {0xbb, 0x00, 0x0535},
4970 {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,07,cc */ 4630 {0xbb, 0x01, 0x0974},
4971 {0xa0, 0xdd, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,dd,cc */ 4631 {0xbb, 0x00, 0x1001},
4972 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ 4632 {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN},
4973 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ 4633 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
4974 {0xa0, 0x3d, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,3d,cc */ 4634 {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID},
4975 {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ 4635 {0xa0, 0xfe, ZC3XX_R192_EXPOSURELIMITLOW},
4976 {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ 4636 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
4977 {0xa0, 0x0c, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,0c,cc */ 4637 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
4978 {0xa0, 0x26, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,26,cc */ 4638 {0xa0, 0x3e, ZC3XX_R197_ANTIFLICKERLOW},
4979 {0xa0, 0x43, ZC3XX_R01D_HSYNC_0}, /* 00,1d,43,cc */ 4639 {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE},
4980 {0xa0, 0x50, ZC3XX_R01E_HSYNC_1}, /* 00,1e,50,cc */ 4640 {0xa0, 0x1a, ZC3XX_R18F_AEUNFREEZE},
4981 {0xa0, 0x90, ZC3XX_R01F_HSYNC_2}, /* 00,1f,90,cc */ 4641 {0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF},
4642 {0xa0, 0x66, ZC3XX_R1AA_DIGITALGAINSTEP},
4643 {0xa0, 0x35, ZC3XX_R01D_HSYNC_0},
4644 {0xa0, 0x50, ZC3XX_R01E_HSYNC_1},
4645 {0xa0, 0x90, ZC3XX_R01F_HSYNC_2},
4646 {0xa0, 0xd0, ZC3XX_R020_HSYNC_3},
4982 {} 4647 {}
4983}; 4648};
4984static const struct usb_action pb0330_60HZScale[] = { 4649static const struct usb_action pb0330_60HZScale[] = {
4985 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ 4650 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
4986 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ 4651 {0xbb, 0x00, 0x0535},
4987 {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,07,cc */ 4652 {0xbb, 0x02, 0x096c},
4988 {0xa0, 0xa0, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,a0,cc */ 4653 {0xbb, 0x00, 0x1002},
4989 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ 4654 {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN},
4990 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ 4655 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
4991 {0xa0, 0x7a, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,7a,cc */ 4656 {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID},
4992 {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ 4657 {0xa0, 0xc0, ZC3XX_R192_EXPOSURELIMITLOW},
4993 {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ 4658 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
4994 {0xa0, 0x0c, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,0c,cc */ 4659 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
4995 {0xa0, 0x26, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,26,cc */ 4660 {0xa0, 0x7c, ZC3XX_R197_ANTIFLICKERLOW},
4996 {0xa0, 0x41, ZC3XX_R01D_HSYNC_0}, /* 00,1d,41,cc */ 4661 {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE},
4997 {0xa0, 0x50, ZC3XX_R01E_HSYNC_1}, /* 00,1e,50,cc */ 4662 {0xa0, 0x1a, ZC3XX_R18F_AEUNFREEZE},
4998 {0xa0, 0x90, ZC3XX_R01F_HSYNC_2}, /* 00,1f,90,cc */ 4663 {0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF},
4664 {0xa0, 0x66, ZC3XX_R1AA_DIGITALGAINSTEP},
4665 {0xa0, 0x35, ZC3XX_R01D_HSYNC_0},
4666 {0xa0, 0x50, ZC3XX_R01E_HSYNC_1},
4667 {0xa0, 0x90, ZC3XX_R01F_HSYNC_2},
4668 {0xa0, 0xd0, ZC3XX_R020_HSYNC_3},
4999 {} 4669 {}
5000}; 4670};
5001static const struct usb_action pb0330_NoFliker[] = { 4671static const struct usb_action pb0330_NoFliker[] = {
5002 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ 4672 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
5003 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ 4673 {0xbb, 0x00, 0x0509},
5004 {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,07,cc */ 4674 {0xbb, 0x02, 0x0940},
5005 {0xa0, 0xf0, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,f0,cc */ 4675 {0xbb, 0x00, 0x1002},
5006 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ 4676 {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN},
5007 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ 4677 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
5008 {0xa0, 0x10, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,10,cc */ 4678 {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID},
5009 {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ 4679 {0xa0, 0xf0, ZC3XX_R192_EXPOSURELIMITLOW},
5010 {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ 4680 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
5011 {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,00,cc */ 4681 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
5012 {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,00,cc */ 4682 {0xa0, 0x01, ZC3XX_R197_ANTIFLICKERLOW},
5013 {0xa0, 0x09, ZC3XX_R01D_HSYNC_0}, /* 00,1d,09,cc */ 4683 {0xa0, 0x10, ZC3XX_R18C_AEFREEZE},
5014 {0xa0, 0x40, ZC3XX_R01E_HSYNC_1}, /* 00,1e,40,cc */ 4684 {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE},
5015 {0xa0, 0x90, ZC3XX_R01F_HSYNC_2}, /* 00,1f,90,cc */ 4685 {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF},
4686 {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP},
4687 {0xa0, 0x09, ZC3XX_R01D_HSYNC_0},
4688 {0xa0, 0x40, ZC3XX_R01E_HSYNC_1},
4689 {0xa0, 0x90, ZC3XX_R01F_HSYNC_2},
4690 {0xa0, 0xe0, ZC3XX_R020_HSYNC_3},
5016 {} 4691 {}
5017}; 4692};
5018static const struct usb_action pb0330_NoFlikerScale[] = { 4693static const struct usb_action pb0330_NoFlikerScale[] = {
5019 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ 4694 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
5020 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ 4695 {0xbb, 0x00, 0x0535},
5021 {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,07,cc */ 4696 {0xbb, 0x01, 0x0980},
5022 {0xa0, 0xf0, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,f0,cc */ 4697 {0xbb, 0x00, 0x1001},
5023 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ 4698 {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN},
5024 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ 4699 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
5025 {0xa0, 0x10, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,10,cc */ 4700 {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID},
5026 {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ 4701 {0xa0, 0xf0, ZC3XX_R192_EXPOSURELIMITLOW},
5027 {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ 4702 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
5028 {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,00,cc */ 4703 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
5029 {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,00,cc */ 4704 {0xa0, 0x01, ZC3XX_R197_ANTIFLICKERLOW},
5030 {0xa0, 0x09, ZC3XX_R01D_HSYNC_0}, /* 00,1d,09,cc */ 4705 {0xa0, 0x10, ZC3XX_R18C_AEFREEZE},
5031 {0xa0, 0x40, ZC3XX_R01E_HSYNC_1}, /* 00,1e,40,cc */ 4706 {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE},
5032 {0xa0, 0x90, ZC3XX_R01F_HSYNC_2}, /* 00,1f,90,cc */ 4707 {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF},
4708 {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP},
4709 {0xa0, 0x35, ZC3XX_R01D_HSYNC_0},
4710 {0xa0, 0x60, ZC3XX_R01E_HSYNC_1},
4711 {0xa0, 0x90, ZC3XX_R01F_HSYNC_2},
4712 {0xa0, 0xe0, ZC3XX_R020_HSYNC_3},
5033 {} 4713 {}
5034}; 4714};
5035 4715
@@ -5655,7 +5335,7 @@ static const struct usb_action tas5130CK_InitialScale[] = {
5655 {} 5335 {}
5656}; 5336};
5657 5337
5658static const struct usb_action tas5130cxx_Initial[] = { 5338static const struct usb_action tas5130cxx_InitialScale[] = { /* 320x240 */
5659 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, 5339 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
5660 {0xa0, 0x50, ZC3XX_R002_CLOCKSELECT}, 5340 {0xa0, 0x50, ZC3XX_R002_CLOCKSELECT},
5661 {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, 5341 {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
@@ -5684,74 +5364,19 @@ static const struct usb_action tas5130cxx_Initial[] = {
5684 {0xa0, 0xf7, ZC3XX_R101_SENSORCORRECTION}, 5364 {0xa0, 0xf7, ZC3XX_R101_SENSORCORRECTION},
5685 {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, 5365 {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE},
5686 {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, 5366 {0xa0, 0x06, ZC3XX_R189_AWBSTATUS},
5687 {0xa0, 0x68, ZC3XX_R18D_YTARGET}, 5367 {0xa0, 0x95, ZC3XX_R18D_YTARGET},
5688 {0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN}, 5368 {0xa0, 0x50, ZC3XX_R1A8_DIGITALGAIN},
5689 {0xa0, 0x00, 0x01ad}, 5369 {0xa0, 0x00, 0x01ad},
5690 {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, 5370 {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE},
5691 {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, 5371 {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05},
5692 {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, 5372 {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE},
5693 {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, 5373 {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
5694 {0xa1, 0x01, 0x0002},
5695 {0xa1, 0x01, 0x0008},
5696 {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* clock ? */
5697 {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */
5698 {0xa1, 0x01, 0x01c8},
5699 {0xa1, 0x01, 0x01c9},
5700 {0xa1, 0x01, 0x01ca},
5701 {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */
5702
5703 {0xa0, 0x68, ZC3XX_R10A_RGB00}, /* matrix */
5704 {0xa0, 0xec, ZC3XX_R10B_RGB01},
5705 {0xa0, 0xec, ZC3XX_R10C_RGB02},
5706 {0xa0, 0xec, ZC3XX_R10D_RGB10},
5707 {0xa0, 0x68, ZC3XX_R10E_RGB11},
5708 {0xa0, 0xec, ZC3XX_R10F_RGB12},
5709 {0xa0, 0xec, ZC3XX_R110_RGB20},
5710 {0xa0, 0xec, ZC3XX_R111_RGB21},
5711 {0xa0, 0x68, ZC3XX_R112_RGB22},
5712
5713 {0xa1, 0x01, 0x018d},
5714 {0xa0, 0x90, ZC3XX_R18D_YTARGET}, /* 90 */
5715 {0xa1, 0x01, 0x0180},
5716 {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
5717 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
5718
5719 {0xaa, 0xa3, 0x0001},
5720 {0xaa, 0xa4, 0x0077},
5721 {0xa0, 0x01, ZC3XX_R0A3_EXPOSURETIMEHIGH},
5722 {0xa0, 0x77, ZC3XX_R0A4_EXPOSURETIMELOW},
5723
5724 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 00 */
5725 {0xa0, 0x03, ZC3XX_R191_EXPOSURELIMITMID}, /* 03 */
5726 {0xa0, 0xe8, ZC3XX_R192_EXPOSURELIMITLOW}, /* e8 */
5727 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 0 */
5728 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 0 */
5729 {0xa0, 0x7d, ZC3XX_R197_ANTIFLICKERLOW}, /* 7d */
5730
5731 {0xa0, 0x0c, ZC3XX_R18C_AEFREEZE},
5732 {0xa0, 0x18, ZC3XX_R18F_AEUNFREEZE},
5733 {0xa0, 0x08, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 08 */
5734 {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 24 */
5735 {0xa0, 0xf0, ZC3XX_R01D_HSYNC_0},
5736 {0xa0, 0xf4, ZC3XX_R01E_HSYNC_1},
5737 {0xa0, 0xf8, ZC3XX_R01F_HSYNC_2},
5738 {0xa0, 0xff, ZC3XX_R020_HSYNC_3},
5739 {0xa0, 0x03, ZC3XX_R09F_MAXXHIGH},
5740 {0xa0, 0xc0, ZC3XX_R0A0_MAXXLOW},
5741 {0xa0, 0x50, ZC3XX_R11D_GLOBALGAIN}, /* 50 */
5742 {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE},
5743 {0xa1, 0x01, 0x0180},
5744 {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
5745 {} 5374 {}
5746}; 5375};
5747static const struct usb_action tas5130cxx_InitialScale[] = { 5376static const struct usb_action tas5130cxx_Initial[] = { /* 640x480 */
5748/*?? {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, */
5749 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, 5377 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
5750 {0xa0, 0x40, ZC3XX_R002_CLOCKSELECT}, 5378 {0xa0, 0x40, ZC3XX_R002_CLOCKSELECT},
5751
5752 {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, 5379 {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
5753 {0xa1, 0x01, 0x0008},
5754
5755 {0xa0, 0x02, ZC3XX_R010_CMOSSENSORSELECT}, 5380 {0xa0, 0x02, ZC3XX_R010_CMOSSENSORSELECT},
5756 {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, 5381 {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING},
5757 {0xa0, 0x00, ZC3XX_R001_SYSTEMOPERATING}, 5382 {0xa0, 0x00, ZC3XX_R001_SYSTEMOPERATING},
@@ -5775,63 +5400,13 @@ static const struct usb_action tas5130cxx_InitialScale[] = {
5775 {0xa0, 0x37, ZC3XX_R101_SENSORCORRECTION}, 5400 {0xa0, 0x37, ZC3XX_R101_SENSORCORRECTION},
5776 {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, 5401 {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE},
5777 {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, 5402 {0xa0, 0x06, ZC3XX_R189_AWBSTATUS},
5778 {0xa0, 0x68, ZC3XX_R18D_YTARGET}, 5403 {0xa0, 0x95, ZC3XX_R18D_YTARGET},
5779 {0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN}, 5404 {0xa0, 0x50, ZC3XX_R1A8_DIGITALGAIN},
5780 {0xa0, 0x00, 0x01ad}, 5405 {0xa0, 0x00, 0x01ad},
5781 {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, 5406 {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE},
5782 {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, 5407 {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05},
5783 {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, 5408 {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE},
5784 {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, 5409 {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
5785 {0xa1, 0x01, 0x0002},
5786 {0xa1, 0x01, 0x0008},
5787
5788 {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
5789 {0xa1, 0x01, 0x0008}, /* clock ? */
5790 {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */
5791 {0xa1, 0x01, 0x01c8},
5792 {0xa1, 0x01, 0x01c9},
5793 {0xa1, 0x01, 0x01ca},
5794 {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */
5795
5796 {0xa0, 0x68, ZC3XX_R10A_RGB00}, /* matrix */
5797 {0xa0, 0xec, ZC3XX_R10B_RGB01},
5798 {0xa0, 0xec, ZC3XX_R10C_RGB02},
5799 {0xa0, 0xec, ZC3XX_R10D_RGB10},
5800 {0xa0, 0x68, ZC3XX_R10E_RGB11},
5801 {0xa0, 0xec, ZC3XX_R10F_RGB12},
5802 {0xa0, 0xec, ZC3XX_R110_RGB20},
5803 {0xa0, 0xec, ZC3XX_R111_RGB21},
5804 {0xa0, 0x68, ZC3XX_R112_RGB22},
5805
5806 {0xa1, 0x01, 0x018d},
5807 {0xa0, 0x90, ZC3XX_R18D_YTARGET},
5808 {0xa1, 0x01, 0x0180},
5809 {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
5810 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
5811 {0xaa, 0xa3, 0x0001},
5812 {0xaa, 0xa4, 0x0063},
5813 {0xa0, 0x01, ZC3XX_R0A3_EXPOSURETIMEHIGH},
5814 {0xa0, 0x63, ZC3XX_R0A4_EXPOSURETIMELOW},
5815 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
5816 {0xa0, 0x02, ZC3XX_R191_EXPOSURELIMITMID},
5817 {0xa0, 0x38, ZC3XX_R192_EXPOSURELIMITLOW},
5818 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
5819 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
5820 {0xa0, 0x47, ZC3XX_R197_ANTIFLICKERLOW},
5821 {0xa0, 0x0c, ZC3XX_R18C_AEFREEZE},
5822 {0xa0, 0x18, ZC3XX_R18F_AEUNFREEZE},
5823 {0xa0, 0x08, ZC3XX_R1A9_DIGITALLIMITDIFF},
5824 {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP},
5825 {0xa0, 0xd3, ZC3XX_R01D_HSYNC_0},
5826 {0xa0, 0xda, ZC3XX_R01E_HSYNC_1},
5827 {0xa0, 0xea, ZC3XX_R01F_HSYNC_2},
5828 {0xa0, 0xff, ZC3XX_R020_HSYNC_3},
5829 {0xa0, 0x03, ZC3XX_R09F_MAXXHIGH},
5830 {0xa0, 0x4c, ZC3XX_R0A0_MAXXLOW},
5831 {0xa0, 0x50, ZC3XX_R11D_GLOBALGAIN},
5832 {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE},
5833 {0xa1, 0x01, 0x0180},
5834 {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
5835 {} 5410 {}
5836}; 5411};
5837static const struct usb_action tas5130cxx_50HZ[] = { 5412static const struct usb_action tas5130cxx_50HZ[] = {
@@ -5841,20 +5416,22 @@ static const struct usb_action tas5130cxx_50HZ[] = {
5841 {0xa0, 0x01, ZC3XX_R0A3_EXPOSURETIMEHIGH}, /* 00,a3,01,cc */ 5416 {0xa0, 0x01, ZC3XX_R0A3_EXPOSURETIMEHIGH}, /* 00,a3,01,cc */
5842 {0xa0, 0x63, ZC3XX_R0A4_EXPOSURETIMELOW}, /* 00,a4,63,cc */ 5417 {0xa0, 0x63, ZC3XX_R0A4_EXPOSURETIMELOW}, /* 00,a4,63,cc */
5843 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ 5418 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
5844 {0xa0, 0x02, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,02,cc */ 5419 {0xa0, 0x04, ZC3XX_R191_EXPOSURELIMITMID},
5845 {0xa0, 0x38, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,38,cc */ 5420 {0xa0, 0xfe, ZC3XX_R192_EXPOSURELIMITLOW},
5846 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ 5421 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
5847 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ 5422 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
5848 {0xa0, 0x47, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,47,cc */ 5423 {0xa0, 0x47, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,47,cc */
5849 {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ 5424 {0xa0, 0x0c, ZC3XX_R18C_AEFREEZE},
5850 {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ 5425 {0xa0, 0x18, ZC3XX_R18F_AEUNFREEZE},
5851 {0xa0, 0x0c, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,0c,cc */ 5426 {0xa0, 0x08, ZC3XX_R1A9_DIGITALLIMITDIFF},
5852 {0xa0, 0x26, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,26,cc */ 5427 {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP},
5853 {0xa0, 0xd3, ZC3XX_R01D_HSYNC_0}, /* 00,1d,d3,cc */ 5428 {0xa0, 0xd3, ZC3XX_R01D_HSYNC_0}, /* 00,1d,d3,cc */
5854 {0xa0, 0xda, ZC3XX_R01E_HSYNC_1}, /* 00,1e,da,cc */ 5429 {0xa0, 0xda, ZC3XX_R01E_HSYNC_1}, /* 00,1e,da,cc */
5855 {0xa0, 0xea, ZC3XX_R01F_HSYNC_2}, /* 00,1f,ea,cc */ 5430 {0xa0, 0xea, ZC3XX_R01F_HSYNC_2}, /* 00,1f,ea,cc */
5856 {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */ 5431 {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */
5857 {0xa0, 0x03, ZC3XX_R09F_MAXXHIGH}, /* 00,9f,03,cc */ 5432 {0xa0, 0x03, ZC3XX_R09F_MAXXHIGH}, /* 00,9f,03,cc */
5433 {0xa0, 0x4c, ZC3XX_R0A0_MAXXLOW},
5434 {0xa0, 0x50, ZC3XX_R11D_GLOBALGAIN},
5858 {} 5435 {}
5859}; 5436};
5860static const struct usb_action tas5130cxx_50HZScale[] = { 5437static const struct usb_action tas5130cxx_50HZScale[] = {
@@ -5864,20 +5441,22 @@ static const struct usb_action tas5130cxx_50HZScale[] = {
5864 {0xa0, 0x01, ZC3XX_R0A3_EXPOSURETIMEHIGH}, /* 00,a3,01,cc */ 5441 {0xa0, 0x01, ZC3XX_R0A3_EXPOSURETIMEHIGH}, /* 00,a3,01,cc */
5865 {0xa0, 0x77, ZC3XX_R0A4_EXPOSURETIMELOW}, /* 00,a4,77,cc */ 5442 {0xa0, 0x77, ZC3XX_R0A4_EXPOSURETIMELOW}, /* 00,a4,77,cc */
5866 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ 5443 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
5867 {0xa0, 0x03, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,03,cc */ 5444 {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID},
5868 {0xa0, 0xe8, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,e8,cc */ 5445 {0xa0, 0xd0, ZC3XX_R192_EXPOSURELIMITLOW},
5869 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ 5446 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
5870 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ 5447 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
5871 {0xa0, 0x7d, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,7d,cc */ 5448 {0xa0, 0x7d, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,7d,cc */
5872 {0xa0, 0x14, ZC3XX_R18C_AEFREEZE}, /* 01,8c,14,cc */ 5449 {0xa0, 0x0c, ZC3XX_R18C_AEFREEZE},
5873 {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ 5450 {0xa0, 0x18, ZC3XX_R18F_AEUNFREEZE},
5874 {0xa0, 0x0c, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,0c,cc */ 5451 {0xa0, 0x08, ZC3XX_R1A9_DIGITALLIMITDIFF},
5875 {0xa0, 0x26, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,26,cc */ 5452 {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP},
5876 {0xa0, 0xf0, ZC3XX_R01D_HSYNC_0}, /* 00,1d,f0,cc */ 5453 {0xa0, 0xf0, ZC3XX_R01D_HSYNC_0}, /* 00,1d,f0,cc */
5877 {0xa0, 0xf4, ZC3XX_R01E_HSYNC_1}, /* 00,1e,f4,cc */ 5454 {0xa0, 0xf4, ZC3XX_R01E_HSYNC_1}, /* 00,1e,f4,cc */
5878 {0xa0, 0xf8, ZC3XX_R01F_HSYNC_2}, /* 00,1f,f8,cc */ 5455 {0xa0, 0xf8, ZC3XX_R01F_HSYNC_2}, /* 00,1f,f8,cc */
5879 {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */ 5456 {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */
5880 {0xa0, 0x03, ZC3XX_R09F_MAXXHIGH}, /* 00,9f,03,cc */ 5457 {0xa0, 0x03, ZC3XX_R09F_MAXXHIGH}, /* 00,9f,03,cc */
5458 {0xa0, 0xc0, ZC3XX_R0A0_MAXXLOW},
5459 {0xa0, 0x50, ZC3XX_R11D_GLOBALGAIN},
5881 {} 5460 {}
5882}; 5461};
5883static const struct usb_action tas5130cxx_60HZ[] = { 5462static const struct usb_action tas5130cxx_60HZ[] = {
@@ -5887,20 +5466,22 @@ static const struct usb_action tas5130cxx_60HZ[] = {
5887 {0xa0, 0x01, ZC3XX_R0A3_EXPOSURETIMEHIGH}, /* 00,a3,01,cc */ 5466 {0xa0, 0x01, ZC3XX_R0A3_EXPOSURETIMEHIGH}, /* 00,a3,01,cc */
5888 {0xa0, 0x36, ZC3XX_R0A4_EXPOSURETIMELOW}, /* 00,a4,36,cc */ 5467 {0xa0, 0x36, ZC3XX_R0A4_EXPOSURETIMELOW}, /* 00,a4,36,cc */
5889 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ 5468 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
5890 {0xa0, 0x01, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,01,cc */ 5469 {0xa0, 0x05, ZC3XX_R191_EXPOSURELIMITMID},
5891 {0xa0, 0xf0, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,f0,cc */ 5470 {0xa0, 0x54, ZC3XX_R192_EXPOSURELIMITLOW},
5892 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ 5471 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
5893 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ 5472 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
5894 {0xa0, 0x3e, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,3e,cc */ 5473 {0xa0, 0x3e, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,3e,cc */
5895 {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ 5474 {0xa0, 0x0c, ZC3XX_R18C_AEFREEZE},
5896 {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ 5475 {0xa0, 0x18, ZC3XX_R18F_AEUNFREEZE},
5897 {0xa0, 0x0c, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,0c,cc */ 5476 {0xa0, 0x08, ZC3XX_R1A9_DIGITALLIMITDIFF},
5898 {0xa0, 0x26, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,26,cc */ 5477 {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP},
5899 {0xa0, 0xca, ZC3XX_R01D_HSYNC_0}, /* 00,1d,ca,cc */ 5478 {0xa0, 0xca, ZC3XX_R01D_HSYNC_0}, /* 00,1d,ca,cc */
5900 {0xa0, 0xd0, ZC3XX_R01E_HSYNC_1}, /* 00,1e,d0,cc */ 5479 {0xa0, 0xd0, ZC3XX_R01E_HSYNC_1}, /* 00,1e,d0,cc */
5901 {0xa0, 0xe0, ZC3XX_R01F_HSYNC_2}, /* 00,1f,e0,cc */ 5480 {0xa0, 0xe0, ZC3XX_R01F_HSYNC_2}, /* 00,1f,e0,cc */
5902 {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */ 5481 {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */
5903 {0xa0, 0x03, ZC3XX_R09F_MAXXHIGH}, /* 00,9f,03,cc */ 5482 {0xa0, 0x03, ZC3XX_R09F_MAXXHIGH}, /* 00,9f,03,cc */
5483 {0xa0, 0x28, ZC3XX_R0A0_MAXXLOW},
5484 {0xa0, 0x50, ZC3XX_R11D_GLOBALGAIN},
5904 {} 5485 {}
5905}; 5486};
5906static const struct usb_action tas5130cxx_60HZScale[] = { 5487static const struct usb_action tas5130cxx_60HZScale[] = {
@@ -5910,20 +5491,22 @@ static const struct usb_action tas5130cxx_60HZScale[] = {
5910 {0xa0, 0x01, ZC3XX_R0A3_EXPOSURETIMEHIGH}, /* 00,a3,01,cc */ 5491 {0xa0, 0x01, ZC3XX_R0A3_EXPOSURETIMEHIGH}, /* 00,a3,01,cc */
5911 {0xa0, 0x77, ZC3XX_R0A4_EXPOSURETIMELOW}, /* 00,a4,77,cc */ 5492 {0xa0, 0x77, ZC3XX_R0A4_EXPOSURETIMELOW}, /* 00,a4,77,cc */
5912 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ 5493 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
5913 {0xa0, 0x03, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,03,cc */ 5494 {0xa0, 0x09, ZC3XX_R191_EXPOSURELIMITMID},
5914 {0xa0, 0xe8, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,e8,cc */ 5495 {0xa0, 0x47, ZC3XX_R192_EXPOSURELIMITLOW},
5915 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ 5496 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
5916 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ 5497 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
5917 {0xa0, 0x7d, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,7d,cc */ 5498 {0xa0, 0x7d, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,7d,cc */
5918 {0xa0, 0x14, ZC3XX_R18C_AEFREEZE}, /* 01,8c,14,cc */ 5499 {0xa0, 0x0c, ZC3XX_R18C_AEFREEZE},
5919 {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ 5500 {0xa0, 0x18, ZC3XX_R18F_AEUNFREEZE},
5920 {0xa0, 0x0c, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,0c,cc */ 5501 {0xa0, 0x08, ZC3XX_R1A9_DIGITALLIMITDIFF},
5921 {0xa0, 0x26, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,26,cc */ 5502 {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP},
5922 {0xa0, 0xc8, ZC3XX_R01D_HSYNC_0}, /* 00,1d,c8,cc */ 5503 {0xa0, 0xc8, ZC3XX_R01D_HSYNC_0}, /* 00,1d,c8,cc */
5923 {0xa0, 0xd0, ZC3XX_R01E_HSYNC_1}, /* 00,1e,d0,cc */ 5504 {0xa0, 0xd0, ZC3XX_R01E_HSYNC_1}, /* 00,1e,d0,cc */
5924 {0xa0, 0xe0, ZC3XX_R01F_HSYNC_2}, /* 00,1f,e0,cc */ 5505 {0xa0, 0xe0, ZC3XX_R01F_HSYNC_2}, /* 00,1f,e0,cc */
5925 {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */ 5506 {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */
5926 {0xa0, 0x03, ZC3XX_R09F_MAXXHIGH}, /* 00,9f,03,cc */ 5507 {0xa0, 0x03, ZC3XX_R09F_MAXXHIGH}, /* 00,9f,03,cc */
5508 {0xa0, 0x20, ZC3XX_R0A0_MAXXLOW},
5509 {0xa0, 0x50, ZC3XX_R11D_GLOBALGAIN},
5927 {} 5510 {}
5928}; 5511};
5929static const struct usb_action tas5130cxx_NoFliker[] = { 5512static const struct usb_action tas5130cxx_NoFliker[] = {
@@ -5933,13 +5516,13 @@ static const struct usb_action tas5130cxx_NoFliker[] = {
5933 {0xa0, 0x01, ZC3XX_R0A3_EXPOSURETIMEHIGH}, /* 00,a3,01,cc */ 5516 {0xa0, 0x01, ZC3XX_R0A3_EXPOSURETIMEHIGH}, /* 00,a3,01,cc */
5934 {0xa0, 0x40, ZC3XX_R0A4_EXPOSURETIMELOW}, /* 00,a4,40,cc */ 5517 {0xa0, 0x40, ZC3XX_R0A4_EXPOSURETIMELOW}, /* 00,a4,40,cc */
5935 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ 5518 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
5936 {0xa0, 0x01, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,01,cc */ 5519 {0xa0, 0x05, ZC3XX_R191_EXPOSURELIMITMID},
5937 {0xa0, 0xf0, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,f0,cc */ 5520 {0xa0, 0xa0, ZC3XX_R192_EXPOSURELIMITLOW},
5938 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ 5521 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
5939 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ 5522 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
5940 {0xa0, 0x10, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,10,cc */ 5523 {0xa0, 0x04, ZC3XX_R197_ANTIFLICKERLOW},
5941 {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ 5524 {0xa0, 0x0c, ZC3XX_R18C_AEFREEZE},
5942 {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ 5525 {0xa0, 0x18, ZC3XX_R18F_AEUNFREEZE},
5943 {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,00,cc */ 5526 {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,00,cc */
5944 {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,00,cc */ 5527 {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,00,cc */
5945 {0xa0, 0xbc, ZC3XX_R01D_HSYNC_0}, /* 00,1d,bc,cc */ 5528 {0xa0, 0xbc, ZC3XX_R01D_HSYNC_0}, /* 00,1d,bc,cc */
@@ -5947,6 +5530,8 @@ static const struct usb_action tas5130cxx_NoFliker[] = {
5947 {0xa0, 0xe0, ZC3XX_R01F_HSYNC_2}, /* 00,1f,e0,cc */ 5530 {0xa0, 0xe0, ZC3XX_R01F_HSYNC_2}, /* 00,1f,e0,cc */
5948 {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */ 5531 {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */
5949 {0xa0, 0x02, ZC3XX_R09F_MAXXHIGH}, /* 00,9f,02,cc */ 5532 {0xa0, 0x02, ZC3XX_R09F_MAXXHIGH}, /* 00,9f,02,cc */
5533 {0xa0, 0xf0, ZC3XX_R0A0_MAXXLOW},
5534 {0xa0, 0x50, ZC3XX_R11D_GLOBALGAIN},
5950 {} 5535 {}
5951}; 5536};
5952 5537
@@ -5957,13 +5542,13 @@ static const struct usb_action tas5130cxx_NoFlikerScale[] = {
5957 {0xa0, 0x01, ZC3XX_R0A3_EXPOSURETIMEHIGH}, /* 00,a3,01,cc */ 5542 {0xa0, 0x01, ZC3XX_R0A3_EXPOSURETIMEHIGH}, /* 00,a3,01,cc */
5958 {0xa0, 0x90, ZC3XX_R0A4_EXPOSURETIMELOW}, /* 00,a4,90,cc */ 5543 {0xa0, 0x90, ZC3XX_R0A4_EXPOSURETIMELOW}, /* 00,a4,90,cc */
5959 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ 5544 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
5960 {0xa0, 0x03, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,03,cc */ 5545 {0xa0, 0x0a, ZC3XX_R191_EXPOSURELIMITMID},
5961 {0xa0, 0xf0, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,f0,cc */ 5546 {0xa0, 0x00, ZC3XX_R192_EXPOSURELIMITLOW},
5962 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ 5547 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
5963 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ 5548 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
5964 {0xa0, 0x10, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,10,cc */ 5549 {0xa0, 0x04, ZC3XX_R197_ANTIFLICKERLOW},
5965 {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ 5550 {0xa0, 0x0c, ZC3XX_R18C_AEFREEZE},
5966 {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ 5551 {0xa0, 0x18, ZC3XX_R18F_AEUNFREEZE},
5967 {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,00,cc */ 5552 {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,00,cc */
5968 {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,00,cc */ 5553 {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,00,cc */
5969 {0xa0, 0xbc, ZC3XX_R01D_HSYNC_0}, /* 00,1d,bc,cc */ 5554 {0xa0, 0xbc, ZC3XX_R01D_HSYNC_0}, /* 00,1d,bc,cc */
@@ -5971,6 +5556,8 @@ static const struct usb_action tas5130cxx_NoFlikerScale[] = {
5971 {0xa0, 0xe0, ZC3XX_R01F_HSYNC_2}, /* 00,1f,e0,cc */ 5556 {0xa0, 0xe0, ZC3XX_R01F_HSYNC_2}, /* 00,1f,e0,cc */
5972 {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */ 5557 {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */
5973 {0xa0, 0x02, ZC3XX_R09F_MAXXHIGH}, /* 00,9f,02,cc */ 5558 {0xa0, 0x02, ZC3XX_R09F_MAXXHIGH}, /* 00,9f,02,cc */
5559 {0xa0, 0xf0, ZC3XX_R0A0_MAXXLOW},
5560 {0xa0, 0x50, ZC3XX_R11D_GLOBALGAIN},
5974 {} 5561 {}
5975}; 5562};
5976 5563
@@ -6303,8 +5890,10 @@ static __u16 i2c_read(struct gspca_dev *gspca_dev,
6303 5890
6304 reg_w_i(gspca_dev->dev, reg, 0x0092); 5891 reg_w_i(gspca_dev->dev, reg, 0x0092);
6305 reg_w_i(gspca_dev->dev, 0x02, 0x0090); /* <- read command */ 5892 reg_w_i(gspca_dev->dev, 0x02, 0x0090); /* <- read command */
6306 msleep(25); 5893 msleep(20);
6307 retbyte = reg_r_i(gspca_dev, 0x0091); /* read status */ 5894 retbyte = reg_r_i(gspca_dev, 0x0091); /* read status */
5895 if (retbyte != 0x00)
5896 err("i2c_r status error %02x", retbyte);
6308 retval = reg_r_i(gspca_dev, 0x0095); /* read Lowbyte */ 5897 retval = reg_r_i(gspca_dev, 0x0095); /* read Lowbyte */
6309 retval |= reg_r_i(gspca_dev, 0x0096) << 8; /* read Hightbyte */ 5898 retval |= reg_r_i(gspca_dev, 0x0096) << 8; /* read Hightbyte */
6310 PDEBUG(D_USBI, "i2c r [%02x] -> %04x (%02x)", 5899 PDEBUG(D_USBI, "i2c r [%02x] -> %04x (%02x)",
@@ -6323,8 +5912,10 @@ static __u8 i2c_write(struct gspca_dev *gspca_dev,
6323 reg_w_i(gspca_dev->dev, valL, 0x93); 5912 reg_w_i(gspca_dev->dev, valL, 0x93);
6324 reg_w_i(gspca_dev->dev, valH, 0x94); 5913 reg_w_i(gspca_dev->dev, valH, 0x94);
6325 reg_w_i(gspca_dev->dev, 0x01, 0x90); /* <- write command */ 5914 reg_w_i(gspca_dev->dev, 0x01, 0x90); /* <- write command */
6326 msleep(15); 5915 msleep(1);
6327 retbyte = reg_r_i(gspca_dev, 0x0091); /* read status */ 5916 retbyte = reg_r_i(gspca_dev, 0x0091); /* read status */
5917 if (retbyte != 0x00)
5918 err("i2c_w status error %02x", retbyte);
6328 PDEBUG(D_USBO, "i2c w [%02x] = %02x%02x (%02x)", 5919 PDEBUG(D_USBO, "i2c w [%02x] = %02x%02x (%02x)",
6329 reg, valH, valL, retbyte); 5920 reg, valH, valL, retbyte);
6330 return retbyte; 5921 return retbyte;
@@ -6359,7 +5950,7 @@ static void usb_exchange(struct gspca_dev *gspca_dev,
6359 break; 5950 break;
6360 } 5951 }
6361 action++; 5952 action++;
6362/* msleep(1); */ 5953 msleep(1);
6363 } 5954 }
6364} 5955}
6365 5956
@@ -6380,11 +5971,13 @@ static void setmatrix(struct gspca_dev *gspca_dev)
6380 {0x4c, 0xf5, 0xff, 0xf9, 0x51, 0xf5, 0xfb, 0xed, 0x5f}; 5971 {0x4c, 0xf5, 0xff, 0xf9, 0x51, 0xf5, 0xfb, 0xed, 0x5f};
6381 static const __u8 po2030_matrix[9] = 5972 static const __u8 po2030_matrix[9] =
6382 {0x60, 0xf0, 0xf0, 0xf0, 0x60, 0xf0, 0xf0, 0xf0, 0x60}; 5973 {0x60, 0xf0, 0xf0, 0xf0, 0x60, 0xf0, 0xf0, 0xf0, 0x60};
5974 static const u8 tas5130c_matrix[9] =
5975 {0x68, 0xec, 0xec, 0xec, 0x68, 0xec, 0xec, 0xec, 0x68};
6383 static const __u8 vf0250_matrix[9] = 5976 static const __u8 vf0250_matrix[9] =
6384 {0x7b, 0xea, 0xea, 0xea, 0x7b, 0xea, 0xea, 0xea, 0x7b}; 5977 {0x7b, 0xea, 0xea, 0xea, 0x7b, 0xea, 0xea, 0xea, 0x7b};
6385 static const __u8 *matrix_tb[SENSOR_MAX] = { 5978 static const __u8 *matrix_tb[SENSOR_MAX] = {
6386 adcm2700_matrix, /* SENSOR_ADCM2700 0 */ 5979 adcm2700_matrix, /* SENSOR_ADCM2700 0 */
6387 NULL, /* SENSOR_CS2102 1 */ 5980 ov7620_matrix, /* SENSOR_CS2102 1 */
6388 NULL, /* SENSOR_CS2102K 2 */ 5981 NULL, /* SENSOR_CS2102K 2 */
6389 gc0305_matrix, /* SENSOR_GC0305 3 */ 5982 gc0305_matrix, /* SENSOR_GC0305 3 */
6390 NULL, /* SENSOR_HDCS2020b 4 */ 5983 NULL, /* SENSOR_HDCS2020b 4 */
@@ -6392,15 +5985,16 @@ static void setmatrix(struct gspca_dev *gspca_dev)
6392 NULL, /* SENSOR_HV7131C 6 */ 5985 NULL, /* SENSOR_HV7131C 6 */
6393 NULL, /* SENSOR_ICM105A 7 */ 5986 NULL, /* SENSOR_ICM105A 7 */
6394 NULL, /* SENSOR_MC501CB 8 */ 5987 NULL, /* SENSOR_MC501CB 8 */
6395 ov7620_matrix, /* SENSOR_OV7620 9 */ 5988 gc0305_matrix, /* SENSOR_MI0360SOC 9 */
6396 NULL, /* SENSOR_OV7630C 10 */ 5989 ov7620_matrix, /* SENSOR_OV7620 10 */
6397 NULL, /* SENSOR_PAS106 11 */ 5990 NULL, /* SENSOR_OV7630C 11 */
6398 pas202b_matrix, /* SENSOR_PAS202B 12 */ 5991 NULL, /* SENSOR_PAS106 12 */
6399 NULL, /* SENSOR_PB0330 13 */ 5992 pas202b_matrix, /* SENSOR_PAS202B 13 */
6400 po2030_matrix, /* SENSOR_PO2030 14 */ 5993 gc0305_matrix, /* SENSOR_PB0330 14 */
6401 NULL, /* SENSOR_TAS5130CK 15 */ 5994 po2030_matrix, /* SENSOR_PO2030 15 */
6402 NULL, /* SENSOR_TAS5130CXX 16 */ 5995 NULL, /* SENSOR_TAS5130CK 16 */
6403 vf0250_matrix, /* SENSOR_TAS5130C_VF0250 17 */ 5996 tas5130c_matrix, /* SENSOR_TAS5130CXX 17 */
5997 vf0250_matrix, /* SENSOR_TAS5130C_VF0250 18 */
6404 }; 5998 };
6405 5999
6406 matrix = matrix_tb[sd->sensor]; 6000 matrix = matrix_tb[sd->sensor];
@@ -6640,39 +6234,43 @@ static int setlightfreq(struct gspca_dev *gspca_dev)
6640 {MC501CB_NoFliker, MC501CB_NoFlikerScale, 6234 {MC501CB_NoFliker, MC501CB_NoFlikerScale,
6641 MC501CB_50HZ, MC501CB_50HZScale, 6235 MC501CB_50HZ, MC501CB_50HZScale,
6642 MC501CB_60HZ, MC501CB_60HZScale}, 6236 MC501CB_60HZ, MC501CB_60HZScale},
6643/* SENSOR_OV7620 9 */ 6237/* SENSOR_MI0360SOC 9 */
6238 {mi360soc_AENoFlikerScale, mi360soc_AENoFliker,
6239 mi360soc_AE50HZScale, mi360soc_AE50HZ,
6240 mi360soc_AE60HZScale, mi360soc_AE60HZ},
6241/* SENSOR_OV7620 10 */
6644 {OV7620_NoFliker, OV7620_NoFliker, 6242 {OV7620_NoFliker, OV7620_NoFliker,
6645 OV7620_50HZ, OV7620_50HZ, 6243 OV7620_50HZ, OV7620_50HZ,
6646 OV7620_60HZ, OV7620_60HZ}, 6244 OV7620_60HZ, OV7620_60HZ},
6647/* SENSOR_OV7630C 10 */ 6245/* SENSOR_OV7630C 11 */
6648 {NULL, NULL, 6246 {NULL, NULL,
6649 NULL, NULL, 6247 NULL, NULL,
6650 NULL, NULL}, 6248 NULL, NULL},
6651/* SENSOR_PAS106 11 */ 6249/* SENSOR_PAS106 12 */
6652 {pas106b_NoFliker, pas106b_NoFliker, 6250 {pas106b_NoFliker, pas106b_NoFliker,
6653 pas106b_50HZ, pas106b_50HZ, 6251 pas106b_50HZ, pas106b_50HZ,
6654 pas106b_60HZ, pas106b_60HZ}, 6252 pas106b_60HZ, pas106b_60HZ},
6655/* SENSOR_PAS202B 12 */ 6253/* SENSOR_PAS202B 13 */
6656 {pas202b_NoFlikerScale, pas202b_NoFliker, 6254 {pas202b_NoFlikerScale, pas202b_NoFliker,
6657 pas202b_50HZScale, pas202b_50HZ, 6255 pas202b_50HZScale, pas202b_50HZ,
6658 pas202b_60HZScale, pas202b_60HZ}, 6256 pas202b_60HZScale, pas202b_60HZ},
6659/* SENSOR_PB0330 13 */ 6257/* SENSOR_PB0330 14 */
6660 {pb0330_NoFliker, pb0330_NoFlikerScale, 6258 {pb0330_NoFlikerScale, pb0330_NoFliker,
6661 pb0330_50HZ, pb0330_50HZScale, 6259 pb0330_50HZScale, pb0330_50HZ,
6662 pb0330_60HZ, pb0330_60HZScale}, 6260 pb0330_60HZScale, pb0330_60HZ},
6663/* SENSOR_PO2030 14 */ 6261/* SENSOR_PO2030 15 */
6664 {PO2030_NoFliker, PO2030_NoFliker, 6262 {PO2030_NoFliker, PO2030_NoFliker,
6665 PO2030_50HZ, PO2030_50HZ, 6263 PO2030_50HZ, PO2030_50HZ,
6666 PO2030_60HZ, PO2030_60HZ}, 6264 PO2030_60HZ, PO2030_60HZ},
6667/* SENSOR_TAS5130CK 15 */ 6265/* SENSOR_TAS5130CK 16 */
6668 {tas5130cxx_NoFliker, tas5130cxx_NoFlikerScale, 6266 {tas5130cxx_NoFlikerScale, tas5130cxx_NoFliker,
6669 tas5130cxx_50HZ, tas5130cxx_50HZScale, 6267 tas5130cxx_50HZScale, tas5130cxx_50HZ,
6670 tas5130cxx_60HZ, tas5130cxx_60HZScale}, 6268 tas5130cxx_60HZScale, tas5130cxx_60HZ},
6671/* SENSOR_TAS5130CXX 16 */ 6269/* SENSOR_TAS5130CXX 17 */
6672 {tas5130cxx_NoFliker, tas5130cxx_NoFlikerScale, 6270 {tas5130cxx_NoFlikerScale, tas5130cxx_NoFliker,
6673 tas5130cxx_50HZ, tas5130cxx_50HZScale, 6271 tas5130cxx_50HZScale, tas5130cxx_50HZ,
6674 tas5130cxx_60HZ, tas5130cxx_60HZScale}, 6272 tas5130cxx_60HZScale, tas5130cxx_60HZ},
6675/* SENSOR_TAS5130C_VF0250 17 */ 6273/* SENSOR_TAS5130C_VF0250 18 */
6676 {tas5130c_vf0250_NoFliker, tas5130c_vf0250_NoFlikerScale, 6274 {tas5130c_vf0250_NoFliker, tas5130c_vf0250_NoFlikerScale,
6677 tas5130c_vf0250_50HZ, tas5130c_vf0250_50HZScale, 6275 tas5130c_vf0250_50HZ, tas5130c_vf0250_50HZScale,
6678 tas5130c_vf0250_60HZ, tas5130c_vf0250_60HZScale}, 6276 tas5130c_vf0250_60HZ, tas5130c_vf0250_60HZScale},
@@ -6729,6 +6327,7 @@ static void send_unknown(struct usb_device *dev, int sensor)
6729 case SENSOR_ADCM2700: 6327 case SENSOR_ADCM2700:
6730 case SENSOR_GC0305: 6328 case SENSOR_GC0305:
6731 case SENSOR_OV7620: 6329 case SENSOR_OV7620:
6330 case SENSOR_MI0360SOC:
6732 case SENSOR_PB0330: 6331 case SENSOR_PB0330:
6733 case SENSOR_PO2030: 6332 case SENSOR_PO2030:
6734 reg_w(dev, 0x0d, 0x003a); 6333 reg_w(dev, 0x0d, 0x003a);
@@ -6820,7 +6419,7 @@ static int vga_2wr_probe(struct gspca_dev *gspca_dev)
6820 start_2wr_probe(dev, 0x0e); /* PAS202BCB */ 6419 start_2wr_probe(dev, 0x0e); /* PAS202BCB */
6821 reg_w(dev, 0x08, 0x008d); 6420 reg_w(dev, 0x08, 0x008d);
6822 i2c_write(gspca_dev, 0x03, 0xaa, 0x00); 6421 i2c_write(gspca_dev, 0x03, 0xaa, 0x00);
6823 msleep(500); 6422 msleep(50);
6824 retword = i2c_read(gspca_dev, 0x03); 6423 retword = i2c_read(gspca_dev, 0x03);
6825 if (retword != 0) 6424 if (retword != 0)
6826 return 0x0e; /* PAS202BCB */ 6425 return 0x0e; /* PAS202BCB */
@@ -6863,7 +6462,8 @@ struct sensor_by_chipset_revision {
6863 __u8 internal_sensor_id; 6462 __u8 internal_sensor_id;
6864}; 6463};
6865static const struct sensor_by_chipset_revision chipset_revision_sensor[] = { 6464static const struct sensor_by_chipset_revision chipset_revision_sensor[] = {
6866 {0xc001, 0x13}, /* MI0360 */ 6465 {0xc000, 0x12}, /* TAS5130C */
6466 {0xc001, 0x13}, /* MI0360SOC */
6867 {0xe001, 0x13}, 6467 {0xe001, 0x13},
6868 {0x8001, 0x13}, 6468 {0x8001, 0x13},
6869 {0x8000, 0x14}, /* CS2102K */ 6469 {0x8000, 0x14}, /* CS2102K */
@@ -6963,7 +6563,6 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev)
6963 reg_w(dev, 0x01, 0x0001); 6563 reg_w(dev, 0x01, 0x0001);
6964 reg_w(dev, 0xee, 0x008b); 6564 reg_w(dev, 0xee, 0x008b);
6965 reg_w(dev, 0x03, 0x0012); 6565 reg_w(dev, 0x03, 0x0012);
6966/* msleep(150); */
6967 reg_w(dev, 0x01, 0x0012); 6566 reg_w(dev, 0x01, 0x0012);
6968 reg_w(dev, 0x05, 0x0012); 6567 reg_w(dev, 0x05, 0x0012);
6969 retword = i2c_read(gspca_dev, 0x00) << 8; /* ID 0 */ 6568 retword = i2c_read(gspca_dev, 0x00) << 8; /* ID 0 */
@@ -7025,7 +6624,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
7025 int vga = 1; /* 1: vga, 0: sif */ 6624 int vga = 1; /* 1: vga, 0: sif */
7026 static const __u8 gamma[SENSOR_MAX] = { 6625 static const __u8 gamma[SENSOR_MAX] = {
7027 4, /* SENSOR_ADCM2700 0 */ 6626 4, /* SENSOR_ADCM2700 0 */
7028 5, /* SENSOR_CS2102 1 */ 6627 4, /* SENSOR_CS2102 1 */
7029 5, /* SENSOR_CS2102K 2 */ 6628 5, /* SENSOR_CS2102K 2 */
7030 4, /* SENSOR_GC0305 3 */ 6629 4, /* SENSOR_GC0305 3 */
7031 4, /* SENSOR_HDCS2020b 4 */ 6630 4, /* SENSOR_HDCS2020b 4 */
@@ -7033,15 +6632,16 @@ static int sd_config(struct gspca_dev *gspca_dev,
7033 4, /* SENSOR_HV7131C 6 */ 6632 4, /* SENSOR_HV7131C 6 */
7034 4, /* SENSOR_ICM105A 7 */ 6633 4, /* SENSOR_ICM105A 7 */
7035 4, /* SENSOR_MC501CB 8 */ 6634 4, /* SENSOR_MC501CB 8 */
7036 3, /* SENSOR_OV7620 9 */ 6635 4, /* SENSOR_MI0360SOC 9 */
7037 4, /* SENSOR_OV7630C 10 */ 6636 3, /* SENSOR_OV7620 10 */
7038 4, /* SENSOR_PAS106 11 */ 6637 4, /* SENSOR_OV7630C 11 */
7039 4, /* SENSOR_PAS202B 12 */ 6638 4, /* SENSOR_PAS106 12 */
7040 4, /* SENSOR_PB0330 13 */ 6639 4, /* SENSOR_PAS202B 13 */
7041 4, /* SENSOR_PO2030 14 */ 6640 4, /* SENSOR_PB0330 14 */
7042 4, /* SENSOR_TAS5130CK 15 */ 6641 4, /* SENSOR_PO2030 15 */
7043 4, /* SENSOR_TAS5130CXX 16 */ 6642 4, /* SENSOR_TAS5130CK 16 */
7044 3, /* SENSOR_TAS5130C_VF0250 17 */ 6643 3, /* SENSOR_TAS5130CXX 17 */
6644 3, /* SENSOR_TAS5130C_VF0250 18 */
7045 }; 6645 };
7046 6646
7047 /* define some sensors from the vendor/product */ 6647 /* define some sensors from the vendor/product */
@@ -7103,7 +6703,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
7103 break; 6703 break;
7104 case 0x10: 6704 case 0x10:
7105 case 0x12: 6705 case 0x12:
7106 PDEBUG(D_PROBE, "Find Sensor TAS5130"); 6706 PDEBUG(D_PROBE, "Find Sensor TAS5130C");
7107 sd->sensor = SENSOR_TAS5130CXX; 6707 sd->sensor = SENSOR_TAS5130CXX;
7108 break; 6708 break;
7109 case 0x11: 6709 case 0x11:
@@ -7112,9 +6712,9 @@ static int sd_config(struct gspca_dev *gspca_dev,
7112 break; 6712 break;
7113 case 0x13: 6713 case 0x13:
7114 PDEBUG(D_PROBE, 6714 PDEBUG(D_PROBE,
7115 "Find Sensor MI0360. Chip revision %x", 6715 "Find Sensor MI0360SOC. Chip revision %x",
7116 sd->chip_revision); 6716 sd->chip_revision);
7117 sd->sensor = SENSOR_PB0330; 6717 sd->sensor = SENSOR_MI0360SOC;
7118 break; 6718 break;
7119 case 0x14: 6719 case 0x14:
7120 PDEBUG(D_PROBE, 6720 PDEBUG(D_PROBE,
@@ -7228,17 +6828,17 @@ static int sd_start(struct gspca_dev *gspca_dev)
7228 {hv7131cxx_InitialScale, hv7131cxx_Initial}, /* 6 */ 6828 {hv7131cxx_InitialScale, hv7131cxx_Initial}, /* 6 */
7229 {icm105axx_InitialScale, icm105axx_Initial}, /* 7 */ 6829 {icm105axx_InitialScale, icm105axx_Initial}, /* 7 */
7230 {MC501CB_InitialScale, MC501CB_Initial}, /* 8 */ 6830 {MC501CB_InitialScale, MC501CB_Initial}, /* 8 */
7231 {OV7620_mode0, OV7620_mode1}, /* 9 */ 6831 {mi0360soc_Initial, mi0360soc_InitialScale}, /* 9 */
7232 {ov7630c_InitialScale, ov7630c_Initial}, /* 10 */ 6832 {OV7620_mode0, OV7620_mode1}, /* 10 */
7233 {pas106b_InitialScale, pas106b_Initial}, /* 11 */ 6833 {ov7630c_InitialScale, ov7630c_Initial}, /* 11 */
7234 {pas202b_Initial, pas202b_InitialScale}, /* 12 */ 6834 {pas106b_InitialScale, pas106b_Initial}, /* 12 */
7235 {pb0330xx_InitialScale, pb0330xx_Initial}, /* 13 */ 6835 {pas202b_Initial, pas202b_InitialScale}, /* 13 */
7236/* or {pb03303x_InitialScale, pb03303x_Initial}, */ 6836 {pb0330_Initial, pb0330_InitialScale}, /* 14 */
7237 {PO2030_mode0, PO2030_mode1}, /* 14 */ 6837 {PO2030_mode0, PO2030_mode1}, /* 15 */
7238 {tas5130CK_InitialScale, tas5130CK_Initial}, /* 15 */ 6838 {tas5130CK_InitialScale, tas5130CK_Initial}, /* 16 */
7239 {tas5130cxx_InitialScale, tas5130cxx_Initial}, /* 16 */ 6839 {tas5130cxx_Initial, tas5130cxx_InitialScale}, /* 17 */
7240 {tas5130c_vf0250_InitialScale, tas5130c_vf0250_Initial}, 6840 {tas5130c_vf0250_InitialScale, tas5130c_vf0250_Initial},
7241 /* 17 */ 6841 /* 18 */
7242 }; 6842 };
7243 6843
7244 /* create the JPEG header */ 6844 /* create the JPEG header */
@@ -7258,19 +6858,6 @@ static int sd_start(struct gspca_dev *gspca_dev)
7258 case SENSOR_PAS106: 6858 case SENSOR_PAS106:
7259 usb_exchange(gspca_dev, pas106b_Initial_com); 6859 usb_exchange(gspca_dev, pas106b_Initial_com);
7260 break; 6860 break;
7261 case SENSOR_PB0330:
7262 if (mode) {
7263 if (sd->chip_revision == 0xc001
7264 || sd->chip_revision == 0xe001
7265 || sd->chip_revision == 0x8001)
7266 zc3_init = pb03303x_Initial;
7267 } else {
7268 if (sd->chip_revision == 0xc001
7269 || sd->chip_revision == 0xe001
7270 || sd->chip_revision == 0x8001)
7271 zc3_init = pb03303x_InitialScale;
7272 }
7273 break;
7274 } 6861 }
7275 usb_exchange(gspca_dev, zc3_init); 6862 usb_exchange(gspca_dev, zc3_init);
7276 6863
@@ -7310,10 +6897,8 @@ static int sd_start(struct gspca_dev *gspca_dev)
7310 6897
7311 /* set the gamma tables when not set */ 6898 /* set the gamma tables when not set */
7312 switch (sd->sensor) { 6899 switch (sd->sensor) {
7313 case SENSOR_CS2102: /* gamma set in xxx_Initial */ 6900 case SENSOR_CS2102K: /* gamma set in xxx_Initial */
7314 case SENSOR_CS2102K:
7315 case SENSOR_HDCS2020b: 6901 case SENSOR_HDCS2020b:
7316 case SENSOR_PB0330: /* pb with chip_revision - see above */
7317 case SENSOR_OV7630C: 6902 case SENSOR_OV7630C:
7318 case SENSOR_TAS5130CK: 6903 case SENSOR_TAS5130CK:
7319 break; 6904 break;
@@ -7365,7 +6950,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
7365 setautogain(gspca_dev); 6950 setautogain(gspca_dev);
7366 switch (sd->sensor) { 6951 switch (sd->sensor) {
7367 case SENSOR_PO2030: 6952 case SENSOR_PO2030:
7368 msleep(500); 6953 msleep(50);
7369 reg_r(gspca_dev, 0x0008); 6954 reg_r(gspca_dev, 0x0008);
7370 reg_r(gspca_dev, 0x0007); 6955 reg_r(gspca_dev, 0x0007);
7371 /*fall thru*/ 6956 /*fall thru*/
@@ -7389,17 +6974,16 @@ static void sd_stop0(struct gspca_dev *gspca_dev)
7389} 6974}
7390 6975
7391static void sd_pkt_scan(struct gspca_dev *gspca_dev, 6976static void sd_pkt_scan(struct gspca_dev *gspca_dev,
7392 struct gspca_frame *frame, 6977 u8 *data,
7393 __u8 *data,
7394 int len) 6978 int len)
7395{ 6979{
7396 struct sd *sd = (struct sd *) gspca_dev; 6980 struct sd *sd = (struct sd *) gspca_dev;
7397 6981
7398 if (data[0] == 0xff && data[1] == 0xd8) { /* start of frame */ 6982 if (data[0] == 0xff && data[1] == 0xd8) { /* start of frame */
7399 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, 6983 gspca_frame_add(gspca_dev, LAST_PACKET,
7400 data, 0); 6984 NULL, 0);
7401 /* put the JPEG header in the new frame */ 6985 /* put the JPEG header in the new frame */
7402 gspca_frame_add(gspca_dev, FIRST_PACKET, frame, 6986 gspca_frame_add(gspca_dev, FIRST_PACKET,
7403 sd->jpeg_hdr, JPEG_HDR_SZ); 6987 sd->jpeg_hdr, JPEG_HDR_SZ);
7404 6988
7405 /* remove the webcam's header: 6989 /* remove the webcam's header:
@@ -7411,7 +6995,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
7411 data += 18; 6995 data += 18;
7412 len -= 18; 6996 len -= 18;
7413 } 6997 }
7414 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); 6998 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
7415} 6999}
7416 7000
7417static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) 7001static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
diff --git a/drivers/media/video/hdpvr/hdpvr-video.c b/drivers/media/video/hdpvr/hdpvr-video.c
index 2eb9dc2ebe59..b5439cabb381 100644
--- a/drivers/media/video/hdpvr/hdpvr-video.c
+++ b/drivers/media/video/hdpvr/hdpvr-video.c
@@ -139,7 +139,7 @@ int hdpvr_alloc_buffers(struct hdpvr_device *dev, uint count)
139 urb = usb_alloc_urb(0, GFP_KERNEL); 139 urb = usb_alloc_urb(0, GFP_KERNEL);
140 if (!urb) { 140 if (!urb) {
141 v4l2_err(&dev->v4l2_dev, "cannot allocate urb\n"); 141 v4l2_err(&dev->v4l2_dev, "cannot allocate urb\n");
142 goto exit; 142 goto exit_urb;
143 } 143 }
144 buf->urb = urb; 144 buf->urb = urb;
145 145
@@ -148,7 +148,7 @@ int hdpvr_alloc_buffers(struct hdpvr_device *dev, uint count)
148 if (!mem) { 148 if (!mem) {
149 v4l2_err(&dev->v4l2_dev, 149 v4l2_err(&dev->v4l2_dev,
150 "cannot allocate usb transfer buffer\n"); 150 "cannot allocate usb transfer buffer\n");
151 goto exit; 151 goto exit_urb_buffer;
152 } 152 }
153 153
154 usb_fill_bulk_urb(buf->urb, dev->udev, 154 usb_fill_bulk_urb(buf->urb, dev->udev,
@@ -161,6 +161,10 @@ int hdpvr_alloc_buffers(struct hdpvr_device *dev, uint count)
161 list_add_tail(&buf->buff_list, &dev->free_buff_list); 161 list_add_tail(&buf->buff_list, &dev->free_buff_list);
162 } 162 }
163 return 0; 163 return 0;
164exit_urb_buffer:
165 usb_free_urb(urb);
166exit_urb:
167 kfree(buf);
164exit: 168exit:
165 hdpvr_free_buffers(dev); 169 hdpvr_free_buffers(dev);
166 return retval; 170 return retval;
diff --git a/drivers/media/video/hexium_gemini.c b/drivers/media/video/hexium_gemini.c
index 71c211402eb5..60d992ee2589 100644
--- a/drivers/media/video/hexium_gemini.c
+++ b/drivers/media/video/hexium_gemini.c
@@ -251,7 +251,7 @@ static int vidioc_s_input(struct file *file, void *fh, unsigned int input)
251 251
252 DEB_EE(("VIDIOC_S_INPUT %d.\n", input)); 252 DEB_EE(("VIDIOC_S_INPUT %d.\n", input));
253 253
254 if (input < 0 || input >= HEXIUM_INPUTS) 254 if (input >= HEXIUM_INPUTS)
255 return -EINVAL; 255 return -EINVAL;
256 256
257 hexium->cur_input = input; 257 hexium->cur_input = input;
diff --git a/drivers/media/video/hexium_orion.c b/drivers/media/video/hexium_orion.c
index 39d65ca41c62..938a1f8f880a 100644
--- a/drivers/media/video/hexium_orion.c
+++ b/drivers/media/video/hexium_orion.c
@@ -350,7 +350,7 @@ static int vidioc_s_input(struct file *file, void *fh, unsigned int input)
350 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; 350 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
351 struct hexium *hexium = (struct hexium *) dev->ext_priv; 351 struct hexium *hexium = (struct hexium *) dev->ext_priv;
352 352
353 if (input < 0 || input >= HEXIUM_INPUTS) 353 if (input >= HEXIUM_INPUTS)
354 return -EINVAL; 354 return -EINVAL;
355 355
356 hexium->cur_input = input; 356 hexium->cur_input = input;
diff --git a/drivers/media/video/ir-kbd-i2c.c b/drivers/media/video/ir-kbd-i2c.c
index 247d3115a9b7..64360d26b32d 100644
--- a/drivers/media/video/ir-kbd-i2c.c
+++ b/drivers/media/video/ir-kbd-i2c.c
@@ -275,7 +275,7 @@ static void ir_key_poll(struct IR_i2c *ir)
275 if (0 == rc) { 275 if (0 == rc) {
276 ir_input_nokey(ir->input, &ir->ir); 276 ir_input_nokey(ir->input, &ir->ir);
277 } else { 277 } else {
278 ir_input_keydown(ir->input, &ir->ir, ir_key, ir_raw); 278 ir_input_keydown(ir->input, &ir->ir, ir_key);
279 } 279 }
280} 280}
281 281
@@ -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; 302 int 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;
@@ -353,10 +353,8 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
353 ir_type = IR_TYPE_RC5; 353 ir_type = IR_TYPE_RC5;
354 ir_codes = &ir_codes_fusionhdtv_mce_table; 354 ir_codes = &ir_codes_fusionhdtv_mce_table;
355 break; 355 break;
356 case 0x7a:
357 case 0x47: 356 case 0x47:
358 case 0x71: 357 case 0x71:
359 case 0x2d:
360 if (adap->id == I2C_HW_B_CX2388x || 358 if (adap->id == I2C_HW_B_CX2388x ||
361 adap->id == I2C_HW_B_CX2341X) { 359 adap->id == I2C_HW_B_CX2341X) {
362 /* Handled by cx88-input */ 360 /* Handled by cx88-input */
@@ -381,10 +379,6 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
381 ir_type = IR_TYPE_OTHER; 379 ir_type = IR_TYPE_OTHER;
382 ir_codes = &ir_codes_avermedia_cardbus_table; 380 ir_codes = &ir_codes_avermedia_cardbus_table;
383 break; 381 break;
384 default:
385 dprintk(1, DEVNAME ": Unsupported i2c address 0x%02x\n", addr);
386 err = -ENODEV;
387 goto err_out_free;
388 } 382 }
389 383
390 /* Let the caller override settings */ 384 /* Let the caller override settings */
@@ -427,7 +421,7 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
427 } 421 }
428 422
429 /* Make sure we are all setup before going on */ 423 /* Make sure we are all setup before going on */
430 if (!name || !ir->get_key || !ir_codes) { 424 if (!name || !ir->get_key || !ir_type || !ir_codes) {
431 dprintk(1, DEVNAME ": Unsupported device at address 0x%02x\n", 425 dprintk(1, DEVNAME ": Unsupported device at address 0x%02x\n",
432 addr); 426 addr);
433 err = -ENODEV; 427 err = -ENODEV;
@@ -443,7 +437,10 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
443 dev_name(&client->dev)); 437 dev_name(&client->dev));
444 438
445 /* init + register input device */ 439 /* init + register input device */
446 ir_input_init(input_dev, &ir->ir, ir_type, ir->ir_codes); 440 err = ir_input_init(input_dev, &ir->ir, ir_type, ir->ir_codes);
441 if (err < 0)
442 goto err_out_free;
443
447 input_dev->id.bustype = BUS_I2C; 444 input_dev->id.bustype = BUS_I2C;
448 input_dev->name = ir->name; 445 input_dev->name = ir->name;
449 input_dev->phys = ir->phys; 446 input_dev->phys = ir->phys;
@@ -462,6 +459,7 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
462 return 0; 459 return 0;
463 460
464 err_out_free: 461 err_out_free:
462 ir_input_free(input_dev);
465 input_free_device(input_dev); 463 input_free_device(input_dev);
466 kfree(ir); 464 kfree(ir);
467 return err; 465 return err;
@@ -475,6 +473,7 @@ static int ir_remove(struct i2c_client *client)
475 cancel_delayed_work_sync(&ir->work); 473 cancel_delayed_work_sync(&ir->work);
476 474
477 /* unregister device */ 475 /* unregister device */
476 ir_input_free(ir->input);
478 input_unregister_device(ir->input); 477 input_unregister_device(ir->input);
479 478
480 /* free memory */ 479 /* free memory */
diff --git a/drivers/media/video/ivtv/ivtv-cards.c b/drivers/media/video/ivtv/ivtv-cards.c
index 4873b6ca5801..79d0fe4990d6 100644
--- a/drivers/media/video/ivtv/ivtv-cards.c
+++ b/drivers/media/video/ivtv/ivtv-cards.c
@@ -136,7 +136,8 @@ static const struct ivtv_card ivtv_card_pvr350 = {
136 .hw_audio = IVTV_HW_MSP34XX, 136 .hw_audio = IVTV_HW_MSP34XX,
137 .hw_audio_ctrl = IVTV_HW_MSP34XX, 137 .hw_audio_ctrl = IVTV_HW_MSP34XX,
138 .hw_all = IVTV_HW_MSP34XX | IVTV_HW_SAA7115 | 138 .hw_all = IVTV_HW_MSP34XX | IVTV_HW_SAA7115 |
139 IVTV_HW_SAA7127 | IVTV_HW_TVEEPROM | IVTV_HW_TUNER, 139 IVTV_HW_SAA7127 | IVTV_HW_TVEEPROM | IVTV_HW_TUNER |
140 IVTV_HW_I2C_IR_RX_HAUP_EXT | IVTV_HW_I2C_IR_RX_HAUP_INT,
140 .video_inputs = { 141 .video_inputs = {
141 { IVTV_CARD_INPUT_VID_TUNER, 0, IVTV_SAA71XX_COMPOSITE4 }, 142 { IVTV_CARD_INPUT_VID_TUNER, 0, IVTV_SAA71XX_COMPOSITE4 },
142 { IVTV_CARD_INPUT_SVIDEO1, 1, IVTV_SAA71XX_SVIDEO0 }, 143 { IVTV_CARD_INPUT_SVIDEO1, 1, IVTV_SAA71XX_SVIDEO0 },
@@ -199,7 +200,9 @@ static const struct ivtv_card ivtv_card_pvr150 = {
199 .hw_audio_ctrl = IVTV_HW_CX25840, 200 .hw_audio_ctrl = IVTV_HW_CX25840,
200 .hw_muxer = IVTV_HW_WM8775, 201 .hw_muxer = IVTV_HW_WM8775,
201 .hw_all = IVTV_HW_WM8775 | IVTV_HW_CX25840 | 202 .hw_all = IVTV_HW_WM8775 | IVTV_HW_CX25840 |
202 IVTV_HW_TVEEPROM | IVTV_HW_TUNER, 203 IVTV_HW_TVEEPROM | IVTV_HW_TUNER |
204 IVTV_HW_I2C_IR_RX_HAUP_EXT | IVTV_HW_I2C_IR_RX_HAUP_INT |
205 IVTV_HW_Z8F0811_IR_HAUP,
203 .video_inputs = { 206 .video_inputs = {
204 { IVTV_CARD_INPUT_VID_TUNER, 0, CX25840_COMPOSITE7 }, 207 { IVTV_CARD_INPUT_VID_TUNER, 0, CX25840_COMPOSITE7 },
205 { IVTV_CARD_INPUT_SVIDEO1, 1, CX25840_SVIDEO1 }, 208 { IVTV_CARD_INPUT_SVIDEO1, 1, CX25840_SVIDEO1 },
@@ -955,7 +958,8 @@ static const struct ivtv_card ivtv_card_avertv_mce116 = {
955 .hw_video = IVTV_HW_CX25840, 958 .hw_video = IVTV_HW_CX25840,
956 .hw_audio = IVTV_HW_CX25840, 959 .hw_audio = IVTV_HW_CX25840,
957 .hw_audio_ctrl = IVTV_HW_CX25840, 960 .hw_audio_ctrl = IVTV_HW_CX25840,
958 .hw_all = IVTV_HW_CX25840 | IVTV_HW_TUNER | IVTV_HW_WM8739, 961 .hw_all = IVTV_HW_CX25840 | IVTV_HW_TUNER | IVTV_HW_WM8739 |
962 IVTV_HW_I2C_IR_RX_AVER,
959 .video_inputs = { 963 .video_inputs = {
960 { IVTV_CARD_INPUT_VID_TUNER, 0, CX25840_COMPOSITE2 }, 964 { IVTV_CARD_INPUT_VID_TUNER, 0, CX25840_COMPOSITE2 },
961 { IVTV_CARD_INPUT_SVIDEO1, 1, CX25840_SVIDEO3 }, 965 { IVTV_CARD_INPUT_SVIDEO1, 1, CX25840_SVIDEO3 },
@@ -965,6 +969,7 @@ static const struct ivtv_card ivtv_card_avertv_mce116 = {
965 { IVTV_CARD_INPUT_AUD_TUNER, CX25840_AUDIO5 }, 969 { IVTV_CARD_INPUT_AUD_TUNER, CX25840_AUDIO5 },
966 { IVTV_CARD_INPUT_LINE_IN1, CX25840_AUDIO_SERIAL, 1 }, 970 { IVTV_CARD_INPUT_LINE_IN1, CX25840_AUDIO_SERIAL, 1 },
967 }, 971 },
972 .radio_input = { IVTV_CARD_INPUT_AUD_TUNER, CX25840_AUDIO5 },
968 /* enable line-in */ 973 /* enable line-in */
969 .gpio_init = { .direction = 0xe000, .initial_value = 0x4000 }, 974 .gpio_init = { .direction = 0xe000, .initial_value = 0x4000 },
970 .xceive_pin = 10, 975 .xceive_pin = 10,
@@ -1025,13 +1030,15 @@ static const struct ivtv_card ivtv_card_aver_pvr150 = {
1025/* AVerMedia UltraTV 1500 MCE (newer non-cx88 version, M113 variant) card */ 1030/* AVerMedia UltraTV 1500 MCE (newer non-cx88 version, M113 variant) card */
1026 1031
1027static const struct ivtv_card_pci_info ivtv_pci_aver_ultra1500mce[] = { 1032static const struct ivtv_card_pci_info ivtv_pci_aver_ultra1500mce[] = {
1028 { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_AVERMEDIA, 0xc019 }, 1033 { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_AVERMEDIA, 0xc019 }, /* NTSC */
1034 { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_AVERMEDIA, 0xc01b }, /* PAL/SECAM */
1029 { 0, 0, 0 } 1035 { 0, 0, 0 }
1030}; 1036};
1031 1037
1032static const struct ivtv_card ivtv_card_aver_ultra1500mce = { 1038static const struct ivtv_card ivtv_card_aver_ultra1500mce = {
1033 .type = IVTV_CARD_AVER_ULTRA1500MCE, 1039 .type = IVTV_CARD_AVER_ULTRA1500MCE,
1034 .name = "AVerMedia UltraTV 1500 MCE / AVerTV M113 Philips Tuner", 1040 .name = "AVerMedia UltraTV 1500 MCE / AVerTV M113 Philips Tuner",
1041 .comment = "For non-NTSC tuners, use the pal= or secam= module options",
1035 .v4l2_capabilities = IVTV_CAP_ENCODER, 1042 .v4l2_capabilities = IVTV_CAP_ENCODER,
1036 .hw_video = IVTV_HW_CX25840, 1043 .hw_video = IVTV_HW_CX25840,
1037 .hw_audio = IVTV_HW_CX25840, 1044 .hw_audio = IVTV_HW_CX25840,
@@ -1058,6 +1065,7 @@ static const struct ivtv_card ivtv_card_aver_ultra1500mce = {
1058 .tuners = { 1065 .tuners = {
1059 /* The UltraTV 1500 MCE has a Philips FM1236 MK5 TV/FM tuner */ 1066 /* The UltraTV 1500 MCE has a Philips FM1236 MK5 TV/FM tuner */
1060 { .std = V4L2_STD_MN, .tuner = TUNER_PHILIPS_FM1236_MK3 }, 1067 { .std = V4L2_STD_MN, .tuner = TUNER_PHILIPS_FM1236_MK3 },
1068 { .std = V4L2_STD_PAL_SECAM, .tuner = TUNER_PHILIPS_FM1216MK5 },
1061 }, 1069 },
1062 .pci_list = ivtv_pci_aver_ultra1500mce, 1070 .pci_list = ivtv_pci_aver_ultra1500mce,
1063 .i2c = &ivtv_i2c_std, 1071 .i2c = &ivtv_i2c_std,
diff --git a/drivers/media/video/ivtv/ivtv-cards.h b/drivers/media/video/ivtv/ivtv-cards.h
index e99a0a255578..6148827ec885 100644
--- a/drivers/media/video/ivtv/ivtv-cards.h
+++ b/drivers/media/video/ivtv/ivtv-cards.h
@@ -87,26 +87,43 @@
87#define IVTV_PCI_ID_GOTVIEW1 0xffac 87#define IVTV_PCI_ID_GOTVIEW1 0xffac
88#define IVTV_PCI_ID_GOTVIEW2 0xffad 88#define IVTV_PCI_ID_GOTVIEW2 0xffad
89 89
90/* hardware flags, no gaps allowed, IVTV_HW_GPIO must always be last */ 90/* hardware flags, no gaps allowed */
91#define IVTV_HW_CX25840 (1 << 0) 91#define IVTV_HW_CX25840 (1 << 0)
92#define IVTV_HW_SAA7115 (1 << 1) 92#define IVTV_HW_SAA7115 (1 << 1)
93#define IVTV_HW_SAA7127 (1 << 2) 93#define IVTV_HW_SAA7127 (1 << 2)
94#define IVTV_HW_MSP34XX (1 << 3) 94#define IVTV_HW_MSP34XX (1 << 3)
95#define IVTV_HW_TUNER (1 << 4) 95#define IVTV_HW_TUNER (1 << 4)
96#define IVTV_HW_WM8775 (1 << 5) 96#define IVTV_HW_WM8775 (1 << 5)
97#define IVTV_HW_CS53L32A (1 << 6) 97#define IVTV_HW_CS53L32A (1 << 6)
98#define IVTV_HW_TVEEPROM (1 << 7) 98#define IVTV_HW_TVEEPROM (1 << 7)
99#define IVTV_HW_SAA7114 (1 << 8) 99#define IVTV_HW_SAA7114 (1 << 8)
100#define IVTV_HW_UPD64031A (1 << 9) 100#define IVTV_HW_UPD64031A (1 << 9)
101#define IVTV_HW_UPD6408X (1 << 10) 101#define IVTV_HW_UPD6408X (1 << 10)
102#define IVTV_HW_SAA717X (1 << 11) 102#define IVTV_HW_SAA717X (1 << 11)
103#define IVTV_HW_WM8739 (1 << 12) 103#define IVTV_HW_WM8739 (1 << 12)
104#define IVTV_HW_VP27SMPX (1 << 13) 104#define IVTV_HW_VP27SMPX (1 << 13)
105#define IVTV_HW_M52790 (1 << 14) 105#define IVTV_HW_M52790 (1 << 14)
106#define IVTV_HW_GPIO (1 << 15) 106#define IVTV_HW_GPIO (1 << 15)
107#define IVTV_HW_I2C_IR_RX_AVER (1 << 16)
108#define IVTV_HW_I2C_IR_RX_HAUP_EXT (1 << 17) /* External before internal */
109#define IVTV_HW_I2C_IR_RX_HAUP_INT (1 << 18)
110#define IVTV_HW_Z8F0811_IR_TX_HAUP (1 << 19)
111#define IVTV_HW_Z8F0811_IR_RX_HAUP (1 << 20)
112
113#define IVTV_HW_Z8F0811_IR_HAUP (IVTV_HW_Z8F0811_IR_RX_HAUP | \
114 IVTV_HW_Z8F0811_IR_TX_HAUP)
107 115
108#define IVTV_HW_SAA711X (IVTV_HW_SAA7115 | IVTV_HW_SAA7114) 116#define IVTV_HW_SAA711X (IVTV_HW_SAA7115 | IVTV_HW_SAA7114)
109 117
118#define IVTV_HW_IR_RX_ANY (IVTV_HW_I2C_IR_RX_AVER | \
119 IVTV_HW_I2C_IR_RX_HAUP_EXT | \
120 IVTV_HW_I2C_IR_RX_HAUP_INT | \
121 IVTV_HW_Z8F0811_IR_RX_HAUP)
122
123#define IVTV_HW_IR_TX_ANY (IVTV_HW_Z8F0811_IR_TX_HAUP)
124
125#define IVTV_HW_IR_ANY (IVTV_HW_IR_RX_ANY | IVTV_HW_IR_TX_ANY)
126
110/* video inputs */ 127/* video inputs */
111#define IVTV_CARD_INPUT_VID_TUNER 1 128#define IVTV_CARD_INPUT_VID_TUNER 1
112#define IVTV_CARD_INPUT_SVIDEO1 2 129#define IVTV_CARD_INPUT_SVIDEO1 2
diff --git a/drivers/media/video/ivtv/ivtv-driver.c b/drivers/media/video/ivtv/ivtv-driver.c
index 7cdbc1a8f218..347c3344f56d 100644
--- a/drivers/media/video/ivtv/ivtv-driver.c
+++ b/drivers/media/video/ivtv/ivtv-driver.c
@@ -91,10 +91,15 @@ static int radio[IVTV_MAX_CARDS] = { -1, -1, -1, -1, -1, -1, -1, -1,
91 -1, -1, -1, -1, -1, -1, -1, -1, 91 -1, -1, -1, -1, -1, -1, -1, -1,
92 -1, -1, -1, -1, -1, -1, -1, -1, 92 -1, -1, -1, -1, -1, -1, -1, -1,
93 -1, -1, -1, -1, -1, -1, -1, -1 }; 93 -1, -1, -1, -1, -1, -1, -1, -1 };
94static int i2c_clock_period[IVTV_MAX_CARDS] = { -1, -1, -1, -1, -1, -1, -1, -1,
95 -1, -1, -1, -1, -1, -1, -1, -1,
96 -1, -1, -1, -1, -1, -1, -1, -1,
97 -1, -1, -1, -1, -1, -1, -1, -1 };
94 98
95static unsigned int cardtype_c = 1; 99static unsigned int cardtype_c = 1;
96static unsigned int tuner_c = 1; 100static unsigned int tuner_c = 1;
97static unsigned int radio_c = 1; 101static unsigned int radio_c = 1;
102static unsigned int i2c_clock_period_c = 1;
98static char pal[] = "---"; 103static char pal[] = "---";
99static char secam[] = "--"; 104static char secam[] = "--";
100static char ntsc[] = "-"; 105static char ntsc[] = "-";
@@ -151,6 +156,7 @@ module_param(dec_vbi_buffers, int, 0644);
151 156
152module_param(tunertype, int, 0644); 157module_param(tunertype, int, 0644);
153module_param(newi2c, int, 0644); 158module_param(newi2c, int, 0644);
159module_param_array(i2c_clock_period, int, &i2c_clock_period_c, 0644);
154 160
155MODULE_PARM_DESC(tuner, "Tuner type selection,\n" 161MODULE_PARM_DESC(tuner, "Tuner type selection,\n"
156 "\t\t\tsee tuner.h for values"); 162 "\t\t\tsee tuner.h for values");
@@ -245,6 +251,10 @@ MODULE_PARM_DESC(newi2c,
245 "Use new I2C implementation\n" 251 "Use new I2C implementation\n"
246 "\t\t\t-1 is autodetect, 0 is off, 1 is on\n" 252 "\t\t\t-1 is autodetect, 0 is off, 1 is on\n"
247 "\t\t\tDefault is autodetect"); 253 "\t\t\tDefault is autodetect");
254MODULE_PARM_DESC(i2c_clock_period,
255 "Period of SCL for the I2C bus controlled by the CX23415/6\n"
256 "\t\t\tMin: 10 usec (100 kHz), Max: 4500 usec (222 Hz)\n"
257 "\t\t\tDefault: " __stringify(IVTV_DEFAULT_I2C_CLOCK_PERIOD));
248 258
249MODULE_PARM_DESC(ivtv_first_minor, "Set device node number assigned to first card"); 259MODULE_PARM_DESC(ivtv_first_minor, "Set device node number assigned to first card");
250 260
@@ -600,6 +610,15 @@ static void ivtv_process_options(struct ivtv *itv)
600 itv->options.cardtype = cardtype[itv->instance]; 610 itv->options.cardtype = cardtype[itv->instance];
601 itv->options.tuner = tuner[itv->instance]; 611 itv->options.tuner = tuner[itv->instance];
602 itv->options.radio = radio[itv->instance]; 612 itv->options.radio = radio[itv->instance];
613
614 itv->options.i2c_clock_period = i2c_clock_period[itv->instance];
615 if (itv->options.i2c_clock_period == -1)
616 itv->options.i2c_clock_period = IVTV_DEFAULT_I2C_CLOCK_PERIOD;
617 else if (itv->options.i2c_clock_period < 10)
618 itv->options.i2c_clock_period = 10;
619 else if (itv->options.i2c_clock_period > 4500)
620 itv->options.i2c_clock_period = 4500;
621
603 itv->options.newi2c = newi2c; 622 itv->options.newi2c = newi2c;
604 if (tunertype < -1 || tunertype > 1) { 623 if (tunertype < -1 || tunertype > 1) {
605 IVTV_WARN("Invalid tunertype argument, will autodetect instead\n"); 624 IVTV_WARN("Invalid tunertype argument, will autodetect instead\n");
@@ -865,6 +884,10 @@ static void ivtv_load_and_init_modules(struct ivtv *itv)
865 itv->hw_flags |= device; 884 itv->hw_flags |= device;
866 } 885 }
867 886
887 /* probe for legacy IR controllers that aren't in card definitions */
888 if ((itv->hw_flags & IVTV_HW_IR_ANY) == 0)
889 ivtv_i2c_new_ir_legacy(itv);
890
868 if (itv->card->hw_all & IVTV_HW_CX25840) 891 if (itv->card->hw_all & IVTV_HW_CX25840)
869 itv->sd_video = ivtv_find_hw(itv, IVTV_HW_CX25840); 892 itv->sd_video = ivtv_find_hw(itv, IVTV_HW_CX25840);
870 else if (itv->card->hw_all & IVTV_HW_SAA717X) 893 else if (itv->card->hw_all & IVTV_HW_SAA717X)
diff --git a/drivers/media/video/ivtv/ivtv-driver.h b/drivers/media/video/ivtv/ivtv-driver.h
index 440f7328a7ed..e4816da6482b 100644
--- a/drivers/media/video/ivtv/ivtv-driver.h
+++ b/drivers/media/video/ivtv/ivtv-driver.h
@@ -64,6 +64,7 @@
64#include <media/v4l2-device.h> 64#include <media/v4l2-device.h>
65#include <media/tuner.h> 65#include <media/tuner.h>
66#include <media/cx2341x.h> 66#include <media/cx2341x.h>
67#include <media/ir-kbd-i2c.h>
67 68
68#include <linux/ivtv.h> 69#include <linux/ivtv.h>
69 70
@@ -176,12 +177,16 @@ extern int ivtv_debug;
176 177
177#define IVTV_MAX_PGM_INDEX (400) 178#define IVTV_MAX_PGM_INDEX (400)
178 179
180/* Default I2C SCL period in microseconds */
181#define IVTV_DEFAULT_I2C_CLOCK_PERIOD 20
182
179struct ivtv_options { 183struct ivtv_options {
180 int kilobytes[IVTV_MAX_STREAMS]; /* size in kilobytes of each stream */ 184 int kilobytes[IVTV_MAX_STREAMS]; /* size in kilobytes of each stream */
181 int cardtype; /* force card type on load */ 185 int cardtype; /* force card type on load */
182 int tuner; /* set tuner on load */ 186 int tuner; /* set tuner on load */
183 int radio; /* enable/disable radio */ 187 int radio; /* enable/disable radio */
184 int newi2c; /* new I2C algorithm */ 188 int newi2c; /* new I2C algorithm */
189 int i2c_clock_period; /* period of SCL for I2C bus */
185}; 190};
186 191
187/* ivtv-specific mailbox template */ 192/* ivtv-specific mailbox template */
@@ -677,6 +682,7 @@ struct ivtv {
677 int i2c_state; /* i2c bit state */ 682 int i2c_state; /* i2c bit state */
678 struct mutex i2c_bus_lock; /* lock i2c bus */ 683 struct mutex i2c_bus_lock; /* lock i2c bus */
679 684
685 struct IR_i2c_init_data ir_i2c_init_data;
680 686
681 /* Program Index information */ 687 /* Program Index information */
682 u32 pgm_info_offset; /* start of pgm info in encoder memory */ 688 u32 pgm_info_offset; /* start of pgm info in encoder memory */
diff --git a/drivers/media/video/ivtv/ivtv-i2c.c b/drivers/media/video/ivtv/ivtv-i2c.c
index b9c71e61f7d6..2ee03c2a1b58 100644
--- a/drivers/media/video/ivtv/ivtv-i2c.c
+++ b/drivers/media/video/ivtv/ivtv-i2c.c
@@ -88,6 +88,11 @@
88#define IVTV_UPD64083_I2C_ADDR 0x5c 88#define IVTV_UPD64083_I2C_ADDR 0x5c
89#define IVTV_VP27SMPX_I2C_ADDR 0x5b 89#define IVTV_VP27SMPX_I2C_ADDR 0x5b
90#define IVTV_M52790_I2C_ADDR 0x48 90#define IVTV_M52790_I2C_ADDR 0x48
91#define IVTV_AVERMEDIA_IR_RX_I2C_ADDR 0x40
92#define IVTV_HAUP_EXT_IR_RX_I2C_ADDR 0x1a
93#define IVTV_HAUP_INT_IR_RX_I2C_ADDR 0x18
94#define IVTV_Z8F0811_IR_TX_I2C_ADDR 0x70
95#define IVTV_Z8F0811_IR_RX_I2C_ADDR 0x71
91 96
92/* This array should match the IVTV_HW_ defines */ 97/* This array should match the IVTV_HW_ defines */
93static const u8 hw_addrs[] = { 98static const u8 hw_addrs[] = {
@@ -106,7 +111,12 @@ static const u8 hw_addrs[] = {
106 IVTV_WM8739_I2C_ADDR, 111 IVTV_WM8739_I2C_ADDR,
107 IVTV_VP27SMPX_I2C_ADDR, 112 IVTV_VP27SMPX_I2C_ADDR,
108 IVTV_M52790_I2C_ADDR, 113 IVTV_M52790_I2C_ADDR,
109 0 /* IVTV_HW_GPIO dummy driver ID */ 114 0, /* IVTV_HW_GPIO dummy driver ID */
115 IVTV_AVERMEDIA_IR_RX_I2C_ADDR, /* IVTV_HW_I2C_IR_RX_AVER */
116 IVTV_HAUP_EXT_IR_RX_I2C_ADDR, /* IVTV_HW_I2C_IR_RX_HAUP_EXT */
117 IVTV_HAUP_INT_IR_RX_I2C_ADDR, /* IVTV_HW_I2C_IR_RX_HAUP_INT */
118 IVTV_Z8F0811_IR_TX_I2C_ADDR, /* IVTV_HW_Z8F0811_IR_TX_HAUP */
119 IVTV_Z8F0811_IR_RX_I2C_ADDR, /* IVTV_HW_Z8F0811_IR_RX_HAUP */
110}; 120};
111 121
112/* This array should match the IVTV_HW_ defines */ 122/* This array should match the IVTV_HW_ defines */
@@ -126,7 +136,12 @@ static const char *hw_modules[] = {
126 "wm8739", 136 "wm8739",
127 "vp27smpx", 137 "vp27smpx",
128 "m52790", 138 "m52790",
129 NULL 139 NULL,
140 NULL, /* IVTV_HW_I2C_IR_RX_AVER */
141 NULL, /* IVTV_HW_I2C_IR_RX_HAUP_EXT */
142 NULL, /* IVTV_HW_I2C_IR_RX_HAUP_INT */
143 NULL, /* IVTV_HW_Z8F0811_IR_TX_HAUP */
144 NULL, /* IVTV_HW_Z8F0811_IR_RX_HAUP */
130}; 145};
131 146
132/* This array should match the IVTV_HW_ defines */ 147/* This array should match the IVTV_HW_ defines */
@@ -147,8 +162,95 @@ static const char * const hw_devicenames[] = {
147 "vp27smpx", 162 "vp27smpx",
148 "m52790", 163 "m52790",
149 "gpio", 164 "gpio",
165 "ir_video", /* IVTV_HW_I2C_IR_RX_AVER */
166 "ir_video", /* IVTV_HW_I2C_IR_RX_HAUP_EXT */
167 "ir_video", /* IVTV_HW_I2C_IR_RX_HAUP_INT */
168 "ir_tx_z8f0811_haup", /* IVTV_HW_Z8F0811_IR_TX_HAUP */
169 "ir_rx_z8f0811_haup", /* IVTV_HW_Z8F0811_IR_RX_HAUP */
150}; 170};
151 171
172static int ivtv_i2c_new_ir(struct ivtv *itv, u32 hw, const char *type, u8 addr)
173{
174 struct i2c_board_info info;
175 struct i2c_adapter *adap = &itv->i2c_adap;
176 struct IR_i2c_init_data *init_data = &itv->ir_i2c_init_data;
177 unsigned short addr_list[2] = { addr, I2C_CLIENT_END };
178
179 /* Only allow one IR transmitter to be registered per board */
180 if (hw & IVTV_HW_IR_TX_ANY) {
181 if (itv->hw_flags & IVTV_HW_IR_TX_ANY)
182 return -1;
183 memset(&info, 0, sizeof(struct i2c_board_info));
184 strlcpy(info.type, type, I2C_NAME_SIZE);
185 return i2c_new_probed_device(adap, &info, addr_list) == NULL
186 ? -1 : 0;
187 }
188
189 /* Only allow one IR receiver to be registered per board */
190 if (itv->hw_flags & IVTV_HW_IR_RX_ANY)
191 return -1;
192
193 /* Our default information for ir-kbd-i2c.c to use */
194 switch (hw) {
195 case IVTV_HW_I2C_IR_RX_AVER:
196 init_data->ir_codes = &ir_codes_avermedia_cardbus_table;
197 init_data->internal_get_key_func =
198 IR_KBD_GET_KEY_AVERMEDIA_CARDBUS;
199 init_data->type = IR_TYPE_OTHER;
200 init_data->name = "AVerMedia AVerTV card";
201 break;
202 case IVTV_HW_I2C_IR_RX_HAUP_EXT:
203 case IVTV_HW_I2C_IR_RX_HAUP_INT:
204 /* Default to old black remote */
205 init_data->ir_codes = &ir_codes_rc5_tv_table;
206 init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP;
207 init_data->type = IR_TYPE_RC5;
208 init_data->name = itv->card_name;
209 break;
210 case IVTV_HW_Z8F0811_IR_RX_HAUP:
211 /* Default to grey remote */
212 init_data->ir_codes = &ir_codes_hauppauge_new_table;
213 init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR;
214 init_data->type = IR_TYPE_RC5;
215 init_data->name = itv->card_name;
216 break;
217 }
218
219 memset(&info, 0, sizeof(struct i2c_board_info));
220 info.platform_data = init_data;
221 strlcpy(info.type, type, I2C_NAME_SIZE);
222
223 return i2c_new_probed_device(adap, &info, addr_list) == NULL ? -1 : 0;
224}
225
226/* Instantiate the IR receiver device using probing -- undesirable */
227struct i2c_client *ivtv_i2c_new_ir_legacy(struct ivtv *itv)
228{
229 struct i2c_board_info info;
230 /*
231 * The external IR receiver is at i2c address 0x34.
232 * The internal IR receiver is at i2c address 0x30.
233 *
234 * In theory, both can be fitted, and Hauppauge suggests an external
235 * overrides an internal. That's why we probe 0x1a (~0x34) first. CB
236 *
237 * Some of these addresses we probe may collide with other i2c address
238 * allocations, so this function must be called after all other i2c
239 * devices we care about are registered.
240 */
241 const unsigned short addr_list[] = {
242 0x1a, /* Hauppauge IR external - collides with WM8739 */
243 0x18, /* Hauppauge IR internal */
244 0x71, /* Hauppauge IR (PVR150) */
245 0x6b, /* Adaptec IR */
246 I2C_CLIENT_END
247 };
248
249 memset(&info, 0, sizeof(struct i2c_board_info));
250 strlcpy(info.type, "ir_video", I2C_NAME_SIZE);
251 return i2c_new_probed_device(&itv->i2c_adap, &info, addr_list);
252}
253
152int ivtv_i2c_register(struct ivtv *itv, unsigned idx) 254int ivtv_i2c_register(struct ivtv *itv, unsigned idx)
153{ 255{
154 struct v4l2_subdev *sd; 256 struct v4l2_subdev *sd;
@@ -178,8 +280,15 @@ int ivtv_i2c_register(struct ivtv *itv, unsigned idx)
178 sd->grp_id = 1 << idx; 280 sd->grp_id = 1 << idx;
179 return sd ? 0 : -1; 281 return sd ? 0 : -1;
180 } 282 }
283
284 if (hw & IVTV_HW_IR_ANY)
285 return ivtv_i2c_new_ir(itv, hw, type, hw_addrs[idx]);
286
287 /* Is it not an I2C device or one we do not wish to register? */
181 if (!hw_addrs[idx]) 288 if (!hw_addrs[idx])
182 return -1; 289 return -1;
290
291 /* It's an I2C device other than an analog tuner or IR chip */
183 if (hw == IVTV_HW_UPD64031A || hw == IVTV_HW_UPD6408X) { 292 if (hw == IVTV_HW_UPD64031A || hw == IVTV_HW_UPD6408X) {
184 sd = v4l2_i2c_new_subdev(&itv->v4l2_dev, 293 sd = v4l2_i2c_new_subdev(&itv->v4l2_dev,
185 adap, mod, type, 0, I2C_ADDRS(hw_addrs[idx])); 294 adap, mod, type, 0, I2C_ADDRS(hw_addrs[idx]));
@@ -564,20 +673,22 @@ static struct i2c_adapter ivtv_i2c_adap_template = {
564 .owner = THIS_MODULE, 673 .owner = THIS_MODULE,
565}; 674};
566 675
676#define IVTV_ALGO_BIT_TIMEOUT (2) /* seconds */
677
567static const struct i2c_algo_bit_data ivtv_i2c_algo_template = { 678static const struct i2c_algo_bit_data ivtv_i2c_algo_template = {
568 .setsda = ivtv_setsda_old, 679 .setsda = ivtv_setsda_old,
569 .setscl = ivtv_setscl_old, 680 .setscl = ivtv_setscl_old,
570 .getsda = ivtv_getsda_old, 681 .getsda = ivtv_getsda_old,
571 .getscl = ivtv_getscl_old, 682 .getscl = ivtv_getscl_old,
572 .udelay = 10, 683 .udelay = IVTV_DEFAULT_I2C_CLOCK_PERIOD / 2, /* microseconds */
573 .timeout = 200, 684 .timeout = IVTV_ALGO_BIT_TIMEOUT * HZ, /* jiffies */
574}; 685};
575 686
576static struct i2c_client ivtv_i2c_client_template = { 687static struct i2c_client ivtv_i2c_client_template = {
577 .name = "ivtv internal", 688 .name = "ivtv internal",
578}; 689};
579 690
580/* init + register i2c adapter + instantiate IR receiver */ 691/* init + register i2c adapter */
581int init_ivtv_i2c(struct ivtv *itv) 692int init_ivtv_i2c(struct ivtv *itv)
582{ 693{
583 int retval; 694 int retval;
@@ -585,11 +696,10 @@ int init_ivtv_i2c(struct ivtv *itv)
585 IVTV_DEBUG_I2C("i2c init\n"); 696 IVTV_DEBUG_I2C("i2c init\n");
586 697
587 /* Sanity checks for the I2C hardware arrays. They must be the 698 /* Sanity checks for the I2C hardware arrays. They must be the
588 * same size and GPIO must be the last entry. 699 * same size.
589 */ 700 */
590 if (ARRAY_SIZE(hw_devicenames) != ARRAY_SIZE(hw_addrs) || 701 if (ARRAY_SIZE(hw_devicenames) != ARRAY_SIZE(hw_addrs) ||
591 ARRAY_SIZE(hw_devicenames) != ARRAY_SIZE(hw_modules) || 702 ARRAY_SIZE(hw_devicenames) != ARRAY_SIZE(hw_modules)) {
592 IVTV_HW_GPIO != (1 << (ARRAY_SIZE(hw_addrs) - 1))) {
593 IVTV_ERR("Mismatched I2C hardware arrays\n"); 703 IVTV_ERR("Mismatched I2C hardware arrays\n");
594 return -ENODEV; 704 return -ENODEV;
595 } 705 }
@@ -602,6 +712,7 @@ int init_ivtv_i2c(struct ivtv *itv)
602 memcpy(&itv->i2c_algo, &ivtv_i2c_algo_template, 712 memcpy(&itv->i2c_algo, &ivtv_i2c_algo_template,
603 sizeof(struct i2c_algo_bit_data)); 713 sizeof(struct i2c_algo_bit_data));
604 } 714 }
715 itv->i2c_algo.udelay = itv->options.i2c_clock_period / 2;
605 itv->i2c_algo.data = itv; 716 itv->i2c_algo.data = itv;
606 itv->i2c_adap.algo_data = &itv->i2c_algo; 717 itv->i2c_adap.algo_data = &itv->i2c_algo;
607 718
@@ -623,32 +734,6 @@ int init_ivtv_i2c(struct ivtv *itv)
623 else 734 else
624 retval = i2c_bit_add_bus(&itv->i2c_adap); 735 retval = i2c_bit_add_bus(&itv->i2c_adap);
625 736
626 /* Instantiate the IR receiver device, if present */
627 if (retval == 0) {
628 struct i2c_board_info info;
629 /* The external IR receiver is at i2c address 0x34 (0x35 for
630 reads). Future Hauppauge cards will have an internal
631 receiver at 0x30 (0x31 for reads). In theory, both can be
632 fitted, and Hauppauge suggest an external overrides an
633 internal.
634
635 That's why we probe 0x1a (~0x34) first. CB
636 */
637 const unsigned short addr_list[] = {
638 0x1a, /* Hauppauge IR external */
639 0x18, /* Hauppauge IR internal */
640 0x71, /* Hauppauge IR (PVR150) */
641 0x64, /* Pixelview IR */
642 0x30, /* KNC ONE IR */
643 0x6b, /* Adaptec IR */
644 I2C_CLIENT_END
645 };
646
647 memset(&info, 0, sizeof(struct i2c_board_info));
648 strlcpy(info.type, "ir_video", I2C_NAME_SIZE);
649 i2c_new_probed_device(&itv->i2c_adap, &info, addr_list);
650 }
651
652 return retval; 737 return retval;
653} 738}
654 739
diff --git a/drivers/media/video/ivtv/ivtv-i2c.h b/drivers/media/video/ivtv/ivtv-i2c.h
index 396928a06a54..9332920ca4ff 100644
--- a/drivers/media/video/ivtv/ivtv-i2c.h
+++ b/drivers/media/video/ivtv/ivtv-i2c.h
@@ -21,6 +21,7 @@
21#ifndef IVTV_I2C_H 21#ifndef IVTV_I2C_H
22#define IVTV_I2C_H 22#define IVTV_I2C_H
23 23
24struct i2c_client *ivtv_i2c_new_ir_legacy(struct ivtv *itv);
24int ivtv_i2c_register(struct ivtv *itv, unsigned idx); 25int ivtv_i2c_register(struct ivtv *itv, unsigned idx);
25struct v4l2_subdev *ivtv_find_hw(struct ivtv *itv, u32 hw); 26struct v4l2_subdev *ivtv_find_hw(struct ivtv *itv, u32 hw);
26 27
diff --git a/drivers/media/video/mxb.c b/drivers/media/video/mxb.c
index 3454070e63f0..c1fc6dc776f5 100644
--- a/drivers/media/video/mxb.c
+++ b/drivers/media/video/mxb.c
@@ -478,7 +478,7 @@ static int vidioc_s_input(struct file *file, void *fh, unsigned int input)
478 478
479 DEB_EE(("VIDIOC_S_INPUT %d.\n", input)); 479 DEB_EE(("VIDIOC_S_INPUT %d.\n", input));
480 480
481 if (input < 0 || input >= MXB_INPUTS) 481 if (input >= MXB_INPUTS)
482 return -EINVAL; 482 return -EINVAL;
483 483
484 mxb->cur_input = input; 484 mxb->cur_input = input;
diff --git a/drivers/media/video/ov9640.c b/drivers/media/video/ov9640.c
new file mode 100644
index 000000000000..c81ae2192887
--- /dev/null
+++ b/drivers/media/video/ov9640.c
@@ -0,0 +1,801 @@
1/*
2 * OmniVision OV96xx Camera Driver
3 *
4 * Copyright (C) 2009 Marek Vasut <marek.vasut@gmail.com>
5 *
6 * Based on ov772x camera driver:
7 *
8 * Copyright (C) 2008 Renesas Solutions Corp.
9 * Kuninori Morimoto <morimoto.kuninori@renesas.com>
10 *
11 * Based on ov7670 and soc_camera_platform driver,
12 *
13 * Copyright 2006-7 Jonathan Corbet <corbet@lwn.net>
14 * Copyright (C) 2008 Magnus Damm
15 * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de>
16 *
17 * This program is free software; you can redistribute it and/or modify
18 * it under the terms of the GNU General Public License version 2 as
19 * published by the Free Software Foundation.
20 */
21
22#include <linux/init.h>
23#include <linux/module.h>
24#include <linux/i2c.h>
25#include <linux/slab.h>
26#include <linux/delay.h>
27#include <linux/videodev2.h>
28#include <media/v4l2-chip-ident.h>
29#include <media/v4l2-common.h>
30#include <media/soc_camera.h>
31
32#include "ov9640.h"
33
34/* default register setup */
35static const struct ov9640_reg ov9640_regs_dflt[] = {
36 { OV9640_COM5, OV9640_COM5_SYSCLK | OV9640_COM5_LONGEXP },
37 { OV9640_COM6, OV9640_COM6_OPT_BLC | OV9640_COM6_ADBLC_BIAS |
38 OV9640_COM6_FMT_RST | OV9640_COM6_ADBLC_OPTEN },
39 { OV9640_PSHFT, OV9640_PSHFT_VAL(0x01) },
40 { OV9640_ACOM, OV9640_ACOM_2X_ANALOG | OV9640_ACOM_RSVD },
41 { OV9640_TSLB, OV9640_TSLB_YUYV_UYVY },
42 { OV9640_COM16, OV9640_COM16_RB_AVG },
43
44 /* Gamma curve P */
45 { 0x6c, 0x40 }, { 0x6d, 0x30 }, { 0x6e, 0x4b }, { 0x6f, 0x60 },
46 { 0x70, 0x70 }, { 0x71, 0x70 }, { 0x72, 0x70 }, { 0x73, 0x70 },
47 { 0x74, 0x60 }, { 0x75, 0x60 }, { 0x76, 0x50 }, { 0x77, 0x48 },
48 { 0x78, 0x3a }, { 0x79, 0x2e }, { 0x7a, 0x28 }, { 0x7b, 0x22 },
49
50 /* Gamma curve T */
51 { 0x7c, 0x04 }, { 0x7d, 0x07 }, { 0x7e, 0x10 }, { 0x7f, 0x28 },
52 { 0x80, 0x36 }, { 0x81, 0x44 }, { 0x82, 0x52 }, { 0x83, 0x60 },
53 { 0x84, 0x6c }, { 0x85, 0x78 }, { 0x86, 0x8c }, { 0x87, 0x9e },
54 { 0x88, 0xbb }, { 0x89, 0xd2 }, { 0x8a, 0xe6 },
55};
56
57/* Configurations
58 * NOTE: for YUV, alter the following registers:
59 * COM12 |= OV9640_COM12_YUV_AVG
60 *
61 * for RGB, alter the following registers:
62 * COM7 |= OV9640_COM7_RGB
63 * COM13 |= OV9640_COM13_RGB_AVG
64 * COM15 |= proper RGB color encoding mode
65 */
66static const struct ov9640_reg ov9640_regs_qqcif[] = {
67 { OV9640_CLKRC, OV9640_CLKRC_DPLL_EN | OV9640_CLKRC_DIV(0x0f) },
68 { OV9640_COM1, OV9640_COM1_QQFMT | OV9640_COM1_HREF_2SKIP },
69 { OV9640_COM4, OV9640_COM4_QQ_VP | OV9640_COM4_RSVD },
70 { OV9640_COM7, OV9640_COM7_QCIF },
71 { OV9640_COM12, OV9640_COM12_RSVD },
72 { OV9640_COM13, OV9640_COM13_GAMMA_RAW | OV9640_COM13_MATRIX_EN },
73 { OV9640_COM15, OV9640_COM15_OR_10F0 },
74};
75
76static const struct ov9640_reg ov9640_regs_qqvga[] = {
77 { OV9640_CLKRC, OV9640_CLKRC_DPLL_EN | OV9640_CLKRC_DIV(0x07) },
78 { OV9640_COM1, OV9640_COM1_QQFMT | OV9640_COM1_HREF_2SKIP },
79 { OV9640_COM4, OV9640_COM4_QQ_VP | OV9640_COM4_RSVD },
80 { OV9640_COM7, OV9640_COM7_QVGA },
81 { OV9640_COM12, OV9640_COM12_RSVD },
82 { OV9640_COM13, OV9640_COM13_GAMMA_RAW | OV9640_COM13_MATRIX_EN },
83 { OV9640_COM15, OV9640_COM15_OR_10F0 },
84};
85
86static const struct ov9640_reg ov9640_regs_qcif[] = {
87 { OV9640_CLKRC, OV9640_CLKRC_DPLL_EN | OV9640_CLKRC_DIV(0x07) },
88 { OV9640_COM4, OV9640_COM4_QQ_VP | OV9640_COM4_RSVD },
89 { OV9640_COM7, OV9640_COM7_QCIF },
90 { OV9640_COM12, OV9640_COM12_RSVD },
91 { OV9640_COM13, OV9640_COM13_GAMMA_RAW | OV9640_COM13_MATRIX_EN },
92 { OV9640_COM15, OV9640_COM15_OR_10F0 },
93};
94
95static const struct ov9640_reg ov9640_regs_qvga[] = {
96 { OV9640_CLKRC, OV9640_CLKRC_DPLL_EN | OV9640_CLKRC_DIV(0x03) },
97 { OV9640_COM4, OV9640_COM4_QQ_VP | OV9640_COM4_RSVD },
98 { OV9640_COM7, OV9640_COM7_QVGA },
99 { OV9640_COM12, OV9640_COM12_RSVD },
100 { OV9640_COM13, OV9640_COM13_GAMMA_RAW | OV9640_COM13_MATRIX_EN },
101 { OV9640_COM15, OV9640_COM15_OR_10F0 },
102};
103
104static const struct ov9640_reg ov9640_regs_cif[] = {
105 { OV9640_CLKRC, OV9640_CLKRC_DPLL_EN | OV9640_CLKRC_DIV(0x03) },
106 { OV9640_COM3, OV9640_COM3_VP },
107 { OV9640_COM7, OV9640_COM7_CIF },
108 { OV9640_COM12, OV9640_COM12_RSVD },
109 { OV9640_COM13, OV9640_COM13_GAMMA_RAW | OV9640_COM13_MATRIX_EN },
110 { OV9640_COM15, OV9640_COM15_OR_10F0 },
111};
112
113static const struct ov9640_reg ov9640_regs_vga[] = {
114 { OV9640_CLKRC, OV9640_CLKRC_DPLL_EN | OV9640_CLKRC_DIV(0x01) },
115 { OV9640_COM3, OV9640_COM3_VP },
116 { OV9640_COM7, OV9640_COM7_VGA },
117 { OV9640_COM12, OV9640_COM12_RSVD },
118 { OV9640_COM13, OV9640_COM13_GAMMA_RAW | OV9640_COM13_MATRIX_EN },
119 { OV9640_COM15, OV9640_COM15_OR_10F0 },
120};
121
122static const struct ov9640_reg ov9640_regs_sxga[] = {
123 { OV9640_CLKRC, OV9640_CLKRC_DPLL_EN | OV9640_CLKRC_DIV(0x01) },
124 { OV9640_COM3, OV9640_COM3_VP },
125 { OV9640_COM7, 0 },
126 { OV9640_COM12, OV9640_COM12_RSVD },
127 { OV9640_COM13, OV9640_COM13_GAMMA_RAW | OV9640_COM13_MATRIX_EN },
128 { OV9640_COM15, OV9640_COM15_OR_10F0 },
129};
130
131static const struct ov9640_reg ov9640_regs_yuv[] = {
132 { OV9640_MTX1, 0x58 },
133 { OV9640_MTX2, 0x48 },
134 { OV9640_MTX3, 0x10 },
135 { OV9640_MTX4, 0x28 },
136 { OV9640_MTX5, 0x48 },
137 { OV9640_MTX6, 0x70 },
138 { OV9640_MTX7, 0x40 },
139 { OV9640_MTX8, 0x40 },
140 { OV9640_MTX9, 0x40 },
141 { OV9640_MTXS, 0x0f },
142};
143
144static const struct ov9640_reg ov9640_regs_rgb[] = {
145 { OV9640_MTX1, 0x71 },
146 { OV9640_MTX2, 0x3e },
147 { OV9640_MTX3, 0x0c },
148 { OV9640_MTX4, 0x33 },
149 { OV9640_MTX5, 0x72 },
150 { OV9640_MTX6, 0x00 },
151 { OV9640_MTX7, 0x2b },
152 { OV9640_MTX8, 0x66 },
153 { OV9640_MTX9, 0xd2 },
154 { OV9640_MTXS, 0x65 },
155};
156
157/*
158 * TODO: this sensor also supports RGB555 and RGB565 formats, but support for
159 * them has not yet been sufficiently tested and so it is not included with
160 * this version of the driver. To test and debug these formats add two entries
161 * to the below array, see ov722x.c for an example.
162 */
163static const struct soc_camera_data_format ov9640_fmt_lists[] = {
164 {
165 .name = "UYVY",
166 .fourcc = V4L2_PIX_FMT_UYVY,
167 .depth = 16,
168 .colorspace = V4L2_COLORSPACE_JPEG,
169 },
170};
171
172static const struct v4l2_queryctrl ov9640_controls[] = {
173 {
174 .id = V4L2_CID_VFLIP,
175 .type = V4L2_CTRL_TYPE_BOOLEAN,
176 .name = "Flip Vertically",
177 .minimum = 0,
178 .maximum = 1,
179 .step = 1,
180 .default_value = 0,
181 },
182 {
183 .id = V4L2_CID_HFLIP,
184 .type = V4L2_CTRL_TYPE_BOOLEAN,
185 .name = "Flip Horizontally",
186 .minimum = 0,
187 .maximum = 1,
188 .step = 1,
189 .default_value = 0,
190 },
191};
192
193/* read a register */
194static int ov9640_reg_read(struct i2c_client *client, u8 reg, u8 *val)
195{
196 int ret;
197 u8 data = reg;
198 struct i2c_msg msg = {
199 .addr = client->addr,
200 .flags = 0,
201 .len = 1,
202 .buf = &data,
203 };
204
205 ret = i2c_transfer(client->adapter, &msg, 1);
206 if (ret < 0)
207 goto err;
208
209 msg.flags = I2C_M_RD;
210 ret = i2c_transfer(client->adapter, &msg, 1);
211 if (ret < 0)
212 goto err;
213
214 *val = data;
215 return 0;
216
217err:
218 dev_err(&client->dev, "Failed reading register 0x%02x!\n", reg);
219 return ret;
220}
221
222/* write a register */
223static int ov9640_reg_write(struct i2c_client *client, u8 reg, u8 val)
224{
225 int ret;
226 u8 _val;
227 unsigned char data[2] = { reg, val };
228 struct i2c_msg msg = {
229 .addr = client->addr,
230 .flags = 0,
231 .len = 2,
232 .buf = data,
233 };
234
235 ret = i2c_transfer(client->adapter, &msg, 1);
236 if (ret < 0) {
237 dev_err(&client->dev, "Failed writing register 0x%02x!\n", reg);
238 return ret;
239 }
240
241 /* we have to read the register back ... no idea why, maybe HW bug */
242 ret = ov9640_reg_read(client, reg, &_val);
243 if (ret)
244 dev_err(&client->dev,
245 "Failed reading back register 0x%02x!\n", reg);
246
247 return 0;
248}
249
250
251/* Read a register, alter its bits, write it back */
252static int ov9640_reg_rmw(struct i2c_client *client, u8 reg, u8 set, u8 unset)
253{
254 u8 val;
255 int ret;
256
257 ret = ov9640_reg_read(client, reg, &val);
258 if (ret) {
259 dev_err(&client->dev,
260 "[Read]-Modify-Write of register %02x failed!\n", reg);
261 return val;
262 }
263
264 val |= set;
265 val &= ~unset;
266
267 ret = ov9640_reg_write(client, reg, val);
268 if (ret)
269 dev_err(&client->dev,
270 "Read-Modify-[Write] of register %02x failed!\n", reg);
271
272 return ret;
273}
274
275/* Soft reset the camera. This has nothing to do with the RESET pin! */
276static int ov9640_reset(struct i2c_client *client)
277{
278 int ret;
279
280 ret = ov9640_reg_write(client, OV9640_COM7, OV9640_COM7_SCCB_RESET);
281 if (ret)
282 dev_err(&client->dev,
283 "An error occured while entering soft reset!\n");
284
285 return ret;
286}
287
288/* Start/Stop streaming from the device */
289static int ov9640_s_stream(struct v4l2_subdev *sd, int enable)
290{
291 return 0;
292}
293
294/* Alter bus settings on camera side */
295static int ov9640_set_bus_param(struct soc_camera_device *icd,
296 unsigned long flags)
297{
298 return 0;
299}
300
301/* Request bus settings on camera side */
302static unsigned long ov9640_query_bus_param(struct soc_camera_device *icd)
303{
304 struct soc_camera_link *icl = to_soc_camera_link(icd);
305
306 /*
307 * REVISIT: the camera probably can do 10 bit transfers, but I don't
308 * have those pins connected on my hardware.
309 */
310 unsigned long flags = SOCAM_PCLK_SAMPLE_RISING | SOCAM_MASTER |
311 SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_HSYNC_ACTIVE_HIGH |
312 SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8;
313
314 return soc_camera_apply_sensor_flags(icl, flags);
315}
316
317/* Get status of additional camera capabilities */
318static int ov9640_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
319{
320 struct i2c_client *client = sd->priv;
321 struct ov9640_priv *priv = container_of(i2c_get_clientdata(client),
322 struct ov9640_priv, subdev);
323
324 switch (ctrl->id) {
325 case V4L2_CID_VFLIP:
326 ctrl->value = priv->flag_vflip;
327 break;
328 case V4L2_CID_HFLIP:
329 ctrl->value = priv->flag_hflip;
330 break;
331 }
332 return 0;
333}
334
335/* Set status of additional camera capabilities */
336static int ov9640_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
337{
338 struct i2c_client *client = sd->priv;
339 struct ov9640_priv *priv = container_of(i2c_get_clientdata(client),
340 struct ov9640_priv, subdev);
341
342 int ret = 0;
343
344 switch (ctrl->id) {
345 case V4L2_CID_VFLIP:
346 priv->flag_vflip = ctrl->value;
347 if (ctrl->value)
348 ret = ov9640_reg_rmw(client, OV9640_MVFP,
349 OV9640_MVFP_V, 0);
350 else
351 ret = ov9640_reg_rmw(client, OV9640_MVFP,
352 0, OV9640_MVFP_V);
353 break;
354 case V4L2_CID_HFLIP:
355 priv->flag_hflip = ctrl->value;
356 if (ctrl->value)
357 ret = ov9640_reg_rmw(client, OV9640_MVFP,
358 OV9640_MVFP_H, 0);
359 else
360 ret = ov9640_reg_rmw(client, OV9640_MVFP,
361 0, OV9640_MVFP_H);
362 break;
363 }
364
365 return ret;
366}
367
368/* Get chip identification */
369static int ov9640_g_chip_ident(struct v4l2_subdev *sd,
370 struct v4l2_dbg_chip_ident *id)
371{
372 struct i2c_client *client = sd->priv;
373 struct ov9640_priv *priv = container_of(i2c_get_clientdata(client),
374 struct ov9640_priv, subdev);
375
376 id->ident = priv->model;
377 id->revision = priv->revision;
378
379 return 0;
380}
381
382#ifdef CONFIG_VIDEO_ADV_DEBUG
383static int ov9640_get_register(struct v4l2_subdev *sd,
384 struct v4l2_dbg_register *reg)
385{
386 struct i2c_client *client = sd->priv;
387 int ret;
388 u8 val;
389
390 if (reg->reg & ~0xff)
391 return -EINVAL;
392
393 reg->size = 1;
394
395 ret = ov9640_reg_read(client, reg->reg, &val);
396 if (ret)
397 return ret;
398
399 reg->val = (__u64)val;
400
401 return 0;
402}
403
404static int ov9640_set_register(struct v4l2_subdev *sd,
405 struct v4l2_dbg_register *reg)
406{
407 struct i2c_client *client = sd->priv;
408
409 if (reg->reg & ~0xff || reg->val & ~0xff)
410 return -EINVAL;
411
412 return ov9640_reg_write(client, reg->reg, reg->val);
413}
414#endif
415
416/* select nearest higher resolution for capture */
417static void ov9640_res_roundup(u32 *width, u32 *height)
418{
419 int i;
420 enum { QQCIF, QQVGA, QCIF, QVGA, CIF, VGA, SXGA };
421 int res_x[] = { 88, 160, 176, 320, 352, 640, 1280 };
422 int res_y[] = { 72, 120, 144, 240, 288, 480, 960 };
423
424 for (i = 0; i < ARRAY_SIZE(res_x); i++) {
425 if (res_x[i] >= *width && res_y[i] >= *height) {
426 *width = res_x[i];
427 *height = res_y[i];
428 return;
429 }
430 }
431
432 *width = res_x[SXGA];
433 *height = res_y[SXGA];
434}
435
436/* Prepare necessary register changes depending on color encoding */
437static void ov9640_alter_regs(u32 pixfmt, struct ov9640_reg_alt *alt)
438{
439 switch (pixfmt) {
440 case V4L2_PIX_FMT_UYVY:
441 alt->com12 = OV9640_COM12_YUV_AVG;
442 alt->com13 = OV9640_COM13_Y_DELAY_EN |
443 OV9640_COM13_YUV_DLY(0x01);
444 break;
445 case V4L2_PIX_FMT_RGB555:
446 alt->com7 = OV9640_COM7_RGB;
447 alt->com13 = OV9640_COM13_RGB_AVG;
448 alt->com15 = OV9640_COM15_RGB_555;
449 break;
450 case V4L2_PIX_FMT_RGB565:
451 alt->com7 = OV9640_COM7_RGB;
452 alt->com13 = OV9640_COM13_RGB_AVG;
453 alt->com15 = OV9640_COM15_RGB_565;
454 break;
455 };
456}
457
458/* Setup registers according to resolution and color encoding */
459static int ov9640_write_regs(struct i2c_client *client,
460 u32 width, u32 pixfmt, struct ov9640_reg_alt *alts)
461{
462 const struct ov9640_reg *ov9640_regs, *matrix_regs;
463 int ov9640_regs_len, matrix_regs_len;
464 int i, ret;
465 u8 val;
466
467 /* select register configuration for given resolution */
468 switch (width) {
469 case W_QQCIF:
470 ov9640_regs = ov9640_regs_qqcif;
471 ov9640_regs_len = ARRAY_SIZE(ov9640_regs_qqcif);
472 break;
473 case W_QQVGA:
474 ov9640_regs = ov9640_regs_qqvga;
475 ov9640_regs_len = ARRAY_SIZE(ov9640_regs_qqvga);
476 break;
477 case W_QCIF:
478 ov9640_regs = ov9640_regs_qcif;
479 ov9640_regs_len = ARRAY_SIZE(ov9640_regs_qcif);
480 break;
481 case W_QVGA:
482 ov9640_regs = ov9640_regs_qvga;
483 ov9640_regs_len = ARRAY_SIZE(ov9640_regs_qvga);
484 break;
485 case W_CIF:
486 ov9640_regs = ov9640_regs_cif;
487 ov9640_regs_len = ARRAY_SIZE(ov9640_regs_cif);
488 break;
489 case W_VGA:
490 ov9640_regs = ov9640_regs_vga;
491 ov9640_regs_len = ARRAY_SIZE(ov9640_regs_vga);
492 break;
493 case W_SXGA:
494 ov9640_regs = ov9640_regs_sxga;
495 ov9640_regs_len = ARRAY_SIZE(ov9640_regs_sxga);
496 break;
497 default:
498 dev_err(&client->dev, "Failed to select resolution!\n");
499 return -EINVAL;
500 }
501
502 /* select color matrix configuration for given color encoding */
503 if (pixfmt == V4L2_PIX_FMT_UYVY) {
504 matrix_regs = ov9640_regs_yuv;
505 matrix_regs_len = ARRAY_SIZE(ov9640_regs_yuv);
506 } else {
507 matrix_regs = ov9640_regs_rgb;
508 matrix_regs_len = ARRAY_SIZE(ov9640_regs_rgb);
509 }
510
511 /* write register settings into the module */
512 for (i = 0; i < ov9640_regs_len; i++) {
513 val = ov9640_regs[i].val;
514
515 switch (ov9640_regs[i].reg) {
516 case OV9640_COM7:
517 val |= alts->com7;
518 break;
519 case OV9640_COM12:
520 val |= alts->com12;
521 break;
522 case OV9640_COM13:
523 val |= alts->com13;
524 break;
525 case OV9640_COM15:
526 val |= alts->com15;
527 break;
528 }
529
530 ret = ov9640_reg_write(client, ov9640_regs[i].reg, val);
531 if (ret)
532 return ret;
533 }
534
535 /* write color matrix configuration into the module */
536 for (i = 0; i < matrix_regs_len; i++) {
537 ret = ov9640_reg_write(client, matrix_regs[i].reg,
538 matrix_regs[i].val);
539 if (ret)
540 return ret;
541 }
542
543 return 0;
544}
545
546/* program default register values */
547static int ov9640_prog_dflt(struct i2c_client *client)
548{
549 int i, ret;
550
551 for (i = 0; i < ARRAY_SIZE(ov9640_regs_dflt); i++) {
552 ret = ov9640_reg_write(client, ov9640_regs_dflt[i].reg,
553 ov9640_regs_dflt[i].val);
554 if (ret)
555 return ret;
556 }
557
558 /* wait for the changes to actually happen, 140ms are not enough yet */
559 mdelay(150);
560
561 return 0;
562}
563
564/* set the format we will capture in */
565static int ov9640_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
566{
567 struct i2c_client *client = sd->priv;
568 struct v4l2_pix_format *pix = &f->fmt.pix;
569 struct ov9640_reg_alt alts = {0};
570 int ret;
571
572 ov9640_res_roundup(&pix->width, &pix->height);
573 ov9640_alter_regs(pix->pixelformat, &alts);
574
575 ov9640_reset(client);
576
577 ret = ov9640_prog_dflt(client);
578 if (ret)
579 return ret;
580
581 return ov9640_write_regs(client, pix->width, pix->pixelformat, &alts);
582}
583
584static int ov9640_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
585{
586 struct v4l2_pix_format *pix = &f->fmt.pix;
587
588 ov9640_res_roundup(&pix->width, &pix->height);
589 pix->field = V4L2_FIELD_NONE;
590
591 return 0;
592}
593
594static int ov9640_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
595{
596 a->c.left = 0;
597 a->c.top = 0;
598 a->c.width = W_SXGA;
599 a->c.height = H_SXGA;
600 a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
601
602 return 0;
603}
604
605static int ov9640_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
606{
607 a->bounds.left = 0;
608 a->bounds.top = 0;
609 a->bounds.width = W_SXGA;
610 a->bounds.height = H_SXGA;
611 a->defrect = a->bounds;
612 a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
613 a->pixelaspect.numerator = 1;
614 a->pixelaspect.denominator = 1;
615
616 return 0;
617}
618
619
620
621static int ov9640_video_probe(struct soc_camera_device *icd,
622 struct i2c_client *client)
623{
624 struct ov9640_priv *priv = i2c_get_clientdata(client);
625 u8 pid, ver, midh, midl;
626 const char *devname;
627 int ret = 0;
628
629 /*
630 * We must have a parent by now. And it cannot be a wrong one.
631 * So this entire test is completely redundant.
632 */
633 if (!icd->dev.parent ||
634 to_soc_camera_host(icd->dev.parent)->nr != icd->iface) {
635 dev_err(&client->dev, "Parent missing or invalid!\n");
636 ret = -ENODEV;
637 goto err;
638 }
639
640 icd->formats = ov9640_fmt_lists;
641 icd->num_formats = ARRAY_SIZE(ov9640_fmt_lists);
642
643 /*
644 * check and show product ID and manufacturer ID
645 */
646
647 ret = ov9640_reg_read(client, OV9640_PID, &pid);
648 if (ret)
649 goto err;
650
651 ret = ov9640_reg_read(client, OV9640_VER, &ver);
652 if (ret)
653 goto err;
654
655 ret = ov9640_reg_read(client, OV9640_MIDH, &midh);
656 if (ret)
657 goto err;
658
659 ret = ov9640_reg_read(client, OV9640_MIDL, &midl);
660 if (ret)
661 goto err;
662
663 switch (VERSION(pid, ver)) {
664 case OV9640_V2:
665 devname = "ov9640";
666 priv->model = V4L2_IDENT_OV9640;
667 priv->revision = 2;
668 case OV9640_V3:
669 devname = "ov9640";
670 priv->model = V4L2_IDENT_OV9640;
671 priv->revision = 3;
672 break;
673 default:
674 dev_err(&client->dev, "Product ID error %x:%x\n", pid, ver);
675 ret = -ENODEV;
676 goto err;
677 }
678
679 dev_info(&client->dev, "%s Product ID %0x:%0x Manufacturer ID %x:%x\n",
680 devname, pid, ver, midh, midl);
681
682err:
683 return ret;
684}
685
686static struct soc_camera_ops ov9640_ops = {
687 .set_bus_param = ov9640_set_bus_param,
688 .query_bus_param = ov9640_query_bus_param,
689 .controls = ov9640_controls,
690 .num_controls = ARRAY_SIZE(ov9640_controls),
691};
692
693static struct v4l2_subdev_core_ops ov9640_core_ops = {
694 .g_ctrl = ov9640_g_ctrl,
695 .s_ctrl = ov9640_s_ctrl,
696 .g_chip_ident = ov9640_g_chip_ident,
697#ifdef CONFIG_VIDEO_ADV_DEBUG
698 .g_register = ov9640_get_register,
699 .s_register = ov9640_set_register,
700#endif
701
702};
703
704static struct v4l2_subdev_video_ops ov9640_video_ops = {
705 .s_stream = ov9640_s_stream,
706 .s_fmt = ov9640_s_fmt,
707 .try_fmt = ov9640_try_fmt,
708 .cropcap = ov9640_cropcap,
709 .g_crop = ov9640_g_crop,
710
711};
712
713static struct v4l2_subdev_ops ov9640_subdev_ops = {
714 .core = &ov9640_core_ops,
715 .video = &ov9640_video_ops,
716};
717
718/*
719 * i2c_driver function
720 */
721static int ov9640_probe(struct i2c_client *client,
722 const struct i2c_device_id *did)
723{
724 struct ov9640_priv *priv;
725 struct soc_camera_device *icd = client->dev.platform_data;
726 struct soc_camera_link *icl;
727 int ret;
728
729 if (!icd) {
730 dev_err(&client->dev, "Missing soc-camera data!\n");
731 return -EINVAL;
732 }
733
734 icl = to_soc_camera_link(icd);
735 if (!icl) {
736 dev_err(&client->dev, "Missing platform_data for driver\n");
737 return -EINVAL;
738 }
739
740 priv = kzalloc(sizeof(struct ov9640_priv), GFP_KERNEL);
741 if (!priv) {
742 dev_err(&client->dev,
743 "Failed to allocate memory for private data!\n");
744 return -ENOMEM;
745 }
746
747 v4l2_i2c_subdev_init(&priv->subdev, client, &ov9640_subdev_ops);
748
749 icd->ops = &ov9640_ops;
750
751 ret = ov9640_video_probe(icd, client);
752
753 if (ret) {
754 icd->ops = NULL;
755 i2c_set_clientdata(client, NULL);
756 kfree(priv);
757 }
758
759 return ret;
760}
761
762static int ov9640_remove(struct i2c_client *client)
763{
764 struct ov9640_priv *priv = i2c_get_clientdata(client);
765
766 i2c_set_clientdata(client, NULL);
767 kfree(priv);
768 return 0;
769}
770
771static const struct i2c_device_id ov9640_id[] = {
772 { "ov9640", 0 },
773 { }
774};
775MODULE_DEVICE_TABLE(i2c, ov9640_id);
776
777static struct i2c_driver ov9640_i2c_driver = {
778 .driver = {
779 .name = "ov9640",
780 },
781 .probe = ov9640_probe,
782 .remove = ov9640_remove,
783 .id_table = ov9640_id,
784};
785
786static int __init ov9640_module_init(void)
787{
788 return i2c_add_driver(&ov9640_i2c_driver);
789}
790
791static void __exit ov9640_module_exit(void)
792{
793 i2c_del_driver(&ov9640_i2c_driver);
794}
795
796module_init(ov9640_module_init);
797module_exit(ov9640_module_exit);
798
799MODULE_DESCRIPTION("SoC Camera driver for OmniVision OV96xx");
800MODULE_AUTHOR("Marek Vasut <marek.vasut@gmail.com>");
801MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/video/ov9640.h b/drivers/media/video/ov9640.h
new file mode 100644
index 000000000000..f8a51b70792e
--- /dev/null
+++ b/drivers/media/video/ov9640.h
@@ -0,0 +1,209 @@
1/*
2 * OmniVision OV96xx Camera Header File
3 *
4 * Copyright (C) 2009 Marek Vasut <marek.vasut@gmail.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 version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#ifndef __DRIVERS_MEDIA_VIDEO_OV9640_H__
12#define __DRIVERS_MEDIA_VIDEO_OV9640_H__
13
14/* Register definitions */
15#define OV9640_GAIN 0x00
16#define OV9640_BLUE 0x01
17#define OV9640_RED 0x02
18#define OV9640_VFER 0x03
19#define OV9640_COM1 0x04
20#define OV9640_BAVE 0x05
21#define OV9640_GEAVE 0x06
22#define OV9640_RSID 0x07
23#define OV9640_RAVE 0x08
24#define OV9640_COM2 0x09
25#define OV9640_PID 0x0a
26#define OV9640_VER 0x0b
27#define OV9640_COM3 0x0c
28#define OV9640_COM4 0x0d
29#define OV9640_COM5 0x0e
30#define OV9640_COM6 0x0f
31#define OV9640_AECH 0x10
32#define OV9640_CLKRC 0x11
33#define OV9640_COM7 0x12
34#define OV9640_COM8 0x13
35#define OV9640_COM9 0x14
36#define OV9640_COM10 0x15
37/* 0x16 - RESERVED */
38#define OV9640_HSTART 0x17
39#define OV9640_HSTOP 0x18
40#define OV9640_VSTART 0x19
41#define OV9640_VSTOP 0x1a
42#define OV9640_PSHFT 0x1b
43#define OV9640_MIDH 0x1c
44#define OV9640_MIDL 0x1d
45#define OV9640_MVFP 0x1e
46#define OV9640_LAEC 0x1f
47#define OV9640_BOS 0x20
48#define OV9640_GBOS 0x21
49#define OV9640_GROS 0x22
50#define OV9640_ROS 0x23
51#define OV9640_AEW 0x24
52#define OV9640_AEB 0x25
53#define OV9640_VPT 0x26
54#define OV9640_BBIAS 0x27
55#define OV9640_GBBIAS 0x28
56/* 0x29 - RESERVED */
57#define OV9640_EXHCH 0x2a
58#define OV9640_EXHCL 0x2b
59#define OV9640_RBIAS 0x2c
60#define OV9640_ADVFL 0x2d
61#define OV9640_ADVFH 0x2e
62#define OV9640_YAVE 0x2f
63#define OV9640_HSYST 0x30
64#define OV9640_HSYEN 0x31
65#define OV9640_HREF 0x32
66#define OV9640_CHLF 0x33
67#define OV9640_ARBLM 0x34
68/* 0x35..0x36 - RESERVED */
69#define OV9640_ADC 0x37
70#define OV9640_ACOM 0x38
71#define OV9640_OFON 0x39
72#define OV9640_TSLB 0x3a
73#define OV9640_COM11 0x3b
74#define OV9640_COM12 0x3c
75#define OV9640_COM13 0x3d
76#define OV9640_COM14 0x3e
77#define OV9640_EDGE 0x3f
78#define OV9640_COM15 0x40
79#define OV9640_COM16 0x41
80#define OV9640_COM17 0x42
81/* 0x43..0x4e - RESERVED */
82#define OV9640_MTX1 0x4f
83#define OV9640_MTX2 0x50
84#define OV9640_MTX3 0x51
85#define OV9640_MTX4 0x52
86#define OV9640_MTX5 0x53
87#define OV9640_MTX6 0x54
88#define OV9640_MTX7 0x55
89#define OV9640_MTX8 0x56
90#define OV9640_MTX9 0x57
91#define OV9640_MTXS 0x58
92/* 0x59..0x61 - RESERVED */
93#define OV9640_LCC1 0x62
94#define OV9640_LCC2 0x63
95#define OV9640_LCC3 0x64
96#define OV9640_LCC4 0x65
97#define OV9640_LCC5 0x66
98#define OV9640_MANU 0x67
99#define OV9640_MANV 0x68
100#define OV9640_HV 0x69
101#define OV9640_MBD 0x6a
102#define OV9640_DBLV 0x6b
103#define OV9640_GSP 0x6c /* ... till 0x7b */
104#define OV9640_GST 0x7c /* ... till 0x8a */
105
106#define OV9640_CLKRC_DPLL_EN 0x80
107#define OV9640_CLKRC_DIRECT 0x40
108#define OV9640_CLKRC_DIV(x) ((x) & 0x3f)
109
110#define OV9640_PSHFT_VAL(x) ((x) & 0xff)
111
112#define OV9640_ACOM_2X_ANALOG 0x80
113#define OV9640_ACOM_RSVD 0x12
114
115#define OV9640_MVFP_V 0x10
116#define OV9640_MVFP_H 0x20
117
118#define OV9640_COM1_HREF_NOSKIP 0x00
119#define OV9640_COM1_HREF_2SKIP 0x04
120#define OV9640_COM1_HREF_3SKIP 0x08
121#define OV9640_COM1_QQFMT 0x20
122
123#define OV9640_COM2_SSM 0x10
124
125#define OV9640_COM3_VP 0x04
126
127#define OV9640_COM4_QQ_VP 0x80
128#define OV9640_COM4_RSVD 0x40
129
130#define OV9640_COM5_SYSCLK 0x80
131#define OV9640_COM5_LONGEXP 0x01
132
133#define OV9640_COM6_OPT_BLC 0x40
134#define OV9640_COM6_ADBLC_BIAS 0x08
135#define OV9640_COM6_FMT_RST 0x82
136#define OV9640_COM6_ADBLC_OPTEN 0x01
137
138#define OV9640_COM7_RAW_RGB 0x01
139#define OV9640_COM7_RGB 0x04
140#define OV9640_COM7_QCIF 0x08
141#define OV9640_COM7_QVGA 0x10
142#define OV9640_COM7_CIF 0x20
143#define OV9640_COM7_VGA 0x40
144#define OV9640_COM7_SCCB_RESET 0x80
145
146#define OV9640_TSLB_YVYU_YUYV 0x04
147#define OV9640_TSLB_YUYV_UYVY 0x08
148
149#define OV9640_COM12_YUV_AVG 0x04
150#define OV9640_COM12_RSVD 0x40
151
152#define OV9640_COM13_GAMMA_NONE 0x00
153#define OV9640_COM13_GAMMA_Y 0x40
154#define OV9640_COM13_GAMMA_RAW 0x80
155#define OV9640_COM13_RGB_AVG 0x20
156#define OV9640_COM13_MATRIX_EN 0x10
157#define OV9640_COM13_Y_DELAY_EN 0x08
158#define OV9640_COM13_YUV_DLY(x) ((x) & 0x07)
159
160#define OV9640_COM15_OR_00FF 0x00
161#define OV9640_COM15_OR_01FE 0x40
162#define OV9640_COM15_OR_10F0 0xc0
163#define OV9640_COM15_RGB_NORM 0x00
164#define OV9640_COM15_RGB_565 0x10
165#define OV9640_COM15_RGB_555 0x30
166
167#define OV9640_COM16_RB_AVG 0x01
168
169/* IDs */
170#define OV9640_V2 0x9648
171#define OV9640_V3 0x9649
172#define VERSION(pid, ver) (((pid) << 8) | ((ver) & 0xFF))
173
174/* supported resolutions */
175enum {
176 W_QQCIF = 88,
177 W_QQVGA = 160,
178 W_QCIF = 176,
179 W_QVGA = 320,
180 W_CIF = 352,
181 W_VGA = 640,
182 W_SXGA = 1280
183};
184#define H_SXGA 960
185
186/* Misc. structures */
187struct ov9640_reg_alt {
188 u8 com7;
189 u8 com12;
190 u8 com13;
191 u8 com15;
192};
193
194struct ov9640_reg {
195 u8 reg;
196 u8 val;
197};
198
199struct ov9640_priv {
200 struct v4l2_subdev subdev;
201
202 int model;
203 int revision;
204
205 bool flag_vflip;
206 bool flag_hflip;
207};
208
209#endif /* __DRIVERS_MEDIA_VIDEO_OV9640_H__ */
diff --git a/drivers/media/video/pms.c b/drivers/media/video/pms.c
index a1ad38fc49c1..73ec970ca5ca 100644
--- a/drivers/media/video/pms.c
+++ b/drivers/media/video/pms.c
@@ -14,8 +14,10 @@
14 * unless the userspace driver also doesn't work for you... 14 * unless the userspace driver also doesn't work for you...
15 * 15 *
16 * Changes: 16 * Changes:
17 * 08/07/2003 Daniele Bellucci <bellucda@tiscali.it> 17 * 25-11-2009 Hans Verkuil <hverkuil@xs4all.nl>
18 * - pms_capture: report back -EFAULT 18 * - converted to version 2 of the V4L API.
19 * 08/07/2003 Daniele Bellucci <bellucda@tiscali.it>
20 * - pms_capture: report back -EFAULT
19 */ 21 */
20 22
21#include <linux/module.h> 23#include <linux/module.h>
@@ -27,175 +29,183 @@
27#include <linux/mm.h> 29#include <linux/mm.h>
28#include <linux/ioport.h> 30#include <linux/ioport.h>
29#include <linux/init.h> 31#include <linux/init.h>
32#include <linux/version.h>
33#include <linux/mutex.h>
34#include <asm/uaccess.h>
30#include <asm/io.h> 35#include <asm/io.h>
31#include <linux/videodev.h> 36
37#include <linux/videodev2.h>
32#include <media/v4l2-common.h> 38#include <media/v4l2-common.h>
33#include <media/v4l2-ioctl.h> 39#include <media/v4l2-ioctl.h>
34#include <linux/mutex.h> 40#include <media/v4l2-device.h>
35 41
36#include <asm/uaccess.h> 42MODULE_LICENSE("GPL");
37 43
38 44
39#define MOTOROLA 1 45#define MOTOROLA 1
40#define PHILIPS2 2 46#define PHILIPS2 2 /* SAA7191 */
41#define PHILIPS1 3 47#define PHILIPS1 3
42#define MVVMEMORYWIDTH 0x40 /* 512 bytes */ 48#define MVVMEMORYWIDTH 0x40 /* 512 bytes */
43 49
44struct pms_device 50struct i2c_info {
45{
46 struct video_device v;
47 struct video_picture picture;
48 int height;
49 int width;
50 unsigned long in_use;
51 struct mutex lock;
52};
53
54struct i2c_info
55{
56 u8 slave; 51 u8 slave;
57 u8 sub; 52 u8 sub;
58 u8 data; 53 u8 data;
59 u8 hits; 54 u8 hits;
60}; 55};
61 56
62static int i2c_count; 57struct pms {
63static struct i2c_info i2cinfo[64]; 58 struct v4l2_device v4l2_dev;
59 struct video_device vdev;
60 int height;
61 int width;
62 int depth;
63 int input;
64 s32 brightness, saturation, hue, contrast;
65 unsigned long in_use;
66 struct mutex lock;
67 int i2c_count;
68 struct i2c_info i2cinfo[64];
69
70 int decoder;
71 int standard; /* 0 - auto 1 - ntsc 2 - pal 3 - secam */
72 v4l2_std_id std;
73 int io;
74 int data;
75 void __iomem *mem;
76};
64 77
65static int decoder = PHILIPS2; 78static struct pms pms_card;
66static int standard; /* 0 - auto 1 - ntsc 2 - pal 3 - secam */
67 79
68/* 80/*
69 * I/O ports and Shared Memory 81 * I/O ports and Shared Memory
70 */ 82 */
71 83
72static int io_port = 0x250; 84static int io_port = 0x250;
73static int data_port = 0x251; 85module_param(io_port, int, 0);
74static int mem_base = 0xC8000;
75static void __iomem *mem;
76static int video_nr = -1;
77 86
87static int mem_base = 0xc8000;
88module_param(mem_base, int, 0);
78 89
90static int video_nr = -1;
91module_param(video_nr, int, 0);
79 92
80static inline void mvv_write(u8 index, u8 value) 93
94static inline void mvv_write(struct pms *dev, u8 index, u8 value)
81{ 95{
82 outw(index|(value<<8), io_port); 96 outw(index | (value << 8), dev->io);
83} 97}
84 98
85static inline u8 mvv_read(u8 index) 99static inline u8 mvv_read(struct pms *dev, u8 index)
86{ 100{
87 outb(index, io_port); 101 outb(index, dev->io);
88 return inb(data_port); 102 return inb(dev->data);
89} 103}
90 104
91static int pms_i2c_stat(u8 slave) 105static int pms_i2c_stat(struct pms *dev, u8 slave)
92{ 106{
93 int counter; 107 int counter = 0;
94 int i; 108 int i;
95 109
96 outb(0x28, io_port); 110 outb(0x28, dev->io);
97 111
98 counter=0; 112 while ((inb(dev->data) & 0x01) == 0)
99 while((inb(data_port)&0x01)==0) 113 if (counter++ == 256)
100 if(counter++==256)
101 break; 114 break;
102 115
103 while((inb(data_port)&0x01)!=0) 116 while ((inb(dev->data) & 0x01) != 0)
104 if(counter++==256) 117 if (counter++ == 256)
105 break; 118 break;
106 119
107 outb(slave, io_port); 120 outb(slave, dev->io);
108 121
109 counter=0; 122 counter = 0;
110 while((inb(data_port)&0x01)==0) 123 while ((inb(dev->data) & 0x01) == 0)
111 if(counter++==256) 124 if (counter++ == 256)
112 break; 125 break;
113 126
114 while((inb(data_port)&0x01)!=0) 127 while ((inb(dev->data) & 0x01) != 0)
115 if(counter++==256) 128 if (counter++ == 256)
116 break; 129 break;
117 130
118 for(i=0;i<12;i++) 131 for (i = 0; i < 12; i++) {
119 { 132 char st = inb(dev->data);
120 char st=inb(data_port); 133
121 if((st&2)!=0) 134 if ((st & 2) != 0)
122 return -1; 135 return -1;
123 if((st&1)==0) 136 if ((st & 1) == 0)
124 break; 137 break;
125 } 138 }
126 outb(0x29, io_port); 139 outb(0x29, dev->io);
127 return inb(data_port); 140 return inb(dev->data);
128} 141}
129 142
130static int pms_i2c_write(u16 slave, u16 sub, u16 data) 143static int pms_i2c_write(struct pms *dev, u16 slave, u16 sub, u16 data)
131{ 144{
132 int skip=0; 145 int skip = 0;
133 int count; 146 int count;
134 int i; 147 int i;
135 148
136 for(i=0;i<i2c_count;i++) 149 for (i = 0; i < dev->i2c_count; i++) {
137 { 150 if ((dev->i2cinfo[i].slave == slave) &&
138 if((i2cinfo[i].slave==slave) && 151 (dev->i2cinfo[i].sub == sub)) {
139 (i2cinfo[i].sub == sub)) 152 if (dev->i2cinfo[i].data == data)
140 { 153 skip = 1;
141 if(i2cinfo[i].data==data) 154 dev->i2cinfo[i].data = data;
142 skip=1; 155 i = dev->i2c_count + 1;
143 i2cinfo[i].data=data;
144 i=i2c_count+1;
145 } 156 }
146 } 157 }
147 158
148 if(i==i2c_count && i2c_count<64) 159 if (i == dev->i2c_count && dev->i2c_count < 64) {
149 { 160 dev->i2cinfo[dev->i2c_count].slave = slave;
150 i2cinfo[i2c_count].slave=slave; 161 dev->i2cinfo[dev->i2c_count].sub = sub;
151 i2cinfo[i2c_count].sub=sub; 162 dev->i2cinfo[dev->i2c_count].data = data;
152 i2cinfo[i2c_count].data=data; 163 dev->i2c_count++;
153 i2c_count++;
154 } 164 }
155 165
156 if(skip) 166 if (skip)
157 return 0; 167 return 0;
158 168
159 mvv_write(0x29, sub); 169 mvv_write(dev, 0x29, sub);
160 mvv_write(0x2A, data); 170 mvv_write(dev, 0x2A, data);
161 mvv_write(0x28, slave); 171 mvv_write(dev, 0x28, slave);
162 172
163 outb(0x28, io_port); 173 outb(0x28, dev->io);
164 174
165 count=0; 175 count = 0;
166 while((inb(data_port)&1)==0) 176 while ((inb(dev->data) & 1) == 0)
167 if(count>255) 177 if (count > 255)
168 break; 178 break;
169 while((inb(data_port)&1)!=0) 179 while ((inb(dev->data) & 1) != 0)
170 if(count>255) 180 if (count > 255)
171 break; 181 break;
172 182
173 count=inb(data_port); 183 count = inb(dev->data);
174 184
175 if(count&2) 185 if (count & 2)
176 return -1; 186 return -1;
177 return count; 187 return count;
178} 188}
179 189
180static int pms_i2c_read(int slave, int sub) 190static int pms_i2c_read(struct pms *dev, int slave, int sub)
181{ 191{
182 int i=0; 192 int i;
183 for(i=0;i<i2c_count;i++) 193
184 { 194 for (i = 0; i < dev->i2c_count; i++) {
185 if(i2cinfo[i].slave==slave && i2cinfo[i].sub==sub) 195 if (dev->i2cinfo[i].slave == slave && dev->i2cinfo[i].sub == sub)
186 return i2cinfo[i].data; 196 return dev->i2cinfo[i].data;
187 } 197 }
188 return 0; 198 return 0;
189} 199}
190 200
191 201
192static void pms_i2c_andor(int slave, int sub, int and, int or) 202static void pms_i2c_andor(struct pms *dev, int slave, int sub, int and, int or)
193{ 203{
194 u8 tmp; 204 u8 tmp;
195 205
196 tmp=pms_i2c_read(slave, sub); 206 tmp = pms_i2c_read(dev, slave, sub);
197 tmp = (tmp&and)|or; 207 tmp = (tmp & and) | or;
198 pms_i2c_write(slave, sub, tmp); 208 pms_i2c_write(dev, slave, sub, tmp);
199} 209}
200 210
201/* 211/*
@@ -203,100 +213,108 @@ static void pms_i2c_andor(int slave, int sub, int and, int or)
203 */ 213 */
204 214
205 215
206static void pms_videosource(short source) 216static void pms_videosource(struct pms *dev, short source)
207{ 217{
208 mvv_write(0x2E, source?0x31:0x30); 218 switch (dev->decoder) {
219 case MOTOROLA:
220 break;
221 case PHILIPS2:
222 pms_i2c_andor(dev, 0x8a, 0x06, 0x7f, source ? 0x80 : 0);
223 break;
224 case PHILIPS1:
225 break;
226 }
227 mvv_write(dev, 0x2E, 0x31);
228 /* Was: mvv_write(dev, 0x2E, source ? 0x31 : 0x30);
229 But could not make this work correctly. Only Composite input
230 worked for me. */
209} 231}
210 232
211static void pms_hue(short hue) 233static void pms_hue(struct pms *dev, short hue)
212{ 234{
213 switch(decoder) 235 switch (dev->decoder) {
214 { 236 case MOTOROLA:
215 case MOTOROLA: 237 pms_i2c_write(dev, 0x8a, 0x00, hue);
216 pms_i2c_write(0x8A, 0x00, hue); 238 break;
217 break; 239 case PHILIPS2:
218 case PHILIPS2: 240 pms_i2c_write(dev, 0x8a, 0x07, hue);
219 pms_i2c_write(0x8A, 0x07, hue); 241 break;
220 break; 242 case PHILIPS1:
221 case PHILIPS1: 243 pms_i2c_write(dev, 0x42, 0x07, hue);
222 pms_i2c_write(0x42, 0x07, hue); 244 break;
223 break;
224 } 245 }
225} 246}
226 247
227static void pms_colour(short colour) 248static void pms_saturation(struct pms *dev, short sat)
228{ 249{
229 switch(decoder) 250 switch (dev->decoder) {
230 { 251 case MOTOROLA:
231 case MOTOROLA: 252 pms_i2c_write(dev, 0x8a, 0x00, sat);
232 pms_i2c_write(0x8A, 0x00, colour); 253 break;
233 break; 254 case PHILIPS1:
234 case PHILIPS1: 255 pms_i2c_write(dev, 0x42, 0x12, sat);
235 pms_i2c_write(0x42, 0x12, colour); 256 break;
236 break;
237 } 257 }
238} 258}
239 259
240 260
241static void pms_contrast(short contrast) 261static void pms_contrast(struct pms *dev, short contrast)
242{ 262{
243 switch(decoder) 263 switch (dev->decoder) {
244 { 264 case MOTOROLA:
245 case MOTOROLA: 265 pms_i2c_write(dev, 0x8a, 0x00, contrast);
246 pms_i2c_write(0x8A, 0x00, contrast); 266 break;
247 break; 267 case PHILIPS1:
248 case PHILIPS1: 268 pms_i2c_write(dev, 0x42, 0x13, contrast);
249 pms_i2c_write(0x42, 0x13, contrast); 269 break;
250 break;
251 } 270 }
252} 271}
253 272
254static void pms_brightness(short brightness) 273static void pms_brightness(struct pms *dev, short brightness)
255{ 274{
256 switch(decoder) 275 switch (dev->decoder) {
257 { 276 case MOTOROLA:
258 case MOTOROLA: 277 pms_i2c_write(dev, 0x8a, 0x00, brightness);
259 pms_i2c_write(0x8A, 0x00, brightness); 278 pms_i2c_write(dev, 0x8a, 0x00, brightness);
260 pms_i2c_write(0x8A, 0x00, brightness); 279 pms_i2c_write(dev, 0x8a, 0x00, brightness);
261 pms_i2c_write(0x8A, 0x00, brightness); 280 break;
262 break; 281 case PHILIPS1:
263 case PHILIPS1: 282 pms_i2c_write(dev, 0x42, 0x19, brightness);
264 pms_i2c_write(0x42, 0x19, brightness); 283 break;
265 break;
266 } 284 }
267} 285}
268 286
269 287
270static void pms_format(short format) 288static void pms_format(struct pms *dev, short format)
271{ 289{
272 int target; 290 int target;
273 standard = format;
274 291
275 if(decoder==PHILIPS1) 292 dev->standard = format;
276 target=0x42; 293
277 else if(decoder==PHILIPS2) 294 if (dev->decoder == PHILIPS1)
278 target=0x8A; 295 target = 0x42;
296 else if (dev->decoder == PHILIPS2)
297 target = 0x8a;
279 else 298 else
280 return; 299 return;
281 300
282 switch(format) 301 switch (format) {
283 { 302 case 0: /* Auto */
284 case 0: /* Auto */ 303 pms_i2c_andor(dev, target, 0x0d, 0xfe, 0x00);
285 pms_i2c_andor(target, 0x0D, 0xFE,0x00); 304 pms_i2c_andor(dev, target, 0x0f, 0x3f, 0x80);
286 pms_i2c_andor(target, 0x0F, 0x3F,0x80); 305 break;
287 break; 306 case 1: /* NTSC */
288 case 1: /* NTSC */ 307 pms_i2c_andor(dev, target, 0x0d, 0xfe, 0x00);
289 pms_i2c_andor(target, 0x0D, 0xFE, 0x00); 308 pms_i2c_andor(dev, target, 0x0f, 0x3f, 0x40);
290 pms_i2c_andor(target, 0x0F, 0x3F, 0x40); 309 break;
291 break; 310 case 2: /* PAL */
292 case 2: /* PAL */ 311 pms_i2c_andor(dev, target, 0x0d, 0xfe, 0x00);
293 pms_i2c_andor(target, 0x0D, 0xFE, 0x00); 312 pms_i2c_andor(dev, target, 0x0f, 0x3f, 0x00);
294 pms_i2c_andor(target, 0x0F, 0x3F, 0x00); 313 break;
295 break; 314 case 3: /* SECAM */
296 case 3: /* SECAM */ 315 pms_i2c_andor(dev, target, 0x0d, 0xfe, 0x01);
297 pms_i2c_andor(target, 0x0D, 0xFE, 0x01); 316 pms_i2c_andor(dev, target, 0x0f, 0x3f, 0x00);
298 pms_i2c_andor(target, 0x0F, 0x3F, 0x00); 317 break;
299 break;
300 } 318 }
301} 319}
302 320
@@ -308,18 +326,17 @@ static void pms_format(short format)
308 * people need it. We also don't yet use the PMS interrupt. 326 * people need it. We also don't yet use the PMS interrupt.
309 */ 327 */
310 328
311static void pms_hstart(short start) 329static void pms_hstart(struct pms *dev, short start)
312{ 330{
313 switch(decoder) 331 switch (dev->decoder) {
314 { 332 case PHILIPS1:
315 case PHILIPS1: 333 pms_i2c_write(dev, 0x8a, 0x05, start);
316 pms_i2c_write(0x8A, 0x05, start); 334 pms_i2c_write(dev, 0x8a, 0x18, start);
317 pms_i2c_write(0x8A, 0x18, start); 335 break;
318 break; 336 case PHILIPS2:
319 case PHILIPS2: 337 pms_i2c_write(dev, 0x42, 0x05, start);
320 pms_i2c_write(0x42, 0x05, start); 338 pms_i2c_write(dev, 0x42, 0x18, start);
321 pms_i2c_write(0x42, 0x18, start); 339 break;
322 break;
323 } 340 }
324} 341}
325 342
@@ -327,293 +344,271 @@ static void pms_hstart(short start)
327 * Bandpass filters 344 * Bandpass filters
328 */ 345 */
329 346
330static void pms_bandpass(short pass) 347static void pms_bandpass(struct pms *dev, short pass)
331{ 348{
332 if(decoder==PHILIPS2) 349 if (dev->decoder == PHILIPS2)
333 pms_i2c_andor(0x8A, 0x06, 0xCF, (pass&0x03)<<4); 350 pms_i2c_andor(dev, 0x8a, 0x06, 0xcf, (pass & 0x03) << 4);
334 else if(decoder==PHILIPS1) 351 else if (dev->decoder == PHILIPS1)
335 pms_i2c_andor(0x42, 0x06, 0xCF, (pass&0x03)<<4); 352 pms_i2c_andor(dev, 0x42, 0x06, 0xcf, (pass & 0x03) << 4);
336} 353}
337 354
338static void pms_antisnow(short snow) 355static void pms_antisnow(struct pms *dev, short snow)
339{ 356{
340 if(decoder==PHILIPS2) 357 if (dev->decoder == PHILIPS2)
341 pms_i2c_andor(0x8A, 0x06, 0xF3, (snow&0x03)<<2); 358 pms_i2c_andor(dev, 0x8a, 0x06, 0xf3, (snow & 0x03) << 2);
342 else if(decoder==PHILIPS1) 359 else if (dev->decoder == PHILIPS1)
343 pms_i2c_andor(0x42, 0x06, 0xF3, (snow&0x03)<<2); 360 pms_i2c_andor(dev, 0x42, 0x06, 0xf3, (snow & 0x03) << 2);
344} 361}
345 362
346static void pms_sharpness(short sharp) 363static void pms_sharpness(struct pms *dev, short sharp)
347{ 364{
348 if(decoder==PHILIPS2) 365 if (dev->decoder == PHILIPS2)
349 pms_i2c_andor(0x8A, 0x06, 0xFC, sharp&0x03); 366 pms_i2c_andor(dev, 0x8a, 0x06, 0xfc, sharp & 0x03);
350 else if(decoder==PHILIPS1) 367 else if (dev->decoder == PHILIPS1)
351 pms_i2c_andor(0x42, 0x06, 0xFC, sharp&0x03); 368 pms_i2c_andor(dev, 0x42, 0x06, 0xfc, sharp & 0x03);
352} 369}
353 370
354static void pms_chromaagc(short agc) 371static void pms_chromaagc(struct pms *dev, short agc)
355{ 372{
356 if(decoder==PHILIPS2) 373 if (dev->decoder == PHILIPS2)
357 pms_i2c_andor(0x8A, 0x0C, 0x9F, (agc&0x03)<<5); 374 pms_i2c_andor(dev, 0x8a, 0x0c, 0x9f, (agc & 0x03) << 5);
358 else if(decoder==PHILIPS1) 375 else if (dev->decoder == PHILIPS1)
359 pms_i2c_andor(0x42, 0x0C, 0x9F, (agc&0x03)<<5); 376 pms_i2c_andor(dev, 0x42, 0x0c, 0x9f, (agc & 0x03) << 5);
360} 377}
361 378
362static void pms_vertnoise(short noise) 379static void pms_vertnoise(struct pms *dev, short noise)
363{ 380{
364 if(decoder==PHILIPS2) 381 if (dev->decoder == PHILIPS2)
365 pms_i2c_andor(0x8A, 0x10, 0xFC, noise&3); 382 pms_i2c_andor(dev, 0x8a, 0x10, 0xfc, noise & 3);
366 else if(decoder==PHILIPS1) 383 else if (dev->decoder == PHILIPS1)
367 pms_i2c_andor(0x42, 0x10, 0xFC, noise&3); 384 pms_i2c_andor(dev, 0x42, 0x10, 0xfc, noise & 3);
368} 385}
369 386
370static void pms_forcecolour(short colour) 387static void pms_forcecolour(struct pms *dev, short colour)
371{ 388{
372 if(decoder==PHILIPS2) 389 if (dev->decoder == PHILIPS2)
373 pms_i2c_andor(0x8A, 0x0C, 0x7F, (colour&1)<<7); 390 pms_i2c_andor(dev, 0x8a, 0x0c, 0x7f, (colour & 1) << 7);
374 else if(decoder==PHILIPS1) 391 else if (dev->decoder == PHILIPS1)
375 pms_i2c_andor(0x42, 0x0C, 0x7, (colour&1)<<7); 392 pms_i2c_andor(dev, 0x42, 0x0c, 0x7, (colour & 1) << 7);
376} 393}
377 394
378static void pms_antigamma(short gamma) 395static void pms_antigamma(struct pms *dev, short gamma)
379{ 396{
380 if(decoder==PHILIPS2) 397 if (dev->decoder == PHILIPS2)
381 pms_i2c_andor(0xB8, 0x00, 0x7F, (gamma&1)<<7); 398 pms_i2c_andor(dev, 0xb8, 0x00, 0x7f, (gamma & 1) << 7);
382 else if(decoder==PHILIPS1) 399 else if (dev->decoder == PHILIPS1)
383 pms_i2c_andor(0x42, 0x20, 0x7, (gamma&1)<<7); 400 pms_i2c_andor(dev, 0x42, 0x20, 0x7, (gamma & 1) << 7);
384} 401}
385 402
386static void pms_prefilter(short filter) 403static void pms_prefilter(struct pms *dev, short filter)
387{ 404{
388 if(decoder==PHILIPS2) 405 if (dev->decoder == PHILIPS2)
389 pms_i2c_andor(0x8A, 0x06, 0xBF, (filter&1)<<6); 406 pms_i2c_andor(dev, 0x8a, 0x06, 0xbf, (filter & 1) << 6);
390 else if(decoder==PHILIPS1) 407 else if (dev->decoder == PHILIPS1)
391 pms_i2c_andor(0x42, 0x06, 0xBF, (filter&1)<<6); 408 pms_i2c_andor(dev, 0x42, 0x06, 0xbf, (filter & 1) << 6);
392} 409}
393 410
394static void pms_hfilter(short filter) 411static void pms_hfilter(struct pms *dev, short filter)
395{ 412{
396 if(decoder==PHILIPS2) 413 if (dev->decoder == PHILIPS2)
397 pms_i2c_andor(0xB8, 0x04, 0x1F, (filter&7)<<5); 414 pms_i2c_andor(dev, 0xb8, 0x04, 0x1f, (filter & 7) << 5);
398 else if(decoder==PHILIPS1) 415 else if (dev->decoder == PHILIPS1)
399 pms_i2c_andor(0x42, 0x24, 0x1F, (filter&7)<<5); 416 pms_i2c_andor(dev, 0x42, 0x24, 0x1f, (filter & 7) << 5);
400} 417}
401 418
402static void pms_vfilter(short filter) 419static void pms_vfilter(struct pms *dev, short filter)
403{ 420{
404 if(decoder==PHILIPS2) 421 if (dev->decoder == PHILIPS2)
405 pms_i2c_andor(0xB8, 0x08, 0x9F, (filter&3)<<5); 422 pms_i2c_andor(dev, 0xb8, 0x08, 0x9f, (filter & 3) << 5);
406 else if(decoder==PHILIPS1) 423 else if (dev->decoder == PHILIPS1)
407 pms_i2c_andor(0x42, 0x28, 0x9F, (filter&3)<<5); 424 pms_i2c_andor(dev, 0x42, 0x28, 0x9f, (filter & 3) << 5);
408} 425}
409 426
410static void pms_killcolour(short colour) 427static void pms_killcolour(struct pms *dev, short colour)
411{ 428{
412 if(decoder==PHILIPS2) 429 if (dev->decoder == PHILIPS2) {
413 { 430 pms_i2c_andor(dev, 0x8a, 0x08, 0x07, (colour & 0x1f) << 3);
414 pms_i2c_andor(0x8A, 0x08, 0x07, (colour&0x1F)<<3); 431 pms_i2c_andor(dev, 0x8a, 0x09, 0x07, (colour & 0x1f) << 3);
415 pms_i2c_andor(0x8A, 0x09, 0x07, (colour&0x1F)<<3); 432 } else if (dev->decoder == PHILIPS1) {
416 } 433 pms_i2c_andor(dev, 0x42, 0x08, 0x07, (colour & 0x1f) << 3);
417 else if(decoder==PHILIPS1) 434 pms_i2c_andor(dev, 0x42, 0x09, 0x07, (colour & 0x1f) << 3);
418 {
419 pms_i2c_andor(0x42, 0x08, 0x07, (colour&0x1F)<<3);
420 pms_i2c_andor(0x42, 0x09, 0x07, (colour&0x1F)<<3);
421 } 435 }
422} 436}
423 437
424static void pms_chromagain(short chroma) 438static void pms_chromagain(struct pms *dev, short chroma)
425{ 439{
426 if(decoder==PHILIPS2) 440 if (dev->decoder == PHILIPS2)
427 { 441 pms_i2c_write(dev, 0x8a, 0x11, chroma);
428 pms_i2c_write(0x8A, 0x11, chroma); 442 else if (dev->decoder == PHILIPS1)
429 } 443 pms_i2c_write(dev, 0x42, 0x11, chroma);
430 else if(decoder==PHILIPS1)
431 {
432 pms_i2c_write(0x42, 0x11, chroma);
433 }
434} 444}
435 445
436 446
437static void pms_spacialcompl(short data) 447static void pms_spacialcompl(struct pms *dev, short data)
438{ 448{
439 mvv_write(0x3B, data); 449 mvv_write(dev, 0x3b, data);
440} 450}
441 451
442static void pms_spacialcomph(short data) 452static void pms_spacialcomph(struct pms *dev, short data)
443{ 453{
444 mvv_write(0x3A, data); 454 mvv_write(dev, 0x3a, data);
445} 455}
446 456
447static void pms_vstart(short start) 457static void pms_vstart(struct pms *dev, short start)
448{ 458{
449 mvv_write(0x16, start); 459 mvv_write(dev, 0x16, start);
450 mvv_write(0x17, (start>>8)&0x01); 460 mvv_write(dev, 0x17, (start >> 8) & 0x01);
451} 461}
452 462
453#endif 463#endif
454 464
455static void pms_secamcross(short cross) 465static void pms_secamcross(struct pms *dev, short cross)
456{ 466{
457 if(decoder==PHILIPS2) 467 if (dev->decoder == PHILIPS2)
458 pms_i2c_andor(0x8A, 0x0F, 0xDF, (cross&1)<<5); 468 pms_i2c_andor(dev, 0x8a, 0x0f, 0xdf, (cross & 1) << 5);
459 else if(decoder==PHILIPS1) 469 else if (dev->decoder == PHILIPS1)
460 pms_i2c_andor(0x42, 0x0F, 0xDF, (cross&1)<<5); 470 pms_i2c_andor(dev, 0x42, 0x0f, 0xdf, (cross & 1) << 5);
461} 471}
462 472
463 473
464static void pms_swsense(short sense) 474static void pms_swsense(struct pms *dev, short sense)
465{ 475{
466 if(decoder==PHILIPS2) 476 if (dev->decoder == PHILIPS2) {
467 { 477 pms_i2c_write(dev, 0x8a, 0x0a, sense);
468 pms_i2c_write(0x8A, 0x0A, sense); 478 pms_i2c_write(dev, 0x8a, 0x0b, sense);
469 pms_i2c_write(0x8A, 0x0B, sense); 479 } else if (dev->decoder == PHILIPS1) {
470 } 480 pms_i2c_write(dev, 0x42, 0x0a, sense);
471 else if(decoder==PHILIPS1) 481 pms_i2c_write(dev, 0x42, 0x0b, sense);
472 {
473 pms_i2c_write(0x42, 0x0A, sense);
474 pms_i2c_write(0x42, 0x0B, sense);
475 } 482 }
476} 483}
477 484
478 485
479static void pms_framerate(short frr) 486static void pms_framerate(struct pms *dev, short frr)
480{ 487{
481 int fps=(standard==1)?30:25; 488 int fps = (dev->std & V4L2_STD_525_60) ? 30 : 25;
482 if(frr==0) 489
490 if (frr == 0)
483 return; 491 return;
484 fps=fps/frr; 492 fps = fps/frr;
485 mvv_write(0x14,0x80|fps); 493 mvv_write(dev, 0x14, 0x80 | fps);
486 mvv_write(0x15,1); 494 mvv_write(dev, 0x15, 1);
487} 495}
488 496
489static void pms_vert(u8 deciden, u8 decinum) 497static void pms_vert(struct pms *dev, u8 deciden, u8 decinum)
490{ 498{
491 mvv_write(0x1C, deciden); /* Denominator */ 499 mvv_write(dev, 0x1c, deciden); /* Denominator */
492 mvv_write(0x1D, decinum); /* Numerator */ 500 mvv_write(dev, 0x1d, decinum); /* Numerator */
493} 501}
494 502
495/* 503/*
496 * Turn 16bit ratios into best small ratio the chipset can grok 504 * Turn 16bit ratios into best small ratio the chipset can grok
497 */ 505 */
498 506
499static void pms_vertdeci(unsigned short decinum, unsigned short deciden) 507static void pms_vertdeci(struct pms *dev, unsigned short decinum, unsigned short deciden)
500{ 508{
501 /* Knock it down by /5 once */ 509 /* Knock it down by / 5 once */
502 if(decinum%5==0) 510 if (decinum % 5 == 0) {
503 { 511 deciden /= 5;
504 deciden/=5; 512 decinum /= 5;
505 decinum/=5;
506 } 513 }
507 /* 514 /*
508 * 3's 515 * 3's
509 */ 516 */
510 while(decinum%3==0 && deciden%3==0) 517 while (decinum % 3 == 0 && deciden % 3 == 0) {
511 { 518 deciden /= 3;
512 deciden/=3; 519 decinum /= 3;
513 decinum/=3;
514 } 520 }
515 /* 521 /*
516 * 2's 522 * 2's
517 */ 523 */
518 while(decinum%2==0 && deciden%2==0) 524 while (decinum % 2 == 0 && deciden % 2 == 0) {
519 { 525 decinum /= 2;
520 decinum/=2; 526 deciden /= 2;
521 deciden/=2;
522 } 527 }
523 /* 528 /*
524 * Fudgyify 529 * Fudgyify
525 */ 530 */
526 while(deciden>32) 531 while (deciden > 32) {
527 { 532 deciden /= 2;
528 deciden/=2; 533 decinum = (decinum + 1) / 2;
529 decinum=(decinum+1)/2;
530 } 534 }
531 if(deciden==32) 535 if (deciden == 32)
532 deciden--; 536 deciden--;
533 pms_vert(deciden,decinum); 537 pms_vert(dev, deciden, decinum);
534} 538}
535 539
536static void pms_horzdeci(short decinum, short deciden) 540static void pms_horzdeci(struct pms *dev, short decinum, short deciden)
537{ 541{
538 if(decinum<=512) 542 if (decinum <= 512) {
539 { 543 if (decinum % 5 == 0) {
540 if(decinum%5==0) 544 decinum /= 5;
541 { 545 deciden /= 5;
542 decinum/=5;
543 deciden/=5;
544 } 546 }
545 } 547 } else {
546 else 548 decinum = 512;
547 { 549 deciden = 640; /* 768 would be ideal */
548 decinum=512;
549 deciden=640; /* 768 would be ideal */
550 } 550 }
551 551
552 while(((decinum|deciden)&1)==0) 552 while (((decinum | deciden) & 1) == 0) {
553 { 553 decinum >>= 1;
554 decinum>>=1; 554 deciden >>= 1;
555 deciden>>=1;
556 } 555 }
557 while(deciden>32) 556 while (deciden > 32) {
558 { 557 deciden >>= 1;
559 deciden>>=1; 558 decinum = (decinum + 1) >> 1;
560 decinum=(decinum+1)>>1;
561 } 559 }
562 if(deciden==32) 560 if (deciden == 32)
563 deciden--; 561 deciden--;
564 562
565 mvv_write(0x24, 0x80|deciden); 563 mvv_write(dev, 0x24, 0x80 | deciden);
566 mvv_write(0x25, decinum); 564 mvv_write(dev, 0x25, decinum);
567} 565}
568 566
569static void pms_resolution(short width, short height) 567static void pms_resolution(struct pms *dev, short width, short height)
570{ 568{
571 int fg_height; 569 int fg_height;
572 570
573 fg_height=height; 571 fg_height = height;
574 if(fg_height>280) 572 if (fg_height > 280)
575 fg_height=280; 573 fg_height = 280;
576 574
577 mvv_write(0x18, fg_height); 575 mvv_write(dev, 0x18, fg_height);
578 mvv_write(0x19, fg_height>>8); 576 mvv_write(dev, 0x19, fg_height >> 8);
579 577
580 if(standard==1) 578 if (dev->std & V4L2_STD_525_60) {
581 { 579 mvv_write(dev, 0x1a, 0xfc);
582 mvv_write(0x1A, 0xFC); 580 mvv_write(dev, 0x1b, 0x00);
583 mvv_write(0x1B, 0x00); 581 if (height > fg_height)
584 if(height>fg_height) 582 pms_vertdeci(dev, 240, 240);
585 pms_vertdeci(240,240);
586 else 583 else
587 pms_vertdeci(fg_height,240); 584 pms_vertdeci(dev, fg_height, 240);
588 } 585 } else {
589 else 586 mvv_write(dev, 0x1a, 0x1a);
590 { 587 mvv_write(dev, 0x1b, 0x01);
591 mvv_write(0x1A, 0x1A); 588 if (fg_height > 256)
592 mvv_write(0x1B, 0x01); 589 pms_vertdeci(dev, 270, 270);
593 if(fg_height>256)
594 pms_vertdeci(270,270);
595 else 590 else
596 pms_vertdeci(fg_height, 270); 591 pms_vertdeci(dev, fg_height, 270);
597 } 592 }
598 mvv_write(0x12,0); 593 mvv_write(dev, 0x12, 0);
599 mvv_write(0x13, MVVMEMORYWIDTH); 594 mvv_write(dev, 0x13, MVVMEMORYWIDTH);
600 mvv_write(0x42, 0x00); 595 mvv_write(dev, 0x42, 0x00);
601 mvv_write(0x43, 0x00); 596 mvv_write(dev, 0x43, 0x00);
602 mvv_write(0x44, MVVMEMORYWIDTH); 597 mvv_write(dev, 0x44, MVVMEMORYWIDTH);
603 598
604 mvv_write(0x22, width+8); 599 mvv_write(dev, 0x22, width + 8);
605 mvv_write(0x23, (width+8)>> 8); 600 mvv_write(dev, 0x23, (width + 8) >> 8);
606 601
607 if(standard==1) 602 if (dev->std & V4L2_STD_525_60)
608 pms_horzdeci(width,640); 603 pms_horzdeci(dev, width, 640);
609 else 604 else
610 pms_horzdeci(width+8, 768); 605 pms_horzdeci(dev, width + 8, 768);
611 606
612 mvv_write(0x30, mvv_read(0x30)&0xFE); 607 mvv_write(dev, 0x30, mvv_read(dev, 0x30) & 0xfe);
613 mvv_write(0x08, mvv_read(0x08)|0x01); 608 mvv_write(dev, 0x08, mvv_read(dev, 0x08) | 0x01);
614 mvv_write(0x01, mvv_read(0x01)&0xFD); 609 mvv_write(dev, 0x01, mvv_read(dev, 0x01) & 0xfd);
615 mvv_write(0x32, 0x00); 610 mvv_write(dev, 0x32, 0x00);
616 mvv_write(0x33, MVVMEMORYWIDTH); 611 mvv_write(dev, 0x33, MVVMEMORYWIDTH);
617} 612}
618 613
619 614
@@ -621,52 +616,49 @@ static void pms_resolution(short width, short height)
621 * Set Input 616 * Set Input
622 */ 617 */
623 618
624static void pms_vcrinput(short input) 619static void pms_vcrinput(struct pms *dev, short input)
625{ 620{
626 if(decoder==PHILIPS2) 621 if (dev->decoder == PHILIPS2)
627 pms_i2c_andor(0x8A,0x0D,0x7F,(input&1)<<7); 622 pms_i2c_andor(dev, 0x8a, 0x0d, 0x7f, (input & 1) << 7);
628 else if(decoder==PHILIPS1) 623 else if (dev->decoder == PHILIPS1)
629 pms_i2c_andor(0x42,0x0D,0x7F,(input&1)<<7); 624 pms_i2c_andor(dev, 0x42, 0x0d, 0x7f, (input & 1) << 7);
630} 625}
631 626
632 627
633static int pms_capture(struct pms_device *dev, char __user *buf, int rgb555, int count) 628static int pms_capture(struct pms *dev, char __user *buf, int rgb555, int count)
634{ 629{
635 int y; 630 int y;
636 int dw = 2*dev->width; 631 int dw = 2 * dev->width;
637 632 char tmp[dw + 32]; /* using a temp buffer is faster than direct */
638 char tmp[dw+32]; /* using a temp buffer is faster than direct */
639 int cnt = 0; 633 int cnt = 0;
640 int len=0; 634 int len = 0;
641 unsigned char r8 = 0x5; /* value for reg8 */ 635 unsigned char r8 = 0x5; /* value for reg8 */
642 636
643 if (rgb555) 637 if (rgb555)
644 r8 |= 0x20; /* else use untranslated rgb = 565 */ 638 r8 |= 0x20; /* else use untranslated rgb = 565 */
645 mvv_write(0x08,r8); /* capture rgb555/565, init DRAM, PC enable */ 639 mvv_write(dev, 0x08, r8); /* capture rgb555/565, init DRAM, PC enable */
646 640
647/* printf("%d %d %d %d %d %x %x\n",width,height,voff,nom,den,mvv_buf); */ 641/* printf("%d %d %d %d %d %x %x\n",width,height,voff,nom,den,mvv_buf); */
648 642
649 for (y = 0; y < dev->height; y++ ) 643 for (y = 0; y < dev->height; y++) {
650 { 644 writeb(0, dev->mem); /* synchronisiert neue Zeile */
651 writeb(0, mem); /* synchronisiert neue Zeile */
652 645
653 /* 646 /*
654 * This is in truth a fifo, be very careful as if you 647 * This is in truth a fifo, be very careful as if you
655 * forgot this odd things will occur 8) 648 * forgot this odd things will occur 8)
656 */ 649 */
657 650
658 memcpy_fromio(tmp, mem, dw+32); /* discard 16 word */ 651 memcpy_fromio(tmp, dev->mem, dw + 32); /* discard 16 word */
659 cnt -= dev->height; 652 cnt -= dev->height;
660 while (cnt <= 0) 653 while (cnt <= 0) {
661 {
662 /* 654 /*
663 * Don't copy too far 655 * Don't copy too far
664 */ 656 */
665 int dt=dw; 657 int dt = dw;
666 if(dt+len>count) 658 if (dt + len > count)
667 dt=count-len; 659 dt = count - len;
668 cnt += dev->height; 660 cnt += dev->height;
669 if (copy_to_user(buf, tmp+32, dt)) 661 if (copy_to_user(buf, tmp + 32, dt))
670 return len ? len : -EFAULT; 662 return len ? len : -EFAULT;
671 buf += dt; 663 buf += dt;
672 len += dt; 664 len += dt;
@@ -680,221 +672,278 @@ static int pms_capture(struct pms_device *dev, char __user *buf, int rgb555, int
680 * Video4linux interfacing 672 * Video4linux interfacing
681 */ 673 */
682 674
683static long pms_do_ioctl(struct file *file, unsigned int cmd, void *arg) 675static int pms_querycap(struct file *file, void *priv,
676 struct v4l2_capability *vcap)
684{ 677{
685 struct video_device *dev = video_devdata(file); 678 struct pms *dev = video_drvdata(file);
686 struct pms_device *pd=(struct pms_device *)dev;
687
688 switch(cmd)
689 {
690 case VIDIOCGCAP:
691 {
692 struct video_capability *b = arg;
693 strcpy(b->name, "Mediavision PMS");
694 b->type = VID_TYPE_CAPTURE|VID_TYPE_SCALES;
695 b->channels = 4;
696 b->audios = 0;
697 b->maxwidth = 640;
698 b->maxheight = 480;
699 b->minwidth = 16;
700 b->minheight = 16;
701 return 0;
702 }
703 case VIDIOCGCHAN:
704 {
705 struct video_channel *v = arg;
706 if(v->channel<0 || v->channel>3)
707 return -EINVAL;
708 v->flags=0;
709 v->tuners=1;
710 /* Good question.. its composite or SVHS so.. */
711 v->type = VIDEO_TYPE_CAMERA;
712 switch(v->channel)
713 {
714 case 0:
715 strcpy(v->name, "Composite");break;
716 case 1:
717 strcpy(v->name, "SVideo");break;
718 case 2:
719 strcpy(v->name, "Composite(VCR)");break;
720 case 3:
721 strcpy(v->name, "SVideo(VCR)");break;
722 }
723 return 0;
724 }
725 case VIDIOCSCHAN:
726 {
727 struct video_channel *v = arg;
728 if(v->channel<0 || v->channel>3)
729 return -EINVAL;
730 mutex_lock(&pd->lock);
731 pms_videosource(v->channel&1);
732 pms_vcrinput(v->channel>>1);
733 mutex_unlock(&pd->lock);
734 return 0;
735 }
736 case VIDIOCGTUNER:
737 {
738 struct video_tuner *v = arg;
739 if(v->tuner)
740 return -EINVAL;
741 strcpy(v->name, "Format");
742 v->rangelow=0;
743 v->rangehigh=0;
744 v->flags= VIDEO_TUNER_PAL|VIDEO_TUNER_NTSC|VIDEO_TUNER_SECAM;
745 switch(standard)
746 {
747 case 0:
748 v->mode = VIDEO_MODE_AUTO;
749 break;
750 case 1:
751 v->mode = VIDEO_MODE_NTSC;
752 break;
753 case 2:
754 v->mode = VIDEO_MODE_PAL;
755 break;
756 case 3:
757 v->mode = VIDEO_MODE_SECAM;
758 break;
759 }
760 return 0;
761 }
762 case VIDIOCSTUNER:
763 {
764 struct video_tuner *v = arg;
765 if(v->tuner)
766 return -EINVAL;
767 mutex_lock(&pd->lock);
768 switch(v->mode)
769 {
770 case VIDEO_MODE_AUTO:
771 pms_framerate(25);
772 pms_secamcross(0);
773 pms_format(0);
774 break;
775 case VIDEO_MODE_NTSC:
776 pms_framerate(30);
777 pms_secamcross(0);
778 pms_format(1);
779 break;
780 case VIDEO_MODE_PAL:
781 pms_framerate(25);
782 pms_secamcross(0);
783 pms_format(2);
784 break;
785 case VIDEO_MODE_SECAM:
786 pms_framerate(25);
787 pms_secamcross(1);
788 pms_format(2);
789 break;
790 default:
791 mutex_unlock(&pd->lock);
792 return -EINVAL;
793 }
794 mutex_unlock(&pd->lock);
795 return 0;
796 }
797 case VIDIOCGPICT:
798 {
799 struct video_picture *p = arg;
800 *p = pd->picture;
801 return 0;
802 }
803 case VIDIOCSPICT:
804 {
805 struct video_picture *p = arg;
806 if(!((p->palette==VIDEO_PALETTE_RGB565 && p->depth==16)
807 ||(p->palette==VIDEO_PALETTE_RGB555 && p->depth==15)))
808 return -EINVAL;
809 pd->picture= *p;
810 679
811 /* 680 strlcpy(vcap->driver, dev->v4l2_dev.name, sizeof(vcap->driver));
812 * Now load the card. 681 strlcpy(vcap->card, "Mediavision PMS", sizeof(vcap->card));
813 */ 682 strlcpy(vcap->bus_info, "ISA", sizeof(vcap->bus_info));
683 vcap->version = KERNEL_VERSION(0, 0, 3);
684 vcap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE;
685 return 0;
686}
814 687
815 mutex_lock(&pd->lock); 688static int pms_enum_input(struct file *file, void *fh, struct v4l2_input *vin)
816 pms_brightness(p->brightness>>8); 689{
817 pms_hue(p->hue>>8); 690 static const char *inputs[4] = {
818 pms_colour(p->colour>>8); 691 "Composite",
819 pms_contrast(p->contrast>>8); 692 "S-Video",
820 mutex_unlock(&pd->lock); 693 "Composite (VCR)",
821 return 0; 694 "S-Video (VCR)"
822 } 695 };
823 case VIDIOCSWIN: 696
824 { 697 if (vin->index > 3)
825 struct video_window *vw = arg; 698 return -EINVAL;
826 if(vw->flags) 699 strlcpy(vin->name, inputs[vin->index], sizeof(vin->name));
827 return -EINVAL; 700 vin->type = V4L2_INPUT_TYPE_CAMERA;
828 if(vw->clipcount) 701 vin->audioset = 0;
829 return -EINVAL; 702 vin->tuner = 0;
830 if(vw->height<16||vw->height>480) 703 vin->std = V4L2_STD_ALL;
831 return -EINVAL; 704 vin->status = 0;
832 if(vw->width<16||vw->width>640) 705 return 0;
833 return -EINVAL; 706}
834 pd->width=vw->width; 707
835 pd->height=vw->height; 708static int pms_g_input(struct file *file, void *fh, unsigned int *inp)
836 mutex_lock(&pd->lock); 709{
837 pms_resolution(pd->width, pd->height); 710 struct pms *dev = video_drvdata(file);
838 mutex_unlock(&pd->lock); /* Ok we figured out what to use from our wide choice */ 711
839 return 0; 712 *inp = dev->input;
840 } 713 return 0;
841 case VIDIOCGWIN: 714}
842 { 715
843 struct video_window *vw = arg; 716static int pms_s_input(struct file *file, void *fh, unsigned int inp)
844 memset(vw,0,sizeof(*vw)); 717{
845 vw->width=pd->width; 718 struct pms *dev = video_drvdata(file);
846 vw->height=pd->height; 719
847 return 0; 720 if (inp > 3)
848 } 721 return -EINVAL;
849 case VIDIOCKEY: 722
850 return 0; 723 mutex_lock(&dev->lock);
851 case VIDIOCCAPTURE: 724 dev->input = inp;
852 case VIDIOCGFBUF: 725 pms_videosource(dev, inp & 1);
853 case VIDIOCSFBUF: 726 pms_vcrinput(dev, inp >> 1);
854 case VIDIOCGFREQ: 727 mutex_unlock(&dev->lock);
855 case VIDIOCSFREQ: 728 return 0;
856 case VIDIOCGAUDIO: 729}
857 case VIDIOCSAUDIO: 730
858 return -EINVAL; 731static int pms_g_std(struct file *file, void *fh, v4l2_std_id *std)
859 default: 732{
860 return -ENOIOCTLCMD; 733 struct pms *dev = video_drvdata(file);
734
735 *std = dev->std;
736 return 0;
737}
738
739static int pms_s_std(struct file *file, void *fh, v4l2_std_id *std)
740{
741 struct pms *dev = video_drvdata(file);
742 int ret = 0;
743
744 dev->std = *std;
745 mutex_lock(&dev->lock);
746 if (dev->std & V4L2_STD_NTSC) {
747 pms_framerate(dev, 30);
748 pms_secamcross(dev, 0);
749 pms_format(dev, 1);
750 } else if (dev->std & V4L2_STD_PAL) {
751 pms_framerate(dev, 25);
752 pms_secamcross(dev, 0);
753 pms_format(dev, 2);
754 } else if (dev->std & V4L2_STD_SECAM) {
755 pms_framerate(dev, 25);
756 pms_secamcross(dev, 1);
757 pms_format(dev, 2);
758 } else {
759 ret = -EINVAL;
760 }
761 /*
762 switch (v->mode) {
763 case VIDEO_MODE_AUTO:
764 pms_framerate(dev, 25);
765 pms_secamcross(dev, 0);
766 pms_format(dev, 0);
767 break;
768 }*/
769 mutex_unlock(&dev->lock);
770 return 0;
771}
772
773static int pms_queryctrl(struct file *file, void *priv,
774 struct v4l2_queryctrl *qc)
775{
776 switch (qc->id) {
777 case V4L2_CID_BRIGHTNESS:
778 return v4l2_ctrl_query_fill(qc, 0, 255, 1, 139);
779 case V4L2_CID_CONTRAST:
780 return v4l2_ctrl_query_fill(qc, 0, 255, 1, 70);
781 case V4L2_CID_SATURATION:
782 return v4l2_ctrl_query_fill(qc, 0, 255, 1, 64);
783 case V4L2_CID_HUE:
784 return v4l2_ctrl_query_fill(qc, 0, 255, 1, 0);
785 }
786 return -EINVAL;
787}
788
789static int pms_g_ctrl(struct file *file, void *priv,
790 struct v4l2_control *ctrl)
791{
792 struct pms *dev = video_drvdata(file);
793 int ret = 0;
794
795 switch (ctrl->id) {
796 case V4L2_CID_BRIGHTNESS:
797 ctrl->value = dev->brightness;
798 break;
799 case V4L2_CID_CONTRAST:
800 ctrl->value = dev->contrast;
801 break;
802 case V4L2_CID_SATURATION:
803 ctrl->value = dev->saturation;
804 break;
805 case V4L2_CID_HUE:
806 ctrl->value = dev->hue;
807 break;
808 default:
809 ret = -EINVAL;
810 break;
811 }
812 return ret;
813}
814
815static int pms_s_ctrl(struct file *file, void *priv,
816 struct v4l2_control *ctrl)
817{
818 struct pms *dev = video_drvdata(file);
819 int ret = 0;
820
821 mutex_lock(&dev->lock);
822 switch (ctrl->id) {
823 case V4L2_CID_BRIGHTNESS:
824 dev->brightness = ctrl->value;
825 pms_brightness(dev, dev->brightness);
826 break;
827 case V4L2_CID_CONTRAST:
828 dev->contrast = ctrl->value;
829 pms_contrast(dev, dev->contrast);
830 break;
831 case V4L2_CID_SATURATION:
832 dev->saturation = ctrl->value;
833 pms_saturation(dev, dev->saturation);
834 break;
835 case V4L2_CID_HUE:
836 dev->hue = ctrl->value;
837 pms_hue(dev, dev->hue);
838 break;
839 default:
840 ret = -EINVAL;
841 break;
861 } 842 }
843 mutex_unlock(&dev->lock);
844 return ret;
845}
846
847static int pms_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
848{
849 struct pms *dev = video_drvdata(file);
850 struct v4l2_pix_format *pix = &fmt->fmt.pix;
851
852 pix->width = dev->width;
853 pix->height = dev->height;
854 pix->pixelformat = dev->width == 15 ?
855 V4L2_PIX_FMT_RGB555 : V4L2_PIX_FMT_RGB565;
856 pix->field = V4L2_FIELD_NONE;
857 pix->bytesperline = 2 * dev->width;
858 pix->sizeimage = 2 * dev->width * dev->height;
859 /* Just a guess */
860 pix->colorspace = V4L2_COLORSPACE_SRGB;
862 return 0; 861 return 0;
863} 862}
864 863
865static long pms_ioctl(struct file *file, 864static int pms_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
866 unsigned int cmd, unsigned long arg)
867{ 865{
868 return video_usercopy(file, cmd, arg, pms_do_ioctl); 866 struct v4l2_pix_format *pix = &fmt->fmt.pix;
867
868 if (pix->height < 16 || pix->height > 480)
869 return -EINVAL;
870 if (pix->width < 16 || pix->width > 640)
871 return -EINVAL;
872 if (pix->pixelformat != V4L2_PIX_FMT_RGB555 &&
873 pix->pixelformat != V4L2_PIX_FMT_RGB565)
874 return -EINVAL;
875 pix->field = V4L2_FIELD_NONE;
876 pix->bytesperline = 2 * pix->width;
877 pix->sizeimage = 2 * pix->width * pix->height;
878 /* Just a guess */
879 pix->colorspace = V4L2_COLORSPACE_SRGB;
880 return 0;
881}
882
883static int pms_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
884{
885 struct pms *dev = video_drvdata(file);
886 struct v4l2_pix_format *pix = &fmt->fmt.pix;
887 int ret = pms_try_fmt_vid_cap(file, fh, fmt);
888
889 if (ret)
890 return ret;
891 mutex_lock(&dev->lock);
892 dev->width = pix->width;
893 dev->height = pix->height;
894 dev->depth = (pix->pixelformat == V4L2_PIX_FMT_RGB555) ? 15 : 16;
895 pms_resolution(dev, dev->width, dev->height);
896 /* Ok we figured out what to use from our wide choice */
897 mutex_unlock(&dev->lock);
898 return 0;
899}
900
901static int pms_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtdesc *fmt)
902{
903 static struct v4l2_fmtdesc formats[] = {
904 { 0, 0, 0,
905 "RGB 5:5:5", V4L2_PIX_FMT_RGB555,
906 { 0, 0, 0, 0 }
907 },
908 { 0, 0, 0,
909 "RGB 5:6:5", V4L2_PIX_FMT_RGB565,
910 { 0, 0, 0, 0 }
911 },
912 };
913 enum v4l2_buf_type type = fmt->type;
914
915 if (fmt->index > 1)
916 return -EINVAL;
917
918 *fmt = formats[fmt->index];
919 fmt->type = type;
920 return 0;
869} 921}
870 922
871static ssize_t pms_read(struct file *file, char __user *buf, 923static ssize_t pms_read(struct file *file, char __user *buf,
872 size_t count, loff_t *ppos) 924 size_t count, loff_t *ppos)
873{ 925{
874 struct video_device *v = video_devdata(file); 926 struct pms *dev = video_drvdata(file);
875 struct pms_device *pd=(struct pms_device *)v;
876 int len; 927 int len;
877 928
878 mutex_lock(&pd->lock); 929 mutex_lock(&dev->lock);
879 len=pms_capture(pd, buf, (pd->picture.depth==16)?0:1,count); 930 len = pms_capture(dev, buf, (dev->depth == 15), count);
880 mutex_unlock(&pd->lock); 931 mutex_unlock(&dev->lock);
881 return len; 932 return len;
882} 933}
883 934
884static int pms_exclusive_open(struct file *file) 935static int pms_exclusive_open(struct file *file)
885{ 936{
886 struct video_device *v = video_devdata(file); 937 struct pms *dev = video_drvdata(file);
887 struct pms_device *pd = (struct pms_device *)v;
888 938
889 return test_and_set_bit(0, &pd->in_use) ? -EBUSY : 0; 939 return test_and_set_bit(0, &dev->in_use) ? -EBUSY : 0;
890} 940}
891 941
892static int pms_exclusive_release(struct file *file) 942static int pms_exclusive_release(struct file *file)
893{ 943{
894 struct video_device *v = video_devdata(file); 944 struct pms *dev = video_drvdata(file);
895 struct pms_device *pd = (struct pms_device *)v;
896 945
897 clear_bit(0, &pd->in_use); 946 clear_bit(0, &dev->in_use);
898 return 0; 947 return 0;
899} 948}
900 949
@@ -902,78 +951,81 @@ static const struct v4l2_file_operations pms_fops = {
902 .owner = THIS_MODULE, 951 .owner = THIS_MODULE,
903 .open = pms_exclusive_open, 952 .open = pms_exclusive_open,
904 .release = pms_exclusive_release, 953 .release = pms_exclusive_release,
905 .ioctl = pms_ioctl, 954 .ioctl = video_ioctl2,
906 .read = pms_read, 955 .read = pms_read,
907}; 956};
908 957
909static struct video_device pms_template= 958static const struct v4l2_ioctl_ops pms_ioctl_ops = {
910{ 959 .vidioc_querycap = pms_querycap,
911 .name = "Mediavision PMS", 960 .vidioc_g_input = pms_g_input,
912 .fops = &pms_fops, 961 .vidioc_s_input = pms_s_input,
913 .release = video_device_release_empty, 962 .vidioc_enum_input = pms_enum_input,
963 .vidioc_g_std = pms_g_std,
964 .vidioc_s_std = pms_s_std,
965 .vidioc_queryctrl = pms_queryctrl,
966 .vidioc_g_ctrl = pms_g_ctrl,
967 .vidioc_s_ctrl = pms_s_ctrl,
968 .vidioc_enum_fmt_vid_cap = pms_enum_fmt_vid_cap,
969 .vidioc_g_fmt_vid_cap = pms_g_fmt_vid_cap,
970 .vidioc_s_fmt_vid_cap = pms_s_fmt_vid_cap,
971 .vidioc_try_fmt_vid_cap = pms_try_fmt_vid_cap,
914}; 972};
915 973
916static struct pms_device pms_device;
917
918
919/* 974/*
920 * Probe for and initialise the Mediavision PMS 975 * Probe for and initialise the Mediavision PMS
921 */ 976 */
922 977
923static int init_mediavision(void) 978static int init_mediavision(struct pms *dev)
924{ 979{
925 int id; 980 int id;
926 int idec, decst; 981 int idec, decst;
927 int i; 982 int i;
928 983 static const unsigned char i2c_defs[] = {
929 unsigned char i2c_defs[]={ 984 0x4c, 0x30, 0x00, 0xe8,
930 0x4C,0x30,0x00,0xE8, 985 0xb6, 0xe2, 0x00, 0x00,
931 0xB6,0xE2,0x00,0x00, 986 0xff, 0xff, 0x00, 0x00,
932 0xFF,0xFF,0x00,0x00, 987 0x00, 0x00, 0x78, 0x98,
933 0x00,0x00,0x78,0x98, 988 0x00, 0x00, 0x00, 0x00,
934 0x00,0x00,0x00,0x00, 989 0x34, 0x0a, 0xf4, 0xce,
935 0x34,0x0A,0xF4,0xCE, 990 0xe4
936 0xE4
937 }; 991 };
938 992
939 mem = ioremap(mem_base, 0x800); 993 dev->mem = ioremap(mem_base, 0x800);
940 if (!mem) 994 if (!dev->mem)
941 return -ENOMEM; 995 return -ENOMEM;
942 996
943 if (!request_region(0x9A01, 1, "Mediavision PMS config")) 997 if (!request_region(0x9a01, 1, "Mediavision PMS config")) {
944 { 998 printk(KERN_WARNING "mediavision: unable to detect: 0x9a01 in use.\n");
945 printk(KERN_WARNING "mediavision: unable to detect: 0x9A01 in use.\n"); 999 iounmap(dev->mem);
946 iounmap(mem);
947 return -EBUSY; 1000 return -EBUSY;
948 } 1001 }
949 if (!request_region(io_port, 3, "Mediavision PMS")) 1002 if (!request_region(dev->io, 3, "Mediavision PMS")) {
950 { 1003 printk(KERN_WARNING "mediavision: I/O port %d in use.\n", dev->io);
951 printk(KERN_WARNING "mediavision: I/O port %d in use.\n", io_port); 1004 release_region(0x9a01, 1);
952 release_region(0x9A01, 1); 1005 iounmap(dev->mem);
953 iounmap(mem);
954 return -EBUSY; 1006 return -EBUSY;
955 } 1007 }
956 outb(0xB8, 0x9A01); /* Unlock */ 1008 outb(0xb8, 0x9a01); /* Unlock */
957 outb(io_port>>4, 0x9A01); /* Set IO port */ 1009 outb(dev->io >> 4, 0x9a01); /* Set IO port */
958 1010
959 1011
960 id=mvv_read(3); 1012 id = mvv_read(dev, 3);
961 decst=pms_i2c_stat(0x43); 1013 decst = pms_i2c_stat(dev, 0x43);
962 1014
963 if(decst!=-1) 1015 if (decst != -1)
964 idec=2; 1016 idec = 2;
965 else if(pms_i2c_stat(0xb9)!=-1) 1017 else if (pms_i2c_stat(dev, 0xb9) != -1)
966 idec=3; 1018 idec = 3;
967 else if(pms_i2c_stat(0x8b)!=-1) 1019 else if (pms_i2c_stat(dev, 0x8b) != -1)
968 idec=1; 1020 idec = 1;
969 else 1021 else
970 idec=0; 1022 idec = 0;
971 1023
972 printk(KERN_INFO "PMS type is %d\n", idec); 1024 printk(KERN_INFO "PMS type is %d\n", idec);
973 if(idec == 0) { 1025 if (idec == 0) {
974 release_region(io_port, 3); 1026 release_region(dev->io, 3);
975 release_region(0x9A01, 1); 1027 release_region(0x9a01, 1);
976 iounmap(mem); 1028 iounmap(dev->mem);
977 return -ENODEV; 1029 return -ENODEV;
978 } 1030 }
979 1031
@@ -981,51 +1033,50 @@ static int init_mediavision(void)
981 * Ok we have a PMS of some sort 1033 * Ok we have a PMS of some sort
982 */ 1034 */
983 1035
984 mvv_write(0x04, mem_base>>12); /* Set the memory area */ 1036 mvv_write(dev, 0x04, mem_base >> 12); /* Set the memory area */
985 1037
986 /* Ok now load the defaults */ 1038 /* Ok now load the defaults */
987 1039
988 for(i=0;i<0x19;i++) 1040 for (i = 0; i < 0x19; i++) {
989 { 1041 if (i2c_defs[i] == 0xff)
990 if(i2c_defs[i]==0xFF) 1042 pms_i2c_andor(dev, 0x8a, i, 0x07, 0x00);
991 pms_i2c_andor(0x8A, i, 0x07,0x00);
992 else 1043 else
993 pms_i2c_write(0x8A, i, i2c_defs[i]); 1044 pms_i2c_write(dev, 0x8a, i, i2c_defs[i]);
994 } 1045 }
995 1046
996 pms_i2c_write(0xB8,0x00,0x12); 1047 pms_i2c_write(dev, 0xb8, 0x00, 0x12);
997 pms_i2c_write(0xB8,0x04,0x00); 1048 pms_i2c_write(dev, 0xb8, 0x04, 0x00);
998 pms_i2c_write(0xB8,0x07,0x00); 1049 pms_i2c_write(dev, 0xb8, 0x07, 0x00);
999 pms_i2c_write(0xB8,0x08,0x00); 1050 pms_i2c_write(dev, 0xb8, 0x08, 0x00);
1000 pms_i2c_write(0xB8,0x09,0xFF); 1051 pms_i2c_write(dev, 0xb8, 0x09, 0xff);
1001 pms_i2c_write(0xB8,0x0A,0x00); 1052 pms_i2c_write(dev, 0xb8, 0x0a, 0x00);
1002 pms_i2c_write(0xB8,0x0B,0x10); 1053 pms_i2c_write(dev, 0xb8, 0x0b, 0x10);
1003 pms_i2c_write(0xB8,0x10,0x03); 1054 pms_i2c_write(dev, 0xb8, 0x10, 0x03);
1004 1055
1005 mvv_write(0x01, 0x00); 1056 mvv_write(dev, 0x01, 0x00);
1006 mvv_write(0x05, 0xA0); 1057 mvv_write(dev, 0x05, 0xa0);
1007 mvv_write(0x08, 0x25); 1058 mvv_write(dev, 0x08, 0x25);
1008 mvv_write(0x09, 0x00); 1059 mvv_write(dev, 0x09, 0x00);
1009 mvv_write(0x0A, 0x20|MVVMEMORYWIDTH); 1060 mvv_write(dev, 0x0a, 0x20 | MVVMEMORYWIDTH);
1010 1061
1011 mvv_write(0x10, 0x02); 1062 mvv_write(dev, 0x10, 0x02);
1012 mvv_write(0x1E, 0x0C); 1063 mvv_write(dev, 0x1e, 0x0c);
1013 mvv_write(0x1F, 0x03); 1064 mvv_write(dev, 0x1f, 0x03);
1014 mvv_write(0x26, 0x06); 1065 mvv_write(dev, 0x26, 0x06);
1015 1066
1016 mvv_write(0x2B, 0x00); 1067 mvv_write(dev, 0x2b, 0x00);
1017 mvv_write(0x2C, 0x20); 1068 mvv_write(dev, 0x2c, 0x20);
1018 mvv_write(0x2D, 0x00); 1069 mvv_write(dev, 0x2d, 0x00);
1019 mvv_write(0x2F, 0x70); 1070 mvv_write(dev, 0x2f, 0x70);
1020 mvv_write(0x32, 0x00); 1071 mvv_write(dev, 0x32, 0x00);
1021 mvv_write(0x33, MVVMEMORYWIDTH); 1072 mvv_write(dev, 0x33, MVVMEMORYWIDTH);
1022 mvv_write(0x34, 0x00); 1073 mvv_write(dev, 0x34, 0x00);
1023 mvv_write(0x35, 0x00); 1074 mvv_write(dev, 0x35, 0x00);
1024 mvv_write(0x3A, 0x80); 1075 mvv_write(dev, 0x3a, 0x80);
1025 mvv_write(0x3B, 0x10); 1076 mvv_write(dev, 0x3b, 0x10);
1026 mvv_write(0x20, 0x00); 1077 mvv_write(dev, 0x20, 0x00);
1027 mvv_write(0x21, 0x00); 1078 mvv_write(dev, 0x21, 0x00);
1028 mvv_write(0x30, 0x22); 1079 mvv_write(dev, 0x30, 0x22);
1029 return 0; 1080 return 0;
1030} 1081}
1031 1082
@@ -1038,53 +1089,77 @@ static int enable;
1038module_param(enable, int, 0); 1089module_param(enable, int, 0);
1039#endif 1090#endif
1040 1091
1041static int __init init_pms_cards(void) 1092static int __init pms_init(void)
1042{ 1093{
1043 printk(KERN_INFO "Mediavision Pro Movie Studio driver 0.02\n"); 1094 struct pms *dev = &pms_card;
1095 struct v4l2_device *v4l2_dev = &dev->v4l2_dev;
1096 int res;
1097
1098 strlcpy(v4l2_dev->name, "pms", sizeof(v4l2_dev->name));
1099
1100 v4l2_info(v4l2_dev, "Mediavision Pro Movie Studio driver 0.03\n");
1044 1101
1045#ifndef MODULE 1102#ifndef MODULE
1046 if (!enable) { 1103 if (!enable) {
1047 printk(KERN_INFO "PMS: not enabled, use pms.enable=1 to " 1104 v4l2_err(v4l2_dev,
1048 "probe\n"); 1105 "PMS: not enabled, use pms.enable=1 to probe\n");
1049 return -ENODEV; 1106 return -ENODEV;
1050 } 1107 }
1051#endif 1108#endif
1052 1109
1053 data_port = io_port +1; 1110 dev->decoder = PHILIPS2;
1111 dev->io = io_port;
1112 dev->data = io_port + 1;
1054 1113
1055 if(init_mediavision()) 1114 if (init_mediavision(dev)) {
1056 { 1115 v4l2_err(v4l2_dev, "Board not found.\n");
1057 printk(KERN_INFO "Board not found.\n");
1058 return -ENODEV; 1116 return -ENODEV;
1059 } 1117 }
1060 memcpy(&pms_device, &pms_template, sizeof(pms_template));
1061 mutex_init(&pms_device.lock);
1062 pms_device.height=240;
1063 pms_device.width=320;
1064 pms_swsense(75);
1065 pms_resolution(320,240);
1066 return video_register_device((struct video_device *)&pms_device, VFL_TYPE_GRABBER, video_nr);
1067}
1068
1069module_param(io_port, int, 0);
1070module_param(mem_base, int, 0);
1071module_param(video_nr, int, 0);
1072MODULE_LICENSE("GPL");
1073 1118
1119 res = v4l2_device_register(NULL, v4l2_dev);
1120 if (res < 0) {
1121 v4l2_err(v4l2_dev, "Could not register v4l2_device\n");
1122 return res;
1123 }
1074 1124
1075static void __exit shutdown_mediavision(void) 1125 strlcpy(dev->vdev.name, v4l2_dev->name, sizeof(dev->vdev.name));
1076{ 1126 dev->vdev.v4l2_dev = v4l2_dev;
1077 release_region(io_port,3); 1127 dev->vdev.fops = &pms_fops;
1078 release_region(0x9A01, 1); 1128 dev->vdev.ioctl_ops = &pms_ioctl_ops;
1129 dev->vdev.release = video_device_release_empty;
1130 video_set_drvdata(&dev->vdev, dev);
1131 mutex_init(&dev->lock);
1132 dev->std = V4L2_STD_NTSC_M;
1133 dev->height = 240;
1134 dev->width = 320;
1135 dev->depth = 15;
1136 dev->brightness = 139;
1137 dev->contrast = 70;
1138 dev->hue = 0;
1139 dev->saturation = 64;
1140 pms_swsense(dev, 75);
1141 pms_resolution(dev, 320, 240);
1142 pms_videosource(dev, 0);
1143 pms_vcrinput(dev, 0);
1144 if (video_register_device(&dev->vdev, VFL_TYPE_GRABBER, video_nr) < 0) {
1145 v4l2_device_unregister(&dev->v4l2_dev);
1146 release_region(dev->io, 3);
1147 release_region(0x9a01, 1);
1148 iounmap(dev->mem);
1149 return -EINVAL;
1150 }
1151 return 0;
1079} 1152}
1080 1153
1081static void __exit cleanup_pms_module(void) 1154static void __exit pms_exit(void)
1082{ 1155{
1083 shutdown_mediavision(); 1156 struct pms *dev = &pms_card;
1084 video_unregister_device((struct video_device *)&pms_device);
1085 iounmap(mem);
1086}
1087 1157
1088module_init(init_pms_cards); 1158 video_unregister_device(&dev->vdev);
1089module_exit(cleanup_pms_module); 1159 release_region(dev->io, 3);
1160 release_region(0x9a01, 1);
1161 iounmap(dev->mem);
1162}
1090 1163
1164module_init(pms_init);
1165module_exit(pms_exit);
diff --git a/drivers/media/video/pvrusb2/pvrusb2-debugifc.c b/drivers/media/video/pvrusb2/pvrusb2-debugifc.c
index fbe3856bdca6..ae977668c496 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-debugifc.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-debugifc.c
@@ -142,6 +142,9 @@ int pvr2_debugifc_print_info(struct pvr2_hdw *hdw,char *buf,unsigned int acnt)
142{ 142{
143 int bcnt = 0; 143 int bcnt = 0;
144 int ccnt; 144 int ccnt;
145 ccnt = scnprintf(buf, acnt, "Driver hardware description: %s\n",
146 pvr2_hdw_get_desc(hdw));
147 bcnt += ccnt; acnt -= ccnt; buf += ccnt;
145 ccnt = scnprintf(buf,acnt,"Driver state info:\n"); 148 ccnt = scnprintf(buf,acnt,"Driver state info:\n");
146 bcnt += ccnt; acnt -= ccnt; buf += ccnt; 149 bcnt += ccnt; acnt -= ccnt; buf += ccnt;
147 ccnt = pvr2_hdw_state_report(hdw,buf,acnt); 150 ccnt = pvr2_hdw_state_report(hdw,buf,acnt);
@@ -249,11 +252,15 @@ static int pvr2_debugifc_do1cmd(struct pvr2_hdw *hdw,const char *buf,
249 scnt = debugifc_isolate_word(buf,count,&wptr,&wlen); 252 scnt = debugifc_isolate_word(buf,count,&wptr,&wlen);
250 if (scnt && wptr) { 253 if (scnt && wptr) {
251 count -= scnt; buf += scnt; 254 count -= scnt; buf += scnt;
252 if (debugifc_match_keyword(wptr,wlen,"prom")) { 255 if (debugifc_match_keyword(wptr, wlen,
253 pvr2_hdw_cpufw_set_enabled(hdw,!0,!0); 256 "prom")) {
254 } else if (debugifc_match_keyword(wptr,wlen, 257 pvr2_hdw_cpufw_set_enabled(hdw, 2, !0);
255 "ram")) { 258 } else if (debugifc_match_keyword(wptr, wlen,
256 pvr2_hdw_cpufw_set_enabled(hdw,0,!0); 259 "ram8k")) {
260 pvr2_hdw_cpufw_set_enabled(hdw, 0, !0);
261 } else if (debugifc_match_keyword(wptr, wlen,
262 "ram16k")) {
263 pvr2_hdw_cpufw_set_enabled(hdw, 1, !0);
257 } else { 264 } else {
258 return -EINVAL; 265 return -EINVAL;
259 } 266 }
diff --git a/drivers/media/video/pvrusb2/pvrusb2-devattr.c b/drivers/media/video/pvrusb2/pvrusb2-devattr.c
index e4d7c13cab87..6bc16c13ccef 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-devattr.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-devattr.c
@@ -58,7 +58,7 @@ static const char *pvr2_fw1_names_29xxx[] = {
58}; 58};
59 59
60static const struct pvr2_device_desc pvr2_device_29xxx = { 60static const struct pvr2_device_desc pvr2_device_29xxx = {
61 .description = "WinTV PVR USB2 Model Category 29xxx", 61 .description = "WinTV PVR USB2 Model 29xxx",
62 .shortname = "29xxx", 62 .shortname = "29xxx",
63 .client_table.lst = pvr2_cli_29xxx, 63 .client_table.lst = pvr2_cli_29xxx,
64 .client_table.cnt = ARRAY_SIZE(pvr2_cli_29xxx), 64 .client_table.cnt = ARRAY_SIZE(pvr2_cli_29xxx),
@@ -91,7 +91,7 @@ static const char *pvr2_fw1_names_24xxx[] = {
91}; 91};
92 92
93static const struct pvr2_device_desc pvr2_device_24xxx = { 93static const struct pvr2_device_desc pvr2_device_24xxx = {
94 .description = "WinTV PVR USB2 Model Category 24xxx", 94 .description = "WinTV PVR USB2 Model 24xxx",
95 .shortname = "24xxx", 95 .shortname = "24xxx",
96 .client_table.lst = pvr2_cli_24xxx, 96 .client_table.lst = pvr2_cli_24xxx,
97 .client_table.cnt = ARRAY_SIZE(pvr2_cli_24xxx), 97 .client_table.cnt = ARRAY_SIZE(pvr2_cli_24xxx),
@@ -340,7 +340,7 @@ static const char *pvr2_fw1_names_73xxx[] = {
340}; 340};
341 341
342static const struct pvr2_device_desc pvr2_device_73xxx = { 342static const struct pvr2_device_desc pvr2_device_73xxx = {
343 .description = "WinTV HVR-1900 Model Category 73xxx", 343 .description = "WinTV HVR-1900 Model 73xxx",
344 .shortname = "73xxx", 344 .shortname = "73xxx",
345 .client_table.lst = pvr2_cli_73xxx, 345 .client_table.lst = pvr2_cli_73xxx,
346 .client_table.cnt = ARRAY_SIZE(pvr2_cli_73xxx), 346 .client_table.cnt = ARRAY_SIZE(pvr2_cli_73xxx),
@@ -351,6 +351,7 @@ static const struct pvr2_device_desc pvr2_device_73xxx = {
351 .flag_has_analogtuner = !0, 351 .flag_has_analogtuner = !0,
352 .flag_has_composite = !0, 352 .flag_has_composite = !0,
353 .flag_has_svideo = !0, 353 .flag_has_svideo = !0,
354 .flag_fx2_16kb = !0,
354 .signal_routing_scheme = PVR2_ROUTING_SCHEME_HAUPPAUGE, 355 .signal_routing_scheme = PVR2_ROUTING_SCHEME_HAUPPAUGE,
355 .digital_control_scheme = PVR2_DIGITAL_SCHEME_HAUPPAUGE, 356 .digital_control_scheme = PVR2_DIGITAL_SCHEME_HAUPPAUGE,
356 .led_scheme = PVR2_LED_SCHEME_HAUPPAUGE, 357 .led_scheme = PVR2_LED_SCHEME_HAUPPAUGE,
@@ -445,7 +446,7 @@ static const char *pvr2_fw1_names_75xxx[] = {
445}; 446};
446 447
447static const struct pvr2_device_desc pvr2_device_750xx = { 448static const struct pvr2_device_desc pvr2_device_750xx = {
448 .description = "WinTV HVR-1950 Model Category 750xx", 449 .description = "WinTV HVR-1950 Model 750xx",
449 .shortname = "750xx", 450 .shortname = "750xx",
450 .client_table.lst = pvr2_cli_73xxx, 451 .client_table.lst = pvr2_cli_73xxx,
451 .client_table.cnt = ARRAY_SIZE(pvr2_cli_73xxx), 452 .client_table.cnt = ARRAY_SIZE(pvr2_cli_73xxx),
@@ -456,6 +457,7 @@ static const struct pvr2_device_desc pvr2_device_750xx = {
456 .flag_has_analogtuner = !0, 457 .flag_has_analogtuner = !0,
457 .flag_has_composite = !0, 458 .flag_has_composite = !0,
458 .flag_has_svideo = !0, 459 .flag_has_svideo = !0,
460 .flag_fx2_16kb = !0,
459 .signal_routing_scheme = PVR2_ROUTING_SCHEME_HAUPPAUGE, 461 .signal_routing_scheme = PVR2_ROUTING_SCHEME_HAUPPAUGE,
460 .digital_control_scheme = PVR2_DIGITAL_SCHEME_HAUPPAUGE, 462 .digital_control_scheme = PVR2_DIGITAL_SCHEME_HAUPPAUGE,
461 .default_std_mask = V4L2_STD_NTSC_M, 463 .default_std_mask = V4L2_STD_NTSC_M,
@@ -467,7 +469,7 @@ static const struct pvr2_device_desc pvr2_device_750xx = {
467}; 469};
468 470
469static const struct pvr2_device_desc pvr2_device_751xx = { 471static const struct pvr2_device_desc pvr2_device_751xx = {
470 .description = "WinTV HVR-1950 Model Category 751xx", 472 .description = "WinTV HVR-1950 Model 751xx",
471 .shortname = "751xx", 473 .shortname = "751xx",
472 .client_table.lst = pvr2_cli_73xxx, 474 .client_table.lst = pvr2_cli_73xxx,
473 .client_table.cnt = ARRAY_SIZE(pvr2_cli_73xxx), 475 .client_table.cnt = ARRAY_SIZE(pvr2_cli_73xxx),
@@ -478,6 +480,7 @@ static const struct pvr2_device_desc pvr2_device_751xx = {
478 .flag_has_analogtuner = !0, 480 .flag_has_analogtuner = !0,
479 .flag_has_composite = !0, 481 .flag_has_composite = !0,
480 .flag_has_svideo = !0, 482 .flag_has_svideo = !0,
483 .flag_fx2_16kb = !0,
481 .signal_routing_scheme = PVR2_ROUTING_SCHEME_HAUPPAUGE, 484 .signal_routing_scheme = PVR2_ROUTING_SCHEME_HAUPPAUGE,
482 .digital_control_scheme = PVR2_DIGITAL_SCHEME_HAUPPAUGE, 485 .digital_control_scheme = PVR2_DIGITAL_SCHEME_HAUPPAUGE,
483 .default_std_mask = V4L2_STD_NTSC_M, 486 .default_std_mask = V4L2_STD_NTSC_M,
diff --git a/drivers/media/video/pvrusb2/pvrusb2-devattr.h b/drivers/media/video/pvrusb2/pvrusb2-devattr.h
index ea04ecf8aa39..e5b9594eb5f6 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-devattr.h
+++ b/drivers/media/video/pvrusb2/pvrusb2-devattr.h
@@ -176,6 +176,7 @@ struct pvr2_device_desc {
176 unsigned int flag_has_analogtuner:1; /* Has analog tuner */ 176 unsigned int flag_has_analogtuner:1; /* Has analog tuner */
177 unsigned int flag_has_composite:1; /* Has composite input */ 177 unsigned int flag_has_composite:1; /* Has composite input */
178 unsigned int flag_has_svideo:1; /* Has s-video input */ 178 unsigned int flag_has_svideo:1; /* Has s-video input */
179 unsigned int flag_fx2_16kb:1; /* 16KB FX2 firmware OK here */
179}; 180};
180 181
181extern struct usb_device_id pvr2_device_table[]; 182extern struct usb_device_id pvr2_device_table[];
diff --git a/drivers/media/video/pvrusb2/pvrusb2-encoder.c b/drivers/media/video/pvrusb2/pvrusb2-encoder.c
index 54ac5349dee2..e046fdaec5ae 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-encoder.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-encoder.c
@@ -294,7 +294,10 @@ static int pvr2_encoder_cmd(void *ctxt,
294 pvr2_trace( 294 pvr2_trace(
295 PVR2_TRACE_ERROR_LEGS, 295 PVR2_TRACE_ERROR_LEGS,
296 "Giving up on command." 296 "Giving up on command."
297 " This is normally recovered by the driver."); 297 " This is normally recovered via a firmware"
298 " reload and re-initialization; concern"
299 " is only warranted if this happens repeatedly"
300 " and rapidly.");
298 break; 301 break;
299 } 302 }
300 wrData[0] = 0x7; 303 wrData[0] = 0x7;
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h b/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h
index 5fcad28211d2..de5485f506b1 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h
@@ -270,6 +270,7 @@ struct pvr2_hdw {
270 270
271 int force_dirty; /* consider all controls dirty if true */ 271 int force_dirty; /* consider all controls dirty if true */
272 int flag_ok; /* device in known good state */ 272 int flag_ok; /* device in known good state */
273 int flag_modulefail; /* true if at least one module failed to load */
273 int flag_disconnected; /* flag_ok == 0 due to disconnect */ 274 int flag_disconnected; /* flag_ok == 0 due to disconnect */
274 int flag_init_ok; /* true if structure is fully initialized */ 275 int flag_init_ok; /* true if structure is fully initialized */
275 int fw1_state; /* current situation with fw1 */ 276 int fw1_state; /* current situation with fw1 */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
index 13639b302700..1bbdab08fe0e 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
@@ -1447,6 +1447,7 @@ static int pvr2_upload_firmware1(struct pvr2_hdw *hdw)
1447 const struct firmware *fw_entry = NULL; 1447 const struct firmware *fw_entry = NULL;
1448 void *fw_ptr; 1448 void *fw_ptr;
1449 unsigned int pipe; 1449 unsigned int pipe;
1450 unsigned int fwsize;
1450 int ret; 1451 int ret;
1451 u16 address; 1452 u16 address;
1452 1453
@@ -1473,9 +1474,21 @@ static int pvr2_upload_firmware1(struct pvr2_hdw *hdw)
1473 usb_clear_halt(hdw->usb_dev, usb_sndbulkpipe(hdw->usb_dev, 0 & 0x7f)); 1474 usb_clear_halt(hdw->usb_dev, usb_sndbulkpipe(hdw->usb_dev, 0 & 0x7f));
1474 1475
1475 pipe = usb_sndctrlpipe(hdw->usb_dev, 0); 1476 pipe = usb_sndctrlpipe(hdw->usb_dev, 0);
1477 fwsize = fw_entry->size;
1476 1478
1477 if (fw_entry->size != 0x2000){ 1479 if ((fwsize != 0x2000) &&
1478 pvr2_trace(PVR2_TRACE_ERROR_LEGS,"wrong fx2 firmware size"); 1480 (!(hdw->hdw_desc->flag_fx2_16kb && (fwsize == 0x4000)))) {
1481 if (hdw->hdw_desc->flag_fx2_16kb) {
1482 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1483 "Wrong fx2 firmware size"
1484 " (expected 8192 or 16384, got %u)",
1485 fwsize);
1486 } else {
1487 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1488 "Wrong fx2 firmware size"
1489 " (expected 8192, got %u)",
1490 fwsize);
1491 }
1479 release_firmware(fw_entry); 1492 release_firmware(fw_entry);
1480 return -ENOMEM; 1493 return -ENOMEM;
1481 } 1494 }
@@ -1493,7 +1506,7 @@ static int pvr2_upload_firmware1(struct pvr2_hdw *hdw)
1493 chunk. */ 1506 chunk. */
1494 1507
1495 ret = 0; 1508 ret = 0;
1496 for(address = 0; address < fw_entry->size; address += 0x800) { 1509 for (address = 0; address < fwsize; address += 0x800) {
1497 memcpy(fw_ptr, fw_entry->data + address, 0x800); 1510 memcpy(fw_ptr, fw_entry->data + address, 0x800);
1498 ret += usb_control_msg(hdw->usb_dev, pipe, 0xa0, 0x40, address, 1511 ret += usb_control_msg(hdw->usb_dev, pipe, 0xa0, 0x40, address,
1499 0, fw_ptr, 0x800, HZ); 1512 0, fw_ptr, 0x800, HZ);
@@ -1509,8 +1522,8 @@ static int pvr2_upload_firmware1(struct pvr2_hdw *hdw)
1509 1522
1510 trace_firmware("Upload done (%d bytes sent)",ret); 1523 trace_firmware("Upload done (%d bytes sent)",ret);
1511 1524
1512 /* We should have written 8192 bytes */ 1525 /* We should have written fwsize bytes */
1513 if (ret == 8192) { 1526 if (ret == fwsize) {
1514 hdw->fw1_state = FW1_STATE_RELOAD; 1527 hdw->fw1_state = FW1_STATE_RELOAD;
1515 return 0; 1528 return 0;
1516 } 1529 }
@@ -2030,7 +2043,8 @@ static int pvr2_hdw_load_subdev(struct pvr2_hdw *hdw,
2030 fname = (mid < ARRAY_SIZE(module_names)) ? module_names[mid] : NULL; 2043 fname = (mid < ARRAY_SIZE(module_names)) ? module_names[mid] : NULL;
2031 if (!fname) { 2044 if (!fname) {
2032 pvr2_trace(PVR2_TRACE_ERROR_LEGS, 2045 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2033 "Module ID %u for device %s has no name", 2046 "Module ID %u for device %s has no name?"
2047 " The driver might have a configuration problem.",
2034 mid, 2048 mid,
2035 hdw->hdw_desc->description); 2049 hdw->hdw_desc->description);
2036 return -EINVAL; 2050 return -EINVAL;
@@ -2058,7 +2072,8 @@ static int pvr2_hdw_load_subdev(struct pvr2_hdw *hdw,
2058 if (!i2ccnt) { 2072 if (!i2ccnt) {
2059 pvr2_trace(PVR2_TRACE_ERROR_LEGS, 2073 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2060 "Module ID %u (%s) for device %s:" 2074 "Module ID %u (%s) for device %s:"
2061 " No i2c addresses", 2075 " No i2c addresses."
2076 " The driver might have a configuration problem.",
2062 mid, fname, hdw->hdw_desc->description); 2077 mid, fname, hdw->hdw_desc->description);
2063 return -EINVAL; 2078 return -EINVAL;
2064 } 2079 }
@@ -2090,7 +2105,9 @@ static int pvr2_hdw_load_subdev(struct pvr2_hdw *hdw,
2090 2105
2091 if (!sd) { 2106 if (!sd) {
2092 pvr2_trace(PVR2_TRACE_ERROR_LEGS, 2107 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2093 "Module ID %u (%s) for device %s failed to load", 2108 "Module ID %u (%s) for device %s failed to load."
2109 " Possible missing sub-device kernel module or"
2110 " initialization failure within module.",
2094 mid, fname, hdw->hdw_desc->description); 2111 mid, fname, hdw->hdw_desc->description);
2095 return -EIO; 2112 return -EIO;
2096 } 2113 }
@@ -2132,7 +2149,10 @@ static void pvr2_hdw_load_modules(struct pvr2_hdw *hdw)
2132 for (idx = 0; idx < ct->cnt; idx++) { 2149 for (idx = 0; idx < ct->cnt; idx++) {
2133 if (pvr2_hdw_load_subdev(hdw, &ct->lst[idx]) < 0) okFl = 0; 2150 if (pvr2_hdw_load_subdev(hdw, &ct->lst[idx]) < 0) okFl = 0;
2134 } 2151 }
2135 if (!okFl) pvr2_hdw_render_useless(hdw); 2152 if (!okFl) {
2153 hdw->flag_modulefail = !0;
2154 pvr2_hdw_render_useless(hdw);
2155 }
2136} 2156}
2137 2157
2138 2158
@@ -2334,6 +2354,20 @@ static void pvr2_hdw_setup(struct pvr2_hdw *hdw)
2334 break; 2354 break;
2335 } 2355 }
2336 } 2356 }
2357 if (hdw->flag_modulefail) {
2358 pvr2_trace(
2359 PVR2_TRACE_ERROR_LEGS,
2360 "***WARNING*** pvrusb2 driver initialization"
2361 " failed due to the failure of one or more"
2362 " sub-device kernel modules.");
2363 pvr2_trace(
2364 PVR2_TRACE_ERROR_LEGS,
2365 "You need to resolve the failing condition"
2366 " before this driver can function. There"
2367 " should be some earlier messages giving more"
2368 " information about the problem.");
2369 break;
2370 }
2337 if (procreload) { 2371 if (procreload) {
2338 pvr2_trace( 2372 pvr2_trace(
2339 PVR2_TRACE_ERROR_LEGS, 2373 PVR2_TRACE_ERROR_LEGS,
@@ -2419,6 +2453,8 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf,
2419 hdw = kzalloc(sizeof(*hdw),GFP_KERNEL); 2453 hdw = kzalloc(sizeof(*hdw),GFP_KERNEL);
2420 pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_create: hdw=%p, type \"%s\"", 2454 pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_create: hdw=%p, type \"%s\"",
2421 hdw,hdw_desc->description); 2455 hdw,hdw_desc->description);
2456 pvr2_trace(PVR2_TRACE_INFO, "Hardware description: %s",
2457 hdw_desc->description);
2422 if (!hdw) goto fail; 2458 if (!hdw) goto fail;
2423 2459
2424 init_timer(&hdw->quiescent_timer); 2460 init_timer(&hdw->quiescent_timer);
@@ -3480,7 +3516,7 @@ static u8 *pvr2_full_eeprom_fetch(struct pvr2_hdw *hdw)
3480 3516
3481 3517
3482void pvr2_hdw_cpufw_set_enabled(struct pvr2_hdw *hdw, 3518void pvr2_hdw_cpufw_set_enabled(struct pvr2_hdw *hdw,
3483 int prom_flag, 3519 int mode,
3484 int enable_flag) 3520 int enable_flag)
3485{ 3521{
3486 int ret; 3522 int ret;
@@ -3503,11 +3539,12 @@ void pvr2_hdw_cpufw_set_enabled(struct pvr2_hdw *hdw,
3503 break; 3539 break;
3504 } 3540 }
3505 3541
3506 hdw->fw_cpu_flag = (prom_flag == 0); 3542 hdw->fw_cpu_flag = (mode != 2);
3507 if (hdw->fw_cpu_flag) { 3543 if (hdw->fw_cpu_flag) {
3544 hdw->fw_size = (mode == 1) ? 0x4000 : 0x2000;
3508 pvr2_trace(PVR2_TRACE_FIRMWARE, 3545 pvr2_trace(PVR2_TRACE_FIRMWARE,
3509 "Preparing to suck out CPU firmware"); 3546 "Preparing to suck out CPU firmware"
3510 hdw->fw_size = 0x2000; 3547 " (size=%u)", hdw->fw_size);
3511 hdw->fw_buffer = kzalloc(hdw->fw_size,GFP_KERNEL); 3548 hdw->fw_buffer = kzalloc(hdw->fw_size,GFP_KERNEL);
3512 if (!hdw->fw_buffer) { 3549 if (!hdw->fw_buffer) {
3513 hdw->fw_size = 0; 3550 hdw->fw_size = 0;
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.h b/drivers/media/video/pvrusb2/pvrusb2-hdw.h
index 7b6940554e9a..56e70eae20c1 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-hdw.h
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.h
@@ -219,7 +219,7 @@ int pvr2_hdw_get_stdenum_value(struct pvr2_hdw *hdw,struct v4l2_standard *std,
219 this may prevent the device from running (and leaving this mode may 219 this may prevent the device from running (and leaving this mode may
220 imply a device reset). */ 220 imply a device reset). */
221void pvr2_hdw_cpufw_set_enabled(struct pvr2_hdw *, 221void pvr2_hdw_cpufw_set_enabled(struct pvr2_hdw *,
222 int prom_flag, 222 int mode, /* 0=8KB FX2, 1=16KB FX2, 2=PROM */
223 int enable_flag); 223 int enable_flag);
224 224
225/* Return true if we're in a mode for retrieval CPU firmware */ 225/* Return true if we're in a mode for retrieval CPU firmware */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c b/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
index a334b1a966a2..7cbe18c4ca95 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
@@ -50,6 +50,7 @@ MODULE_PARM_DESC(disable_autoload_ir_video,
50 50
51/* Mapping of IR schemes to known I2C addresses - if any */ 51/* Mapping of IR schemes to known I2C addresses - if any */
52static const unsigned char ir_video_addresses[] = { 52static const unsigned char ir_video_addresses[] = {
53 [PVR2_IR_SCHEME_ZILOG] = 0x71,
53 [PVR2_IR_SCHEME_29XXX] = 0x18, 54 [PVR2_IR_SCHEME_29XXX] = 0x18,
54 [PVR2_IR_SCHEME_24XXX] = 0x18, 55 [PVR2_IR_SCHEME_24XXX] = 0x18,
55}; 56};
diff --git a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
index 2d8825e5b1be..6aa48e0ae731 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
@@ -913,6 +913,15 @@ static void pvr2_v4l2_dev_destroy(struct pvr2_v4l2_dev *dip)
913} 913}
914 914
915 915
916static void pvr2_v4l2_dev_disassociate_parent(struct pvr2_v4l2_dev *dip)
917{
918 if (!dip) return;
919 if (!dip->devbase.parent) return;
920 dip->devbase.parent = NULL;
921 device_move(&dip->devbase.dev, NULL, DPM_ORDER_NONE);
922}
923
924
916static void pvr2_v4l2_destroy_no_lock(struct pvr2_v4l2 *vp) 925static void pvr2_v4l2_destroy_no_lock(struct pvr2_v4l2 *vp)
917{ 926{
918 if (vp->dev_video) { 927 if (vp->dev_video) {
@@ -943,6 +952,8 @@ static void pvr2_v4l2_internal_check(struct pvr2_channel *chp)
943 struct pvr2_v4l2 *vp; 952 struct pvr2_v4l2 *vp;
944 vp = container_of(chp,struct pvr2_v4l2,channel); 953 vp = container_of(chp,struct pvr2_v4l2,channel);
945 if (!vp->channel.mc_head->disconnect_flag) return; 954 if (!vp->channel.mc_head->disconnect_flag) return;
955 pvr2_v4l2_dev_disassociate_parent(vp->dev_video);
956 pvr2_v4l2_dev_disassociate_parent(vp->dev_radio);
946 if (vp->vfirst) return; 957 if (vp->vfirst) return;
947 pvr2_v4l2_destroy_no_lock(vp); 958 pvr2_v4l2_destroy_no_lock(vp);
948} 959}
@@ -1250,12 +1261,13 @@ static void pvr2_v4l2_dev_init(struct pvr2_v4l2_dev *dip,
1250 struct pvr2_v4l2 *vp, 1261 struct pvr2_v4l2 *vp,
1251 int v4l_type) 1262 int v4l_type)
1252{ 1263{
1264 struct usb_device *usbdev;
1253 int mindevnum; 1265 int mindevnum;
1254 int unit_number; 1266 int unit_number;
1255 int *nr_ptr = NULL; 1267 int *nr_ptr = NULL;
1256 dip->v4lp = vp; 1268 dip->v4lp = vp;
1257 1269
1258 1270 usbdev = pvr2_hdw_get_dev(vp->channel.mc_head->hdw);
1259 dip->v4l_type = v4l_type; 1271 dip->v4l_type = v4l_type;
1260 switch (v4l_type) { 1272 switch (v4l_type) {
1261 case VFL_TYPE_GRABBER: 1273 case VFL_TYPE_GRABBER:
@@ -1296,6 +1308,7 @@ static void pvr2_v4l2_dev_init(struct pvr2_v4l2_dev *dip,
1296 if (nr_ptr && (unit_number >= 0) && (unit_number < PVR_NUM)) { 1308 if (nr_ptr && (unit_number >= 0) && (unit_number < PVR_NUM)) {
1297 mindevnum = nr_ptr[unit_number]; 1309 mindevnum = nr_ptr[unit_number];
1298 } 1310 }
1311 dip->devbase.parent = &usbdev->dev;
1299 if ((video_register_device(&dip->devbase, 1312 if ((video_register_device(&dip->devbase,
1300 dip->v4l_type, mindevnum) < 0) && 1313 dip->v4l_type, mindevnum) < 0) &&
1301 (video_register_device(&dip->devbase, 1314 (video_register_device(&dip->devbase,
diff --git a/drivers/media/video/pwc/pwc-if.c b/drivers/media/video/pwc/pwc-if.c
index f976df452a34..89b620f6db7b 100644
--- a/drivers/media/video/pwc/pwc-if.c
+++ b/drivers/media/video/pwc/pwc-if.c
@@ -68,6 +68,7 @@
68#endif 68#endif
69#include <linux/vmalloc.h> 69#include <linux/vmalloc.h>
70#include <asm/io.h> 70#include <asm/io.h>
71#include <linux/kernel.h> /* simple_strtol() */
71 72
72#include "pwc.h" 73#include "pwc.h"
73#include "pwc-kiara.h" 74#include "pwc-kiara.h"
@@ -1916,19 +1917,6 @@ disconnect_out:
1916 unlock_kernel(); 1917 unlock_kernel();
1917} 1918}
1918 1919
1919/* *grunt* We have to do atoi ourselves :-( */
1920static int pwc_atoi(const char *s)
1921{
1922 int k = 0;
1923
1924 k = 0;
1925 while (*s != '\0' && *s >= '0' && *s <= '9') {
1926 k = 10 * k + (*s - '0');
1927 s++;
1928 }
1929 return k;
1930}
1931
1932 1920
1933/* 1921/*
1934 * Initialization code & module stuff 1922 * Initialization code & module stuff
@@ -2078,13 +2066,16 @@ static int __init usb_pwc_init(void)
2078 } 2066 }
2079 else { 2067 else {
2080 /* No type or serial number specified, just a number. */ 2068 /* No type or serial number specified, just a number. */
2081 device_hint[i].device_node = pwc_atoi(s); 2069 device_hint[i].device_node =
2070 simple_strtol(s, NULL, 10);
2082 } 2071 }
2083 } 2072 }
2084 else { 2073 else {
2085 /* There's a colon, so we have at least a type and a device node */ 2074 /* There's a colon, so we have at least a type and a device node */
2086 device_hint[i].type = pwc_atoi(s); 2075 device_hint[i].type =
2087 device_hint[i].device_node = pwc_atoi(colon + 1); 2076 simple_strtol(s, NULL, 10);
2077 device_hint[i].device_node =
2078 simple_strtol(colon + 1, NULL, 10);
2088 if (*dot != '\0') { 2079 if (*dot != '\0') {
2089 /* There's a serial number as well */ 2080 /* There's a serial number as well */
2090 int k; 2081 int k;
diff --git a/drivers/media/video/rj54n1cb0c.c b/drivers/media/video/rj54n1cb0c.c
new file mode 100644
index 000000000000..373f2a30a677
--- /dev/null
+++ b/drivers/media/video/rj54n1cb0c.c
@@ -0,0 +1,1219 @@
1/*
2 * Driver for RJ54N1CB0C CMOS Image Sensor from Micron
3 *
4 * Copyright (C) 2009, Guennadi Liakhovetski <g.liakhovetski@gmx.de>
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 version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#include <linux/delay.h>
12#include <linux/i2c.h>
13#include <linux/slab.h>
14#include <linux/videodev2.h>
15
16#include <media/v4l2-subdev.h>
17#include <media/v4l2-chip-ident.h>
18#include <media/soc_camera.h>
19
20#define RJ54N1_DEV_CODE 0x0400
21#define RJ54N1_DEV_CODE2 0x0401
22#define RJ54N1_OUT_SEL 0x0403
23#define RJ54N1_XY_OUTPUT_SIZE_S_H 0x0404
24#define RJ54N1_X_OUTPUT_SIZE_S_L 0x0405
25#define RJ54N1_Y_OUTPUT_SIZE_S_L 0x0406
26#define RJ54N1_XY_OUTPUT_SIZE_P_H 0x0407
27#define RJ54N1_X_OUTPUT_SIZE_P_L 0x0408
28#define RJ54N1_Y_OUTPUT_SIZE_P_L 0x0409
29#define RJ54N1_LINE_LENGTH_PCK_S_H 0x040a
30#define RJ54N1_LINE_LENGTH_PCK_S_L 0x040b
31#define RJ54N1_LINE_LENGTH_PCK_P_H 0x040c
32#define RJ54N1_LINE_LENGTH_PCK_P_L 0x040d
33#define RJ54N1_RESIZE_N 0x040e
34#define RJ54N1_RESIZE_N_STEP 0x040f
35#define RJ54N1_RESIZE_STEP 0x0410
36#define RJ54N1_RESIZE_HOLD_H 0x0411
37#define RJ54N1_RESIZE_HOLD_L 0x0412
38#define RJ54N1_H_OBEN_OFS 0x0413
39#define RJ54N1_V_OBEN_OFS 0x0414
40#define RJ54N1_RESIZE_CONTROL 0x0415
41#define RJ54N1_INC_USE_SEL_H 0x0425
42#define RJ54N1_INC_USE_SEL_L 0x0426
43#define RJ54N1_MIRROR_STILL_MODE 0x0427
44#define RJ54N1_INIT_START 0x0428
45#define RJ54N1_SCALE_1_2_LEV 0x0429
46#define RJ54N1_SCALE_4_LEV 0x042a
47#define RJ54N1_Y_GAIN 0x04d8
48#define RJ54N1_APT_GAIN_UP 0x04fa
49#define RJ54N1_RA_SEL_UL 0x0530
50#define RJ54N1_BYTE_SWAP 0x0531
51#define RJ54N1_OUT_SIGPO 0x053b
52#define RJ54N1_FRAME_LENGTH_S_H 0x0595
53#define RJ54N1_FRAME_LENGTH_S_L 0x0596
54#define RJ54N1_FRAME_LENGTH_P_H 0x0597
55#define RJ54N1_FRAME_LENGTH_P_L 0x0598
56#define RJ54N1_IOC 0x05ef
57#define RJ54N1_TG_BYPASS 0x0700
58#define RJ54N1_PLL_L 0x0701
59#define RJ54N1_PLL_N 0x0702
60#define RJ54N1_PLL_EN 0x0704
61#define RJ54N1_RATIO_TG 0x0706
62#define RJ54N1_RATIO_T 0x0707
63#define RJ54N1_RATIO_R 0x0708
64#define RJ54N1_RAMP_TGCLK_EN 0x0709
65#define RJ54N1_OCLK_DSP 0x0710
66#define RJ54N1_RATIO_OP 0x0711
67#define RJ54N1_RATIO_O 0x0712
68#define RJ54N1_OCLK_SEL_EN 0x0713
69#define RJ54N1_CLK_RST 0x0717
70#define RJ54N1_RESET_STANDBY 0x0718
71
72#define E_EXCLK (1 << 7)
73#define SOFT_STDBY (1 << 4)
74#define SEN_RSTX (1 << 2)
75#define TG_RSTX (1 << 1)
76#define DSP_RSTX (1 << 0)
77
78#define RESIZE_HOLD_SEL (1 << 2)
79#define RESIZE_GO (1 << 1)
80
81#define RJ54N1_COLUMN_SKIP 0
82#define RJ54N1_ROW_SKIP 0
83#define RJ54N1_MAX_WIDTH 1600
84#define RJ54N1_MAX_HEIGHT 1200
85
86/* I2C addresses: 0x50, 0x51, 0x60, 0x61 */
87
88static const struct soc_camera_data_format rj54n1_colour_formats[] = {
89 {
90 .name = "YUYV",
91 .depth = 16,
92 .fourcc = V4L2_PIX_FMT_YUYV,
93 .colorspace = V4L2_COLORSPACE_JPEG,
94 }, {
95 .name = "RGB565",
96 .depth = 16,
97 .fourcc = V4L2_PIX_FMT_RGB565,
98 .colorspace = V4L2_COLORSPACE_SRGB,
99 }
100};
101
102struct rj54n1_clock_div {
103 u8 ratio_tg;
104 u8 ratio_t;
105 u8 ratio_r;
106 u8 ratio_op;
107 u8 ratio_o;
108};
109
110struct rj54n1 {
111 struct v4l2_subdev subdev;
112 struct v4l2_rect rect; /* Sensor window */
113 unsigned short width; /* Output window */
114 unsigned short height;
115 unsigned short resize; /* Sensor * 1024 / resize = Output */
116 struct rj54n1_clock_div clk_div;
117 u32 fourcc;
118 unsigned short scale;
119 u8 bank;
120};
121
122struct rj54n1_reg_val {
123 u16 reg;
124 u8 val;
125};
126
127const static struct rj54n1_reg_val bank_4[] = {
128 {0x417, 0},
129 {0x42c, 0},
130 {0x42d, 0xf0},
131 {0x42e, 0},
132 {0x42f, 0x50},
133 {0x430, 0xf5},
134 {0x431, 0x16},
135 {0x432, 0x20},
136 {0x433, 0},
137 {0x434, 0xc8},
138 {0x43c, 8},
139 {0x43e, 0x90},
140 {0x445, 0x83},
141 {0x4ba, 0x58},
142 {0x4bb, 4},
143 {0x4bc, 0x20},
144 {0x4db, 4},
145 {0x4fe, 2},
146};
147
148const static struct rj54n1_reg_val bank_5[] = {
149 {0x514, 0},
150 {0x516, 0},
151 {0x518, 0},
152 {0x51a, 0},
153 {0x51d, 0xff},
154 {0x56f, 0x28},
155 {0x575, 0x40},
156 {0x5bc, 0x48},
157 {0x5c1, 6},
158 {0x5e5, 0x11},
159 {0x5e6, 0x43},
160 {0x5e7, 0x33},
161 {0x5e8, 0x21},
162 {0x5e9, 0x30},
163 {0x5ea, 0x0},
164 {0x5eb, 0xa5},
165 {0x5ec, 0xff},
166 {0x5fe, 2},
167};
168
169const static struct rj54n1_reg_val bank_7[] = {
170 {0x70a, 0},
171 {0x714, 0xff},
172 {0x715, 0xff},
173 {0x716, 0x1f},
174 {0x7FE, 0x02},
175};
176
177const static struct rj54n1_reg_val bank_8[] = {
178 {0x800, 0x00},
179 {0x801, 0x01},
180 {0x802, 0x61},
181 {0x805, 0x00},
182 {0x806, 0x00},
183 {0x807, 0x00},
184 {0x808, 0x00},
185 {0x809, 0x01},
186 {0x80A, 0x61},
187 {0x80B, 0x00},
188 {0x80C, 0x01},
189 {0x80D, 0x00},
190 {0x80E, 0x00},
191 {0x80F, 0x00},
192 {0x810, 0x00},
193 {0x811, 0x01},
194 {0x812, 0x61},
195 {0x813, 0x00},
196 {0x814, 0x11},
197 {0x815, 0x00},
198 {0x816, 0x41},
199 {0x817, 0x00},
200 {0x818, 0x51},
201 {0x819, 0x01},
202 {0x81A, 0x1F},
203 {0x81B, 0x00},
204 {0x81C, 0x01},
205 {0x81D, 0x00},
206 {0x81E, 0x11},
207 {0x81F, 0x00},
208 {0x820, 0x41},
209 {0x821, 0x00},
210 {0x822, 0x51},
211 {0x823, 0x00},
212 {0x824, 0x00},
213 {0x825, 0x00},
214 {0x826, 0x47},
215 {0x827, 0x01},
216 {0x828, 0x4F},
217 {0x829, 0x00},
218 {0x82A, 0x00},
219 {0x82B, 0x00},
220 {0x82C, 0x30},
221 {0x82D, 0x00},
222 {0x82E, 0x40},
223 {0x82F, 0x00},
224 {0x830, 0xB3},
225 {0x831, 0x00},
226 {0x832, 0xE3},
227 {0x833, 0x00},
228 {0x834, 0x00},
229 {0x835, 0x00},
230 {0x836, 0x00},
231 {0x837, 0x00},
232 {0x838, 0x00},
233 {0x839, 0x01},
234 {0x83A, 0x61},
235 {0x83B, 0x00},
236 {0x83C, 0x01},
237 {0x83D, 0x00},
238 {0x83E, 0x00},
239 {0x83F, 0x00},
240 {0x840, 0x00},
241 {0x841, 0x01},
242 {0x842, 0x61},
243 {0x843, 0x00},
244 {0x844, 0x1D},
245 {0x845, 0x00},
246 {0x846, 0x00},
247 {0x847, 0x00},
248 {0x848, 0x00},
249 {0x849, 0x01},
250 {0x84A, 0x1F},
251 {0x84B, 0x00},
252 {0x84C, 0x05},
253 {0x84D, 0x00},
254 {0x84E, 0x19},
255 {0x84F, 0x01},
256 {0x850, 0x21},
257 {0x851, 0x01},
258 {0x852, 0x5D},
259 {0x853, 0x00},
260 {0x854, 0x00},
261 {0x855, 0x00},
262 {0x856, 0x19},
263 {0x857, 0x01},
264 {0x858, 0x21},
265 {0x859, 0x00},
266 {0x85A, 0x00},
267 {0x85B, 0x00},
268 {0x85C, 0x00},
269 {0x85D, 0x00},
270 {0x85E, 0x00},
271 {0x85F, 0x00},
272 {0x860, 0xB3},
273 {0x861, 0x00},
274 {0x862, 0xE3},
275 {0x863, 0x00},
276 {0x864, 0x00},
277 {0x865, 0x00},
278 {0x866, 0x00},
279 {0x867, 0x00},
280 {0x868, 0x00},
281 {0x869, 0xE2},
282 {0x86A, 0x00},
283 {0x86B, 0x01},
284 {0x86C, 0x06},
285 {0x86D, 0x00},
286 {0x86E, 0x00},
287 {0x86F, 0x00},
288 {0x870, 0x60},
289 {0x871, 0x8C},
290 {0x872, 0x10},
291 {0x873, 0x00},
292 {0x874, 0xE0},
293 {0x875, 0x00},
294 {0x876, 0x27},
295 {0x877, 0x01},
296 {0x878, 0x00},
297 {0x879, 0x00},
298 {0x87A, 0x00},
299 {0x87B, 0x03},
300 {0x87C, 0x00},
301 {0x87D, 0x00},
302 {0x87E, 0x00},
303 {0x87F, 0x00},
304 {0x880, 0x00},
305 {0x881, 0x00},
306 {0x882, 0x00},
307 {0x883, 0x00},
308 {0x884, 0x00},
309 {0x885, 0x00},
310 {0x886, 0xF8},
311 {0x887, 0x00},
312 {0x888, 0x03},
313 {0x889, 0x00},
314 {0x88A, 0x64},
315 {0x88B, 0x00},
316 {0x88C, 0x03},
317 {0x88D, 0x00},
318 {0x88E, 0xB1},
319 {0x88F, 0x00},
320 {0x890, 0x03},
321 {0x891, 0x01},
322 {0x892, 0x1D},
323 {0x893, 0x00},
324 {0x894, 0x03},
325 {0x895, 0x01},
326 {0x896, 0x4B},
327 {0x897, 0x00},
328 {0x898, 0xE5},
329 {0x899, 0x00},
330 {0x89A, 0x01},
331 {0x89B, 0x00},
332 {0x89C, 0x01},
333 {0x89D, 0x04},
334 {0x89E, 0xC8},
335 {0x89F, 0x00},
336 {0x8A0, 0x01},
337 {0x8A1, 0x01},
338 {0x8A2, 0x61},
339 {0x8A3, 0x00},
340 {0x8A4, 0x01},
341 {0x8A5, 0x00},
342 {0x8A6, 0x00},
343 {0x8A7, 0x00},
344 {0x8A8, 0x00},
345 {0x8A9, 0x00},
346 {0x8AA, 0x7F},
347 {0x8AB, 0x03},
348 {0x8AC, 0x00},
349 {0x8AD, 0x00},
350 {0x8AE, 0x00},
351 {0x8AF, 0x00},
352 {0x8B0, 0x00},
353 {0x8B1, 0x00},
354 {0x8B6, 0x00},
355 {0x8B7, 0x01},
356 {0x8B8, 0x00},
357 {0x8B9, 0x00},
358 {0x8BA, 0x02},
359 {0x8BB, 0x00},
360 {0x8BC, 0xFF},
361 {0x8BD, 0x00},
362 {0x8FE, 0x02},
363};
364
365const static struct rj54n1_reg_val bank_10[] = {
366 {0x10bf, 0x69}
367};
368
369/* Clock dividers - these are default register values, divider = register + 1 */
370const static struct rj54n1_clock_div clk_div = {
371 .ratio_tg = 3 /* default: 5 */,
372 .ratio_t = 4 /* default: 1 */,
373 .ratio_r = 4 /* default: 0 */,
374 .ratio_op = 1 /* default: 5 */,
375 .ratio_o = 9 /* default: 0 */,
376};
377
378static struct rj54n1 *to_rj54n1(const struct i2c_client *client)
379{
380 return container_of(i2c_get_clientdata(client), struct rj54n1, subdev);
381}
382
383static int reg_read(struct i2c_client *client, const u16 reg)
384{
385 struct rj54n1 *rj54n1 = to_rj54n1(client);
386 int ret;
387
388 /* set bank */
389 if (rj54n1->bank != reg >> 8) {
390 dev_dbg(&client->dev, "[0x%x] = 0x%x\n", 0xff, reg >> 8);
391 ret = i2c_smbus_write_byte_data(client, 0xff, reg >> 8);
392 if (ret < 0)
393 return ret;
394 rj54n1->bank = reg >> 8;
395 }
396 return i2c_smbus_read_byte_data(client, reg & 0xff);
397}
398
399static int reg_write(struct i2c_client *client, const u16 reg,
400 const u8 data)
401{
402 struct rj54n1 *rj54n1 = to_rj54n1(client);
403 int ret;
404
405 /* set bank */
406 if (rj54n1->bank != reg >> 8) {
407 dev_dbg(&client->dev, "[0x%x] = 0x%x\n", 0xff, reg >> 8);
408 ret = i2c_smbus_write_byte_data(client, 0xff, reg >> 8);
409 if (ret < 0)
410 return ret;
411 rj54n1->bank = reg >> 8;
412 }
413 dev_dbg(&client->dev, "[0x%x] = 0x%x\n", reg & 0xff, data);
414 return i2c_smbus_write_byte_data(client, reg & 0xff, data);
415}
416
417static int reg_set(struct i2c_client *client, const u16 reg,
418 const u8 data, const u8 mask)
419{
420 int ret;
421
422 ret = reg_read(client, reg);
423 if (ret < 0)
424 return ret;
425 return reg_write(client, reg, (ret & ~mask) | (data & mask));
426}
427
428static int reg_write_multiple(struct i2c_client *client,
429 const struct rj54n1_reg_val *rv, const int n)
430{
431 int i, ret;
432
433 for (i = 0; i < n; i++) {
434 ret = reg_write(client, rv->reg, rv->val);
435 if (ret < 0)
436 return ret;
437 rv++;
438 }
439
440 return 0;
441}
442
443static int rj54n1_s_stream(struct v4l2_subdev *sd, int enable)
444{
445 /* TODO: start / stop streaming */
446 return 0;
447}
448
449static int rj54n1_set_bus_param(struct soc_camera_device *icd,
450 unsigned long flags)
451{
452 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
453 struct i2c_client *client = sd->priv;
454 /* Figures 2.5-1 to 2.5-3 - default falling pixclk edge */
455
456 if (flags & SOCAM_PCLK_SAMPLE_RISING)
457 return reg_write(client, RJ54N1_OUT_SIGPO, 1 << 4);
458 else
459 return reg_write(client, RJ54N1_OUT_SIGPO, 0);
460}
461
462static unsigned long rj54n1_query_bus_param(struct soc_camera_device *icd)
463{
464 struct soc_camera_link *icl = to_soc_camera_link(icd);
465 const unsigned long flags =
466 SOCAM_PCLK_SAMPLE_RISING | SOCAM_PCLK_SAMPLE_FALLING |
467 SOCAM_MASTER | SOCAM_DATAWIDTH_8 |
468 SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_HIGH |
469 SOCAM_DATA_ACTIVE_HIGH;
470
471 return soc_camera_apply_sensor_flags(icl, flags);
472}
473
474static int rj54n1_set_rect(struct i2c_client *client,
475 u16 reg_x, u16 reg_y, u16 reg_xy,
476 u32 width, u32 height)
477{
478 int ret;
479
480 ret = reg_write(client, reg_xy,
481 ((width >> 4) & 0x70) |
482 ((height >> 8) & 7));
483
484 if (!ret)
485 ret = reg_write(client, reg_x, width & 0xff);
486 if (!ret)
487 ret = reg_write(client, reg_y, height & 0xff);
488
489 return ret;
490}
491
492/*
493 * Some commands, specifically certain initialisation sequences, require
494 * a commit operation.
495 */
496static int rj54n1_commit(struct i2c_client *client)
497{
498 int ret = reg_write(client, RJ54N1_INIT_START, 1);
499 msleep(10);
500 if (!ret)
501 ret = reg_write(client, RJ54N1_INIT_START, 0);
502 return ret;
503}
504
505static int rj54n1_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
506{
507 struct i2c_client *client = sd->priv;
508 struct rj54n1 *rj54n1 = to_rj54n1(client);
509
510 a->c = rj54n1->rect;
511 a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
512
513 return 0;
514}
515
516static int rj54n1_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
517{
518 a->bounds.left = RJ54N1_COLUMN_SKIP;
519 a->bounds.top = RJ54N1_ROW_SKIP;
520 a->bounds.width = RJ54N1_MAX_WIDTH;
521 a->bounds.height = RJ54N1_MAX_HEIGHT;
522 a->defrect = a->bounds;
523 a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
524 a->pixelaspect.numerator = 1;
525 a->pixelaspect.denominator = 1;
526
527 return 0;
528}
529
530static int rj54n1_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
531{
532 struct i2c_client *client = sd->priv;
533 struct rj54n1 *rj54n1 = to_rj54n1(client);
534 struct v4l2_pix_format *pix = &f->fmt.pix;
535
536 pix->pixelformat = rj54n1->fourcc;
537 pix->field = V4L2_FIELD_NONE;
538 pix->width = rj54n1->width;
539 pix->height = rj54n1->height;
540
541 return 0;
542}
543
544/*
545 * The actual geometry configuration routine. It scales the input window into
546 * the output one, updates the window sizes and returns an error or the resize
547 * coefficient on success. Note: we only use the "Fixed Scaling" on this camera.
548 */
549static int rj54n1_sensor_scale(struct v4l2_subdev *sd, u32 *in_w, u32 *in_h,
550 u32 *out_w, u32 *out_h)
551{
552 struct i2c_client *client = sd->priv;
553 unsigned int skip, resize, input_w = *in_w, input_h = *in_h,
554 output_w = *out_w, output_h = *out_h;
555 u16 inc_sel;
556 int ret;
557
558 ret = rj54n1_set_rect(client, RJ54N1_X_OUTPUT_SIZE_S_L,
559 RJ54N1_Y_OUTPUT_SIZE_S_L,
560 RJ54N1_XY_OUTPUT_SIZE_S_H, output_w, output_h);
561 if (!ret)
562 ret = rj54n1_set_rect(client, RJ54N1_X_OUTPUT_SIZE_P_L,
563 RJ54N1_Y_OUTPUT_SIZE_P_L,
564 RJ54N1_XY_OUTPUT_SIZE_P_H, output_w, output_h);
565
566 if (ret < 0)
567 return ret;
568
569 if (output_w > input_w || output_h > input_h) {
570 input_w = output_w;
571 input_h = output_h;
572
573 resize = 1024;
574 } else {
575 unsigned int resize_x, resize_y;
576 resize_x = input_w * 1024 / output_w;
577 resize_y = input_h * 1024 / output_h;
578
579 resize = min(resize_x, resize_y);
580
581 /* Prohibited value ranges */
582 switch (resize) {
583 case 2040 ... 2047:
584 resize = 2039;
585 break;
586 case 4080 ... 4095:
587 resize = 4079;
588 break;
589 case 8160 ... 8191:
590 resize = 8159;
591 break;
592 case 16320 ... 16383:
593 resize = 16319;
594 }
595
596 input_w = output_w * resize / 1024;
597 input_h = output_h * resize / 1024;
598 }
599
600 /* Set scaling */
601 ret = reg_write(client, RJ54N1_RESIZE_HOLD_L, resize & 0xff);
602 if (!ret)
603 ret = reg_write(client, RJ54N1_RESIZE_HOLD_H, resize >> 8);
604
605 if (ret < 0)
606 return ret;
607
608 /*
609 * Configure a skipping bitmask. The sensor will select a skipping value
610 * among set bits automatically.
611 */
612 skip = min(resize / 1024, (unsigned)15);
613 inc_sel = 1 << skip;
614
615 if (inc_sel <= 2)
616 inc_sel = 0xc;
617 else if (resize & 1023 && skip < 15)
618 inc_sel |= 1 << (skip + 1);
619
620 ret = reg_write(client, RJ54N1_INC_USE_SEL_L, inc_sel & 0xfc);
621 if (!ret)
622 ret = reg_write(client, RJ54N1_INC_USE_SEL_H, inc_sel >> 8);
623
624 /* Start resizing */
625 if (!ret)
626 ret = reg_write(client, RJ54N1_RESIZE_CONTROL,
627 RESIZE_HOLD_SEL | RESIZE_GO | 1);
628
629 if (ret < 0)
630 return ret;
631
632 dev_dbg(&client->dev, "resize %u, skip %u\n", resize, skip);
633
634 /* Constant taken from manufacturer's example */
635 msleep(230);
636
637 ret = reg_write(client, RJ54N1_RESIZE_CONTROL, RESIZE_HOLD_SEL | 1);
638 if (ret < 0)
639 return ret;
640
641 *in_w = input_w;
642 *in_h = input_h;
643 *out_w = output_w;
644 *out_h = output_h;
645
646 return resize;
647}
648
649static int rj54n1_set_clock(struct i2c_client *client)
650{
651 struct rj54n1 *rj54n1 = to_rj54n1(client);
652 int ret;
653
654 /* Enable external clock */
655 ret = reg_write(client, RJ54N1_RESET_STANDBY, E_EXCLK | SOFT_STDBY);
656 /* Leave stand-by */
657 if (!ret)
658 ret = reg_write(client, RJ54N1_RESET_STANDBY, E_EXCLK);
659
660 if (!ret)
661 ret = reg_write(client, RJ54N1_PLL_L, 2);
662 if (!ret)
663 ret = reg_write(client, RJ54N1_PLL_N, 0x31);
664
665 /* TGCLK dividers */
666 if (!ret)
667 ret = reg_write(client, RJ54N1_RATIO_TG,
668 rj54n1->clk_div.ratio_tg);
669 if (!ret)
670 ret = reg_write(client, RJ54N1_RATIO_T,
671 rj54n1->clk_div.ratio_t);
672 if (!ret)
673 ret = reg_write(client, RJ54N1_RATIO_R,
674 rj54n1->clk_div.ratio_r);
675
676 /* Enable TGCLK & RAMP */
677 if (!ret)
678 ret = reg_write(client, RJ54N1_RAMP_TGCLK_EN, 3);
679
680 /* Disable clock output */
681 if (!ret)
682 ret = reg_write(client, RJ54N1_OCLK_DSP, 0);
683
684 /* Set divisors */
685 if (!ret)
686 ret = reg_write(client, RJ54N1_RATIO_OP,
687 rj54n1->clk_div.ratio_op);
688 if (!ret)
689 ret = reg_write(client, RJ54N1_RATIO_O,
690 rj54n1->clk_div.ratio_o);
691
692 /* Enable OCLK */
693 if (!ret)
694 ret = reg_write(client, RJ54N1_OCLK_SEL_EN, 1);
695
696 /* Use PLL for Timing Generator, write 2 to reserved bits */
697 if (!ret)
698 ret = reg_write(client, RJ54N1_TG_BYPASS, 2);
699
700 /* Take sensor out of reset */
701 if (!ret)
702 ret = reg_write(client, RJ54N1_RESET_STANDBY,
703 E_EXCLK | SEN_RSTX);
704 /* Enable PLL */
705 if (!ret)
706 ret = reg_write(client, RJ54N1_PLL_EN, 1);
707
708 /* Wait for PLL to stabilise */
709 msleep(10);
710
711 /* Enable clock to frequency divider */
712 if (!ret)
713 ret = reg_write(client, RJ54N1_CLK_RST, 1);
714
715 if (!ret)
716 ret = reg_read(client, RJ54N1_CLK_RST);
717 if (ret != 1) {
718 dev_err(&client->dev,
719 "Resetting RJ54N1CB0C clock failed: %d!\n", ret);
720 return -EIO;
721 }
722 /* Start the PLL */
723 ret = reg_set(client, RJ54N1_OCLK_DSP, 1, 1);
724
725 /* Enable OCLK */
726 if (!ret)
727 ret = reg_write(client, RJ54N1_OCLK_SEL_EN, 1);
728
729 return ret;
730}
731
732static int rj54n1_reg_init(struct i2c_client *client)
733{
734 int ret = rj54n1_set_clock(client);
735
736 if (!ret)
737 ret = reg_write_multiple(client, bank_7, ARRAY_SIZE(bank_7));
738 if (!ret)
739 ret = reg_write_multiple(client, bank_10, ARRAY_SIZE(bank_10));
740
741 /* Set binning divisors */
742 if (!ret)
743 ret = reg_write(client, RJ54N1_SCALE_1_2_LEV, 3 | (7 << 4));
744 if (!ret)
745 ret = reg_write(client, RJ54N1_SCALE_4_LEV, 0xf);
746
747 /* Switch to fixed resize mode */
748 if (!ret)
749 ret = reg_write(client, RJ54N1_RESIZE_CONTROL,
750 RESIZE_HOLD_SEL | 1);
751
752 /* Set gain */
753 if (!ret)
754 ret = reg_write(client, RJ54N1_Y_GAIN, 0x84);
755
756 /* Mirror the image back: default is upside down and left-to-right... */
757 if (!ret)
758 ret = reg_set(client, RJ54N1_MIRROR_STILL_MODE, 3, 3);
759
760 if (!ret)
761 ret = reg_write_multiple(client, bank_4, ARRAY_SIZE(bank_4));
762 if (!ret)
763 ret = reg_write_multiple(client, bank_5, ARRAY_SIZE(bank_5));
764 if (!ret)
765 ret = reg_write_multiple(client, bank_8, ARRAY_SIZE(bank_8));
766
767 if (!ret)
768 ret = reg_write(client, RJ54N1_RESET_STANDBY,
769 E_EXCLK | DSP_RSTX | SEN_RSTX);
770
771 /* Commit init */
772 if (!ret)
773 ret = rj54n1_commit(client);
774
775 /* Take DSP, TG, sensor out of reset */
776 if (!ret)
777 ret = reg_write(client, RJ54N1_RESET_STANDBY,
778 E_EXCLK | DSP_RSTX | TG_RSTX | SEN_RSTX);
779
780 if (!ret)
781 ret = reg_write(client, 0x7fe, 2);
782
783 /* Constant taken from manufacturer's example */
784 msleep(700);
785
786 return ret;
787}
788
789/* FIXME: streaming output only up to 800x600 is functional */
790static int rj54n1_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
791{
792 struct v4l2_pix_format *pix = &f->fmt.pix;
793
794 pix->field = V4L2_FIELD_NONE;
795
796 if (pix->width > 800)
797 pix->width = 800;
798 if (pix->height > 600)
799 pix->height = 600;
800
801 return 0;
802}
803
804static int rj54n1_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
805{
806 struct i2c_client *client = sd->priv;
807 struct rj54n1 *rj54n1 = to_rj54n1(client);
808 struct v4l2_pix_format *pix = &f->fmt.pix;
809 unsigned int output_w, output_h,
810 input_w = rj54n1->rect.width, input_h = rj54n1->rect.height;
811 int ret;
812
813 /*
814 * The host driver can call us without .try_fmt(), so, we have to take
815 * care ourseleves
816 */
817 ret = rj54n1_try_fmt(sd, f);
818
819 /*
820 * Verify if the sensor has just been powered on. TODO: replace this
821 * with proper PM, when a suitable API is available.
822 */
823 if (!ret)
824 ret = reg_read(client, RJ54N1_RESET_STANDBY);
825 if (ret < 0)
826 return ret;
827
828 if (!(ret & E_EXCLK)) {
829 ret = rj54n1_reg_init(client);
830 if (ret < 0)
831 return ret;
832 }
833
834 /* RA_SEL_UL is only relevant for raw modes, ignored otherwise. */
835 switch (pix->pixelformat) {
836 case V4L2_PIX_FMT_YUYV:
837 ret = reg_write(client, RJ54N1_OUT_SEL, 0);
838 if (!ret)
839 ret = reg_set(client, RJ54N1_BYTE_SWAP, 8, 8);
840 break;
841 case V4L2_PIX_FMT_RGB565:
842 ret = reg_write(client, RJ54N1_OUT_SEL, 0x11);
843 if (!ret)
844 ret = reg_set(client, RJ54N1_BYTE_SWAP, 8, 8);
845 break;
846 default:
847 ret = -EINVAL;
848 }
849
850 if (ret < 0)
851 return ret;
852
853 /* Supported scales 1:1 - 1:16 */
854 if (pix->width < input_w / 16)
855 pix->width = input_w / 16;
856 if (pix->height < input_h / 16)
857 pix->height = input_h / 16;
858
859 output_w = pix->width;
860 output_h = pix->height;
861
862 ret = rj54n1_sensor_scale(sd, &input_w, &input_h, &output_w, &output_h);
863 if (ret < 0)
864 return ret;
865
866 rj54n1->fourcc = pix->pixelformat;
867 rj54n1->resize = ret;
868 rj54n1->rect.width = input_w;
869 rj54n1->rect.height = input_h;
870 rj54n1->width = output_w;
871 rj54n1->height = output_h;
872
873 pix->width = output_w;
874 pix->height = output_h;
875 pix->field = V4L2_FIELD_NONE;
876
877 return ret;
878}
879
880static int rj54n1_g_chip_ident(struct v4l2_subdev *sd,
881 struct v4l2_dbg_chip_ident *id)
882{
883 struct i2c_client *client = sd->priv;
884
885 if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR)
886 return -EINVAL;
887
888 if (id->match.addr != client->addr)
889 return -ENODEV;
890
891 id->ident = V4L2_IDENT_RJ54N1CB0C;
892 id->revision = 0;
893
894 return 0;
895}
896
897#ifdef CONFIG_VIDEO_ADV_DEBUG
898static int rj54n1_g_register(struct v4l2_subdev *sd,
899 struct v4l2_dbg_register *reg)
900{
901 struct i2c_client *client = sd->priv;
902
903 if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR ||
904 reg->reg < 0x400 || reg->reg > 0x1fff)
905 /* Registers > 0x0800 are only available from Sharp support */
906 return -EINVAL;
907
908 if (reg->match.addr != client->addr)
909 return -ENODEV;
910
911 reg->size = 1;
912 reg->val = reg_read(client, reg->reg);
913
914 if (reg->val > 0xff)
915 return -EIO;
916
917 return 0;
918}
919
920static int rj54n1_s_register(struct v4l2_subdev *sd,
921 struct v4l2_dbg_register *reg)
922{
923 struct i2c_client *client = sd->priv;
924
925 if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR ||
926 reg->reg < 0x400 || reg->reg > 0x1fff)
927 /* Registers >= 0x0800 are only available from Sharp support */
928 return -EINVAL;
929
930 if (reg->match.addr != client->addr)
931 return -ENODEV;
932
933 if (reg_write(client, reg->reg, reg->val) < 0)
934 return -EIO;
935
936 return 0;
937}
938#endif
939
940static const struct v4l2_queryctrl rj54n1_controls[] = {
941 {
942 .id = V4L2_CID_VFLIP,
943 .type = V4L2_CTRL_TYPE_BOOLEAN,
944 .name = "Flip Vertically",
945 .minimum = 0,
946 .maximum = 1,
947 .step = 1,
948 .default_value = 0,
949 }, {
950 .id = V4L2_CID_HFLIP,
951 .type = V4L2_CTRL_TYPE_BOOLEAN,
952 .name = "Flip Horizontally",
953 .minimum = 0,
954 .maximum = 1,
955 .step = 1,
956 .default_value = 0,
957 }, {
958 .id = V4L2_CID_GAIN,
959 .type = V4L2_CTRL_TYPE_INTEGER,
960 .name = "Gain",
961 .minimum = 0,
962 .maximum = 127,
963 .step = 1,
964 .default_value = 66,
965 .flags = V4L2_CTRL_FLAG_SLIDER,
966 },
967};
968
969static struct soc_camera_ops rj54n1_ops = {
970 .set_bus_param = rj54n1_set_bus_param,
971 .query_bus_param = rj54n1_query_bus_param,
972 .controls = rj54n1_controls,
973 .num_controls = ARRAY_SIZE(rj54n1_controls),
974};
975
976static int rj54n1_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
977{
978 struct i2c_client *client = sd->priv;
979 int data;
980
981 switch (ctrl->id) {
982 case V4L2_CID_VFLIP:
983 data = reg_read(client, RJ54N1_MIRROR_STILL_MODE);
984 if (data < 0)
985 return -EIO;
986 ctrl->value = !(data & 1);
987 break;
988 case V4L2_CID_HFLIP:
989 data = reg_read(client, RJ54N1_MIRROR_STILL_MODE);
990 if (data < 0)
991 return -EIO;
992 ctrl->value = !(data & 2);
993 break;
994 case V4L2_CID_GAIN:
995 data = reg_read(client, RJ54N1_Y_GAIN);
996 if (data < 0)
997 return -EIO;
998
999 ctrl->value = data / 2;
1000 break;
1001 }
1002
1003 return 0;
1004}
1005
1006static int rj54n1_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
1007{
1008 int data;
1009 struct i2c_client *client = sd->priv;
1010 const struct v4l2_queryctrl *qctrl;
1011
1012 qctrl = soc_camera_find_qctrl(&rj54n1_ops, ctrl->id);
1013 if (!qctrl)
1014 return -EINVAL;
1015
1016 switch (ctrl->id) {
1017 case V4L2_CID_VFLIP:
1018 if (ctrl->value)
1019 data = reg_set(client, RJ54N1_MIRROR_STILL_MODE, 0, 1);
1020 else
1021 data = reg_set(client, RJ54N1_MIRROR_STILL_MODE, 1, 1);
1022 if (data < 0)
1023 return -EIO;
1024 break;
1025 case V4L2_CID_HFLIP:
1026 if (ctrl->value)
1027 data = reg_set(client, RJ54N1_MIRROR_STILL_MODE, 0, 2);
1028 else
1029 data = reg_set(client, RJ54N1_MIRROR_STILL_MODE, 2, 2);
1030 if (data < 0)
1031 return -EIO;
1032 break;
1033 case V4L2_CID_GAIN:
1034 if (ctrl->value > qctrl->maximum ||
1035 ctrl->value < qctrl->minimum)
1036 return -EINVAL;
1037 else if (reg_write(client, RJ54N1_Y_GAIN, ctrl->value * 2) < 0)
1038 return -EIO;
1039 break;
1040 }
1041
1042 return 0;
1043}
1044
1045static struct v4l2_subdev_core_ops rj54n1_subdev_core_ops = {
1046 .g_ctrl = rj54n1_g_ctrl,
1047 .s_ctrl = rj54n1_s_ctrl,
1048 .g_chip_ident = rj54n1_g_chip_ident,
1049#ifdef CONFIG_VIDEO_ADV_DEBUG
1050 .g_register = rj54n1_g_register,
1051 .s_register = rj54n1_s_register,
1052#endif
1053};
1054
1055static struct v4l2_subdev_video_ops rj54n1_subdev_video_ops = {
1056 .s_stream = rj54n1_s_stream,
1057 .s_fmt = rj54n1_s_fmt,
1058 .g_fmt = rj54n1_g_fmt,
1059 .try_fmt = rj54n1_try_fmt,
1060 .g_crop = rj54n1_g_crop,
1061 .cropcap = rj54n1_cropcap,
1062};
1063
1064static struct v4l2_subdev_ops rj54n1_subdev_ops = {
1065 .core = &rj54n1_subdev_core_ops,
1066 .video = &rj54n1_subdev_video_ops,
1067};
1068
1069static int rj54n1_pin_config(struct i2c_client *client)
1070{
1071 /*
1072 * Experimentally found out IOCTRL wired to 0. TODO: add to platform
1073 * data: 0 or 1 << 7.
1074 */
1075 return reg_write(client, RJ54N1_IOC, 0);
1076}
1077
1078/*
1079 * Interface active, can use i2c. If it fails, it can indeed mean, that
1080 * this wasn't our capture interface, so, we wait for the right one
1081 */
1082static int rj54n1_video_probe(struct soc_camera_device *icd,
1083 struct i2c_client *client)
1084{
1085 int data1, data2;
1086 int ret;
1087
1088 /* This could be a BUG_ON() or a WARN_ON(), or remove it completely */
1089 if (!icd->dev.parent ||
1090 to_soc_camera_host(icd->dev.parent)->nr != icd->iface)
1091 return -ENODEV;
1092
1093 /* Read out the chip version register */
1094 data1 = reg_read(client, RJ54N1_DEV_CODE);
1095 data2 = reg_read(client, RJ54N1_DEV_CODE2);
1096
1097 if (data1 != 0x51 || data2 != 0x10) {
1098 ret = -ENODEV;
1099 dev_info(&client->dev, "No RJ54N1CB0C found, read 0x%x:0x%x\n",
1100 data1, data2);
1101 goto ei2c;
1102 }
1103
1104 ret = rj54n1_pin_config(client);
1105 if (ret < 0)
1106 goto ei2c;
1107
1108 dev_info(&client->dev, "Detected a RJ54N1CB0C chip ID 0x%x:0x%x\n",
1109 data1, data2);
1110
1111ei2c:
1112 return ret;
1113}
1114
1115static int rj54n1_probe(struct i2c_client *client,
1116 const struct i2c_device_id *did)
1117{
1118 struct rj54n1 *rj54n1;
1119 struct soc_camera_device *icd = client->dev.platform_data;
1120 struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
1121 struct soc_camera_link *icl;
1122 int ret;
1123
1124 if (!icd) {
1125 dev_err(&client->dev, "RJ54N1CB0C: missing soc-camera data!\n");
1126 return -EINVAL;
1127 }
1128
1129 icl = to_soc_camera_link(icd);
1130 if (!icl) {
1131 dev_err(&client->dev, "RJ54N1CB0C: missing platform data!\n");
1132 return -EINVAL;
1133 }
1134
1135 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
1136 dev_warn(&adapter->dev,
1137 "I2C-Adapter doesn't support I2C_FUNC_SMBUS_BYTE\n");
1138 return -EIO;
1139 }
1140
1141 rj54n1 = kzalloc(sizeof(struct rj54n1), GFP_KERNEL);
1142 if (!rj54n1)
1143 return -ENOMEM;
1144
1145 v4l2_i2c_subdev_init(&rj54n1->subdev, client, &rj54n1_subdev_ops);
1146
1147 icd->ops = &rj54n1_ops;
1148
1149 rj54n1->clk_div = clk_div;
1150 rj54n1->rect.left = RJ54N1_COLUMN_SKIP;
1151 rj54n1->rect.top = RJ54N1_ROW_SKIP;
1152 rj54n1->rect.width = RJ54N1_MAX_WIDTH;
1153 rj54n1->rect.height = RJ54N1_MAX_HEIGHT;
1154 rj54n1->width = RJ54N1_MAX_WIDTH;
1155 rj54n1->height = RJ54N1_MAX_HEIGHT;
1156 rj54n1->fourcc = V4L2_PIX_FMT_YUYV;
1157 rj54n1->resize = 1024;
1158
1159 ret = rj54n1_video_probe(icd, client);
1160 if (ret < 0) {
1161 icd->ops = NULL;
1162 i2c_set_clientdata(client, NULL);
1163 kfree(rj54n1);
1164 return ret;
1165 }
1166
1167 icd->formats = rj54n1_colour_formats;
1168 icd->num_formats = ARRAY_SIZE(rj54n1_colour_formats);
1169
1170 return ret;
1171}
1172
1173static int rj54n1_remove(struct i2c_client *client)
1174{
1175 struct rj54n1 *rj54n1 = to_rj54n1(client);
1176 struct soc_camera_device *icd = client->dev.platform_data;
1177 struct soc_camera_link *icl = to_soc_camera_link(icd);
1178
1179 icd->ops = NULL;
1180 if (icl->free_bus)
1181 icl->free_bus(icl);
1182 i2c_set_clientdata(client, NULL);
1183 client->driver = NULL;
1184 kfree(rj54n1);
1185
1186 return 0;
1187}
1188
1189static const struct i2c_device_id rj54n1_id[] = {
1190 { "rj54n1cb0c", 0 },
1191 { }
1192};
1193MODULE_DEVICE_TABLE(i2c, rj54n1_id);
1194
1195static struct i2c_driver rj54n1_i2c_driver = {
1196 .driver = {
1197 .name = "rj54n1cb0c",
1198 },
1199 .probe = rj54n1_probe,
1200 .remove = rj54n1_remove,
1201 .id_table = rj54n1_id,
1202};
1203
1204static int __init rj54n1_mod_init(void)
1205{
1206 return i2c_add_driver(&rj54n1_i2c_driver);
1207}
1208
1209static void __exit rj54n1_mod_exit(void)
1210{
1211 i2c_del_driver(&rj54n1_i2c_driver);
1212}
1213
1214module_init(rj54n1_mod_init);
1215module_exit(rj54n1_mod_exit);
1216
1217MODULE_DESCRIPTION("Sharp RJ54N1CB0C Camera driver");
1218MODULE_AUTHOR("Guennadi Liakhovetski <g.liakhovetski@gmx.de>");
1219MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/video/s2255drv.c b/drivers/media/video/s2255drv.c
index 03d39266d293..41765f3c7c28 100644
--- a/drivers/media/video/s2255drv.c
+++ b/drivers/media/video/s2255drv.c
@@ -1958,7 +1958,7 @@ static int save_frame(struct s2255_dev *dev, struct s2255_pipeinfo *pipe_info)
1958 if (pdword[1] >= MAX_CHANNELS) 1958 if (pdword[1] >= MAX_CHANNELS)
1959 break; 1959 break;
1960 cc = G_chnmap[pdword[1]]; 1960 cc = G_chnmap[pdword[1]];
1961 if (!(cc >= 0 && cc < MAX_CHANNELS)) 1961 if (cc >= MAX_CHANNELS)
1962 break; 1962 break;
1963 switch (pdword[2]) { 1963 switch (pdword[2]) {
1964 case S2255_RESPONSE_SETMODE: 1964 case S2255_RESPONSE_SETMODE:
diff --git a/drivers/media/video/saa7110.c b/drivers/media/video/saa7110.c
index 5c24c993ac16..3bca744e43af 100644
--- a/drivers/media/video/saa7110.c
+++ b/drivers/media/video/saa7110.c
@@ -304,7 +304,7 @@ static int saa7110_s_routing(struct v4l2_subdev *sd,
304{ 304{
305 struct saa7110 *decoder = to_saa7110(sd); 305 struct saa7110 *decoder = to_saa7110(sd);
306 306
307 if (input < 0 || input >= SAA7110_MAX_INPUT) { 307 if (input >= SAA7110_MAX_INPUT) {
308 v4l2_dbg(1, debug, sd, "input=%d not available\n", input); 308 v4l2_dbg(1, debug, sd, "input=%d not available\n", input);
309 return -EINVAL; 309 return -EINVAL;
310 } 310 }
diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c
index 09013229d4aa..7e40d6d99dd0 100644
--- a/drivers/media/video/saa7134/saa7134-cards.c
+++ b/drivers/media/video/saa7134/saa7134-cards.c
@@ -5239,6 +5239,7 @@ struct saa7134_board saa7134_boards[] = {
5239 .radio_type = UNSET, 5239 .radio_type = UNSET,
5240 .tuner_addr = ADDR_UNSET, 5240 .tuner_addr = ADDR_UNSET,
5241 .radio_addr = ADDR_UNSET, 5241 .radio_addr = ADDR_UNSET,
5242 .mpeg = SAA7134_MPEG_DVB,
5242 .inputs = { { 5243 .inputs = { {
5243 .name = name_tv, 5244 .name = name_tv,
5244 .vmux = 2, 5245 .vmux = 2,
@@ -5279,6 +5280,46 @@ struct saa7134_board saa7134_boards[] = {
5279 .amux = TV, 5280 .amux = TV,
5280 }, 5281 },
5281 }, 5282 },
5283 [SAA7134_BOARD_ASUS_EUROPA_HYBRID] = {
5284 .name = "Asus Europa Hybrid OEM",
5285 .audio_clock = 0x00187de7,
5286 .tuner_type = TUNER_PHILIPS_TD1316,
5287 .radio_type = UNSET,
5288 .tuner_addr = 0x61,
5289 .radio_addr = ADDR_UNSET,
5290 .tda9887_conf = TDA9887_PRESENT | TDA9887_PORT1_ACTIVE,
5291 .mpeg = SAA7134_MPEG_DVB,
5292 .inputs = { {
5293 .name = name_tv,
5294 .vmux = 3,
5295 .amux = TV,
5296 .tv = 1,
5297 }, {
5298 .name = name_comp1,
5299 .vmux = 4,
5300 .amux = LINE2,
5301 }, {
5302 .name = name_svideo,
5303 .vmux = 8,
5304 .amux = LINE2,
5305 } },
5306 },
5307 [SAA7134_BOARD_LEADTEK_WINFAST_DTV1000S] = {
5308 .name = "Leadtek Winfast DTV1000S",
5309 .audio_clock = 0x00187de7,
5310 .tuner_type = TUNER_PHILIPS_TDA8290,
5311 .radio_type = UNSET,
5312 .tuner_addr = ADDR_UNSET,
5313 .radio_addr = ADDR_UNSET,
5314 .mpeg = SAA7134_MPEG_DVB,
5315 .inputs = { {
5316 .name = name_comp1,
5317 .vmux = 3,
5318 }, {
5319 .name = name_svideo,
5320 .vmux = 8,
5321 } },
5322 },
5282 5323
5283}; 5324};
5284 5325
@@ -6418,6 +6459,18 @@ struct pci_device_id saa7134_pci_tbl[] = {
6418 .subdevice = 0x2004, 6459 .subdevice = 0x2004,
6419 .driver_data = SAA7134_BOARD_ZOLID_HYBRID_PCI, 6460 .driver_data = SAA7134_BOARD_ZOLID_HYBRID_PCI,
6420 }, { 6461 }, {
6462 .vendor = PCI_VENDOR_ID_PHILIPS,
6463 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
6464 .subvendor = 0x1043,
6465 .subdevice = 0x4847,
6466 .driver_data = SAA7134_BOARD_ASUS_EUROPA_HYBRID,
6467 }, {
6468 .vendor = PCI_VENDOR_ID_PHILIPS,
6469 .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
6470 .subvendor = 0x107d,
6471 .subdevice = 0x6655,
6472 .driver_data = SAA7134_BOARD_LEADTEK_WINFAST_DTV1000S,
6473 }, {
6421 /* --- boards without eeprom + subsystem ID --- */ 6474 /* --- boards without eeprom + subsystem ID --- */
6422 .vendor = PCI_VENDOR_ID_PHILIPS, 6475 .vendor = PCI_VENDOR_ID_PHILIPS,
6423 .device = PCI_DEVICE_ID_PHILIPS_SAA7134, 6476 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
@@ -6748,6 +6801,7 @@ int saa7134_board_init1(struct saa7134_dev *dev)
6748 case SAA7134_BOARD_KWORLD_PLUS_TV_ANALOG: 6801 case SAA7134_BOARD_KWORLD_PLUS_TV_ANALOG:
6749 case SAA7134_BOARD_AVERMEDIA_GO_007_FM_PLUS: 6802 case SAA7134_BOARD_AVERMEDIA_GO_007_FM_PLUS:
6750 case SAA7134_BOARD_ROVERMEDIA_LINK_PRO_FM: 6803 case SAA7134_BOARD_ROVERMEDIA_LINK_PRO_FM:
6804 case SAA7134_BOARD_LEADTEK_WINFAST_DTV1000S:
6751 dev->has_remote = SAA7134_REMOTE_GPIO; 6805 dev->has_remote = SAA7134_REMOTE_GPIO;
6752 break; 6806 break;
6753 case SAA7134_BOARD_FLYDVBS_LR300: 6807 case SAA7134_BOARD_FLYDVBS_LR300:
@@ -7079,6 +7133,7 @@ int saa7134_board_init2(struct saa7134_dev *dev)
7079 /* break intentionally omitted */ 7133 /* break intentionally omitted */
7080 case SAA7134_BOARD_VIDEOMATE_DVBT_300: 7134 case SAA7134_BOARD_VIDEOMATE_DVBT_300:
7081 case SAA7134_BOARD_ASUS_EUROPA2_HYBRID: 7135 case SAA7134_BOARD_ASUS_EUROPA2_HYBRID:
7136 case SAA7134_BOARD_ASUS_EUROPA_HYBRID:
7082 { 7137 {
7083 7138
7084 /* The Philips EUROPA based hybrid boards have the tuner 7139 /* The Philips EUROPA based hybrid boards have the tuner
diff --git a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c
index c673901cb2b5..0ba7f5af0fc3 100644
--- a/drivers/media/video/saa7134/saa7134-core.c
+++ b/drivers/media/video/saa7134/saa7134-core.c
@@ -1032,7 +1032,7 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
1032 saa7134_irq_video_signalchange(dev); 1032 saa7134_irq_video_signalchange(dev);
1033 1033
1034 if (TUNER_ABSENT != dev->tuner_type) 1034 if (TUNER_ABSENT != dev->tuner_type)
1035 saa_call_all(dev, tuner, s_standby); 1035 saa_call_all(dev, core, s_power, 0);
1036 1036
1037 /* register v4l devices */ 1037 /* register v4l devices */
1038 if (saa7134_no_overlay > 0) 1038 if (saa7134_no_overlay > 0)
diff --git a/drivers/media/video/saa7134/saa7134-dvb.c b/drivers/media/video/saa7134/saa7134-dvb.c
index a26e997a9ce6..73739d2a63dd 100644
--- a/drivers/media/video/saa7134/saa7134-dvb.c
+++ b/drivers/media/video/saa7134/saa7134-dvb.c
@@ -40,6 +40,7 @@
40#include "tda1004x.h" 40#include "tda1004x.h"
41#include "nxt200x.h" 41#include "nxt200x.h"
42#include "tuner-xc2028.h" 42#include "tuner-xc2028.h"
43#include "xc5000.h"
43 44
44#include "tda10086.h" 45#include "tda10086.h"
45#include "tda826x.h" 46#include "tda826x.h"
@@ -871,6 +872,20 @@ static struct zl10353_config behold_h6_config = {
871 .disable_i2c_gate_ctrl = 1, 872 .disable_i2c_gate_ctrl = 1,
872}; 873};
873 874
875static struct xc5000_config behold_x7_tunerconfig = {
876 .i2c_address = 0xc2>>1,
877 .if_khz = 4560,
878 .radio_input = XC5000_RADIO_FM1,
879};
880
881static struct zl10353_config behold_x7_config = {
882 .demod_address = 0x1e>>1,
883 .if2 = 45600,
884 .no_tuner = 1,
885 .parallel_ts = 1,
886 .disable_i2c_gate_ctrl = 1,
887};
888
874/* ================================================================== 889/* ==================================================================
875 * tda10086 based DVB-S cards, helper functions 890 * tda10086 based DVB-S cards, helper functions
876 */ 891 */
@@ -1030,6 +1045,32 @@ static struct tda18271_config zolid_tda18271_config = {
1030 .gate = TDA18271_GATE_ANALOG, 1045 .gate = TDA18271_GATE_ANALOG,
1031}; 1046};
1032 1047
1048static struct tda10048_config dtv1000s_tda10048_config = {
1049 .demod_address = 0x10 >> 1,
1050 .output_mode = TDA10048_PARALLEL_OUTPUT,
1051 .fwbulkwritelen = TDA10048_BULKWRITE_200,
1052 .inversion = TDA10048_INVERSION_ON,
1053 .dtv6_if_freq_khz = TDA10048_IF_3300,
1054 .dtv7_if_freq_khz = TDA10048_IF_3800,
1055 .dtv8_if_freq_khz = TDA10048_IF_4300,
1056 .clk_freq_khz = TDA10048_CLK_16000,
1057 .disable_gate_access = 1,
1058};
1059
1060static struct tda18271_std_map dtv1000s_tda18271_std_map = {
1061 .dvbt_6 = { .if_freq = 3300, .agc_mode = 3, .std = 4,
1062 .if_lvl = 1, .rfagc_top = 0x37, },
1063 .dvbt_7 = { .if_freq = 3800, .agc_mode = 3, .std = 5,
1064 .if_lvl = 1, .rfagc_top = 0x37, },
1065 .dvbt_8 = { .if_freq = 4300, .agc_mode = 3, .std = 6,
1066 .if_lvl = 1, .rfagc_top = 0x37, },
1067};
1068
1069static struct tda18271_config dtv1000s_tda18271_config = {
1070 .std_map = &dtv1000s_tda18271_std_map,
1071 .gate = TDA18271_GATE_ANALOG,
1072};
1073
1033/* ================================================================== 1074/* ==================================================================
1034 * Core code 1075 * Core code
1035 */ 1076 */
@@ -1116,6 +1157,7 @@ static int dvb_init(struct saa7134_dev *dev)
1116 break; 1157 break;
1117 case SAA7134_BOARD_PHILIPS_EUROPA: 1158 case SAA7134_BOARD_PHILIPS_EUROPA:
1118 case SAA7134_BOARD_VIDEOMATE_DVBT_300: 1159 case SAA7134_BOARD_VIDEOMATE_DVBT_300:
1160 case SAA7134_BOARD_ASUS_EUROPA_HYBRID:
1119 fe0->dvb.frontend = dvb_attach(tda10046_attach, 1161 fe0->dvb.frontend = dvb_attach(tda10046_attach,
1120 &philips_europa_config, 1162 &philips_europa_config,
1121 &dev->i2c_adap); 1163 &dev->i2c_adap);
@@ -1482,6 +1524,15 @@ static int dvb_init(struct saa7134_dev *dev)
1482 TUNER_PHILIPS_FMD1216MEX_MK3); 1524 TUNER_PHILIPS_FMD1216MEX_MK3);
1483 } 1525 }
1484 break; 1526 break;
1527 case SAA7134_BOARD_BEHOLD_X7:
1528 fe0->dvb.frontend = dvb_attach(zl10353_attach,
1529 &behold_x7_config,
1530 &dev->i2c_adap);
1531 if (fe0->dvb.frontend) {
1532 dvb_attach(xc5000_attach, fe0->dvb.frontend,
1533 &dev->i2c_adap, &behold_x7_tunerconfig);
1534 }
1535 break;
1485 case SAA7134_BOARD_AVERMEDIA_A700_PRO: 1536 case SAA7134_BOARD_AVERMEDIA_A700_PRO:
1486 case SAA7134_BOARD_AVERMEDIA_A700_HYBRID: 1537 case SAA7134_BOARD_AVERMEDIA_A700_HYBRID:
1487 /* Zarlink ZL10313 */ 1538 /* Zarlink ZL10313 */
@@ -1518,6 +1569,19 @@ static int dvb_init(struct saa7134_dev *dev)
1518 &zolid_tda18271_config); 1569 &zolid_tda18271_config);
1519 } 1570 }
1520 break; 1571 break;
1572 case SAA7134_BOARD_LEADTEK_WINFAST_DTV1000S:
1573 fe0->dvb.frontend = dvb_attach(tda10048_attach,
1574 &dtv1000s_tda10048_config,
1575 &dev->i2c_adap);
1576 if (fe0->dvb.frontend != NULL) {
1577 dvb_attach(tda829x_attach, fe0->dvb.frontend,
1578 &dev->i2c_adap, 0x4b,
1579 &tda829x_no_probe);
1580 dvb_attach(tda18271_attach, fe0->dvb.frontend,
1581 0x60, &dev->i2c_adap,
1582 &dtv1000s_tda18271_config);
1583 }
1584 break;
1521 default: 1585 default:
1522 wprintk("Huh? unknown DVB card?\n"); 1586 wprintk("Huh? unknown DVB card?\n");
1523 break; 1587 break;
@@ -1550,7 +1614,7 @@ static int dvb_init(struct saa7134_dev *dev)
1550 1614
1551 /* register everything else */ 1615 /* register everything else */
1552 ret = videobuf_dvb_register_bus(&dev->frontends, THIS_MODULE, dev, 1616 ret = videobuf_dvb_register_bus(&dev->frontends, THIS_MODULE, dev,
1553 &dev->pci->dev, adapter_nr, 0); 1617 &dev->pci->dev, adapter_nr, 0, NULL);
1554 1618
1555 /* this sequence is necessary to make the tda1004x load its firmware 1619 /* this sequence is necessary to make the tda1004x load its firmware
1556 * and to enter analog mode of hybrid boards 1620 * and to enter analog mode of hybrid boards
diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c
index a0e8c62e6ae1..744918b1cd47 100644
--- a/drivers/media/video/saa7134/saa7134-input.c
+++ b/drivers/media/video/saa7134/saa7134-input.c
@@ -102,14 +102,14 @@ static int build_key(struct saa7134_dev *dev)
102 if (data == ir->mask_keycode) 102 if (data == ir->mask_keycode)
103 ir_input_nokey(ir->dev, &ir->ir); 103 ir_input_nokey(ir->dev, &ir->ir);
104 else 104 else
105 ir_input_keydown(ir->dev, &ir->ir, data, data); 105 ir_input_keydown(ir->dev, &ir->ir, data);
106 return 0; 106 return 0;
107 } 107 }
108 108
109 if (ir->polling) { 109 if (ir->polling) {
110 if ((ir->mask_keydown && (0 != (gpio & ir->mask_keydown))) || 110 if ((ir->mask_keydown && (0 != (gpio & ir->mask_keydown))) ||
111 (ir->mask_keyup && (0 == (gpio & ir->mask_keyup)))) { 111 (ir->mask_keyup && (0 == (gpio & ir->mask_keyup)))) {
112 ir_input_keydown(ir->dev, &ir->ir, data, data); 112 ir_input_keydown(ir->dev, &ir->ir, data);
113 } else { 113 } else {
114 ir_input_nokey(ir->dev, &ir->ir); 114 ir_input_nokey(ir->dev, &ir->ir);
115 } 115 }
@@ -117,7 +117,7 @@ static int build_key(struct saa7134_dev *dev)
117 else { /* IRQ driven mode - handle key press and release in one go */ 117 else { /* IRQ driven mode - handle key press and release in one go */
118 if ((ir->mask_keydown && (0 != (gpio & ir->mask_keydown))) || 118 if ((ir->mask_keydown && (0 != (gpio & ir->mask_keydown))) ||
119 (ir->mask_keyup && (0 == (gpio & ir->mask_keyup)))) { 119 (ir->mask_keyup && (0 == (gpio & ir->mask_keyup)))) {
120 ir_input_keydown(ir->dev, &ir->ir, data, data); 120 ir_input_keydown(ir->dev, &ir->ir, data);
121 ir_input_nokey(ir->dev, &ir->ir); 121 ir_input_nokey(ir->dev, &ir->ir);
122 } 122 }
123 } 123 }
@@ -616,6 +616,12 @@ int saa7134_input_init1(struct saa7134_dev *dev)
616 mask_keycode = 0x003f00; 616 mask_keycode = 0x003f00;
617 mask_keydown = 0x040000; 617 mask_keydown = 0x040000;
618 break; 618 break;
619 case SAA7134_BOARD_LEADTEK_WINFAST_DTV1000S:
620 ir_codes = &ir_codes_winfast_table;
621 mask_keycode = 0x5f00;
622 mask_keyup = 0x020000;
623 polling = 50; /* ms */
624 break;
619 } 625 }
620 if (NULL == ir_codes) { 626 if (NULL == ir_codes) {
621 printk("%s: Oops: IR config error [card=%d]\n", 627 printk("%s: Oops: IR config error [card=%d]\n",
@@ -646,7 +652,10 @@ int saa7134_input_init1(struct saa7134_dev *dev)
646 snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0", 652 snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0",
647 pci_name(dev->pci)); 653 pci_name(dev->pci));
648 654
649 ir_input_init(input_dev, &ir->ir, ir_type, ir_codes); 655 err = ir_input_init(input_dev, &ir->ir, ir_type, ir_codes);
656 if (err < 0)
657 goto err_out_free;
658
650 input_dev->name = ir->name; 659 input_dev->name = ir->name;
651 input_dev->phys = ir->phys; 660 input_dev->phys = ir->phys;
652 input_dev->id.bustype = BUS_PCI; 661 input_dev->id.bustype = BUS_PCI;
@@ -677,6 +686,7 @@ int saa7134_input_init1(struct saa7134_dev *dev)
677 saa7134_ir_stop(dev); 686 saa7134_ir_stop(dev);
678 dev->remote = NULL; 687 dev->remote = NULL;
679 err_out_free: 688 err_out_free:
689 ir_input_free(input_dev);
680 input_free_device(input_dev); 690 input_free_device(input_dev);
681 kfree(ir); 691 kfree(ir);
682 return err; 692 return err;
@@ -688,6 +698,7 @@ void saa7134_input_fini(struct saa7134_dev *dev)
688 return; 698 return;
689 699
690 saa7134_ir_stop(dev); 700 saa7134_ir_stop(dev);
701 ir_input_free(dev->remote->dev);
691 input_unregister_device(dev->remote->dev); 702 input_unregister_device(dev->remote->dev);
692 kfree(dev->remote); 703 kfree(dev->remote);
693 dev->remote = NULL; 704 dev->remote = NULL;
@@ -695,10 +706,7 @@ void saa7134_input_fini(struct saa7134_dev *dev)
695 706
696void saa7134_probe_i2c_ir(struct saa7134_dev *dev) 707void saa7134_probe_i2c_ir(struct saa7134_dev *dev)
697{ 708{
698 const unsigned short addr_list[] = { 709 struct i2c_board_info info;
699 0x7a, 0x47, 0x71, 0x2d,
700 I2C_CLIENT_END
701 };
702 710
703 struct i2c_msg msg_msi = { 711 struct i2c_msg msg_msi = {
704 .addr = 0x50, 712 .addr = 0x50,
@@ -714,9 +722,9 @@ void saa7134_probe_i2c_ir(struct saa7134_dev *dev)
714 return; 722 return;
715 } 723 }
716 724
717 memset(&dev->info, 0, sizeof(dev->info)); 725 memset(&info, 0, sizeof(struct i2c_board_info));
718 memset(&dev->init_data, 0, sizeof(dev->init_data)); 726 memset(&dev->init_data, 0, sizeof(dev->init_data));
719 strlcpy(dev->info.type, "ir_video", I2C_NAME_SIZE); 727 strlcpy(info.type, "ir_video", I2C_NAME_SIZE);
720 728
721 switch (dev->board) { 729 switch (dev->board) {
722 case SAA7134_BOARD_PINNACLE_PCTV_110i: 730 case SAA7134_BOARD_PINNACLE_PCTV_110i:
@@ -725,23 +733,24 @@ void saa7134_probe_i2c_ir(struct saa7134_dev *dev)
725 if (pinnacle_remote == 0) { 733 if (pinnacle_remote == 0) {
726 dev->init_data.get_key = get_key_pinnacle_color; 734 dev->init_data.get_key = get_key_pinnacle_color;
727 dev->init_data.ir_codes = &ir_codes_pinnacle_color_table; 735 dev->init_data.ir_codes = &ir_codes_pinnacle_color_table;
728 dev->info.addr = 0x47; 736 info.addr = 0x47;
729 } else { 737 } else {
730 dev->init_data.get_key = get_key_pinnacle_grey; 738 dev->init_data.get_key = get_key_pinnacle_grey;
731 dev->init_data.ir_codes = &ir_codes_pinnacle_grey_table; 739 dev->init_data.ir_codes = &ir_codes_pinnacle_grey_table;
732 dev->info.addr = 0x47; 740 info.addr = 0x47;
733 } 741 }
734 break; 742 break;
735 case SAA7134_BOARD_UPMOST_PURPLE_TV: 743 case SAA7134_BOARD_UPMOST_PURPLE_TV:
736 dev->init_data.name = "Purple TV"; 744 dev->init_data.name = "Purple TV";
737 dev->init_data.get_key = get_key_purpletv; 745 dev->init_data.get_key = get_key_purpletv;
738 dev->init_data.ir_codes = &ir_codes_purpletv_table; 746 dev->init_data.ir_codes = &ir_codes_purpletv_table;
747 info.addr = 0x7a;
739 break; 748 break;
740 case SAA7134_BOARD_MSI_TVATANYWHERE_PLUS: 749 case SAA7134_BOARD_MSI_TVATANYWHERE_PLUS:
741 dev->init_data.name = "MSI TV@nywhere Plus"; 750 dev->init_data.name = "MSI TV@nywhere Plus";
742 dev->init_data.get_key = get_key_msi_tvanywhere_plus; 751 dev->init_data.get_key = get_key_msi_tvanywhere_plus;
743 dev->init_data.ir_codes = &ir_codes_msi_tvanywhere_plus_table; 752 dev->init_data.ir_codes = &ir_codes_msi_tvanywhere_plus_table;
744 dev->info.addr = 0x30; 753 info.addr = 0x30;
745 /* MSI TV@nywhere Plus controller doesn't seem to 754 /* MSI TV@nywhere Plus controller doesn't seem to
746 respond to probes unless we read something from 755 respond to probes unless we read something from
747 an existing device. Weird... 756 an existing device. Weird...
@@ -755,6 +764,7 @@ void saa7134_probe_i2c_ir(struct saa7134_dev *dev)
755 dev->init_data.name = "HVR 1110"; 764 dev->init_data.name = "HVR 1110";
756 dev->init_data.get_key = get_key_hvr1110; 765 dev->init_data.get_key = get_key_hvr1110;
757 dev->init_data.ir_codes = &ir_codes_hauppauge_new_table; 766 dev->init_data.ir_codes = &ir_codes_hauppauge_new_table;
767 info.addr = 0x71;
758 break; 768 break;
759 case SAA7134_BOARD_BEHOLD_607FM_MK3: 769 case SAA7134_BOARD_BEHOLD_607FM_MK3:
760 case SAA7134_BOARD_BEHOLD_607FM_MK5: 770 case SAA7134_BOARD_BEHOLD_607FM_MK5:
@@ -772,23 +782,20 @@ void saa7134_probe_i2c_ir(struct saa7134_dev *dev)
772 dev->init_data.name = "BeholdTV"; 782 dev->init_data.name = "BeholdTV";
773 dev->init_data.get_key = get_key_beholdm6xx; 783 dev->init_data.get_key = get_key_beholdm6xx;
774 dev->init_data.ir_codes = &ir_codes_behold_table; 784 dev->init_data.ir_codes = &ir_codes_behold_table;
785 info.addr = 0x2d;
775 break; 786 break;
776 case SAA7134_BOARD_AVERMEDIA_CARDBUS_501: 787 case SAA7134_BOARD_AVERMEDIA_CARDBUS_501:
777 case SAA7134_BOARD_AVERMEDIA_CARDBUS_506: 788 case SAA7134_BOARD_AVERMEDIA_CARDBUS_506:
778 dev->info.addr = 0x40; 789 info.addr = 0x40;
779 break; 790 break;
780 } 791 default:
781 792 dprintk("No I2C IR support for board %x\n", dev->board);
782 if (dev->init_data.name)
783 dev->info.platform_data = &dev->init_data;
784 /* No need to probe if address is known */
785 if (dev->info.addr) {
786 i2c_new_device(&dev->i2c_adap, &dev->info);
787 return; 793 return;
788 } 794 }
789 795
790 /* Address not known, fallback to probing */ 796 if (dev->init_data.name)
791 i2c_new_probed_device(&dev->i2c_adap, &dev->info, addr_list); 797 info.platform_data = &dev->init_data;
798 i2c_new_device(&dev->i2c_adap, &info);
792} 799}
793 800
794static int saa7134_rc5_irq(struct saa7134_dev *dev) 801static int saa7134_rc5_irq(struct saa7134_dev *dev)
@@ -936,7 +943,7 @@ static void nec_task(unsigned long data)
936 dprintk("scancode = 0x%02x (code = 0x%02x, notcode= 0x%02x)\n", 943 dprintk("scancode = 0x%02x (code = 0x%02x, notcode= 0x%02x)\n",
937 ir->code, ircode, not_code); 944 ir->code, ircode, not_code);
938 945
939 ir_input_keydown(ir->dev, &ir->ir, ir->code, ir->code); 946 ir_input_keydown(ir->dev, &ir->ir, ir->code);
940 } else 947 } else
941 dprintk("Repeat last key\n"); 948 dprintk("Repeat last key\n");
942 949
diff --git a/drivers/media/video/saa7134/saa7134-video.c b/drivers/media/video/saa7134/saa7134-video.c
index da26f476a302..35f8daa3a359 100644
--- a/drivers/media/video/saa7134/saa7134-video.c
+++ b/drivers/media/video/saa7134/saa7134-video.c
@@ -1499,7 +1499,7 @@ static int video_release(struct file *file)
1499 saa_andorb(SAA7134_OFMT_DATA_A, 0x1f, 0); 1499 saa_andorb(SAA7134_OFMT_DATA_A, 0x1f, 0);
1500 saa_andorb(SAA7134_OFMT_DATA_B, 0x1f, 0); 1500 saa_andorb(SAA7134_OFMT_DATA_B, 0x1f, 0);
1501 1501
1502 saa_call_all(dev, tuner, s_standby); 1502 saa_call_all(dev, core, s_power, 0);
1503 if (fh->radio) 1503 if (fh->radio)
1504 saa_call_all(dev, core, ioctl, RDS_CMD_CLOSE, &cmd); 1504 saa_call_all(dev, core, ioctl, RDS_CMD_CLOSE, &cmd);
1505 1505
diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h
index f8697d46ff5f..53b7e0b8a2fb 100644
--- a/drivers/media/video/saa7134/saa7134.h
+++ b/drivers/media/video/saa7134/saa7134.h
@@ -297,6 +297,8 @@ struct saa7134_format {
297#define SAA7134_BOARD_BEHOLD_X7 171 297#define SAA7134_BOARD_BEHOLD_X7 171
298#define SAA7134_BOARD_ROVERMEDIA_LINK_PRO_FM 172 298#define SAA7134_BOARD_ROVERMEDIA_LINK_PRO_FM 172
299#define SAA7134_BOARD_ZOLID_HYBRID_PCI 173 299#define SAA7134_BOARD_ZOLID_HYBRID_PCI 173
300#define SAA7134_BOARD_ASUS_EUROPA_HYBRID 174
301#define SAA7134_BOARD_LEADTEK_WINFAST_DTV1000S 175
300 302
301#define SAA7134_MAXBOARDS 32 303#define SAA7134_MAXBOARDS 32
302#define SAA7134_INPUT_MAX 8 304#define SAA7134_INPUT_MAX 8
@@ -592,7 +594,6 @@ struct saa7134_dev {
592 unsigned int insuspend; 594 unsigned int insuspend;
593 595
594 /* I2C keyboard data */ 596 /* I2C keyboard data */
595 struct i2c_board_info info;
596 struct IR_i2c_init_data init_data; 597 struct IR_i2c_init_data init_data;
597 598
598 /* SAA7134_MPEG_* */ 599 /* SAA7134_MPEG_* */
diff --git a/drivers/media/video/saa7164/saa7164-dvb.c b/drivers/media/video/saa7164/saa7164-dvb.c
index 6a2d847d6a88..cf099c59b38e 100644
--- a/drivers/media/video/saa7164/saa7164-dvb.c
+++ b/drivers/media/video/saa7164/saa7164-dvb.c
@@ -68,6 +68,7 @@ static struct tda18271_config hauppauge_hvr22x0s_tuner_config = {
68 .std_map = &hauppauge_tda18271_std_map, 68 .std_map = &hauppauge_tda18271_std_map,
69 .gate = TDA18271_GATE_ANALOG, 69 .gate = TDA18271_GATE_ANALOG,
70 .role = TDA18271_SLAVE, 70 .role = TDA18271_SLAVE,
71 .output_opt = TDA18271_OUTPUT_LT_OFF,
71 .rf_cal_on_startup = 1 72 .rf_cal_on_startup = 1
72}; 73};
73 74
diff --git a/drivers/media/video/saa717x.c b/drivers/media/video/saa717x.c
index b15c40908e84..6818df571168 100644
--- a/drivers/media/video/saa717x.c
+++ b/drivers/media/video/saa717x.c
@@ -1115,7 +1115,7 @@ static int saa717x_s_video_routing(struct v4l2_subdev *sd,
1115 v4l2_dbg(1, debug, sd, "decoder set input (%d)\n", input); 1115 v4l2_dbg(1, debug, sd, "decoder set input (%d)\n", input);
1116 /* inputs from 0-9 are available*/ 1116 /* inputs from 0-9 are available*/
1117 /* saa717x have mode0-mode9 but mode5 is reserved. */ 1117 /* saa717x have mode0-mode9 but mode5 is reserved. */
1118 if (input < 0 || input > 9 || input == 5) 1118 if (input > 9 || input == 5)
1119 return -EINVAL; 1119 return -EINVAL;
1120 1120
1121 if (decoder->input != input) { 1121 if (decoder->input != input) {
@@ -1312,7 +1312,7 @@ static int saa717x_s_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
1312 "MONO", "STEREO", "LANG1", "LANG2/SAP" 1312 "MONO", "STEREO", "LANG1", "LANG2/SAP"
1313 }; 1313 };
1314 1314
1315 audio_mode = V4L2_TUNER_MODE_STEREO; 1315 audio_mode = TUNER_AUDIO_STEREO;
1316 1316
1317 switch (vt->audmode) { 1317 switch (vt->audmode) {
1318 case V4L2_TUNER_MODE_MONO: 1318 case V4L2_TUNER_MODE_MONO:
diff --git a/drivers/media/video/sh_mobile_ceu_camera.c b/drivers/media/video/sh_mobile_ceu_camera.c
index 9c8b7c7b89ee..a4f3472d4db8 100644
--- a/drivers/media/video/sh_mobile_ceu_camera.c
+++ b/drivers/media/video/sh_mobile_ceu_camera.c
@@ -153,6 +153,40 @@ static u32 ceu_read(struct sh_mobile_ceu_dev *priv, unsigned long reg_offs)
153 return ioread32(priv->base + reg_offs); 153 return ioread32(priv->base + reg_offs);
154} 154}
155 155
156static int sh_mobile_ceu_soft_reset(struct sh_mobile_ceu_dev *pcdev)
157{
158 int i, success = 0;
159 struct soc_camera_device *icd = pcdev->icd;
160
161 ceu_write(pcdev, CAPSR, 1 << 16); /* reset */
162
163 /* wait CSTSR.CPTON bit */
164 for (i = 0; i < 1000; i++) {
165 if (!(ceu_read(pcdev, CSTSR) & 1)) {
166 success++;
167 break;
168 }
169 udelay(1);
170 }
171
172 /* wait CAPSR.CPKIL bit */
173 for (i = 0; i < 1000; i++) {
174 if (!(ceu_read(pcdev, CAPSR) & (1 << 16))) {
175 success++;
176 break;
177 }
178 udelay(1);
179 }
180
181
182 if (2 != success) {
183 dev_warn(&icd->dev, "soft reset time out\n");
184 return -EIO;
185 }
186
187 return 0;
188}
189
156/* 190/*
157 * Videobuf operations 191 * Videobuf operations
158 */ 192 */
@@ -202,26 +236,45 @@ static void free_buffer(struct videobuf_queue *vq,
202#define CEU_CETCR_MAGIC 0x0317f313 /* acknowledge magical interrupt sources */ 236#define CEU_CETCR_MAGIC 0x0317f313 /* acknowledge magical interrupt sources */
203#define CEU_CETCR_IGRW (1 << 4) /* prohibited register access interrupt bit */ 237#define CEU_CETCR_IGRW (1 << 4) /* prohibited register access interrupt bit */
204#define CEU_CEIER_CPEIE (1 << 0) /* one-frame capture end interrupt */ 238#define CEU_CEIER_CPEIE (1 << 0) /* one-frame capture end interrupt */
239#define CEU_CEIER_VBP (1 << 20) /* vbp error */
205#define CEU_CAPCR_CTNCP (1 << 16) /* continuous capture mode (if set) */ 240#define CEU_CAPCR_CTNCP (1 << 16) /* continuous capture mode (if set) */
241#define CEU_CEIER_MASK (CEU_CEIER_CPEIE | CEU_CEIER_VBP)
206 242
207 243
208static void sh_mobile_ceu_capture(struct sh_mobile_ceu_dev *pcdev) 244/*
245 * return value doesn't reflex the success/failure to queue the new buffer,
246 * but rather the status of the previous buffer.
247 */
248static int sh_mobile_ceu_capture(struct sh_mobile_ceu_dev *pcdev)
209{ 249{
210 struct soc_camera_device *icd = pcdev->icd; 250 struct soc_camera_device *icd = pcdev->icd;
211 dma_addr_t phys_addr_top, phys_addr_bottom; 251 dma_addr_t phys_addr_top, phys_addr_bottom;
252 u32 status;
253 int ret = 0;
212 254
213 /* The hardware is _very_ picky about this sequence. Especially 255 /* The hardware is _very_ picky about this sequence. Especially
214 * the CEU_CETCR_MAGIC value. It seems like we need to acknowledge 256 * the CEU_CETCR_MAGIC value. It seems like we need to acknowledge
215 * several not-so-well documented interrupt sources in CETCR. 257 * several not-so-well documented interrupt sources in CETCR.
216 */ 258 */
217 ceu_write(pcdev, CEIER, ceu_read(pcdev, CEIER) & ~CEU_CEIER_CPEIE); 259 ceu_write(pcdev, CEIER, ceu_read(pcdev, CEIER) & ~CEU_CEIER_MASK);
218 ceu_write(pcdev, CETCR, ~ceu_read(pcdev, CETCR) & CEU_CETCR_MAGIC); 260 status = ceu_read(pcdev, CETCR);
219 ceu_write(pcdev, CEIER, ceu_read(pcdev, CEIER) | CEU_CEIER_CPEIE); 261 ceu_write(pcdev, CETCR, ~status & CEU_CETCR_MAGIC);
262 ceu_write(pcdev, CEIER, ceu_read(pcdev, CEIER) | CEU_CEIER_MASK);
220 ceu_write(pcdev, CAPCR, ceu_read(pcdev, CAPCR) & ~CEU_CAPCR_CTNCP); 263 ceu_write(pcdev, CAPCR, ceu_read(pcdev, CAPCR) & ~CEU_CAPCR_CTNCP);
221 ceu_write(pcdev, CETCR, CEU_CETCR_MAGIC ^ CEU_CETCR_IGRW); 264 ceu_write(pcdev, CETCR, CEU_CETCR_MAGIC ^ CEU_CETCR_IGRW);
222 265
266 /*
267 * When a VBP interrupt occurs, a capture end interrupt does not occur
268 * and the image of that frame is not captured correctly. So, soft reset
269 * is needed here.
270 */
271 if (status & CEU_CEIER_VBP) {
272 sh_mobile_ceu_soft_reset(pcdev);
273 ret = -EIO;
274 }
275
223 if (!pcdev->active) 276 if (!pcdev->active)
224 return; 277 return ret;
225 278
226 phys_addr_top = videobuf_to_dma_contig(pcdev->active); 279 phys_addr_top = videobuf_to_dma_contig(pcdev->active);
227 ceu_write(pcdev, CDAYR, phys_addr_top); 280 ceu_write(pcdev, CDAYR, phys_addr_top);
@@ -247,6 +300,8 @@ static void sh_mobile_ceu_capture(struct sh_mobile_ceu_dev *pcdev)
247 300
248 pcdev->active->state = VIDEOBUF_ACTIVE; 301 pcdev->active->state = VIDEOBUF_ACTIVE;
249 ceu_write(pcdev, CAPSR, 0x1); /* start capture */ 302 ceu_write(pcdev, CAPSR, 0x1); /* start capture */
303
304 return ret;
250} 305}
251 306
252static int sh_mobile_ceu_videobuf_prepare(struct videobuf_queue *vq, 307static int sh_mobile_ceu_videobuf_prepare(struct videobuf_queue *vq,
@@ -319,6 +374,11 @@ static void sh_mobile_ceu_videobuf_queue(struct videobuf_queue *vq,
319 list_add_tail(&vb->queue, &pcdev->capture); 374 list_add_tail(&vb->queue, &pcdev->capture);
320 375
321 if (!pcdev->active) { 376 if (!pcdev->active) {
377 /*
378 * Because there were no active buffer at this moment,
379 * we are not interested in the return value of
380 * sh_mobile_ceu_capture here.
381 */
322 pcdev->active = vb; 382 pcdev->active = vb;
323 sh_mobile_ceu_capture(pcdev); 383 sh_mobile_ceu_capture(pcdev);
324 } 384 }
@@ -379,9 +439,8 @@ static irqreturn_t sh_mobile_ceu_irq(int irq, void *data)
379 else 439 else
380 pcdev->active = NULL; 440 pcdev->active = NULL;
381 441
382 sh_mobile_ceu_capture(pcdev); 442 vb->state = (sh_mobile_ceu_capture(pcdev) < 0) ?
383 443 VIDEOBUF_ERROR : VIDEOBUF_DONE;
384 vb->state = VIDEOBUF_DONE;
385 do_gettimeofday(&vb->ts); 444 do_gettimeofday(&vb->ts);
386 vb->field_count++; 445 vb->field_count++;
387 wake_up(&vb->done); 446 wake_up(&vb->done);
@@ -407,13 +466,9 @@ static int sh_mobile_ceu_add_device(struct soc_camera_device *icd)
407 466
408 pm_runtime_get_sync(ici->v4l2_dev.dev); 467 pm_runtime_get_sync(ici->v4l2_dev.dev);
409 468
410 ceu_write(pcdev, CAPSR, 1 << 16); /* reset */
411 while (ceu_read(pcdev, CSTSR) & 1)
412 msleep(1);
413
414 pcdev->icd = icd; 469 pcdev->icd = icd;
415 470
416 return 0; 471 return sh_mobile_ceu_soft_reset(pcdev);
417} 472}
418 473
419/* Called with .video_lock held */ 474/* Called with .video_lock held */
@@ -427,7 +482,7 @@ static void sh_mobile_ceu_remove_device(struct soc_camera_device *icd)
427 482
428 /* disable capture, disable interrupts */ 483 /* disable capture, disable interrupts */
429 ceu_write(pcdev, CEIER, 0); 484 ceu_write(pcdev, CEIER, 0);
430 ceu_write(pcdev, CAPSR, 1 << 16); /* reset */ 485 sh_mobile_ceu_soft_reset(pcdev);
431 486
432 /* make sure active buffer is canceled */ 487 /* make sure active buffer is canceled */
433 spin_lock_irqsave(&pcdev->lock, flags); 488 spin_lock_irqsave(&pcdev->lock, flags);
diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c
index aba92e2313d8..5b3eaa16afd2 100644
--- a/drivers/media/video/tuner-core.c
+++ b/drivers/media/video/tuner-core.c
@@ -320,6 +320,7 @@ static void set_type(struct i2c_client *c, unsigned int type,
320 struct dvb_tuner_ops *fe_tuner_ops = &t->fe.ops.tuner_ops; 320 struct dvb_tuner_ops *fe_tuner_ops = &t->fe.ops.tuner_ops;
321 struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops; 321 struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops;
322 unsigned char buffer[4]; 322 unsigned char buffer[4];
323 int tune_now = 1;
323 324
324 if (type == UNSET || type == TUNER_ABSENT) { 325 if (type == UNSET || type == TUNER_ABSENT) {
325 tuner_dbg ("tuner 0x%02x: Tuner type absent\n",c->addr); 326 tuner_dbg ("tuner 0x%02x: Tuner type absent\n",c->addr);
@@ -328,7 +329,7 @@ static void set_type(struct i2c_client *c, unsigned int type,
328 329
329 t->type = type; 330 t->type = type;
330 /* prevent invalid config values */ 331 /* prevent invalid config values */
331 t->config = ((new_config >= 0) && (new_config < 256)) ? new_config : 0; 332 t->config = new_config < 256 ? new_config : 0;
332 if (tuner_callback != NULL) { 333 if (tuner_callback != NULL) {
333 tuner_dbg("defining GPIO callback\n"); 334 tuner_dbg("defining GPIO callback\n");
334 t->fe.callback = tuner_callback; 335 t->fe.callback = tuner_callback;
@@ -404,6 +405,7 @@ static void set_type(struct i2c_client *c, unsigned int type,
404 }; 405 };
405 if (!dvb_attach(xc2028_attach, &t->fe, &cfg)) 406 if (!dvb_attach(xc2028_attach, &t->fe, &cfg))
406 goto attach_failed; 407 goto attach_failed;
408 tune_now = 0;
407 break; 409 break;
408 } 410 }
409 case TUNER_TDA9887: 411 case TUNER_TDA9887:
@@ -419,6 +421,7 @@ static void set_type(struct i2c_client *c, unsigned int type,
419 if (!dvb_attach(xc5000_attach, 421 if (!dvb_attach(xc5000_attach,
420 &t->fe, t->i2c->adapter, &xc5000_cfg)) 422 &t->fe, t->i2c->adapter, &xc5000_cfg))
421 goto attach_failed; 423 goto attach_failed;
424 tune_now = 0;
422 break; 425 break;
423 } 426 }
424 case TUNER_NXP_TDA18271: 427 case TUNER_NXP_TDA18271:
@@ -430,6 +433,7 @@ static void set_type(struct i2c_client *c, unsigned int type,
430 if (!dvb_attach(tda18271_attach, &t->fe, t->i2c->addr, 433 if (!dvb_attach(tda18271_attach, &t->fe, t->i2c->addr,
431 t->i2c->adapter, &cfg)) 434 t->i2c->adapter, &cfg))
432 goto attach_failed; 435 goto attach_failed;
436 tune_now = 0;
433 break; 437 break;
434 } 438 }
435 default: 439 default:
@@ -458,12 +462,13 @@ static void set_type(struct i2c_client *c, unsigned int type,
458 if (t->mode_mask == T_UNINITIALIZED) 462 if (t->mode_mask == T_UNINITIALIZED)
459 t->mode_mask = new_mode_mask; 463 t->mode_mask = new_mode_mask;
460 464
461 /* xc2028/3028 and xc5000 requires a firmware to be set-up later 465 /* Some tuners require more initialization setup before use,
466 such as firmware download or device calibration.
462 trying to set a frequency here will just fail 467 trying to set a frequency here will just fail
463 FIXME: better to move set_freq to the tuner code. This is needed 468 FIXME: better to move set_freq to the tuner code. This is needed
464 on analog tuners for PLL to properly work 469 on analog tuners for PLL to properly work
465 */ 470 */
466 if (t->type != TUNER_XC2028 && t->type != TUNER_XC5000) 471 if (tune_now)
467 set_freq(c, (V4L2_TUNER_RADIO == t->mode) ? 472 set_freq(c, (V4L2_TUNER_RADIO == t->mode) ?
468 t->radio_freq : t->tv_freq); 473 t->radio_freq : t->tv_freq);
469 474
@@ -752,14 +757,17 @@ static int tuner_s_radio(struct v4l2_subdev *sd)
752 return 0; 757 return 0;
753} 758}
754 759
755static int tuner_s_standby(struct v4l2_subdev *sd) 760static int tuner_s_power(struct v4l2_subdev *sd, int on)
756{ 761{
757 struct tuner *t = to_tuner(sd); 762 struct tuner *t = to_tuner(sd);
758 struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops; 763 struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops;
759 764
765 if (on)
766 return 0;
767
760 tuner_dbg("Putting tuner to sleep\n"); 768 tuner_dbg("Putting tuner to sleep\n");
761 769
762 if (check_mode(t, "s_standby") == -EINVAL) 770 if (check_mode(t, "s_power") == -EINVAL)
763 return 0; 771 return 0;
764 t->mode = T_STANDBY; 772 t->mode = T_STANDBY;
765 if (analog_ops->standby) 773 if (analog_ops->standby)
@@ -961,6 +969,7 @@ static int tuner_command(struct i2c_client *client, unsigned cmd, void *arg)
961static const struct v4l2_subdev_core_ops tuner_core_ops = { 969static const struct v4l2_subdev_core_ops tuner_core_ops = {
962 .log_status = tuner_log_status, 970 .log_status = tuner_log_status,
963 .s_std = tuner_s_std, 971 .s_std = tuner_s_std,
972 .s_power = tuner_s_power,
964}; 973};
965 974
966static const struct v4l2_subdev_tuner_ops tuner_tuner_ops = { 975static const struct v4l2_subdev_tuner_ops tuner_tuner_ops = {
@@ -971,7 +980,6 @@ static const struct v4l2_subdev_tuner_ops tuner_tuner_ops = {
971 .g_frequency = tuner_g_frequency, 980 .g_frequency = tuner_g_frequency,
972 .s_type_addr = tuner_s_type_addr, 981 .s_type_addr = tuner_s_type_addr,
973 .s_config = tuner_s_config, 982 .s_config = tuner_s_config,
974 .s_standby = tuner_s_standby,
975}; 983};
976 984
977static const struct v4l2_subdev_ops tuner_ops = { 985static const struct v4l2_subdev_ops tuner_ops = {
diff --git a/drivers/media/video/tvaudio.c b/drivers/media/video/tvaudio.c
index 0869bafc2b56..800fc1b111ef 100644
--- a/drivers/media/video/tvaudio.c
+++ b/drivers/media/video/tvaudio.c
@@ -1919,7 +1919,7 @@ static const struct v4l2_subdev_tuner_ops tvaudio_tuner_ops = {
1919 .s_radio = tvaudio_s_radio, 1919 .s_radio = tvaudio_s_radio,
1920 .s_frequency = tvaudio_s_frequency, 1920 .s_frequency = tvaudio_s_frequency,
1921 .s_tuner = tvaudio_s_tuner, 1921 .s_tuner = tvaudio_s_tuner,
1922 .s_tuner = tvaudio_g_tuner, 1922 .g_tuner = tvaudio_g_tuner,
1923}; 1923};
1924 1924
1925static const struct v4l2_subdev_audio_ops tvaudio_audio_ops = { 1925static const struct v4l2_subdev_audio_ops tvaudio_audio_ops = {
diff --git a/drivers/media/video/tvp514x.c b/drivers/media/video/tvp514x.c
index 244372627df2..26b4e718cd6d 100644
--- a/drivers/media/video/tvp514x.c
+++ b/drivers/media/video/tvp514x.c
@@ -272,7 +272,7 @@ static int tvp514x_read_reg(struct v4l2_subdev *sd, u8 reg)
272read_again: 272read_again:
273 273
274 err = i2c_smbus_read_byte_data(client, reg); 274 err = i2c_smbus_read_byte_data(client, reg);
275 if (err == -1) { 275 if (err < 0) {
276 if (retry <= I2C_RETRY_COUNT) { 276 if (retry <= I2C_RETRY_COUNT) {
277 v4l2_warn(sd, "Read: retry ... %d\n", retry); 277 v4l2_warn(sd, "Read: retry ... %d\n", retry);
278 retry++; 278 retry++;
diff --git a/drivers/media/video/usbvideo/konicawc.c b/drivers/media/video/usbvideo/konicawc.c
index 31d57f2d09e1..a0addcb04295 100644
--- a/drivers/media/video/usbvideo/konicawc.c
+++ b/drivers/media/video/usbvideo/konicawc.c
@@ -225,7 +225,7 @@ static void konicawc_register_input(struct konicawc *cam, struct usb_device *dev
225 int error; 225 int error;
226 226
227 usb_make_path(dev, cam->input_physname, sizeof(cam->input_physname)); 227 usb_make_path(dev, cam->input_physname, sizeof(cam->input_physname));
228 strncat(cam->input_physname, "/input0", sizeof(cam->input_physname)); 228 strlcat(cam->input_physname, "/input0", sizeof(cam->input_physname));
229 229
230 cam->input = input_dev = input_allocate_device(); 230 cam->input = input_dev = input_allocate_device();
231 if (!input_dev) { 231 if (!input_dev) {
diff --git a/drivers/media/video/usbvideo/quickcam_messenger.c b/drivers/media/video/usbvideo/quickcam_messenger.c
index 803d3e4e29a2..c4d1b96b5cee 100644
--- a/drivers/media/video/usbvideo/quickcam_messenger.c
+++ b/drivers/media/video/usbvideo/quickcam_messenger.c
@@ -89,7 +89,7 @@ static void qcm_register_input(struct qcm *cam, struct usb_device *dev)
89 int error; 89 int error;
90 90
91 usb_make_path(dev, cam->input_physname, sizeof(cam->input_physname)); 91 usb_make_path(dev, cam->input_physname, sizeof(cam->input_physname));
92 strncat(cam->input_physname, "/input0", sizeof(cam->input_physname)); 92 strlcat(cam->input_physname, "/input0", sizeof(cam->input_physname));
93 93
94 cam->input = input_dev = input_allocate_device(); 94 cam->input = input_dev = input_allocate_device();
95 if (!input_dev) { 95 if (!input_dev) {
diff --git a/drivers/media/video/usbvision/usbvision-video.c b/drivers/media/video/usbvision/usbvision-video.c
index a2a50d608a3f..c07b0ac452ab 100644
--- a/drivers/media/video/usbvision/usbvision-video.c
+++ b/drivers/media/video/usbvision/usbvision-video.c
@@ -601,7 +601,7 @@ static int vidioc_s_input (struct file *file, void *priv, unsigned int input)
601{ 601{
602 struct usb_usbvision *usbvision = video_drvdata(file); 602 struct usb_usbvision *usbvision = video_drvdata(file);
603 603
604 if ((input >= usbvision->video_inputs) || (input < 0) ) 604 if (input >= usbvision->video_inputs)
605 return -EINVAL; 605 return -EINVAL;
606 606
607 mutex_lock(&usbvision->lock); 607 mutex_lock(&usbvision->lock);
diff --git a/drivers/media/video/uvc/uvc_ctrl.c b/drivers/media/video/uvc/uvc_ctrl.c
index 1b89735e62fd..0469d7a876a8 100644
--- a/drivers/media/video/uvc/uvc_ctrl.c
+++ b/drivers/media/video/uvc/uvc_ctrl.c
@@ -742,17 +742,7 @@ struct uvc_control *uvc_find_control(struct uvc_video_chain *chain,
742 v4l2_id &= V4L2_CTRL_ID_MASK; 742 v4l2_id &= V4L2_CTRL_ID_MASK;
743 743
744 /* Find the control. */ 744 /* Find the control. */
745 __uvc_find_control(chain->processing, v4l2_id, mapping, &ctrl, next); 745 list_for_each_entry(entity, &chain->entities, chain) {
746 if (ctrl && !next)
747 return ctrl;
748
749 list_for_each_entry(entity, &chain->iterms, chain) {
750 __uvc_find_control(entity, v4l2_id, mapping, &ctrl, next);
751 if (ctrl && !next)
752 return ctrl;
753 }
754
755 list_for_each_entry(entity, &chain->extensions, chain) {
756 __uvc_find_control(entity, v4l2_id, mapping, &ctrl, next); 746 __uvc_find_control(entity, v4l2_id, mapping, &ctrl, next);
757 if (ctrl && !next) 747 if (ctrl && !next)
758 return ctrl; 748 return ctrl;
@@ -826,6 +816,13 @@ int uvc_query_v4l2_ctrl(struct uvc_video_chain *chain,
826 ret = 0; 816 ret = 0;
827 goto out; 817 goto out;
828 818
819 case V4L2_CTRL_TYPE_BUTTON:
820 v4l2_ctrl->minimum = 0;
821 v4l2_ctrl->maximum = 0;
822 v4l2_ctrl->step = 0;
823 ret = 0;
824 goto out;
825
829 default: 826 default:
830 break; 827 break;
831 } 828 }
@@ -944,17 +941,7 @@ int __uvc_ctrl_commit(struct uvc_video_chain *chain, int rollback)
944 int ret = 0; 941 int ret = 0;
945 942
946 /* Find the control. */ 943 /* Find the control. */
947 ret = uvc_ctrl_commit_entity(chain->dev, chain->processing, rollback); 944 list_for_each_entry(entity, &chain->entities, chain) {
948 if (ret < 0)
949 goto done;
950
951 list_for_each_entry(entity, &chain->iterms, chain) {
952 ret = uvc_ctrl_commit_entity(chain->dev, entity, rollback);
953 if (ret < 0)
954 goto done;
955 }
956
957 list_for_each_entry(entity, &chain->extensions, chain) {
958 ret = uvc_ctrl_commit_entity(chain->dev, entity, rollback); 945 ret = uvc_ctrl_commit_entity(chain->dev, entity, rollback);
959 if (ret < 0) 946 if (ret < 0)
960 goto done; 947 goto done;
@@ -1068,8 +1055,9 @@ int uvc_xu_ctrl_query(struct uvc_video_chain *chain,
1068 int ret; 1055 int ret;
1069 1056
1070 /* Find the extension unit. */ 1057 /* Find the extension unit. */
1071 list_for_each_entry(entity, &chain->extensions, chain) { 1058 list_for_each_entry(entity, &chain->entities, chain) {
1072 if (entity->id == xctrl->unit) 1059 if (UVC_ENTITY_TYPE(entity) == UVC_VC_EXTENSION_UNIT &&
1060 entity->id == xctrl->unit)
1073 break; 1061 break;
1074 } 1062 }
1075 1063
diff --git a/drivers/media/video/uvc/uvc_driver.c b/drivers/media/video/uvc/uvc_driver.c
index 8756be569154..c31bc50113bc 100644
--- a/drivers/media/video/uvc/uvc_driver.c
+++ b/drivers/media/video/uvc/uvc_driver.c
@@ -46,6 +46,7 @@
46unsigned int uvc_no_drop_param; 46unsigned int uvc_no_drop_param;
47static unsigned int uvc_quirks_param; 47static unsigned int uvc_quirks_param;
48unsigned int uvc_trace_param; 48unsigned int uvc_trace_param;
49unsigned int uvc_timeout_param = UVC_CTRL_STREAMING_TIMEOUT;
49 50
50/* ------------------------------------------------------------------------ 51/* ------------------------------------------------------------------------
51 * Video formats 52 * Video formats
@@ -248,29 +249,9 @@ static struct uvc_entity *uvc_entity_by_reference(struct uvc_device *dev,
248 entity = list_entry(&dev->entities, struct uvc_entity, list); 249 entity = list_entry(&dev->entities, struct uvc_entity, list);
249 250
250 list_for_each_entry_continue(entity, &dev->entities, list) { 251 list_for_each_entry_continue(entity, &dev->entities, list) {
251 switch (UVC_ENTITY_TYPE(entity)) { 252 for (i = 0; i < entity->bNrInPins; ++i)
252 case UVC_TT_STREAMING: 253 if (entity->baSourceID[i] == id)
253 if (entity->output.bSourceID == id)
254 return entity;
255 break;
256
257 case UVC_VC_PROCESSING_UNIT:
258 if (entity->processing.bSourceID == id)
259 return entity; 254 return entity;
260 break;
261
262 case UVC_VC_SELECTOR_UNIT:
263 for (i = 0; i < entity->selector.bNrInPins; ++i)
264 if (entity->selector.baSourceID[i] == id)
265 return entity;
266 break;
267
268 case UVC_VC_EXTENSION_UNIT:
269 for (i = 0; i < entity->extension.bNrInPins; ++i)
270 if (entity->extension.baSourceID[i] == id)
271 return entity;
272 break;
273 }
274 } 255 }
275 256
276 return NULL; 257 return NULL;
@@ -426,7 +407,8 @@ static int uvc_parse_format(struct uvc_device *dev,
426 /* Parse the frame descriptors. Only uncompressed, MJPEG and frame 407 /* Parse the frame descriptors. Only uncompressed, MJPEG and frame
427 * based formats have frame descriptors. 408 * based formats have frame descriptors.
428 */ 409 */
429 while (buflen > 2 && buffer[2] == ftype) { 410 while (buflen > 2 && buffer[1] == USB_DT_CS_INTERFACE &&
411 buffer[2] == ftype) {
430 frame = &format->frame[format->nframes]; 412 frame = &format->frame[format->nframes];
431 if (ftype != UVC_VS_FRAME_FRAME_BASED) 413 if (ftype != UVC_VS_FRAME_FRAME_BASED)
432 n = buflen > 25 ? buffer[25] : 0; 414 n = buflen > 25 ? buffer[25] : 0;
@@ -503,12 +485,14 @@ static int uvc_parse_format(struct uvc_device *dev,
503 buffer += buffer[0]; 485 buffer += buffer[0];
504 } 486 }
505 487
506 if (buflen > 2 && buffer[2] == UVC_VS_STILL_IMAGE_FRAME) { 488 if (buflen > 2 && buffer[1] == USB_DT_CS_INTERFACE &&
489 buffer[2] == UVC_VS_STILL_IMAGE_FRAME) {
507 buflen -= buffer[0]; 490 buflen -= buffer[0];
508 buffer += buffer[0]; 491 buffer += buffer[0];
509 } 492 }
510 493
511 if (buflen > 2 && buffer[2] == UVC_VS_COLORFORMAT) { 494 if (buflen > 2 && buffer[1] == USB_DT_CS_INTERFACE &&
495 buffer[2] == UVC_VS_COLORFORMAT) {
512 if (buflen < 6) { 496 if (buflen < 6) {
513 uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming " 497 uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming "
514 "interface %d COLORFORMAT error\n", 498 "interface %d COLORFORMAT error\n",
@@ -749,6 +733,11 @@ static int uvc_parse_streaming(struct uvc_device *dev,
749 buffer += buffer[0]; 733 buffer += buffer[0];
750 } 734 }
751 735
736 if (buflen)
737 uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming interface "
738 "%d has %u bytes of trailing descriptor garbage.\n",
739 dev->udev->devnum, alts->desc.bInterfaceNumber, buflen);
740
752 /* Parse the alternate settings to find the maximum bandwidth. */ 741 /* Parse the alternate settings to find the maximum bandwidth. */
753 for (i = 0; i < intf->num_altsetting; ++i) { 742 for (i = 0; i < intf->num_altsetting; ++i) {
754 struct usb_host_endpoint *ep; 743 struct usb_host_endpoint *ep;
@@ -776,6 +765,28 @@ error:
776 return ret; 765 return ret;
777} 766}
778 767
768static struct uvc_entity *uvc_alloc_entity(u16 type, u8 id,
769 unsigned int num_pads, unsigned int extra_size)
770{
771 struct uvc_entity *entity;
772 unsigned int num_inputs;
773 unsigned int size;
774
775 num_inputs = (type & UVC_TERM_OUTPUT) ? num_pads : num_pads - 1;
776 size = sizeof(*entity) + extra_size + num_inputs;
777 entity = kzalloc(size, GFP_KERNEL);
778 if (entity == NULL)
779 return NULL;
780
781 entity->id = id;
782 entity->type = type;
783
784 entity->bNrInPins = num_inputs;
785 entity->baSourceID = ((__u8 *)entity) + sizeof(*entity) + extra_size;
786
787 return entity;
788}
789
779/* Parse vendor-specific extensions. */ 790/* Parse vendor-specific extensions. */
780static int uvc_parse_vendor_control(struct uvc_device *dev, 791static int uvc_parse_vendor_control(struct uvc_device *dev,
781 const unsigned char *buffer, int buflen) 792 const unsigned char *buffer, int buflen)
@@ -827,21 +838,18 @@ static int uvc_parse_vendor_control(struct uvc_device *dev,
827 break; 838 break;
828 } 839 }
829 840
830 unit = kzalloc(sizeof *unit + p + 2*n, GFP_KERNEL); 841 unit = uvc_alloc_entity(UVC_VC_EXTENSION_UNIT, buffer[3],
842 p + 1, 2*n);
831 if (unit == NULL) 843 if (unit == NULL)
832 return -ENOMEM; 844 return -ENOMEM;
833 845
834 unit->id = buffer[3];
835 unit->type = UVC_VC_EXTENSION_UNIT;
836 memcpy(unit->extension.guidExtensionCode, &buffer[4], 16); 846 memcpy(unit->extension.guidExtensionCode, &buffer[4], 16);
837 unit->extension.bNumControls = buffer[20]; 847 unit->extension.bNumControls = buffer[20];
838 unit->extension.bNrInPins = get_unaligned_le16(&buffer[21]); 848 memcpy(unit->baSourceID, &buffer[22], p);
839 unit->extension.baSourceID = (__u8 *)unit + sizeof *unit;
840 memcpy(unit->extension.baSourceID, &buffer[22], p);
841 unit->extension.bControlSize = buffer[22+p]; 849 unit->extension.bControlSize = buffer[22+p];
842 unit->extension.bmControls = (__u8 *)unit + sizeof *unit + p; 850 unit->extension.bmControls = (__u8 *)unit + sizeof(*unit);
843 unit->extension.bmControlsType = (__u8 *)unit + sizeof *unit 851 unit->extension.bmControlsType = (__u8 *)unit + sizeof(*unit)
844 + p + n; 852 + n;
845 memcpy(unit->extension.bmControls, &buffer[23+p], 2*n); 853 memcpy(unit->extension.bmControls, &buffer[23+p], 2*n);
846 854
847 if (buffer[24+p+2*n] != 0) 855 if (buffer[24+p+2*n] != 0)
@@ -938,13 +946,11 @@ static int uvc_parse_standard_control(struct uvc_device *dev,
938 return -EINVAL; 946 return -EINVAL;
939 } 947 }
940 948
941 term = kzalloc(sizeof *term + n + p, GFP_KERNEL); 949 term = uvc_alloc_entity(type | UVC_TERM_INPUT, buffer[3],
950 1, n + p);
942 if (term == NULL) 951 if (term == NULL)
943 return -ENOMEM; 952 return -ENOMEM;
944 953
945 term->id = buffer[3];
946 term->type = type | UVC_TERM_INPUT;
947
948 if (UVC_ENTITY_TYPE(term) == UVC_ITT_CAMERA) { 954 if (UVC_ENTITY_TYPE(term) == UVC_ITT_CAMERA) {
949 term->camera.bControlSize = n; 955 term->camera.bControlSize = n;
950 term->camera.bmControls = (__u8 *)term + sizeof *term; 956 term->camera.bmControls = (__u8 *)term + sizeof *term;
@@ -999,13 +1005,12 @@ static int uvc_parse_standard_control(struct uvc_device *dev,
999 return 0; 1005 return 0;
1000 } 1006 }
1001 1007
1002 term = kzalloc(sizeof *term, GFP_KERNEL); 1008 term = uvc_alloc_entity(type | UVC_TERM_OUTPUT, buffer[3],
1009 1, 0);
1003 if (term == NULL) 1010 if (term == NULL)
1004 return -ENOMEM; 1011 return -ENOMEM;
1005 1012
1006 term->id = buffer[3]; 1013 memcpy(term->baSourceID, &buffer[7], 1);
1007 term->type = type | UVC_TERM_OUTPUT;
1008 term->output.bSourceID = buffer[7];
1009 1014
1010 if (buffer[8] != 0) 1015 if (buffer[8] != 0)
1011 usb_string(udev, buffer[8], term->name, 1016 usb_string(udev, buffer[8], term->name,
@@ -1026,15 +1031,11 @@ static int uvc_parse_standard_control(struct uvc_device *dev,
1026 return -EINVAL; 1031 return -EINVAL;
1027 } 1032 }
1028 1033
1029 unit = kzalloc(sizeof *unit + p, GFP_KERNEL); 1034 unit = uvc_alloc_entity(buffer[2], buffer[3], p + 1, 0);
1030 if (unit == NULL) 1035 if (unit == NULL)
1031 return -ENOMEM; 1036 return -ENOMEM;
1032 1037
1033 unit->id = buffer[3]; 1038 memcpy(unit->baSourceID, &buffer[5], p);
1034 unit->type = buffer[2];
1035 unit->selector.bNrInPins = buffer[4];
1036 unit->selector.baSourceID = (__u8 *)unit + sizeof *unit;
1037 memcpy(unit->selector.baSourceID, &buffer[5], p);
1038 1039
1039 if (buffer[5+p] != 0) 1040 if (buffer[5+p] != 0)
1040 usb_string(udev, buffer[5+p], unit->name, 1041 usb_string(udev, buffer[5+p], unit->name,
@@ -1056,13 +1057,11 @@ static int uvc_parse_standard_control(struct uvc_device *dev,
1056 return -EINVAL; 1057 return -EINVAL;
1057 } 1058 }
1058 1059
1059 unit = kzalloc(sizeof *unit + n, GFP_KERNEL); 1060 unit = uvc_alloc_entity(buffer[2], buffer[3], 2, n);
1060 if (unit == NULL) 1061 if (unit == NULL)
1061 return -ENOMEM; 1062 return -ENOMEM;
1062 1063
1063 unit->id = buffer[3]; 1064 memcpy(unit->baSourceID, &buffer[4], 1);
1064 unit->type = buffer[2];
1065 unit->processing.bSourceID = buffer[4];
1066 unit->processing.wMaxMultiplier = 1065 unit->processing.wMaxMultiplier =
1067 get_unaligned_le16(&buffer[5]); 1066 get_unaligned_le16(&buffer[5]);
1068 unit->processing.bControlSize = buffer[7]; 1067 unit->processing.bControlSize = buffer[7];
@@ -1091,19 +1090,15 @@ static int uvc_parse_standard_control(struct uvc_device *dev,
1091 return -EINVAL; 1090 return -EINVAL;
1092 } 1091 }
1093 1092
1094 unit = kzalloc(sizeof *unit + p + n, GFP_KERNEL); 1093 unit = uvc_alloc_entity(buffer[2], buffer[3], p + 1, n);
1095 if (unit == NULL) 1094 if (unit == NULL)
1096 return -ENOMEM; 1095 return -ENOMEM;
1097 1096
1098 unit->id = buffer[3];
1099 unit->type = buffer[2];
1100 memcpy(unit->extension.guidExtensionCode, &buffer[4], 16); 1097 memcpy(unit->extension.guidExtensionCode, &buffer[4], 16);
1101 unit->extension.bNumControls = buffer[20]; 1098 unit->extension.bNumControls = buffer[20];
1102 unit->extension.bNrInPins = get_unaligned_le16(&buffer[21]); 1099 memcpy(unit->baSourceID, &buffer[22], p);
1103 unit->extension.baSourceID = (__u8 *)unit + sizeof *unit;
1104 memcpy(unit->extension.baSourceID, &buffer[22], p);
1105 unit->extension.bControlSize = buffer[22+p]; 1100 unit->extension.bControlSize = buffer[22+p];
1106 unit->extension.bmControls = (__u8 *)unit + sizeof *unit + p; 1101 unit->extension.bmControls = (__u8 *)unit + sizeof *unit;
1107 memcpy(unit->extension.bmControls, &buffer[23+p], n); 1102 memcpy(unit->extension.bmControls, &buffer[23+p], n);
1108 1103
1109 if (buffer[23+p+n] != 0) 1104 if (buffer[23+p+n] != 0)
@@ -1209,13 +1204,12 @@ static int uvc_scan_chain_entity(struct uvc_video_chain *chain,
1209 if (uvc_trace_param & UVC_TRACE_PROBE) 1204 if (uvc_trace_param & UVC_TRACE_PROBE)
1210 printk(" <- XU %d", entity->id); 1205 printk(" <- XU %d", entity->id);
1211 1206
1212 if (entity->extension.bNrInPins != 1) { 1207 if (entity->bNrInPins != 1) {
1213 uvc_trace(UVC_TRACE_DESCR, "Extension unit %d has more " 1208 uvc_trace(UVC_TRACE_DESCR, "Extension unit %d has more "
1214 "than 1 input pin.\n", entity->id); 1209 "than 1 input pin.\n", entity->id);
1215 return -1; 1210 return -1;
1216 } 1211 }
1217 1212
1218 list_add_tail(&entity->chain, &chain->extensions);
1219 break; 1213 break;
1220 1214
1221 case UVC_VC_PROCESSING_UNIT: 1215 case UVC_VC_PROCESSING_UNIT:
@@ -1236,7 +1230,7 @@ static int uvc_scan_chain_entity(struct uvc_video_chain *chain,
1236 printk(" <- SU %d", entity->id); 1230 printk(" <- SU %d", entity->id);
1237 1231
1238 /* Single-input selector units are ignored. */ 1232 /* Single-input selector units are ignored. */
1239 if (entity->selector.bNrInPins == 1) 1233 if (entity->bNrInPins == 1)
1240 break; 1234 break;
1241 1235
1242 if (chain->selector != NULL) { 1236 if (chain->selector != NULL) {
@@ -1254,20 +1248,17 @@ static int uvc_scan_chain_entity(struct uvc_video_chain *chain,
1254 if (uvc_trace_param & UVC_TRACE_PROBE) 1248 if (uvc_trace_param & UVC_TRACE_PROBE)
1255 printk(" <- IT %d\n", entity->id); 1249 printk(" <- IT %d\n", entity->id);
1256 1250
1257 list_add_tail(&entity->chain, &chain->iterms);
1258 break; 1251 break;
1259 1252
1260 case UVC_TT_STREAMING: 1253 case UVC_TT_STREAMING:
1261 if (uvc_trace_param & UVC_TRACE_PROBE) 1254 if (UVC_ENTITY_IS_ITERM(entity)) {
1262 printk(" <- IT %d\n", entity->id); 1255 if (uvc_trace_param & UVC_TRACE_PROBE)
1263 1256 printk(" <- IT %d\n", entity->id);
1264 if (!UVC_ENTITY_IS_ITERM(entity)) { 1257 } else {
1265 uvc_trace(UVC_TRACE_DESCR, "Unsupported input " 1258 if (uvc_trace_param & UVC_TRACE_PROBE)
1266 "terminal %u.\n", entity->id); 1259 printk(" OT %d", entity->id);
1267 return -1;
1268 } 1260 }
1269 1261
1270 list_add_tail(&entity->chain, &chain->iterms);
1271 break; 1262 break;
1272 1263
1273 default: 1264 default:
@@ -1276,6 +1267,7 @@ static int uvc_scan_chain_entity(struct uvc_video_chain *chain,
1276 return -1; 1267 return -1;
1277 } 1268 }
1278 1269
1270 list_add_tail(&entity->chain, &chain->entities);
1279 return 0; 1271 return 0;
1280} 1272}
1281 1273
@@ -1299,14 +1291,14 @@ static int uvc_scan_chain_forward(struct uvc_video_chain *chain,
1299 1291
1300 switch (UVC_ENTITY_TYPE(forward)) { 1292 switch (UVC_ENTITY_TYPE(forward)) {
1301 case UVC_VC_EXTENSION_UNIT: 1293 case UVC_VC_EXTENSION_UNIT:
1302 if (forward->extension.bNrInPins != 1) { 1294 if (forward->bNrInPins != 1) {
1303 uvc_trace(UVC_TRACE_DESCR, "Extension unit %d " 1295 uvc_trace(UVC_TRACE_DESCR, "Extension unit %d "
1304 "has more than 1 input pin.\n", 1296 "has more than 1 input pin.\n",
1305 entity->id); 1297 entity->id);
1306 return -EINVAL; 1298 return -EINVAL;
1307 } 1299 }
1308 1300
1309 list_add_tail(&forward->chain, &chain->extensions); 1301 list_add_tail(&forward->chain, &chain->entities);
1310 if (uvc_trace_param & UVC_TRACE_PROBE) { 1302 if (uvc_trace_param & UVC_TRACE_PROBE) {
1311 if (!found) 1303 if (!found)
1312 printk(" (->"); 1304 printk(" (->");
@@ -1326,7 +1318,7 @@ static int uvc_scan_chain_forward(struct uvc_video_chain *chain,
1326 return -EINVAL; 1318 return -EINVAL;
1327 } 1319 }
1328 1320
1329 list_add_tail(&forward->chain, &chain->oterms); 1321 list_add_tail(&forward->chain, &chain->entities);
1330 if (uvc_trace_param & UVC_TRACE_PROBE) { 1322 if (uvc_trace_param & UVC_TRACE_PROBE) {
1331 if (!found) 1323 if (!found)
1332 printk(" (->"); 1324 printk(" (->");
@@ -1344,24 +1336,22 @@ static int uvc_scan_chain_forward(struct uvc_video_chain *chain,
1344} 1336}
1345 1337
1346static int uvc_scan_chain_backward(struct uvc_video_chain *chain, 1338static int uvc_scan_chain_backward(struct uvc_video_chain *chain,
1347 struct uvc_entity *entity) 1339 struct uvc_entity **_entity)
1348{ 1340{
1341 struct uvc_entity *entity = *_entity;
1349 struct uvc_entity *term; 1342 struct uvc_entity *term;
1350 int id = -1, i; 1343 int id = -EINVAL, i;
1351 1344
1352 switch (UVC_ENTITY_TYPE(entity)) { 1345 switch (UVC_ENTITY_TYPE(entity)) {
1353 case UVC_VC_EXTENSION_UNIT: 1346 case UVC_VC_EXTENSION_UNIT:
1354 id = entity->extension.baSourceID[0];
1355 break;
1356
1357 case UVC_VC_PROCESSING_UNIT: 1347 case UVC_VC_PROCESSING_UNIT:
1358 id = entity->processing.bSourceID; 1348 id = entity->baSourceID[0];
1359 break; 1349 break;
1360 1350
1361 case UVC_VC_SELECTOR_UNIT: 1351 case UVC_VC_SELECTOR_UNIT:
1362 /* Single-input selector units are ignored. */ 1352 /* Single-input selector units are ignored. */
1363 if (entity->selector.bNrInPins == 1) { 1353 if (entity->bNrInPins == 1) {
1364 id = entity->selector.baSourceID[0]; 1354 id = entity->baSourceID[0];
1365 break; 1355 break;
1366 } 1356 }
1367 1357
@@ -1369,8 +1359,8 @@ static int uvc_scan_chain_backward(struct uvc_video_chain *chain,
1369 printk(" <- IT"); 1359 printk(" <- IT");
1370 1360
1371 chain->selector = entity; 1361 chain->selector = entity;
1372 for (i = 0; i < entity->selector.bNrInPins; ++i) { 1362 for (i = 0; i < entity->bNrInPins; ++i) {
1373 id = entity->selector.baSourceID[i]; 1363 id = entity->baSourceID[i];
1374 term = uvc_entity_by_id(chain->dev, id); 1364 term = uvc_entity_by_id(chain->dev, id);
1375 if (term == NULL || !UVC_ENTITY_IS_ITERM(term)) { 1365 if (term == NULL || !UVC_ENTITY_IS_ITERM(term)) {
1376 uvc_trace(UVC_TRACE_DESCR, "Selector unit %d " 1366 uvc_trace(UVC_TRACE_DESCR, "Selector unit %d "
@@ -1382,7 +1372,7 @@ static int uvc_scan_chain_backward(struct uvc_video_chain *chain,
1382 if (uvc_trace_param & UVC_TRACE_PROBE) 1372 if (uvc_trace_param & UVC_TRACE_PROBE)
1383 printk(" %d", term->id); 1373 printk(" %d", term->id);
1384 1374
1385 list_add_tail(&term->chain, &chain->iterms); 1375 list_add_tail(&term->chain, &chain->entities);
1386 uvc_scan_chain_forward(chain, term, entity); 1376 uvc_scan_chain_forward(chain, term, entity);
1387 } 1377 }
1388 1378
@@ -1391,34 +1381,49 @@ static int uvc_scan_chain_backward(struct uvc_video_chain *chain,
1391 1381
1392 id = 0; 1382 id = 0;
1393 break; 1383 break;
1384
1385 case UVC_ITT_VENDOR_SPECIFIC:
1386 case UVC_ITT_CAMERA:
1387 case UVC_ITT_MEDIA_TRANSPORT_INPUT:
1388 case UVC_OTT_VENDOR_SPECIFIC:
1389 case UVC_OTT_DISPLAY:
1390 case UVC_OTT_MEDIA_TRANSPORT_OUTPUT:
1391 case UVC_TT_STREAMING:
1392 id = UVC_ENTITY_IS_OTERM(entity) ? entity->baSourceID[0] : 0;
1393 break;
1394 }
1395
1396 if (id <= 0) {
1397 *_entity = NULL;
1398 return id;
1394 } 1399 }
1395 1400
1396 return id; 1401 entity = uvc_entity_by_id(chain->dev, id);
1402 if (entity == NULL) {
1403 uvc_trace(UVC_TRACE_DESCR, "Found reference to "
1404 "unknown entity %d.\n", id);
1405 return -EINVAL;
1406 }
1407
1408 *_entity = entity;
1409 return 0;
1397} 1410}
1398 1411
1399static int uvc_scan_chain(struct uvc_video_chain *chain, 1412static int uvc_scan_chain(struct uvc_video_chain *chain,
1400 struct uvc_entity *oterm) 1413 struct uvc_entity *term)
1401{ 1414{
1402 struct uvc_entity *entity, *prev; 1415 struct uvc_entity *entity, *prev;
1403 int id;
1404 1416
1405 entity = oterm; 1417 uvc_trace(UVC_TRACE_PROBE, "Scanning UVC chain:");
1406 list_add_tail(&entity->chain, &chain->oterms);
1407 uvc_trace(UVC_TRACE_PROBE, "Scanning UVC chain: OT %d", entity->id);
1408 1418
1409 id = entity->output.bSourceID; 1419 entity = term;
1410 while (id != 0) { 1420 prev = NULL;
1411 prev = entity;
1412 entity = uvc_entity_by_id(chain->dev, id);
1413 if (entity == NULL) {
1414 uvc_trace(UVC_TRACE_DESCR, "Found reference to "
1415 "unknown entity %d.\n", id);
1416 return -EINVAL;
1417 }
1418 1421
1422 while (entity != NULL) {
1423 /* Entity must not be part of an existing chain */
1419 if (entity->chain.next || entity->chain.prev) { 1424 if (entity->chain.next || entity->chain.prev) {
1420 uvc_trace(UVC_TRACE_DESCR, "Found reference to " 1425 uvc_trace(UVC_TRACE_DESCR, "Found reference to "
1421 "entity %d already in chain.\n", id); 1426 "entity %d already in chain.\n", entity->id);
1422 return -EINVAL; 1427 return -EINVAL;
1423 } 1428 }
1424 1429
@@ -1430,34 +1435,34 @@ static int uvc_scan_chain(struct uvc_video_chain *chain,
1430 if (uvc_scan_chain_forward(chain, entity, prev) < 0) 1435 if (uvc_scan_chain_forward(chain, entity, prev) < 0)
1431 return -EINVAL; 1436 return -EINVAL;
1432 1437
1433 /* Stop when a terminal is found. */
1434 if (UVC_ENTITY_IS_TERM(entity))
1435 break;
1436
1437 /* Backward scan */ 1438 /* Backward scan */
1438 id = uvc_scan_chain_backward(chain, entity); 1439 prev = entity;
1439 if (id < 0) 1440 if (uvc_scan_chain_backward(chain, &entity) < 0)
1440 return id; 1441 return -EINVAL;
1441 } 1442 }
1442 1443
1443 return 0; 1444 return 0;
1444} 1445}
1445 1446
1446static unsigned int uvc_print_terms(struct list_head *terms, char *buffer) 1447static unsigned int uvc_print_terms(struct list_head *terms, u16 dir,
1448 char *buffer)
1447{ 1449{
1448 struct uvc_entity *term; 1450 struct uvc_entity *term;
1449 unsigned int nterms = 0; 1451 unsigned int nterms = 0;
1450 char *p = buffer; 1452 char *p = buffer;
1451 1453
1452 list_for_each_entry(term, terms, chain) { 1454 list_for_each_entry(term, terms, chain) {
1453 p += sprintf(p, "%u", term->id); 1455 if (!UVC_ENTITY_IS_TERM(term) ||
1454 if (term->chain.next != terms) { 1456 UVC_TERM_DIRECTION(term) != dir)
1457 continue;
1458
1459 if (nterms)
1455 p += sprintf(p, ","); 1460 p += sprintf(p, ",");
1456 if (++nterms >= 4) { 1461 if (++nterms >= 4) {
1457 p += sprintf(p, "..."); 1462 p += sprintf(p, "...");
1458 break; 1463 break;
1459 }
1460 } 1464 }
1465 p += sprintf(p, "%u", term->id);
1461 } 1466 }
1462 1467
1463 return p - buffer; 1468 return p - buffer;
@@ -1468,9 +1473,9 @@ static const char *uvc_print_chain(struct uvc_video_chain *chain)
1468 static char buffer[43]; 1473 static char buffer[43];
1469 char *p = buffer; 1474 char *p = buffer;
1470 1475
1471 p += uvc_print_terms(&chain->iterms, p); 1476 p += uvc_print_terms(&chain->entities, UVC_TERM_INPUT, p);
1472 p += sprintf(p, " -> "); 1477 p += sprintf(p, " -> ");
1473 uvc_print_terms(&chain->oterms, p); 1478 uvc_print_terms(&chain->entities, UVC_TERM_OUTPUT, p);
1474 1479
1475 return buffer; 1480 return buffer;
1476} 1481}
@@ -1501,9 +1506,7 @@ static int uvc_scan_device(struct uvc_device *dev)
1501 if (chain == NULL) 1506 if (chain == NULL)
1502 return -ENOMEM; 1507 return -ENOMEM;
1503 1508
1504 INIT_LIST_HEAD(&chain->iterms); 1509 INIT_LIST_HEAD(&chain->entities);
1505 INIT_LIST_HEAD(&chain->oterms);
1506 INIT_LIST_HEAD(&chain->extensions);
1507 mutex_init(&chain->ctrl_mutex); 1510 mutex_init(&chain->ctrl_mutex);
1508 chain->dev = dev; 1511 chain->dev = dev;
1509 1512
@@ -1531,22 +1534,92 @@ static int uvc_scan_device(struct uvc_device *dev)
1531 */ 1534 */
1532 1535
1533/* 1536/*
1537 * Delete the UVC device.
1538 *
1539 * Called by the kernel when the last reference to the uvc_device structure
1540 * is released.
1541 *
1542 * As this function is called after or during disconnect(), all URBs have
1543 * already been canceled by the USB core. There is no need to kill the
1544 * interrupt URB manually.
1545 */
1546static void uvc_delete(struct uvc_device *dev)
1547{
1548 struct list_head *p, *n;
1549
1550 usb_put_intf(dev->intf);
1551 usb_put_dev(dev->udev);
1552
1553 uvc_status_cleanup(dev);
1554 uvc_ctrl_cleanup_device(dev);
1555
1556 list_for_each_safe(p, n, &dev->chains) {
1557 struct uvc_video_chain *chain;
1558 chain = list_entry(p, struct uvc_video_chain, list);
1559 kfree(chain);
1560 }
1561
1562 list_for_each_safe(p, n, &dev->entities) {
1563 struct uvc_entity *entity;
1564 entity = list_entry(p, struct uvc_entity, list);
1565 kfree(entity);
1566 }
1567
1568 list_for_each_safe(p, n, &dev->streams) {
1569 struct uvc_streaming *streaming;
1570 streaming = list_entry(p, struct uvc_streaming, list);
1571 usb_driver_release_interface(&uvc_driver.driver,
1572 streaming->intf);
1573 usb_put_intf(streaming->intf);
1574 kfree(streaming->format);
1575 kfree(streaming->header.bmaControls);
1576 kfree(streaming);
1577 }
1578
1579 kfree(dev);
1580}
1581
1582static void uvc_release(struct video_device *vdev)
1583{
1584 struct uvc_streaming *stream = video_get_drvdata(vdev);
1585 struct uvc_device *dev = stream->dev;
1586
1587 video_device_release(vdev);
1588
1589 /* Decrement the registered streams count and delete the device when it
1590 * reaches zero.
1591 */
1592 if (atomic_dec_and_test(&dev->nstreams))
1593 uvc_delete(dev);
1594}
1595
1596/*
1534 * Unregister the video devices. 1597 * Unregister the video devices.
1535 */ 1598 */
1536static void uvc_unregister_video(struct uvc_device *dev) 1599static void uvc_unregister_video(struct uvc_device *dev)
1537{ 1600{
1538 struct uvc_streaming *stream; 1601 struct uvc_streaming *stream;
1539 1602
1603 /* Unregistering all video devices might result in uvc_delete() being
1604 * called from inside the loop if there's no open file handle. To avoid
1605 * that, increment the stream count before iterating over the streams
1606 * and decrement it when done.
1607 */
1608 atomic_inc(&dev->nstreams);
1609
1540 list_for_each_entry(stream, &dev->streams, list) { 1610 list_for_each_entry(stream, &dev->streams, list) {
1541 if (stream->vdev == NULL) 1611 if (stream->vdev == NULL)
1542 continue; 1612 continue;
1543 1613
1544 if (stream->vdev->minor == -1) 1614 video_unregister_device(stream->vdev);
1545 video_device_release(stream->vdev);
1546 else
1547 video_unregister_device(stream->vdev);
1548 stream->vdev = NULL; 1615 stream->vdev = NULL;
1549 } 1616 }
1617
1618 /* Decrement the stream count and call uvc_delete explicitly if there
1619 * are no stream left.
1620 */
1621 if (atomic_dec_and_test(&dev->nstreams))
1622 uvc_delete(dev);
1550} 1623}
1551 1624
1552static int uvc_register_video(struct uvc_device *dev, 1625static int uvc_register_video(struct uvc_device *dev,
@@ -1580,7 +1653,7 @@ static int uvc_register_video(struct uvc_device *dev,
1580 vdev->parent = &dev->intf->dev; 1653 vdev->parent = &dev->intf->dev;
1581 vdev->minor = -1; 1654 vdev->minor = -1;
1582 vdev->fops = &uvc_fops; 1655 vdev->fops = &uvc_fops;
1583 vdev->release = video_device_release; 1656 vdev->release = uvc_release;
1584 strlcpy(vdev->name, dev->name, sizeof vdev->name); 1657 strlcpy(vdev->name, dev->name, sizeof vdev->name);
1585 1658
1586 /* Set the driver data before calling video_register_device, otherwise 1659 /* Set the driver data before calling video_register_device, otherwise
@@ -1598,6 +1671,7 @@ static int uvc_register_video(struct uvc_device *dev,
1598 return ret; 1671 return ret;
1599 } 1672 }
1600 1673
1674 atomic_inc(&dev->nstreams);
1601 return 0; 1675 return 0;
1602} 1676}
1603 1677
@@ -1605,13 +1679,13 @@ static int uvc_register_video(struct uvc_device *dev,
1605 * Register all video devices in all chains. 1679 * Register all video devices in all chains.
1606 */ 1680 */
1607static int uvc_register_terms(struct uvc_device *dev, 1681static int uvc_register_terms(struct uvc_device *dev,
1608 struct uvc_video_chain *chain, struct list_head *terms) 1682 struct uvc_video_chain *chain)
1609{ 1683{
1610 struct uvc_streaming *stream; 1684 struct uvc_streaming *stream;
1611 struct uvc_entity *term; 1685 struct uvc_entity *term;
1612 int ret; 1686 int ret;
1613 1687
1614 list_for_each_entry(term, terms, chain) { 1688 list_for_each_entry(term, &chain->entities, chain) {
1615 if (UVC_ENTITY_TYPE(term) != UVC_TT_STREAMING) 1689 if (UVC_ENTITY_TYPE(term) != UVC_TT_STREAMING)
1616 continue; 1690 continue;
1617 1691
@@ -1637,11 +1711,7 @@ static int uvc_register_chains(struct uvc_device *dev)
1637 int ret; 1711 int ret;
1638 1712
1639 list_for_each_entry(chain, &dev->chains, list) { 1713 list_for_each_entry(chain, &dev->chains, list) {
1640 ret = uvc_register_terms(dev, chain, &chain->iterms); 1714 ret = uvc_register_terms(dev, chain);
1641 if (ret < 0)
1642 return ret;
1643
1644 ret = uvc_register_terms(dev, chain, &chain->oterms);
1645 if (ret < 0) 1715 if (ret < 0)
1646 return ret; 1716 return ret;
1647 } 1717 }
@@ -1653,61 +1723,6 @@ static int uvc_register_chains(struct uvc_device *dev)
1653 * USB probe, disconnect, suspend and resume 1723 * USB probe, disconnect, suspend and resume
1654 */ 1724 */
1655 1725
1656/*
1657 * Delete the UVC device.
1658 *
1659 * Called by the kernel when the last reference to the uvc_device structure
1660 * is released.
1661 *
1662 * Unregistering the video devices is done here because every opened instance
1663 * must be closed before the device can be unregistered. An alternative would
1664 * have been to use another reference count for uvc_v4l2_open/uvc_release, and
1665 * unregister the video devices on disconnect when that reference count drops
1666 * to zero.
1667 *
1668 * As this function is called after or during disconnect(), all URBs have
1669 * already been canceled by the USB core. There is no need to kill the
1670 * interrupt URB manually.
1671 */
1672void uvc_delete(struct kref *kref)
1673{
1674 struct uvc_device *dev = container_of(kref, struct uvc_device, kref);
1675 struct list_head *p, *n;
1676
1677 /* Unregister the video devices. */
1678 uvc_unregister_video(dev);
1679 usb_put_intf(dev->intf);
1680 usb_put_dev(dev->udev);
1681
1682 uvc_status_cleanup(dev);
1683 uvc_ctrl_cleanup_device(dev);
1684
1685 list_for_each_safe(p, n, &dev->chains) {
1686 struct uvc_video_chain *chain;
1687 chain = list_entry(p, struct uvc_video_chain, list);
1688 kfree(chain);
1689 }
1690
1691 list_for_each_safe(p, n, &dev->entities) {
1692 struct uvc_entity *entity;
1693 entity = list_entry(p, struct uvc_entity, list);
1694 kfree(entity);
1695 }
1696
1697 list_for_each_safe(p, n, &dev->streams) {
1698 struct uvc_streaming *streaming;
1699 streaming = list_entry(p, struct uvc_streaming, list);
1700 usb_driver_release_interface(&uvc_driver.driver,
1701 streaming->intf);
1702 usb_put_intf(streaming->intf);
1703 kfree(streaming->format);
1704 kfree(streaming->header.bmaControls);
1705 kfree(streaming);
1706 }
1707
1708 kfree(dev);
1709}
1710
1711static int uvc_probe(struct usb_interface *intf, 1726static int uvc_probe(struct usb_interface *intf,
1712 const struct usb_device_id *id) 1727 const struct usb_device_id *id)
1713{ 1728{
@@ -1730,7 +1745,7 @@ static int uvc_probe(struct usb_interface *intf,
1730 INIT_LIST_HEAD(&dev->entities); 1745 INIT_LIST_HEAD(&dev->entities);
1731 INIT_LIST_HEAD(&dev->chains); 1746 INIT_LIST_HEAD(&dev->chains);
1732 INIT_LIST_HEAD(&dev->streams); 1747 INIT_LIST_HEAD(&dev->streams);
1733 kref_init(&dev->kref); 1748 atomic_set(&dev->nstreams, 0);
1734 atomic_set(&dev->users, 0); 1749 atomic_set(&dev->users, 0);
1735 1750
1736 dev->udev = usb_get_dev(udev); 1751 dev->udev = usb_get_dev(udev);
@@ -1792,7 +1807,7 @@ static int uvc_probe(struct usb_interface *intf,
1792 return 0; 1807 return 0;
1793 1808
1794error: 1809error:
1795 kref_put(&dev->kref, uvc_delete); 1810 uvc_unregister_video(dev);
1796 return -ENODEV; 1811 return -ENODEV;
1797} 1812}
1798 1813
@@ -1809,21 +1824,9 @@ static void uvc_disconnect(struct usb_interface *intf)
1809 UVC_SC_VIDEOSTREAMING) 1824 UVC_SC_VIDEOSTREAMING)
1810 return; 1825 return;
1811 1826
1812 /* uvc_v4l2_open() might race uvc_disconnect(). A static driver-wide
1813 * lock is needed to prevent uvc_disconnect from releasing its
1814 * reference to the uvc_device instance after uvc_v4l2_open() received
1815 * the pointer to the device (video_devdata) but before it got the
1816 * chance to increase the reference count (kref_get).
1817 *
1818 * Note that the reference can't be released with the lock held,
1819 * otherwise a AB-BA deadlock can occur with videodev_lock that
1820 * videodev acquires in videodev_open() and video_unregister_device().
1821 */
1822 mutex_lock(&uvc_driver.open_mutex);
1823 dev->state |= UVC_DEV_DISCONNECTED; 1827 dev->state |= UVC_DEV_DISCONNECTED;
1824 mutex_unlock(&uvc_driver.open_mutex);
1825 1828
1826 kref_put(&dev->kref, uvc_delete); 1829 uvc_unregister_video(dev);
1827} 1830}
1828 1831
1829static int uvc_suspend(struct usb_interface *intf, pm_message_t message) 1832static int uvc_suspend(struct usb_interface *intf, pm_message_t message)
@@ -1899,6 +1902,15 @@ static int uvc_reset_resume(struct usb_interface *intf)
1899 * though they are compliant. 1902 * though they are compliant.
1900 */ 1903 */
1901static struct usb_device_id uvc_ids[] = { 1904static struct usb_device_id uvc_ids[] = {
1905 /* Genius eFace 2025 */
1906 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
1907 | USB_DEVICE_ID_MATCH_INT_INFO,
1908 .idVendor = 0x0458,
1909 .idProduct = 0x706e,
1910 .bInterfaceClass = USB_CLASS_VIDEO,
1911 .bInterfaceSubClass = 1,
1912 .bInterfaceProtocol = 0,
1913 .driver_info = UVC_QUIRK_PROBE_MINMAX },
1902 /* Microsoft Lifecam NX-6000 */ 1914 /* Microsoft Lifecam NX-6000 */
1903 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE 1915 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
1904 | USB_DEVICE_ID_MATCH_INT_INFO, 1916 | USB_DEVICE_ID_MATCH_INT_INFO,
@@ -2123,6 +2135,15 @@ static struct usb_device_id uvc_ids[] = {
2123 .bInterfaceSubClass = 1, 2135 .bInterfaceSubClass = 1,
2124 .bInterfaceProtocol = 0, 2136 .bInterfaceProtocol = 0,
2125 .driver_info = UVC_QUIRK_STATUS_INTERVAL }, 2137 .driver_info = UVC_QUIRK_STATUS_INTERVAL },
2138 /* MSI StarCam 370i */
2139 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2140 | USB_DEVICE_ID_MATCH_INT_INFO,
2141 .idVendor = 0x1b3b,
2142 .idProduct = 0x2951,
2143 .bInterfaceClass = USB_CLASS_VIDEO,
2144 .bInterfaceSubClass = 1,
2145 .bInterfaceProtocol = 0,
2146 .driver_info = UVC_QUIRK_PROBE_MINMAX },
2126 /* SiGma Micro USB Web Camera */ 2147 /* SiGma Micro USB Web Camera */
2127 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE 2148 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2128 | USB_DEVICE_ID_MATCH_INT_INFO, 2149 | USB_DEVICE_ID_MATCH_INT_INFO,
@@ -2159,7 +2180,6 @@ static int __init uvc_init(void)
2159 2180
2160 INIT_LIST_HEAD(&uvc_driver.devices); 2181 INIT_LIST_HEAD(&uvc_driver.devices);
2161 INIT_LIST_HEAD(&uvc_driver.controls); 2182 INIT_LIST_HEAD(&uvc_driver.controls);
2162 mutex_init(&uvc_driver.open_mutex);
2163 mutex_init(&uvc_driver.ctrl_mutex); 2183 mutex_init(&uvc_driver.ctrl_mutex);
2164 2184
2165 uvc_ctrl_init(); 2185 uvc_ctrl_init();
@@ -2184,6 +2204,8 @@ module_param_named(quirks, uvc_quirks_param, uint, S_IRUGO|S_IWUSR);
2184MODULE_PARM_DESC(quirks, "Forced device quirks"); 2204MODULE_PARM_DESC(quirks, "Forced device quirks");
2185module_param_named(trace, uvc_trace_param, uint, S_IRUGO|S_IWUSR); 2205module_param_named(trace, uvc_trace_param, uint, S_IRUGO|S_IWUSR);
2186MODULE_PARM_DESC(trace, "Trace level bitmask"); 2206MODULE_PARM_DESC(trace, "Trace level bitmask");
2207module_param_named(timeout, uvc_timeout_param, uint, S_IRUGO|S_IWUSR);
2208MODULE_PARM_DESC(timeout, "Streaming control requests timeout");
2187 2209
2188MODULE_AUTHOR(DRIVER_AUTHOR); 2210MODULE_AUTHOR(DRIVER_AUTHOR);
2189MODULE_DESCRIPTION(DRIVER_DESC); 2211MODULE_DESCRIPTION(DRIVER_DESC);
diff --git a/drivers/media/video/uvc/uvc_v4l2.c b/drivers/media/video/uvc/uvc_v4l2.c
index a2bdd806efab..23239a4adefe 100644
--- a/drivers/media/video/uvc/uvc_v4l2.c
+++ b/drivers/media/video/uvc/uvc_v4l2.c
@@ -364,37 +364,30 @@ static int uvc_v4l2_set_streamparm(struct uvc_streaming *stream,
364 * unprivileged state. Only a single instance can be in a privileged state at 364 * unprivileged state. Only a single instance can be in a privileged state at
365 * a given time. Trying to perform an operation that requires privileges will 365 * a given time. Trying to perform an operation that requires privileges will
366 * automatically acquire the required privileges if possible, or return -EBUSY 366 * automatically acquire the required privileges if possible, or return -EBUSY
367 * otherwise. Privileges are dismissed when closing the instance. 367 * otherwise. Privileges are dismissed when closing the instance or when
368 * freeing the video buffers using VIDIOC_REQBUFS.
368 * 369 *
369 * Operations that require privileges are: 370 * Operations that require privileges are:
370 * 371 *
371 * - VIDIOC_S_INPUT 372 * - VIDIOC_S_INPUT
372 * - VIDIOC_S_PARM 373 * - VIDIOC_S_PARM
373 * - VIDIOC_S_FMT 374 * - VIDIOC_S_FMT
374 * - VIDIOC_TRY_FMT
375 * - VIDIOC_REQBUFS 375 * - VIDIOC_REQBUFS
376 */ 376 */
377static int uvc_acquire_privileges(struct uvc_fh *handle) 377static int uvc_acquire_privileges(struct uvc_fh *handle)
378{ 378{
379 int ret = 0;
380
381 /* Always succeed if the handle is already privileged. */ 379 /* Always succeed if the handle is already privileged. */
382 if (handle->state == UVC_HANDLE_ACTIVE) 380 if (handle->state == UVC_HANDLE_ACTIVE)
383 return 0; 381 return 0;
384 382
385 /* Check if the device already has a privileged handle. */ 383 /* Check if the device already has a privileged handle. */
386 mutex_lock(&uvc_driver.open_mutex);
387 if (atomic_inc_return(&handle->stream->active) != 1) { 384 if (atomic_inc_return(&handle->stream->active) != 1) {
388 atomic_dec(&handle->stream->active); 385 atomic_dec(&handle->stream->active);
389 ret = -EBUSY; 386 return -EBUSY;
390 goto done;
391 } 387 }
392 388
393 handle->state = UVC_HANDLE_ACTIVE; 389 handle->state = UVC_HANDLE_ACTIVE;
394 390 return 0;
395done:
396 mutex_unlock(&uvc_driver.open_mutex);
397 return ret;
398} 391}
399 392
400static void uvc_dismiss_privileges(struct uvc_fh *handle) 393static void uvc_dismiss_privileges(struct uvc_fh *handle)
@@ -421,24 +414,20 @@ static int uvc_v4l2_open(struct file *file)
421 int ret = 0; 414 int ret = 0;
422 415
423 uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_open\n"); 416 uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_open\n");
424 mutex_lock(&uvc_driver.open_mutex);
425 stream = video_drvdata(file); 417 stream = video_drvdata(file);
426 418
427 if (stream->dev->state & UVC_DEV_DISCONNECTED) { 419 if (stream->dev->state & UVC_DEV_DISCONNECTED)
428 ret = -ENODEV; 420 return -ENODEV;
429 goto done;
430 }
431 421
432 ret = usb_autopm_get_interface(stream->dev->intf); 422 ret = usb_autopm_get_interface(stream->dev->intf);
433 if (ret < 0) 423 if (ret < 0)
434 goto done; 424 return ret;
435 425
436 /* Create the device handle. */ 426 /* Create the device handle. */
437 handle = kzalloc(sizeof *handle, GFP_KERNEL); 427 handle = kzalloc(sizeof *handle, GFP_KERNEL);
438 if (handle == NULL) { 428 if (handle == NULL) {
439 usb_autopm_put_interface(stream->dev->intf); 429 usb_autopm_put_interface(stream->dev->intf);
440 ret = -ENOMEM; 430 return -ENOMEM;
441 goto done;
442 } 431 }
443 432
444 if (atomic_inc_return(&stream->dev->users) == 1) { 433 if (atomic_inc_return(&stream->dev->users) == 1) {
@@ -447,7 +436,7 @@ static int uvc_v4l2_open(struct file *file)
447 usb_autopm_put_interface(stream->dev->intf); 436 usb_autopm_put_interface(stream->dev->intf);
448 atomic_dec(&stream->dev->users); 437 atomic_dec(&stream->dev->users);
449 kfree(handle); 438 kfree(handle);
450 goto done; 439 return ret;
451 } 440 }
452 } 441 }
453 442
@@ -456,11 +445,7 @@ static int uvc_v4l2_open(struct file *file)
456 handle->state = UVC_HANDLE_PASSIVE; 445 handle->state = UVC_HANDLE_PASSIVE;
457 file->private_data = handle; 446 file->private_data = handle;
458 447
459 kref_get(&stream->dev->kref); 448 return 0;
460
461done:
462 mutex_unlock(&uvc_driver.open_mutex);
463 return ret;
464} 449}
465 450
466static int uvc_v4l2_release(struct file *file) 451static int uvc_v4l2_release(struct file *file)
@@ -490,7 +475,6 @@ static int uvc_v4l2_release(struct file *file)
490 uvc_status_stop(stream->dev); 475 uvc_status_stop(stream->dev);
491 476
492 usb_autopm_put_interface(stream->dev->intf); 477 usb_autopm_put_interface(stream->dev->intf);
493 kref_put(&stream->dev->kref, uvc_delete);
494 return 0; 478 return 0;
495} 479}
496 480
@@ -636,12 +620,16 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
636 (chain->dev->quirks & UVC_QUIRK_IGNORE_SELECTOR_UNIT)) { 620 (chain->dev->quirks & UVC_QUIRK_IGNORE_SELECTOR_UNIT)) {
637 if (index != 0) 621 if (index != 0)
638 return -EINVAL; 622 return -EINVAL;
639 iterm = list_first_entry(&chain->iterms, 623 list_for_each_entry(iterm, &chain->entities, chain) {
640 struct uvc_entity, chain); 624 if (UVC_ENTITY_IS_ITERM(iterm))
625 break;
626 }
641 pin = iterm->id; 627 pin = iterm->id;
642 } else if (pin < selector->selector.bNrInPins) { 628 } else if (pin < selector->bNrInPins) {
643 pin = selector->selector.baSourceID[index]; 629 pin = selector->baSourceID[index];
644 list_for_each_entry(iterm, chain->iterms.next, chain) { 630 list_for_each_entry(iterm, &chain->entities, chain) {
631 if (!UVC_ENTITY_IS_ITERM(iterm))
632 continue;
645 if (iterm->id == pin) 633 if (iterm->id == pin)
646 break; 634 break;
647 } 635 }
@@ -692,7 +680,7 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
692 break; 680 break;
693 } 681 }
694 682
695 if (input == 0 || input > chain->selector->selector.bNrInPins) 683 if (input == 0 || input > chain->selector->bNrInPins)
696 return -EINVAL; 684 return -EINVAL;
697 685
698 return uvc_query_ctrl(chain->dev, UVC_SET_CUR, 686 return uvc_query_ctrl(chain->dev, UVC_SET_CUR,
@@ -731,9 +719,6 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
731 { 719 {
732 struct uvc_streaming_control probe; 720 struct uvc_streaming_control probe;
733 721
734 if ((ret = uvc_acquire_privileges(handle)) < 0)
735 return ret;
736
737 return uvc_v4l2_try_format(stream, arg, &probe, NULL, NULL); 722 return uvc_v4l2_try_format(stream, arg, &probe, NULL, NULL);
738 } 723 }
739 724
@@ -888,6 +873,9 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
888 if (ret < 0) 873 if (ret < 0)
889 return ret; 874 return ret;
890 875
876 if (ret == 0)
877 uvc_dismiss_privileges(handle);
878
891 rb->count = ret; 879 rb->count = ret;
892 ret = 0; 880 ret = 0;
893 break; 881 break;
@@ -1051,7 +1039,7 @@ static ssize_t uvc_v4l2_read(struct file *file, char __user *data,
1051 size_t count, loff_t *ppos) 1039 size_t count, loff_t *ppos)
1052{ 1040{
1053 uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_read: not implemented.\n"); 1041 uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_read: not implemented.\n");
1054 return -ENODEV; 1042 return -EINVAL;
1055} 1043}
1056 1044
1057/* 1045/*
diff --git a/drivers/media/video/uvc/uvc_video.c b/drivers/media/video/uvc/uvc_video.c
index a6e41d12b221..05139a4f14f6 100644
--- a/drivers/media/video/uvc/uvc_video.c
+++ b/drivers/media/video/uvc/uvc_video.c
@@ -135,7 +135,7 @@ static int uvc_get_video_ctrl(struct uvc_streaming *stream,
135 135
136 ret = __uvc_query_ctrl(stream->dev, query, 0, stream->intfnum, 136 ret = __uvc_query_ctrl(stream->dev, query, 0, stream->intfnum,
137 probe ? UVC_VS_PROBE_CONTROL : UVC_VS_COMMIT_CONTROL, data, 137 probe ? UVC_VS_PROBE_CONTROL : UVC_VS_COMMIT_CONTROL, data,
138 size, UVC_CTRL_STREAMING_TIMEOUT); 138 size, uvc_timeout_param);
139 139
140 if ((query == UVC_GET_MIN || query == UVC_GET_MAX) && ret == 2) { 140 if ((query == UVC_GET_MIN || query == UVC_GET_MAX) && ret == 2) {
141 /* Some cameras, mostly based on Bison Electronics chipsets, 141 /* Some cameras, mostly based on Bison Electronics chipsets,
@@ -239,7 +239,7 @@ static int uvc_set_video_ctrl(struct uvc_streaming *stream,
239 239
240 ret = __uvc_query_ctrl(stream->dev, UVC_SET_CUR, 0, stream->intfnum, 240 ret = __uvc_query_ctrl(stream->dev, UVC_SET_CUR, 0, stream->intfnum,
241 probe ? UVC_VS_PROBE_CONTROL : UVC_VS_COMMIT_CONTROL, data, 241 probe ? UVC_VS_PROBE_CONTROL : UVC_VS_COMMIT_CONTROL, data,
242 size, UVC_CTRL_STREAMING_TIMEOUT); 242 size, uvc_timeout_param);
243 if (ret != size) { 243 if (ret != size) {
244 uvc_printk(KERN_ERR, "Failed to set UVC %s control : " 244 uvc_printk(KERN_ERR, "Failed to set UVC %s control : "
245 "%d (exp. %u).\n", probe ? "probe" : "commit", 245 "%d (exp. %u).\n", probe ? "probe" : "commit",
@@ -770,8 +770,9 @@ static int uvc_alloc_urb_buffers(struct uvc_streaming *stream,
770 /* Retry allocations until one succeed. */ 770 /* Retry allocations until one succeed. */
771 for (; npackets > 1; npackets /= 2) { 771 for (; npackets > 1; npackets /= 2) {
772 for (i = 0; i < UVC_URBS; ++i) { 772 for (i = 0; i < UVC_URBS; ++i) {
773 stream->urb_size = psize * npackets;
773 stream->urb_buffer[i] = usb_buffer_alloc( 774 stream->urb_buffer[i] = usb_buffer_alloc(
774 stream->dev->udev, psize * npackets, 775 stream->dev->udev, stream->urb_size,
775 gfp_flags | __GFP_NOWARN, &stream->urb_dma[i]); 776 gfp_flags | __GFP_NOWARN, &stream->urb_dma[i]);
776 if (!stream->urb_buffer[i]) { 777 if (!stream->urb_buffer[i]) {
777 uvc_free_urb_buffers(stream); 778 uvc_free_urb_buffers(stream);
@@ -780,11 +781,15 @@ static int uvc_alloc_urb_buffers(struct uvc_streaming *stream,
780 } 781 }
781 782
782 if (i == UVC_URBS) { 783 if (i == UVC_URBS) {
783 stream->urb_size = psize * npackets; 784 uvc_trace(UVC_TRACE_VIDEO, "Allocated %u URB buffers "
785 "of %ux%u bytes each.\n", UVC_URBS, npackets,
786 psize);
784 return npackets; 787 return npackets;
785 } 788 }
786 } 789 }
787 790
791 uvc_trace(UVC_TRACE_VIDEO, "Failed to allocate URB buffers (%u bytes "
792 "per packet).\n", psize);
788 return 0; 793 return 0;
789} 794}
790 795
@@ -935,10 +940,12 @@ static int uvc_init_video(struct uvc_streaming *stream, gfp_t gfp_flags)
935 bandwidth = stream->ctrl.dwMaxPayloadTransferSize; 940 bandwidth = stream->ctrl.dwMaxPayloadTransferSize;
936 941
937 if (bandwidth == 0) { 942 if (bandwidth == 0) {
938 uvc_printk(KERN_WARNING, "device %s requested null " 943 uvc_trace(UVC_TRACE_VIDEO, "Device requested null "
939 "bandwidth, defaulting to lowest.\n", 944 "bandwidth, defaulting to lowest.\n");
940 stream->dev->name);
941 bandwidth = 1; 945 bandwidth = 1;
946 } else {
947 uvc_trace(UVC_TRACE_VIDEO, "Device requested %u "
948 "B/frame bandwidth.\n", bandwidth);
942 } 949 }
943 950
944 for (i = 0; i < intf->num_altsetting; ++i) { 951 for (i = 0; i < intf->num_altsetting; ++i) {
@@ -955,8 +962,11 @@ static int uvc_init_video(struct uvc_streaming *stream, gfp_t gfp_flags)
955 break; 962 break;
956 } 963 }
957 964
958 if (i >= intf->num_altsetting) 965 if (i >= intf->num_altsetting) {
966 uvc_trace(UVC_TRACE_VIDEO, "No fast enough alt setting "
967 "for requested bandwidth.\n");
959 return -EIO; 968 return -EIO;
969 }
960 970
961 ret = usb_set_interface(stream->dev->udev, intfnum, i); 971 ret = usb_set_interface(stream->dev->udev, intfnum, i);
962 if (ret < 0) 972 if (ret < 0)
diff --git a/drivers/media/video/uvc/uvcvideo.h b/drivers/media/video/uvc/uvcvideo.h
index e7958aa454ce..7ec9a04ced50 100644
--- a/drivers/media/video/uvc/uvcvideo.h
+++ b/drivers/media/video/uvc/uvcvideo.h
@@ -75,6 +75,7 @@ struct uvc_xu_control {
75 75
76#define UVC_TERM_INPUT 0x0000 76#define UVC_TERM_INPUT 0x0000
77#define UVC_TERM_OUTPUT 0x8000 77#define UVC_TERM_OUTPUT 0x8000
78#define UVC_TERM_DIRECTION(term) ((term)->type & 0x8000)
78 79
79#define UVC_ENTITY_TYPE(entity) ((entity)->type & 0x7fff) 80#define UVC_ENTITY_TYPE(entity) ((entity)->type & 0x7fff)
80#define UVC_ENTITY_IS_UNIT(entity) (((entity)->type & 0xff00) == 0) 81#define UVC_ENTITY_IS_UNIT(entity) (((entity)->type & 0xff00) == 0)
@@ -148,7 +149,7 @@ struct uvc_xu_control {
148#define UVC_MAX_STATUS_SIZE 16 149#define UVC_MAX_STATUS_SIZE 16
149 150
150#define UVC_CTRL_CONTROL_TIMEOUT 300 151#define UVC_CTRL_CONTROL_TIMEOUT 300
151#define UVC_CTRL_STREAMING_TIMEOUT 1000 152#define UVC_CTRL_STREAMING_TIMEOUT 3000
152 153
153/* Devices quirks */ 154/* Devices quirks */
154#define UVC_QUIRK_STATUS_INTERVAL 0x00000001 155#define UVC_QUIRK_STATUS_INTERVAL 0x00000001
@@ -292,11 +293,9 @@ struct uvc_entity {
292 } media; 293 } media;
293 294
294 struct { 295 struct {
295 __u8 bSourceID;
296 } output; 296 } output;
297 297
298 struct { 298 struct {
299 __u8 bSourceID;
300 __u16 wMaxMultiplier; 299 __u16 wMaxMultiplier;
301 __u8 bControlSize; 300 __u8 bControlSize;
302 __u8 *bmControls; 301 __u8 *bmControls;
@@ -304,21 +303,20 @@ struct uvc_entity {
304 } processing; 303 } processing;
305 304
306 struct { 305 struct {
307 __u8 bNrInPins;
308 __u8 *baSourceID;
309 } selector; 306 } selector;
310 307
311 struct { 308 struct {
312 __u8 guidExtensionCode[16]; 309 __u8 guidExtensionCode[16];
313 __u8 bNumControls; 310 __u8 bNumControls;
314 __u8 bNrInPins;
315 __u8 *baSourceID;
316 __u8 bControlSize; 311 __u8 bControlSize;
317 __u8 *bmControls; 312 __u8 *bmControls;
318 __u8 *bmControlsType; 313 __u8 *bmControlsType;
319 } extension; 314 } extension;
320 }; 315 };
321 316
317 __u8 bNrInPins;
318 __u8 *baSourceID;
319
322 unsigned int ncontrols; 320 unsigned int ncontrols;
323 struct uvc_control *controls; 321 struct uvc_control *controls;
324}; 322};
@@ -408,11 +406,9 @@ struct uvc_video_chain {
408 struct uvc_device *dev; 406 struct uvc_device *dev;
409 struct list_head list; 407 struct list_head list;
410 408
411 struct list_head iterms; /* Input terminals */ 409 struct list_head entities; /* All entities */
412 struct list_head oterms; /* Output terminals */
413 struct uvc_entity *processing; /* Processing unit */ 410 struct uvc_entity *processing; /* Processing unit */
414 struct uvc_entity *selector; /* Selector unit */ 411 struct uvc_entity *selector; /* Selector unit */
415 struct list_head extensions; /* Extension units */
416 412
417 struct mutex ctrl_mutex; 413 struct mutex ctrl_mutex;
418}; 414};
@@ -475,7 +471,6 @@ struct uvc_device {
475 char name[32]; 471 char name[32];
476 472
477 enum uvc_device_state state; 473 enum uvc_device_state state;
478 struct kref kref;
479 struct list_head list; 474 struct list_head list;
480 atomic_t users; 475 atomic_t users;
481 476
@@ -488,6 +483,7 @@ struct uvc_device {
488 483
489 /* Video Streaming interfaces */ 484 /* Video Streaming interfaces */
490 struct list_head streams; 485 struct list_head streams;
486 atomic_t nstreams;
491 487
492 /* Status Interrupt Endpoint */ 488 /* Status Interrupt Endpoint */
493 struct usb_host_endpoint *int_ep; 489 struct usb_host_endpoint *int_ep;
@@ -511,8 +507,6 @@ struct uvc_fh {
511struct uvc_driver { 507struct uvc_driver {
512 struct usb_driver driver; 508 struct usb_driver driver;
513 509
514 struct mutex open_mutex; /* protects from open/disconnect race */
515
516 struct list_head devices; /* struct uvc_device list */ 510 struct list_head devices; /* struct uvc_device list */
517 struct list_head controls; /* struct uvc_control_info list */ 511 struct list_head controls; /* struct uvc_control_info list */
518 struct mutex ctrl_mutex; /* protects controls and devices 512 struct mutex ctrl_mutex; /* protects controls and devices
@@ -533,12 +527,14 @@ struct uvc_driver {
533#define UVC_TRACE_FRAME (1 << 7) 527#define UVC_TRACE_FRAME (1 << 7)
534#define UVC_TRACE_SUSPEND (1 << 8) 528#define UVC_TRACE_SUSPEND (1 << 8)
535#define UVC_TRACE_STATUS (1 << 9) 529#define UVC_TRACE_STATUS (1 << 9)
530#define UVC_TRACE_VIDEO (1 << 10)
536 531
537#define UVC_WARN_MINMAX 0 532#define UVC_WARN_MINMAX 0
538#define UVC_WARN_PROBE_DEF 1 533#define UVC_WARN_PROBE_DEF 1
539 534
540extern unsigned int uvc_no_drop_param; 535extern unsigned int uvc_no_drop_param;
541extern unsigned int uvc_trace_param; 536extern unsigned int uvc_trace_param;
537extern unsigned int uvc_timeout_param;
542 538
543#define uvc_trace(flag, msg...) \ 539#define uvc_trace(flag, msg...) \
544 do { \ 540 do { \
@@ -571,7 +567,6 @@ extern unsigned int uvc_trace_param;
571 567
572/* Core driver */ 568/* Core driver */
573extern struct uvc_driver uvc_driver; 569extern struct uvc_driver uvc_driver;
574extern void uvc_delete(struct kref *kref);
575 570
576/* Video buffers queue management. */ 571/* Video buffers queue management. */
577extern void uvc_queue_init(struct uvc_video_queue *queue, 572extern void uvc_queue_init(struct uvc_video_queue *queue,
diff --git a/drivers/media/video/v4l2-common.c b/drivers/media/video/v4l2-common.c
index f5a93ae3cdf9..e8e5affbabce 100644
--- a/drivers/media/video/v4l2-common.c
+++ b/drivers/media/video/v4l2-common.c
@@ -431,6 +431,8 @@ const char *v4l2_ctrl_get_name(u32 id)
431 case V4L2_CID_CHROMA_AGC: return "Chroma AGC"; 431 case V4L2_CID_CHROMA_AGC: return "Chroma AGC";
432 case V4L2_CID_COLOR_KILLER: return "Color Killer"; 432 case V4L2_CID_COLOR_KILLER: return "Color Killer";
433 case V4L2_CID_COLORFX: return "Color Effects"; 433 case V4L2_CID_COLORFX: return "Color Effects";
434 case V4L2_CID_ROTATE: return "Rotate";
435 case V4L2_CID_BG_COLOR: return "Background color";
434 436
435 /* MPEG controls */ 437 /* MPEG controls */
436 case V4L2_CID_MPEG_CLASS: return "MPEG Encoder Controls"; 438 case V4L2_CID_MPEG_CLASS: return "MPEG Encoder Controls";
@@ -587,6 +589,13 @@ int v4l2_ctrl_query_fill(struct v4l2_queryctrl *qctrl, s32 min, s32 max, s32 ste
587 qctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY; 589 qctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
588 min = max = step = def = 0; 590 min = max = step = def = 0;
589 break; 591 break;
592 case V4L2_CID_BG_COLOR:
593 qctrl->type = V4L2_CTRL_TYPE_INTEGER;
594 step = 1;
595 min = 0;
596 /* Max is calculated as RGB888 that is 2^24 */
597 max = 0xFFFFFF;
598 break;
590 default: 599 default:
591 qctrl->type = V4L2_CTRL_TYPE_INTEGER; 600 qctrl->type = V4L2_CTRL_TYPE_INTEGER;
592 break; 601 break;
diff --git a/drivers/media/video/videobuf-core.c b/drivers/media/video/videobuf-core.c
index 8e93c6f25c83..bb0a1c8de414 100644
--- a/drivers/media/video/videobuf-core.c
+++ b/drivers/media/video/videobuf-core.c
@@ -110,7 +110,7 @@ EXPORT_SYMBOL_GPL(videobuf_queue_to_vmalloc);
110 110
111 111
112void videobuf_queue_core_init(struct videobuf_queue *q, 112void videobuf_queue_core_init(struct videobuf_queue *q,
113 struct videobuf_queue_ops *ops, 113 const struct videobuf_queue_ops *ops,
114 struct device *dev, 114 struct device *dev,
115 spinlock_t *irqlock, 115 spinlock_t *irqlock,
116 enum v4l2_buf_type type, 116 enum v4l2_buf_type type,
@@ -360,7 +360,7 @@ int __videobuf_mmap_setup(struct videobuf_queue *q,
360 q->bufs[i]->bsize = bsize; 360 q->bufs[i]->bsize = bsize;
361 switch (memory) { 361 switch (memory) {
362 case V4L2_MEMORY_MMAP: 362 case V4L2_MEMORY_MMAP:
363 q->bufs[i]->boff = bsize * i; 363 q->bufs[i]->boff = PAGE_ALIGN(bsize) * i;
364 break; 364 break;
365 case V4L2_MEMORY_USERPTR: 365 case V4L2_MEMORY_USERPTR:
366 case V4L2_MEMORY_OVERLAY: 366 case V4L2_MEMORY_OVERLAY:
@@ -430,9 +430,9 @@ int videobuf_reqbufs(struct videobuf_queue *q,
430 count = VIDEO_MAX_FRAME; 430 count = VIDEO_MAX_FRAME;
431 size = 0; 431 size = 0;
432 q->ops->buf_setup(q, &count, &size); 432 q->ops->buf_setup(q, &count, &size);
433 size = PAGE_ALIGN(size); 433 dprintk(1, "reqbufs: bufs=%d, size=0x%x [%u pages total]\n",
434 dprintk(1, "reqbufs: bufs=%d, size=0x%x [%d pages total]\n", 434 count, size,
435 count, size, (count*size)>>PAGE_SHIFT); 435 (unsigned int)((count*PAGE_ALIGN(size))>>PAGE_SHIFT) );
436 436
437 retval = __videobuf_mmap_setup(q, count, size, req->memory); 437 retval = __videobuf_mmap_setup(q, count, size, req->memory);
438 if (retval < 0) { 438 if (retval < 0) {
@@ -1099,7 +1099,7 @@ int videobuf_cgmbuf(struct videobuf_queue *q,
1099 mbuf->size = 0; 1099 mbuf->size = 0;
1100 for (i = 0; i < mbuf->frames; i++) { 1100 for (i = 0; i < mbuf->frames; i++) {
1101 mbuf->offsets[i] = q->bufs[i]->boff; 1101 mbuf->offsets[i] = q->bufs[i]->boff;
1102 mbuf->size += q->bufs[i]->bsize; 1102 mbuf->size += PAGE_ALIGN(q->bufs[i]->bsize);
1103 } 1103 }
1104 1104
1105 return 0; 1105 return 0;
diff --git a/drivers/media/video/videobuf-dma-contig.c b/drivers/media/video/videobuf-dma-contig.c
index c3065c4bcba9..d25f28461da1 100644
--- a/drivers/media/video/videobuf-dma-contig.c
+++ b/drivers/media/video/videobuf-dma-contig.c
@@ -429,7 +429,7 @@ static struct videobuf_qtype_ops qops = {
429}; 429};
430 430
431void videobuf_queue_dma_contig_init(struct videobuf_queue *q, 431void videobuf_queue_dma_contig_init(struct videobuf_queue *q,
432 struct videobuf_queue_ops *ops, 432 const struct videobuf_queue_ops *ops,
433 struct device *dev, 433 struct device *dev,
434 spinlock_t *irqlock, 434 spinlock_t *irqlock,
435 enum v4l2_buf_type type, 435 enum v4l2_buf_type type,
diff --git a/drivers/media/video/videobuf-dma-sg.c b/drivers/media/video/videobuf-dma-sg.c
index 032ebae0134a..fa78555b118b 100644
--- a/drivers/media/video/videobuf-dma-sg.c
+++ b/drivers/media/video/videobuf-dma-sg.c
@@ -588,7 +588,7 @@ static int __videobuf_mmap_mapper(struct videobuf_queue *q,
588 retval = -EBUSY; 588 retval = -EBUSY;
589 goto done; 589 goto done;
590 } 590 }
591 size += q->bufs[last]->bsize; 591 size += PAGE_ALIGN(q->bufs[last]->bsize);
592 if (size == (vma->vm_end - vma->vm_start)) 592 if (size == (vma->vm_end - vma->vm_start))
593 break; 593 break;
594 } 594 }
@@ -610,7 +610,7 @@ static int __videobuf_mmap_mapper(struct videobuf_queue *q,
610 continue; 610 continue;
611 q->bufs[i]->map = map; 611 q->bufs[i]->map = map;
612 q->bufs[i]->baddr = vma->vm_start + size; 612 q->bufs[i]->baddr = vma->vm_start + size;
613 size += q->bufs[i]->bsize; 613 size += PAGE_ALIGN(q->bufs[i]->bsize);
614 } 614 }
615 615
616 map->count = 1; 616 map->count = 1;
@@ -702,7 +702,7 @@ void *videobuf_sg_alloc(size_t size)
702} 702}
703 703
704void videobuf_queue_sg_init(struct videobuf_queue* q, 704void videobuf_queue_sg_init(struct videobuf_queue* q,
705 struct videobuf_queue_ops *ops, 705 const struct videobuf_queue_ops *ops,
706 struct device *dev, 706 struct device *dev,
707 spinlock_t *irqlock, 707 spinlock_t *irqlock,
708 enum v4l2_buf_type type, 708 enum v4l2_buf_type type,
diff --git a/drivers/media/video/videobuf-dvb.c b/drivers/media/video/videobuf-dvb.c
index 0e7dcba8e4ae..a56cf0d3a6d6 100644
--- a/drivers/media/video/videobuf-dvb.c
+++ b/drivers/media/video/videobuf-dvb.c
@@ -139,7 +139,9 @@ static int videobuf_dvb_register_adapter(struct videobuf_dvb_frontends *fe,
139 struct device *device, 139 struct device *device,
140 char *adapter_name, 140 char *adapter_name,
141 short *adapter_nr, 141 short *adapter_nr,
142 int mfe_shared) 142 int mfe_shared,
143 int (*fe_ioctl_override)(struct dvb_frontend *,
144 unsigned int, void *, unsigned int))
143{ 145{
144 int result; 146 int result;
145 147
@@ -154,6 +156,7 @@ static int videobuf_dvb_register_adapter(struct videobuf_dvb_frontends *fe,
154 } 156 }
155 fe->adapter.priv = adapter_priv; 157 fe->adapter.priv = adapter_priv;
156 fe->adapter.mfe_shared = mfe_shared; 158 fe->adapter.mfe_shared = mfe_shared;
159 fe->adapter.fe_ioctl_override = fe_ioctl_override;
157 160
158 return result; 161 return result;
159} 162}
@@ -253,7 +256,9 @@ int videobuf_dvb_register_bus(struct videobuf_dvb_frontends *f,
253 void *adapter_priv, 256 void *adapter_priv,
254 struct device *device, 257 struct device *device,
255 short *adapter_nr, 258 short *adapter_nr,
256 int mfe_shared) 259 int mfe_shared,
260 int (*fe_ioctl_override)(struct dvb_frontend *,
261 unsigned int, void *, unsigned int))
257{ 262{
258 struct list_head *list, *q; 263 struct list_head *list, *q;
259 struct videobuf_dvb_frontend *fe; 264 struct videobuf_dvb_frontend *fe;
@@ -267,7 +272,7 @@ int videobuf_dvb_register_bus(struct videobuf_dvb_frontends *f,
267 272
268 /* Bring up the adapter */ 273 /* Bring up the adapter */
269 res = videobuf_dvb_register_adapter(f, module, adapter_priv, device, 274 res = videobuf_dvb_register_adapter(f, module, adapter_priv, device,
270 fe->dvb.name, adapter_nr, mfe_shared); 275 fe->dvb.name, adapter_nr, mfe_shared, fe_ioctl_override);
271 if (res < 0) { 276 if (res < 0) {
272 printk(KERN_WARNING "videobuf_dvb_register_adapter failed (errno = %d)\n", res); 277 printk(KERN_WARNING "videobuf_dvb_register_adapter failed (errno = %d)\n", res);
273 return res; 278 return res;
diff --git a/drivers/media/video/videobuf-vmalloc.c b/drivers/media/video/videobuf-vmalloc.c
index 35f3900c5633..d6e6a28fb6b8 100644
--- a/drivers/media/video/videobuf-vmalloc.c
+++ b/drivers/media/video/videobuf-vmalloc.c
@@ -391,8 +391,8 @@ static struct videobuf_qtype_ops qops = {
391}; 391};
392 392
393void videobuf_queue_vmalloc_init(struct videobuf_queue* q, 393void videobuf_queue_vmalloc_init(struct videobuf_queue* q,
394 struct videobuf_queue_ops *ops, 394 const struct videobuf_queue_ops *ops,
395 void *dev, 395 struct device *dev,
396 spinlock_t *irqlock, 396 spinlock_t *irqlock,
397 enum v4l2_buf_type type, 397 enum v4l2_buf_type type,
398 enum v4l2_field field, 398 enum v4l2_field field,
diff --git a/drivers/media/video/vpx3220.c b/drivers/media/video/vpx3220.c
index 97e0ce28ff18..33205d7537d8 100644
--- a/drivers/media/video/vpx3220.c
+++ b/drivers/media/video/vpx3220.c
@@ -391,7 +391,7 @@ static int vpx3220_s_routing(struct v4l2_subdev *sd,
391 {0x0e, 1} 391 {0x0e, 1}
392 }; 392 };
393 393
394 if (input < 0 || input > 2) 394 if (input > 2)
395 return -EINVAL; 395 return -EINVAL;
396 396
397 v4l2_dbg(1, debug, sd, "input switched to %s\n", inputs[input]); 397 v4l2_dbg(1, debug, sd, "input switched to %s\n", inputs[input]);
diff --git a/drivers/media/video/zoran/zoran_driver.c b/drivers/media/video/zoran/zoran_driver.c
index 47137deafcfd..e9f72ca458f1 100644
--- a/drivers/media/video/zoran/zoran_driver.c
+++ b/drivers/media/video/zoran/zoran_driver.c
@@ -2764,7 +2764,7 @@ static int zoran_enum_input(struct file *file, void *__fh,
2764 struct zoran_fh *fh = __fh; 2764 struct zoran_fh *fh = __fh;
2765 struct zoran *zr = fh->zr; 2765 struct zoran *zr = fh->zr;
2766 2766
2767 if (inp->index < 0 || inp->index >= zr->card.inputs) 2767 if (inp->index >= zr->card.inputs)
2768 return -EINVAL; 2768 return -EINVAL;
2769 else { 2769 else {
2770 int id = inp->index; 2770 int id = inp->index;
diff --git a/drivers/media/video/zr364xx.c b/drivers/media/video/zr364xx.c
index 9aae011d92ab..2ef110b5221b 100644
--- a/drivers/media/video/zr364xx.c
+++ b/drivers/media/video/zr364xx.c
@@ -115,6 +115,7 @@ static struct usb_device_id device_table[] = {
115 {USB_DEVICE(0x0a17, 0x004e), .driver_info = METHOD2 }, 115 {USB_DEVICE(0x0a17, 0x004e), .driver_info = METHOD2 },
116 {USB_DEVICE(0x041e, 0x405d), .driver_info = METHOD2 }, 116 {USB_DEVICE(0x041e, 0x405d), .driver_info = METHOD2 },
117 {USB_DEVICE(0x08ca, 0x2102), .driver_info = METHOD2 }, 117 {USB_DEVICE(0x08ca, 0x2102), .driver_info = METHOD2 },
118 {USB_DEVICE(0x06d6, 0x003d), .driver_info = METHOD0 },
118 {} /* Terminating entry */ 119 {} /* Terminating entry */
119}; 120};
120 121