aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-05-24 00:12:49 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-05-24 00:12:49 -0400
commitdf462b3dbeeaae7141f1b63cbfcc1e1bae6a85fc (patch)
treebca52fce066159f136d75c69e79016422212cb1d /drivers/media/video
parent343800e7d20944aead238c2c6e3f7789f8b6587c (diff)
parentcf25220677b3f10468a74278130fe224f73632a6 (diff)
Merge branch 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6
* 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6: (247 commits) [media] gspca - sunplus: Fix some warnings and simplify code [media] gspca: Fix some warnings tied to 'no debug' [media] gspca: Unset debug by default [media] gspca - cpia1: Remove a bad conditional compilation instruction [media] gspca - main: Remove USB traces [media] gspca - main: Version change to 2.13 [media] gspca - stk014 / t613: Accept the index 0 in querymenu [media] gspca - kinect: Remove __devinitdata [media] gspca - cpia1: Fix some warnings [media] video/Kconfig: Fix mis-classified devices [media] support for medion dvb stick 1660:1921 [media] tm6000: fix uninitialized field, change prink to dprintk [media] cx231xx: Add support for Iconbit U100 [media] saa7134 add new TV cards [media] Use a more consistent value for RC repeat period [media] cx18: Move spinlock and vb_type initialisation into stream_init [media] tm6000: remove tm6010 sif audio start and stop [media] tm6000: remove unused exports [media] tm6000: add pts logging [media] tm6000: change from ioctl to unlocked_ioctl ...
Diffstat (limited to 'drivers/media/video')
-rw-r--r--drivers/media/video/Kconfig149
-rw-r--r--drivers/media/video/Makefile2
-rw-r--r--drivers/media/video/bt8xx/bttv-driver.c2
-rw-r--r--drivers/media/video/cpia2/cpia2_v4l.c2
-rw-r--r--drivers/media/video/cx18/Kconfig4
-rw-r--r--drivers/media/video/cx18/cx18-cards.c18
-rw-r--r--drivers/media/video/cx18/cx18-cards.h2
-rw-r--r--drivers/media/video/cx18/cx18-driver.c27
-rw-r--r--drivers/media/video/cx18/cx18-driver.h25
-rw-r--r--drivers/media/video/cx18/cx18-fileops.c70
-rw-r--r--drivers/media/video/cx18/cx18-fileops.h2
-rw-r--r--drivers/media/video/cx18/cx18-ioctl.c144
-rw-r--r--drivers/media/video/cx18/cx18-mailbox.c58
-rw-r--r--drivers/media/video/cx18/cx18-streams.c177
-rw-r--r--drivers/media/video/cx18/cx18-version.h2
-rw-r--r--drivers/media/video/cx18/cx23418.h6
-rw-r--r--drivers/media/video/cx231xx/cx231xx-cards.c67
-rw-r--r--drivers/media/video/cx231xx/cx231xx-dvb.c1
-rw-r--r--drivers/media/video/cx231xx/cx231xx.h2
-rw-r--r--drivers/media/video/cx23885/cx23885-cards.c1
-rw-r--r--drivers/media/video/cx23885/cx23885-core.c2
-rw-r--r--drivers/media/video/cx88/cx88-blackbird.c41
-rw-r--r--drivers/media/video/cx88/cx88-dvb.c2
-rw-r--r--drivers/media/video/cx88/cx88-mpeg.c42
-rw-r--r--drivers/media/video/cx88/cx88-video.c7
-rw-r--r--drivers/media/video/cx88/cx88.h11
-rw-r--r--drivers/media/video/em28xx/Kconfig2
-rw-r--r--drivers/media/video/em28xx/em28xx-cards.c49
-rw-r--r--drivers/media/video/em28xx/em28xx-core.c9
-rw-r--r--drivers/media/video/em28xx/em28xx-dvb.c160
-rw-r--r--drivers/media/video/em28xx/em28xx-i2c.c2
-rw-r--r--drivers/media/video/em28xx/em28xx-reg.h1
-rw-r--r--drivers/media/video/em28xx/em28xx.h3
-rw-r--r--drivers/media/video/fsl-viu.c56
-rw-r--r--drivers/media/video/gspca/Kconfig9
-rw-r--r--drivers/media/video/gspca/Makefile2
-rw-r--r--drivers/media/video/gspca/cpia1.c6
-rw-r--r--drivers/media/video/gspca/gl860/gl860.c15
-rw-r--r--drivers/media/video/gspca/gspca.c4
-rw-r--r--drivers/media/video/gspca/gspca.h6
-rw-r--r--drivers/media/video/gspca/jeilinj.c581
-rw-r--r--drivers/media/video/gspca/kinect.c429
-rw-r--r--drivers/media/video/gspca/spca508.c5
-rw-r--r--drivers/media/video/gspca/stk014.c15
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx_pb0100.c2
-rw-r--r--drivers/media/video/gspca/sunplus.c99
-rw-r--r--drivers/media/video/gspca/t613.c17
-rw-r--r--drivers/media/video/gspca/zc3xx.c47
-rw-r--r--drivers/media/video/ivtv/ivtv-driver.c4
-rw-r--r--drivers/media/video/mt9m111.c14
-rw-r--r--drivers/media/video/mt9v022.c2
-rw-r--r--drivers/media/video/mt9v032.c773
-rw-r--r--drivers/media/video/mx3_camera.c60
-rw-r--r--drivers/media/video/omap1_camera.c43
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-std.c10
-rw-r--r--drivers/media/video/pwc/pwc-if.c2
-rw-r--r--drivers/media/video/pwc/pwc-v4l.c23
-rw-r--r--drivers/media/video/pxa_camera.c8
-rw-r--r--drivers/media/video/s2255drv.c27
-rw-r--r--drivers/media/video/s5p-fimc/Makefile6
-rw-r--r--drivers/media/video/s5p-fimc/mipi-csis.c724
-rw-r--r--drivers/media/video/s5p-fimc/mipi-csis.h22
-rw-r--r--drivers/media/video/saa7134/saa7134-cards.c125
-rw-r--r--drivers/media/video/saa7134/saa7134-core.c2
-rw-r--r--drivers/media/video/saa7134/saa7134-dvb.c34
-rw-r--r--drivers/media/video/saa7134/saa7134-input.c8
-rw-r--r--drivers/media/video/saa7134/saa7134.h3
-rw-r--r--drivers/media/video/saa7164/saa7164-core.c2
-rw-r--r--drivers/media/video/sh_mobile_ceu_camera.c148
-rw-r--r--drivers/media/video/soc_camera.c29
-rw-r--r--drivers/media/video/soc_mediabus.c265
-rw-r--r--drivers/media/video/tveeprom.c32
-rw-r--r--drivers/media/video/usbvision/usbvision-cards.c33
-rw-r--r--drivers/media/video/usbvision/usbvision-cards.h2
-rw-r--r--drivers/media/video/usbvision/usbvision-core.c165
-rw-r--r--drivers/media/video/usbvision/usbvision-i2c.c2
-rw-r--r--drivers/media/video/usbvision/usbvision-video.c3
-rw-r--r--drivers/media/video/usbvision/usbvision.h6
-rw-r--r--drivers/media/video/uvc/uvc_ctrl.c367
-rw-r--r--drivers/media/video/uvc/uvc_driver.c28
-rw-r--r--drivers/media/video/uvc/uvc_queue.c34
-rw-r--r--drivers/media/video/uvc/uvc_v4l2.c68
-rw-r--r--drivers/media/video/uvc/uvcvideo.h64
-rw-r--r--drivers/media/video/v4l2-dev.c18
-rw-r--r--drivers/media/video/via-camera.c1
-rw-r--r--drivers/media/video/zoran/zoran_card.c10
86 files changed, 4649 insertions, 903 deletions
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index 00f51dd121f3..3be180b3ba27 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -128,10 +128,10 @@ config VIDEO_IR_I2C
128# Encoder / Decoder module configuration 128# Encoder / Decoder module configuration
129# 129#
130 130
131menu "Encoders/decoders and other helper chips" 131menu "Encoders, decoders, sensors and other helper chips"
132 visible if !VIDEO_HELPER_CHIPS_AUTO 132 visible if !VIDEO_HELPER_CHIPS_AUTO
133 133
134comment "Audio decoders" 134comment "Audio decoders, processors and mixers"
135 135
136config VIDEO_TVAUDIO 136config VIDEO_TVAUDIO
137 tristate "Simple audio decoder chips" 137 tristate "Simple audio decoder chips"
@@ -210,15 +210,6 @@ config VIDEO_CS53L32A
210 To compile this driver as a module, choose M here: the 210 To compile this driver as a module, choose M here: the
211 module will be called cs53l32a. 211 module will be called cs53l32a.
212 212
213config VIDEO_M52790
214 tristate "Mitsubishi M52790 A/V switch"
215 depends on VIDEO_V4L2 && I2C
216 ---help---
217 Support for the Mitsubishi M52790 A/V switch.
218
219 To compile this driver as a module, choose M here: the
220 module will be called m52790.
221
222config VIDEO_TLV320AIC23B 213config VIDEO_TLV320AIC23B
223 tristate "Texas Instruments TLV320AIC23B audio codec" 214 tristate "Texas Instruments TLV320AIC23B audio codec"
224 depends on VIDEO_V4L2 && I2C && EXPERIMENTAL 215 depends on VIDEO_V4L2 && I2C && EXPERIMENTAL
@@ -321,29 +312,6 @@ config VIDEO_KS0127
321 To compile this driver as a module, choose M here: the 312 To compile this driver as a module, choose M here: the
322 module will be called ks0127. 313 module will be called ks0127.
323 314
324config VIDEO_OV7670
325 tristate "OmniVision OV7670 sensor support"
326 depends on I2C && VIDEO_V4L2
327 ---help---
328 This is a Video4Linux2 sensor-level driver for the OmniVision
329 OV7670 VGA camera. It currently only works with the M88ALP01
330 controller.
331
332config VIDEO_MT9V011
333 tristate "Micron mt9v011 sensor support"
334 depends on I2C && VIDEO_V4L2
335 ---help---
336 This is a Video4Linux2 sensor-level driver for the Micron
337 mt0v011 1.3 Mpixel camera. It currently only works with the
338 em28xx driver.
339
340config VIDEO_TCM825X
341 tristate "TCM825x camera sensor support"
342 depends on I2C && VIDEO_V4L2
343 ---help---
344 This is a driver for the Toshiba TCM825x VGA camera sensor.
345 It is used for example in Nokia N800.
346
347config VIDEO_SAA7110 315config VIDEO_SAA7110
348 tristate "Philips SAA7110 video decoder" 316 tristate "Philips SAA7110 video decoder"
349 depends on VIDEO_V4L2 && I2C 317 depends on VIDEO_V4L2 && I2C
@@ -362,15 +330,6 @@ config VIDEO_SAA711X
362 To compile this driver as a module, choose M here: the 330 To compile this driver as a module, choose M here: the
363 module will be called saa7115. 331 module will be called saa7115.
364 332
365config VIDEO_SAA717X
366 tristate "Philips SAA7171/3/4 audio/video decoders"
367 depends on VIDEO_V4L2 && I2C
368 ---help---
369 Support for the Philips SAA7171/3/4 audio/video decoders.
370
371 To compile this driver as a module, choose M here: the
372 module will be called saa717x.
373
374config VIDEO_SAA7191 333config VIDEO_SAA7191
375 tristate "Philips SAA7191 video decoder" 334 tristate "Philips SAA7191 video decoder"
376 depends on VIDEO_V4L2 && I2C 335 depends on VIDEO_V4L2 && I2C
@@ -420,6 +379,15 @@ config VIDEO_VPX3220
420 379
421comment "Video and audio decoders" 380comment "Video and audio decoders"
422 381
382config VIDEO_SAA717X
383 tristate "Philips SAA7171/3/4 audio/video decoders"
384 depends on VIDEO_V4L2 && I2C
385 ---help---
386 Support for the Philips SAA7171/3/4 audio/video decoders.
387
388 To compile this driver as a module, choose M here: the
389 module will be called saa717x.
390
423source "drivers/media/video/cx25840/Kconfig" 391source "drivers/media/video/cx25840/Kconfig"
424 392
425comment "MPEG video encoders" 393comment "MPEG video encoders"
@@ -474,15 +442,6 @@ config VIDEO_ADV7175
474 To compile this driver as a module, choose M here: the 442 To compile this driver as a module, choose M here: the
475 module will be called adv7175. 443 module will be called adv7175.
476 444
477config VIDEO_THS7303
478 tristate "THS7303 Video Amplifier"
479 depends on I2C
480 help
481 Support for TI THS7303 video amplifier
482
483 To compile this driver as a module, choose M here: the
484 module will be called ths7303.
485
486config VIDEO_ADV7343 445config VIDEO_ADV7343
487 tristate "ADV7343 video encoder" 446 tristate "ADV7343 video encoder"
488 depends on I2C 447 depends on I2C
@@ -498,6 +457,38 @@ config VIDEO_AK881X
498 help 457 help
499 Video output driver for AKM AK8813 and AK8814 TV encoders 458 Video output driver for AKM AK8813 and AK8814 TV encoders
500 459
460comment "Camera sensor devices"
461
462config VIDEO_OV7670
463 tristate "OmniVision OV7670 sensor support"
464 depends on I2C && VIDEO_V4L2
465 ---help---
466 This is a Video4Linux2 sensor-level driver for the OmniVision
467 OV7670 VGA camera. It currently only works with the M88ALP01
468 controller.
469
470config VIDEO_MT9V011
471 tristate "Micron mt9v011 sensor support"
472 depends on I2C && VIDEO_V4L2
473 ---help---
474 This is a Video4Linux2 sensor-level driver for the Micron
475 mt0v011 1.3 Mpixel camera. It currently only works with the
476 em28xx driver.
477
478config VIDEO_MT9V032
479 tristate "Micron MT9V032 sensor support"
480 depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
481 ---help---
482 This is a Video4Linux2 sensor-level driver for the Micron
483 MT9V032 752x480 CMOS sensor.
484
485config VIDEO_TCM825X
486 tristate "TCM825x camera sensor support"
487 depends on I2C && VIDEO_V4L2
488 ---help---
489 This is a driver for the Toshiba TCM825x VGA camera sensor.
490 It is used for example in Nokia N800.
491
501comment "Video improvement chips" 492comment "Video improvement chips"
502 493
503config VIDEO_UPD64031A 494config VIDEO_UPD64031A
@@ -523,6 +514,26 @@ config VIDEO_UPD64083
523 To compile this driver as a module, choose M here: the 514 To compile this driver as a module, choose M here: the
524 module will be called upd64083. 515 module will be called upd64083.
525 516
517comment "Miscelaneous helper chips"
518
519config VIDEO_THS7303
520 tristate "THS7303 Video Amplifier"
521 depends on I2C
522 help
523 Support for TI THS7303 video amplifier
524
525 To compile this driver as a module, choose M here: the
526 module will be called ths7303.
527
528config VIDEO_M52790
529 tristate "Mitsubishi M52790 A/V switch"
530 depends on VIDEO_V4L2 && I2C
531 ---help---
532 Support for the Mitsubishi M52790 A/V switch.
533
534 To compile this driver as a module, choose M here: the
535 module will be called m52790.
536
526endmenu # encoder / decoder chips 537endmenu # encoder / decoder chips
527 538
528config VIDEO_SH_VOU 539config VIDEO_SH_VOU
@@ -682,7 +693,7 @@ config VIDEO_TIMBERDALE
682 select VIDEO_ADV7180 693 select VIDEO_ADV7180
683 select VIDEOBUF_DMA_CONTIG 694 select VIDEOBUF_DMA_CONTIG
684 ---help--- 695 ---help---
685 Add support for the Video In peripherial of the timberdale FPGA. 696 Add support for the Video In peripherial of the timberdale FPGA.
686 697
687source "drivers/media/video/cx88/Kconfig" 698source "drivers/media/video/cx88/Kconfig"
688 699
@@ -916,7 +927,7 @@ config VIDEO_OMAP2
916 This is a v4l2 driver for the TI OMAP2 camera capture interface 927 This is a v4l2 driver for the TI OMAP2 camera capture interface
917 928
918config VIDEO_MX2_HOSTSUPPORT 929config VIDEO_MX2_HOSTSUPPORT
919 bool 930 bool
920 931
921config VIDEO_MX2 932config VIDEO_MX2
922 tristate "i.MX27/i.MX25 Camera Sensor Interface driver" 933 tristate "i.MX27/i.MX25 Camera Sensor Interface driver"
@@ -927,6 +938,26 @@ config VIDEO_MX2
927 This is a v4l2 driver for the i.MX27 and the i.MX25 Camera Sensor 938 This is a v4l2 driver for the i.MX27 and the i.MX25 Camera Sensor
928 Interface 939 Interface
929 940
941config VIDEO_SAMSUNG_S5P_FIMC
942 tristate "Samsung S5P and EXYNOS4 camera host interface driver"
943 depends on VIDEO_DEV && VIDEO_V4L2 && PLAT_S5P
944 select VIDEOBUF2_DMA_CONTIG
945 select V4L2_MEM2MEM_DEV
946 ---help---
947 This is a v4l2 driver for Samsung S5P and EXYNOS4 camera
948 host interface and video postprocessor.
949
950 To compile this driver as a module, choose M here: the
951 module will be called s5p-fimc.
952
953config VIDEO_S5P_MIPI_CSIS
954 tristate "Samsung S5P and EXYNOS4 MIPI CSI receiver driver"
955 depends on VIDEO_V4L2 && PM_RUNTIME && VIDEO_V4L2_SUBDEV_API
956 ---help---
957 This is a v4l2 driver for Samsung S5P/EXYNOS4 MIPI-CSI receiver.
958
959 To compile this driver as a module, choose M here: the
960 module will be called s5p-csis.
930 961
931# 962#
932# USB Multimedia device configuration 963# USB Multimedia device configuration
@@ -983,7 +1014,7 @@ config USB_STKWEBCAM
983 Supported devices are typically found in some Asus laptops, 1014 Supported devices are typically found in some Asus laptops,
984 with USB id 174f:a311 and 05e1:0501. Other Syntek cameras 1015 with USB id 174f:a311 and 05e1:0501. Other Syntek cameras
985 may be supported by the stk11xx driver, from which this is 1016 may be supported by the stk11xx driver, from which this is
986 derived, see <http://sourceforge.net/projects/syntekdriver/> 1017 derived, see <http://sourceforge.net/projects/syntekdriver/>
987 1018
988 To compile this driver as a module, choose M here: the 1019 To compile this driver as a module, choose M here: the
989 module will be called stkwebcam. 1020 module will be called stkwebcam.
@@ -1022,13 +1053,5 @@ config VIDEO_MEM2MEM_TESTDEV
1022 This is a virtual test device for the memory-to-memory driver 1053 This is a virtual test device for the memory-to-memory driver
1023 framework. 1054 framework.
1024 1055
1025config VIDEO_SAMSUNG_S5P_FIMC
1026 tristate "Samsung S5P FIMC (video postprocessor) driver"
1027 depends on VIDEO_DEV && VIDEO_V4L2 && PLAT_S5P
1028 select VIDEOBUF2_DMA_CONTIG
1029 select V4L2_MEM2MEM_DEV
1030 help
1031 This is a v4l2 driver for the S5P camera interface
1032 (video postprocessor)
1033 1056
1034endif # V4L_MEM2MEM_DRIVERS 1057endif # V4L_MEM2MEM_DRIVERS
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile
index ace5d8b57221..9519160c2e01 100644
--- a/drivers/media/video/Makefile
+++ b/drivers/media/video/Makefile
@@ -66,6 +66,7 @@ obj-$(CONFIG_VIDEO_OV7670) += ov7670.o
66obj-$(CONFIG_VIDEO_TCM825X) += tcm825x.o 66obj-$(CONFIG_VIDEO_TCM825X) += tcm825x.o
67obj-$(CONFIG_VIDEO_TVEEPROM) += tveeprom.o 67obj-$(CONFIG_VIDEO_TVEEPROM) += tveeprom.o
68obj-$(CONFIG_VIDEO_MT9V011) += mt9v011.o 68obj-$(CONFIG_VIDEO_MT9V011) += mt9v011.o
69obj-$(CONFIG_VIDEO_MT9V032) += mt9v032.o
69obj-$(CONFIG_VIDEO_SR030PC30) += sr030pc30.o 70obj-$(CONFIG_VIDEO_SR030PC30) += sr030pc30.o
70obj-$(CONFIG_VIDEO_NOON010PC30) += noon010pc30.o 71obj-$(CONFIG_VIDEO_NOON010PC30) += noon010pc30.o
71 72
@@ -164,6 +165,7 @@ obj-$(CONFIG_VIDEO_PXA27x) += pxa_camera.o
164obj-$(CONFIG_VIDEO_SH_MOBILE_CSI2) += sh_mobile_csi2.o 165obj-$(CONFIG_VIDEO_SH_MOBILE_CSI2) += sh_mobile_csi2.o
165obj-$(CONFIG_VIDEO_SH_MOBILE_CEU) += sh_mobile_ceu_camera.o 166obj-$(CONFIG_VIDEO_SH_MOBILE_CEU) += sh_mobile_ceu_camera.o
166obj-$(CONFIG_VIDEO_OMAP1) += omap1_camera.o 167obj-$(CONFIG_VIDEO_OMAP1) += omap1_camera.o
168
167obj-$(CONFIG_VIDEO_SAMSUNG_S5P_FIMC) += s5p-fimc/ 169obj-$(CONFIG_VIDEO_SAMSUNG_S5P_FIMC) += s5p-fimc/
168 170
169obj-$(CONFIG_ARCH_DAVINCI) += davinci/ 171obj-$(CONFIG_ARCH_DAVINCI) += davinci/
diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c
index 91399c94cd18..a97cf2750bd9 100644
--- a/drivers/media/video/bt8xx/bttv-driver.c
+++ b/drivers/media/video/bt8xx/bttv-driver.c
@@ -4303,7 +4303,7 @@ static int __devinit bttv_probe(struct pci_dev *dev,
4303 goto fail0; 4303 goto fail0;
4304 } 4304 }
4305 4305
4306 pci_read_config_byte(dev, PCI_CLASS_REVISION, &btv->revision); 4306 btv->revision = dev->revision;
4307 pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat); 4307 pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat);
4308 printk(KERN_INFO "bttv%d: Bt%d (rev %d) at %s, ", 4308 printk(KERN_INFO "bttv%d: Bt%d (rev %d) at %s, ",
4309 bttv_num,btv->id, btv->revision, pci_name(dev)); 4309 bttv_num,btv->id, btv->revision, pci_name(dev));
diff --git a/drivers/media/video/cpia2/cpia2_v4l.c b/drivers/media/video/cpia2/cpia2_v4l.c
index 5111bbcefad5..0073a8c55336 100644
--- a/drivers/media/video/cpia2/cpia2_v4l.c
+++ b/drivers/media/video/cpia2/cpia2_v4l.c
@@ -1313,7 +1313,7 @@ static int cpia2_g_priority(struct file *file, void *_fh, enum v4l2_priority *p)
1313static int cpia2_s_priority(struct file *file, void *_fh, enum v4l2_priority prio) 1313static int cpia2_s_priority(struct file *file, void *_fh, enum v4l2_priority prio)
1314{ 1314{
1315 struct camera_data *cam = video_drvdata(file); 1315 struct camera_data *cam = video_drvdata(file);
1316 struct cpia2_fh *fh = fh; 1316 struct cpia2_fh *fh = _fh;
1317 1317
1318 if (cam->streaming && prio != fh->prio && 1318 if (cam->streaming && prio != fh->prio &&
1319 fh->prio == V4L2_PRIORITY_RECORD) 1319 fh->prio == V4L2_PRIORITY_RECORD)
diff --git a/drivers/media/video/cx18/Kconfig b/drivers/media/video/cx18/Kconfig
index d9d2f6ad6ffb..53b3c7702573 100644
--- a/drivers/media/video/cx18/Kconfig
+++ b/drivers/media/video/cx18/Kconfig
@@ -2,6 +2,7 @@ config VIDEO_CX18
2 tristate "Conexant cx23418 MPEG encoder support" 2 tristate "Conexant cx23418 MPEG encoder support"
3 depends on VIDEO_V4L2 && DVB_CORE && PCI && I2C && EXPERIMENTAL 3 depends on VIDEO_V4L2 && DVB_CORE && PCI && I2C && EXPERIMENTAL
4 select I2C_ALGOBIT 4 select I2C_ALGOBIT
5 select VIDEOBUF_VMALLOC
5 depends on RC_CORE 6 depends on RC_CORE
6 select VIDEO_TUNER 7 select VIDEO_TUNER
7 select VIDEO_TVEEPROM 8 select VIDEO_TVEEPROM
@@ -9,6 +10,9 @@ config VIDEO_CX18
9 select VIDEO_CS5345 10 select VIDEO_CS5345
10 select DVB_S5H1409 if !DVB_FE_CUSTOMISE 11 select DVB_S5H1409 if !DVB_FE_CUSTOMISE
11 select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMISE 12 select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMISE
13 select DVB_S5H1411 if !DVB_FE_CUSTOMISE
14 select MEDIA_TUNER_TDA18271 if !MEDIA_TUNER_CUSTOMISE
15 select MEDIA_TUNER_TDA8290 if !MEDIA_TUNER_CUSTOMISE
12 ---help--- 16 ---help---
13 This is a video4linux driver for Conexant cx23418 based 17 This is a video4linux driver for Conexant cx23418 based
14 PCI combo video recorder devices. 18 PCI combo video recorder devices.
diff --git a/drivers/media/video/cx18/cx18-cards.c b/drivers/media/video/cx18/cx18-cards.c
index 68ad1963f421..c07c849b1aaf 100644
--- a/drivers/media/video/cx18/cx18-cards.c
+++ b/drivers/media/video/cx18/cx18-cards.c
@@ -39,6 +39,16 @@ static struct cx18_card_tuner_i2c cx18_i2c_std = {
39 .tv = { 0x61, 0x60, I2C_CLIENT_END }, 39 .tv = { 0x61, 0x60, I2C_CLIENT_END },
40}; 40};
41 41
42/*
43 * usual i2c tuner addresses to probe with additional demod address for
44 * an NXP TDA8295 at 0x42 (N.B. it can possibly be at 0x4b or 0x4c too).
45 */
46static struct cx18_card_tuner_i2c cx18_i2c_nxp = {
47 .radio = { I2C_CLIENT_END },
48 .demod = { 0x42, 0x43, I2C_CLIENT_END },
49 .tv = { 0x61, 0x60, I2C_CLIENT_END },
50};
51
42/* Please add new PCI IDs to: http://pci-ids.ucw.cz/ 52/* Please add new PCI IDs to: http://pci-ids.ucw.cz/
43 This keeps the PCI ID database up to date. Note that the entries 53 This keeps the PCI ID database up to date. Note that the entries
44 must be added under vendor 0x4444 (Conexant) as subsystem IDs. 54 must be added under vendor 0x4444 (Conexant) as subsystem IDs.
@@ -131,15 +141,15 @@ static const struct cx18_card cx18_card_hvr1600_s5h1411 = {
131 .tune_lane = 0, 141 .tune_lane = 0,
132 .initial_emrs = 0, 142 .initial_emrs = 0,
133 }, 143 },
134 .gpio_init.initial_value = 0x3001, 144 .gpio_init.initial_value = 0x3801,
135 .gpio_init.direction = 0x3001, 145 .gpio_init.direction = 0x3801,
136 .gpio_i2c_slave_reset = { 146 .gpio_i2c_slave_reset = {
137 .active_lo_mask = 0x3001, 147 .active_lo_mask = 0x3801,
138 .msecs_asserted = 10, 148 .msecs_asserted = 10,
139 .msecs_recovery = 40, 149 .msecs_recovery = 40,
140 .ir_reset_mask = 0x0001, 150 .ir_reset_mask = 0x0001,
141 }, 151 },
142 .i2c = &cx18_i2c_std, 152 .i2c = &cx18_i2c_nxp,
143}; 153};
144 154
145static const struct cx18_card cx18_card_hvr1600_samsung = { 155static const struct cx18_card cx18_card_hvr1600_samsung = {
diff --git a/drivers/media/video/cx18/cx18-cards.h b/drivers/media/video/cx18/cx18-cards.h
index 3e750068f275..add7391ecaba 100644
--- a/drivers/media/video/cx18/cx18-cards.h
+++ b/drivers/media/video/cx18/cx18-cards.h
@@ -109,7 +109,7 @@ struct cx18_card_tuner {
109 109
110struct cx18_card_tuner_i2c { 110struct cx18_card_tuner_i2c {
111 unsigned short radio[2];/* radio tuner i2c address to probe */ 111 unsigned short radio[2];/* radio tuner i2c address to probe */
112 unsigned short demod[2];/* demodulator i2c address to probe */ 112 unsigned short demod[3];/* demodulator i2c address to probe */
113 unsigned short tv[4]; /* tv tuner i2c addresses to probe */ 113 unsigned short tv[4]; /* tv tuner i2c addresses to probe */
114}; 114};
115 115
diff --git a/drivers/media/video/cx18/cx18-driver.c b/drivers/media/video/cx18/cx18-driver.c
index 321c1b79794c..9e2f870f4258 100644
--- a/drivers/media/video/cx18/cx18-driver.c
+++ b/drivers/media/video/cx18/cx18-driver.c
@@ -423,7 +423,16 @@ static void cx18_process_eeprom(struct cx18 *cx)
423 return; 423 return;
424 424
425 /* autodetect tuner standard */ 425 /* autodetect tuner standard */
426 if (tv.tuner_formats & V4L2_STD_PAL) { 426#define TVEEPROM_TUNER_FORMAT_ALL (V4L2_STD_B | V4L2_STD_GH | \
427 V4L2_STD_MN | \
428 V4L2_STD_PAL_I | \
429 V4L2_STD_SECAM_L | V4L2_STD_SECAM_LC | \
430 V4L2_STD_DK)
431 if ((tv.tuner_formats & TVEEPROM_TUNER_FORMAT_ALL)
432 == TVEEPROM_TUNER_FORMAT_ALL) {
433 CX18_DEBUG_INFO("Worldwide tuner detected\n");
434 cx->std = V4L2_STD_ALL;
435 } else if (tv.tuner_formats & V4L2_STD_PAL) {
427 CX18_DEBUG_INFO("PAL tuner detected\n"); 436 CX18_DEBUG_INFO("PAL tuner detected\n");
428 cx->std |= V4L2_STD_PAL_BG | V4L2_STD_PAL_H; 437 cx->std |= V4L2_STD_PAL_BG | V4L2_STD_PAL_H;
429 } else if (tv.tuner_formats & V4L2_STD_NTSC) { 438 } else if (tv.tuner_formats & V4L2_STD_NTSC) {
@@ -818,7 +827,7 @@ static int cx18_setup_pci(struct cx18 *cx, struct pci_dev *pci_dev,
818 cmd |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER; 827 cmd |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER;
819 pci_write_config_word(pci_dev, PCI_COMMAND, cmd); 828 pci_write_config_word(pci_dev, PCI_COMMAND, cmd);
820 829
821 pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &cx->card_rev); 830 cx->card_rev = pci_dev->revision;
822 pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &pci_latency); 831 pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &pci_latency);
823 832
824 if (pci_latency < 64 && cx18_pci_latency) { 833 if (pci_latency < 64 && cx18_pci_latency) {
@@ -1001,7 +1010,15 @@ static int __devinit cx18_probe(struct pci_dev *pci_dev,
1001 if (cx->card->hw_all & CX18_HW_TVEEPROM) { 1010 if (cx->card->hw_all & CX18_HW_TVEEPROM) {
1002 /* Based on the model number the cardtype may be changed. 1011 /* Based on the model number the cardtype may be changed.
1003 The PCI IDs are not always reliable. */ 1012 The PCI IDs are not always reliable. */
1013 const struct cx18_card *orig_card = cx->card;
1004 cx18_process_eeprom(cx); 1014 cx18_process_eeprom(cx);
1015
1016 if (cx->card != orig_card) {
1017 /* Changed the cardtype; re-reset the I2C chips */
1018 cx18_gpio_init(cx);
1019 cx18_call_hw(cx, CX18_HW_GPIO_RESET_CTRL,
1020 core, reset, (u32) CX18_GPIO_RESET_I2C);
1021 }
1005 } 1022 }
1006 if (cx->card->comment) 1023 if (cx->card->comment)
1007 CX18_INFO("%s", cx->card->comment); 1024 CX18_INFO("%s", cx->card->comment);
@@ -1087,6 +1104,8 @@ static int __devinit cx18_probe(struct pci_dev *pci_dev,
1087 /* The tuner is fixed to the standard. The other inputs (e.g. S-Video) 1104 /* The tuner is fixed to the standard. The other inputs (e.g. S-Video)
1088 are not. */ 1105 are not. */
1089 cx->tuner_std = cx->std; 1106 cx->tuner_std = cx->std;
1107 if (cx->std == V4L2_STD_ALL)
1108 cx->std = V4L2_STD_NTSC_M;
1090 1109
1091 retval = cx18_streams_setup(cx); 1110 retval = cx18_streams_setup(cx);
1092 if (retval) { 1111 if (retval) {
@@ -1133,6 +1152,7 @@ int cx18_init_on_first_open(struct cx18 *cx)
1133 int fw_retry_count = 3; 1152 int fw_retry_count = 3;
1134 struct v4l2_frequency vf; 1153 struct v4l2_frequency vf;
1135 struct cx18_open_id fh; 1154 struct cx18_open_id fh;
1155 v4l2_std_id std;
1136 1156
1137 fh.cx = cx; 1157 fh.cx = cx;
1138 1158
@@ -1220,7 +1240,8 @@ int cx18_init_on_first_open(struct cx18 *cx)
1220 /* Let the VIDIOC_S_STD ioctl do all the work, keeps the code 1240 /* Let the VIDIOC_S_STD ioctl do all the work, keeps the code
1221 in one place. */ 1241 in one place. */
1222 cx->std++; /* Force full standard initialization */ 1242 cx->std++; /* Force full standard initialization */
1223 cx18_s_std(NULL, &fh, &cx->tuner_std); 1243 std = (cx->tuner_std == V4L2_STD_ALL) ? V4L2_STD_NTSC_M : cx->tuner_std;
1244 cx18_s_std(NULL, &fh, &std);
1224 cx18_s_frequency(NULL, &fh, &vf); 1245 cx18_s_frequency(NULL, &fh, &vf);
1225 return 0; 1246 return 0;
1226} 1247}
diff --git a/drivers/media/video/cx18/cx18-driver.h b/drivers/media/video/cx18/cx18-driver.h
index b86a740c68df..086427288de8 100644
--- a/drivers/media/video/cx18/cx18-driver.h
+++ b/drivers/media/video/cx18/cx18-driver.h
@@ -65,6 +65,10 @@
65#include "dvb_net.h" 65#include "dvb_net.h"
66#include "dvbdev.h" 66#include "dvbdev.h"
67 67
68/* Videobuf / YUV support */
69#include <media/videobuf-core.h>
70#include <media/videobuf-vmalloc.h>
71
68#ifndef CONFIG_PCI 72#ifndef CONFIG_PCI
69# error "This driver requires kernel PCI support." 73# error "This driver requires kernel PCI support."
70#endif 74#endif
@@ -403,6 +407,23 @@ struct cx18_stream {
403 struct cx18_queue q_idle; /* idle - not in rotation */ 407 struct cx18_queue q_idle; /* idle - not in rotation */
404 408
405 struct work_struct out_work_order; 409 struct work_struct out_work_order;
410
411 /* Videobuf for YUV video */
412 u32 pixelformat;
413 struct list_head vb_capture; /* video capture queue */
414 spinlock_t vb_lock;
415 struct timer_list vb_timeout;
416
417 struct videobuf_queue vbuf_q;
418 spinlock_t vbuf_q_lock; /* Protect vbuf_q */
419 enum v4l2_buf_type vb_type;
420};
421
422struct cx18_videobuf_buffer {
423 /* Common video buffer sub-system struct */
424 struct videobuf_buffer vb;
425 v4l2_std_id tvnorm; /* selected tv norm */
426 u32 bytes_used;
406}; 427};
407 428
408struct cx18_open_id { 429struct cx18_open_id {
@@ -410,6 +431,10 @@ struct cx18_open_id {
410 u32 open_id; 431 u32 open_id;
411 int type; 432 int type;
412 struct cx18 *cx; 433 struct cx18 *cx;
434
435 struct videobuf_queue vbuf_q;
436 spinlock_t s_lock; /* Protect vbuf_q */
437 enum v4l2_buf_type vb_type;
413}; 438};
414 439
415static inline struct cx18_open_id *fh2id(struct v4l2_fh *fh) 440static inline struct cx18_open_id *fh2id(struct v4l2_fh *fh)
diff --git a/drivers/media/video/cx18/cx18-fileops.c b/drivers/media/video/cx18/cx18-fileops.c
index e9802d99439b..07411f34885a 100644
--- a/drivers/media/video/cx18/cx18-fileops.c
+++ b/drivers/media/video/cx18/cx18-fileops.c
@@ -597,6 +597,13 @@ ssize_t cx18_v4l2_read(struct file *filp, char __user *buf, size_t count,
597 mutex_unlock(&cx->serialize_lock); 597 mutex_unlock(&cx->serialize_lock);
598 if (rc) 598 if (rc)
599 return rc; 599 return rc;
600
601 if ((s->vb_type == V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
602 (id->type == CX18_ENC_STREAM_TYPE_YUV)) {
603 return videobuf_read_stream(&s->vbuf_q, buf, count, pos, 0,
604 filp->f_flags & O_NONBLOCK);
605 }
606
600 return cx18_read_pos(s, buf, count, pos, filp->f_flags & O_NONBLOCK); 607 return cx18_read_pos(s, buf, count, pos, filp->f_flags & O_NONBLOCK);
601} 608}
602 609
@@ -622,6 +629,15 @@ unsigned int cx18_v4l2_enc_poll(struct file *filp, poll_table *wait)
622 CX18_DEBUG_FILE("Encoder poll started capture\n"); 629 CX18_DEBUG_FILE("Encoder poll started capture\n");
623 } 630 }
624 631
632 if ((s->vb_type == V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
633 (id->type == CX18_ENC_STREAM_TYPE_YUV)) {
634 int videobuf_poll = videobuf_poll_stream(filp, &s->vbuf_q, wait);
635 if (eof && videobuf_poll == POLLERR)
636 return POLLHUP;
637 else
638 return videobuf_poll;
639 }
640
625 /* add stream's waitq to the poll list */ 641 /* add stream's waitq to the poll list */
626 CX18_DEBUG_HI_FILE("Encoder poll\n"); 642 CX18_DEBUG_HI_FILE("Encoder poll\n");
627 poll_wait(filp, &s->waitq, wait); 643 poll_wait(filp, &s->waitq, wait);
@@ -633,6 +649,58 @@ unsigned int cx18_v4l2_enc_poll(struct file *filp, poll_table *wait)
633 return 0; 649 return 0;
634} 650}
635 651
652int cx18_v4l2_mmap(struct file *file, struct vm_area_struct *vma)
653{
654 struct cx18_open_id *id = file->private_data;
655 struct cx18 *cx = id->cx;
656 struct cx18_stream *s = &cx->streams[id->type];
657 int eof = test_bit(CX18_F_S_STREAMOFF, &s->s_flags);
658
659 if ((s->vb_type == V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
660 (id->type == CX18_ENC_STREAM_TYPE_YUV)) {
661
662 /* Start a capture if there is none */
663 if (!eof && !test_bit(CX18_F_S_STREAMING, &s->s_flags)) {
664 int rc;
665
666 mutex_lock(&cx->serialize_lock);
667 rc = cx18_start_capture(id);
668 mutex_unlock(&cx->serialize_lock);
669 if (rc) {
670 CX18_DEBUG_INFO(
671 "Could not start capture for %s (%d)\n",
672 s->name, rc);
673 return -EINVAL;
674 }
675 CX18_DEBUG_FILE("Encoder mmap started capture\n");
676 }
677
678 return videobuf_mmap_mapper(&s->vbuf_q, vma);
679 }
680
681 return -EINVAL;
682}
683
684void cx18_vb_timeout(unsigned long data)
685{
686 struct cx18_stream *s = (struct cx18_stream *)data;
687 struct cx18_videobuf_buffer *buf;
688 unsigned long flags;
689
690 /* Return all of the buffers in error state, so the vbi/vid inode
691 * can return from blocking.
692 */
693 spin_lock_irqsave(&s->vb_lock, flags);
694 while (!list_empty(&s->vb_capture)) {
695 buf = list_entry(s->vb_capture.next,
696 struct cx18_videobuf_buffer, vb.queue);
697 list_del(&buf->vb.queue);
698 buf->vb.state = VIDEOBUF_ERROR;
699 wake_up(&buf->vb.done);
700 }
701 spin_unlock_irqrestore(&s->vb_lock, flags);
702}
703
636void cx18_stop_capture(struct cx18_open_id *id, int gop_end) 704void cx18_stop_capture(struct cx18_open_id *id, int gop_end)
637{ 705{
638 struct cx18 *cx = id->cx; 706 struct cx18 *cx = id->cx;
@@ -716,6 +784,8 @@ int cx18_v4l2_close(struct file *filp)
716 cx18_release_stream(s); 784 cx18_release_stream(s);
717 } else { 785 } else {
718 cx18_stop_capture(id, 0); 786 cx18_stop_capture(id, 0);
787 if (id->type == CX18_ENC_STREAM_TYPE_YUV)
788 videobuf_mmap_free(&id->vbuf_q);
719 } 789 }
720 kfree(id); 790 kfree(id);
721 mutex_unlock(&cx->serialize_lock); 791 mutex_unlock(&cx->serialize_lock);
diff --git a/drivers/media/video/cx18/cx18-fileops.h b/drivers/media/video/cx18/cx18-fileops.h
index 5c8fcb884f0a..b9e5110ad043 100644
--- a/drivers/media/video/cx18/cx18-fileops.h
+++ b/drivers/media/video/cx18/cx18-fileops.h
@@ -33,6 +33,8 @@ int cx18_start_capture(struct cx18_open_id *id);
33void cx18_stop_capture(struct cx18_open_id *id, int gop_end); 33void cx18_stop_capture(struct cx18_open_id *id, int gop_end);
34void cx18_mute(struct cx18 *cx); 34void cx18_mute(struct cx18 *cx);
35void cx18_unmute(struct cx18 *cx); 35void cx18_unmute(struct cx18 *cx);
36int cx18_v4l2_mmap(struct file *file, struct vm_area_struct *vma);
37void cx18_vb_timeout(unsigned long data);
36 38
37/* Shared with cx18-alsa module */ 39/* Shared with cx18-alsa module */
38int cx18_claim_stream(struct cx18_open_id *id, int type); 40int cx18_claim_stream(struct cx18_open_id *id, int type);
diff --git a/drivers/media/video/cx18/cx18-ioctl.c b/drivers/media/video/cx18/cx18-ioctl.c
index 4f041c033c54..1933d4d11bf2 100644
--- a/drivers/media/video/cx18/cx18-ioctl.c
+++ b/drivers/media/video/cx18/cx18-ioctl.c
@@ -150,6 +150,7 @@ static int cx18_g_fmt_vid_cap(struct file *file, void *fh,
150{ 150{
151 struct cx18_open_id *id = fh2id(fh); 151 struct cx18_open_id *id = fh2id(fh);
152 struct cx18 *cx = id->cx; 152 struct cx18 *cx = id->cx;
153 struct cx18_stream *s = &cx->streams[id->type];
153 struct v4l2_pix_format *pixfmt = &fmt->fmt.pix; 154 struct v4l2_pix_format *pixfmt = &fmt->fmt.pix;
154 155
155 pixfmt->width = cx->cxhdl.width; 156 pixfmt->width = cx->cxhdl.width;
@@ -158,9 +159,13 @@ static int cx18_g_fmt_vid_cap(struct file *file, void *fh,
158 pixfmt->field = V4L2_FIELD_INTERLACED; 159 pixfmt->field = V4L2_FIELD_INTERLACED;
159 pixfmt->priv = 0; 160 pixfmt->priv = 0;
160 if (id->type == CX18_ENC_STREAM_TYPE_YUV) { 161 if (id->type == CX18_ENC_STREAM_TYPE_YUV) {
161 pixfmt->pixelformat = V4L2_PIX_FMT_HM12; 162 pixfmt->pixelformat = s->pixelformat;
162 /* YUV size is (Y=(h*720) + UV=(h*(720/2))) */ 163 /* HM12 YUV size is (Y=(h*720) + UV=(h*(720/2)))
163 pixfmt->sizeimage = pixfmt->height * 720 * 3 / 2; 164 UYUV YUV size is (Y=(h*720) + UV=(h*(720))) */
165 if (s->pixelformat == V4L2_PIX_FMT_HM12)
166 pixfmt->sizeimage = pixfmt->height * 720 * 3 / 2;
167 else
168 pixfmt->sizeimage = pixfmt->height * 720 * 2;
164 pixfmt->bytesperline = 720; 169 pixfmt->bytesperline = 720;
165 } else { 170 } else {
166 pixfmt->pixelformat = V4L2_PIX_FMT_MPEG; 171 pixfmt->pixelformat = V4L2_PIX_FMT_MPEG;
@@ -237,7 +242,6 @@ static int cx18_try_fmt_vid_cap(struct file *file, void *fh,
237 h = min(h, cx->is_50hz ? 576 : 480); 242 h = min(h, cx->is_50hz ? 576 : 480);
238 h = max(h, min_h); 243 h = max(h, min_h);
239 244
240 cx18_g_fmt_vid_cap(file, fh, fmt);
241 fmt->fmt.pix.width = w; 245 fmt->fmt.pix.width = w;
242 fmt->fmt.pix.height = h; 246 fmt->fmt.pix.height = h;
243 return 0; 247 return 0;
@@ -274,6 +278,7 @@ static int cx18_s_fmt_vid_cap(struct file *file, void *fh,
274 struct cx18_open_id *id = fh2id(fh); 278 struct cx18_open_id *id = fh2id(fh);
275 struct cx18 *cx = id->cx; 279 struct cx18 *cx = id->cx;
276 struct v4l2_mbus_framefmt mbus_fmt; 280 struct v4l2_mbus_framefmt mbus_fmt;
281 struct cx18_stream *s = &cx->streams[id->type];
277 int ret; 282 int ret;
278 int w, h; 283 int w, h;
279 284
@@ -283,12 +288,15 @@ static int cx18_s_fmt_vid_cap(struct file *file, void *fh,
283 w = fmt->fmt.pix.width; 288 w = fmt->fmt.pix.width;
284 h = fmt->fmt.pix.height; 289 h = fmt->fmt.pix.height;
285 290
286 if (cx->cxhdl.width == w && cx->cxhdl.height == h) 291 if (cx->cxhdl.width == w && cx->cxhdl.height == h &&
292 s->pixelformat == fmt->fmt.pix.pixelformat)
287 return 0; 293 return 0;
288 294
289 if (atomic_read(&cx->ana_capturing) > 0) 295 if (atomic_read(&cx->ana_capturing) > 0)
290 return -EBUSY; 296 return -EBUSY;
291 297
298 s->pixelformat = fmt->fmt.pix.pixelformat;
299
292 mbus_fmt.width = cx->cxhdl.width = w; 300 mbus_fmt.width = cx->cxhdl.width = w;
293 mbus_fmt.height = cx->cxhdl.height = h; 301 mbus_fmt.height = cx->cxhdl.height = h;
294 mbus_fmt.code = V4L2_MBUS_FMT_FIXED; 302 mbus_fmt.code = V4L2_MBUS_FMT_FIXED;
@@ -540,16 +548,19 @@ static int cx18_g_crop(struct file *file, void *fh, struct v4l2_crop *crop)
540static int cx18_enum_fmt_vid_cap(struct file *file, void *fh, 548static int cx18_enum_fmt_vid_cap(struct file *file, void *fh,
541 struct v4l2_fmtdesc *fmt) 549 struct v4l2_fmtdesc *fmt)
542{ 550{
543 static struct v4l2_fmtdesc formats[] = { 551 static const struct v4l2_fmtdesc formats[] = {
544 { 0, V4L2_BUF_TYPE_VIDEO_CAPTURE, 0, 552 { 0, V4L2_BUF_TYPE_VIDEO_CAPTURE, 0,
545 "HM12 (YUV 4:1:1)", V4L2_PIX_FMT_HM12, { 0, 0, 0, 0 } 553 "HM12 (YUV 4:1:1)", V4L2_PIX_FMT_HM12, { 0, 0, 0, 0 }
546 }, 554 },
547 { 1, V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FMT_FLAG_COMPRESSED, 555 { 1, V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FMT_FLAG_COMPRESSED,
548 "MPEG", V4L2_PIX_FMT_MPEG, { 0, 0, 0, 0 } 556 "MPEG", V4L2_PIX_FMT_MPEG, { 0, 0, 0, 0 }
549 } 557 },
558 { 2, V4L2_BUF_TYPE_VIDEO_CAPTURE, 0,
559 "UYVY 4:2:2", V4L2_PIX_FMT_UYVY, { 0, 0, 0, 0 }
560 },
550 }; 561 };
551 562
552 if (fmt->index > 1) 563 if (fmt->index > ARRAY_SIZE(formats) - 1)
553 return -EINVAL; 564 return -EINVAL;
554 *fmt = formats[fmt->index]; 565 *fmt = formats[fmt->index];
555 return 0; 566 return 0;
@@ -863,6 +874,117 @@ static int cx18_g_enc_index(struct file *file, void *fh,
863 return 0; 874 return 0;
864} 875}
865 876
877static struct videobuf_queue *cx18_vb_queue(struct cx18_open_id *id)
878{
879 struct videobuf_queue *q = NULL;
880 struct cx18 *cx = id->cx;
881 struct cx18_stream *s = &cx->streams[id->type];
882
883 switch (s->vb_type) {
884 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
885 q = &s->vbuf_q;
886 break;
887 case V4L2_BUF_TYPE_VBI_CAPTURE:
888 break;
889 default:
890 break;
891 }
892 return q;
893}
894
895static int cx18_streamon(struct file *file, void *priv,
896 enum v4l2_buf_type type)
897{
898 struct cx18_open_id *id = file->private_data;
899 struct cx18 *cx = id->cx;
900 struct cx18_stream *s = &cx->streams[id->type];
901
902 /* Start the hardware only if we're the video device */
903 if ((s->vb_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
904 (s->vb_type != V4L2_BUF_TYPE_VBI_CAPTURE))
905 return -EINVAL;
906
907 if (id->type != CX18_ENC_STREAM_TYPE_YUV)
908 return -EINVAL;
909
910 /* Establish a buffer timeout */
911 mod_timer(&s->vb_timeout, msecs_to_jiffies(2000) + jiffies);
912
913 return videobuf_streamon(cx18_vb_queue(id));
914}
915
916static int cx18_streamoff(struct file *file, void *priv,
917 enum v4l2_buf_type type)
918{
919 struct cx18_open_id *id = file->private_data;
920 struct cx18 *cx = id->cx;
921 struct cx18_stream *s = &cx->streams[id->type];
922
923 /* Start the hardware only if we're the video device */
924 if ((s->vb_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
925 (s->vb_type != V4L2_BUF_TYPE_VBI_CAPTURE))
926 return -EINVAL;
927
928 if (id->type != CX18_ENC_STREAM_TYPE_YUV)
929 return -EINVAL;
930
931 return videobuf_streamoff(cx18_vb_queue(id));
932}
933
934static int cx18_reqbufs(struct file *file, void *priv,
935 struct v4l2_requestbuffers *rb)
936{
937 struct cx18_open_id *id = file->private_data;
938 struct cx18 *cx = id->cx;
939 struct cx18_stream *s = &cx->streams[id->type];
940
941 if ((s->vb_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
942 (s->vb_type != V4L2_BUF_TYPE_VBI_CAPTURE))
943 return -EINVAL;
944
945 return videobuf_reqbufs(cx18_vb_queue(id), rb);
946}
947
948static int cx18_querybuf(struct file *file, void *priv,
949 struct v4l2_buffer *b)
950{
951 struct cx18_open_id *id = file->private_data;
952 struct cx18 *cx = id->cx;
953 struct cx18_stream *s = &cx->streams[id->type];
954
955 if ((s->vb_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
956 (s->vb_type != V4L2_BUF_TYPE_VBI_CAPTURE))
957 return -EINVAL;
958
959 return videobuf_querybuf(cx18_vb_queue(id), b);
960}
961
962static int cx18_qbuf(struct file *file, void *priv, struct v4l2_buffer *b)
963{
964 struct cx18_open_id *id = file->private_data;
965 struct cx18 *cx = id->cx;
966 struct cx18_stream *s = &cx->streams[id->type];
967
968 if ((s->vb_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
969 (s->vb_type != V4L2_BUF_TYPE_VBI_CAPTURE))
970 return -EINVAL;
971
972 return videobuf_qbuf(cx18_vb_queue(id), b);
973}
974
975static int cx18_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b)
976{
977 struct cx18_open_id *id = file->private_data;
978 struct cx18 *cx = id->cx;
979 struct cx18_stream *s = &cx->streams[id->type];
980
981 if ((s->vb_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
982 (s->vb_type != V4L2_BUF_TYPE_VBI_CAPTURE))
983 return -EINVAL;
984
985 return videobuf_dqbuf(cx18_vb_queue(id), b, file->f_flags & O_NONBLOCK);
986}
987
866static int cx18_encoder_cmd(struct file *file, void *fh, 988static int cx18_encoder_cmd(struct file *file, void *fh,
867 struct v4l2_encoder_cmd *enc) 989 struct v4l2_encoder_cmd *enc)
868{ 990{
@@ -1081,6 +1203,12 @@ static const struct v4l2_ioctl_ops cx18_ioctl_ops = {
1081 .vidioc_s_register = cx18_s_register, 1203 .vidioc_s_register = cx18_s_register,
1082#endif 1204#endif
1083 .vidioc_default = cx18_default, 1205 .vidioc_default = cx18_default,
1206 .vidioc_streamon = cx18_streamon,
1207 .vidioc_streamoff = cx18_streamoff,
1208 .vidioc_reqbufs = cx18_reqbufs,
1209 .vidioc_querybuf = cx18_querybuf,
1210 .vidioc_qbuf = cx18_qbuf,
1211 .vidioc_dqbuf = cx18_dqbuf,
1084}; 1212};
1085 1213
1086void cx18_set_funcs(struct video_device *vdev) 1214void cx18_set_funcs(struct video_device *vdev)
diff --git a/drivers/media/video/cx18/cx18-mailbox.c b/drivers/media/video/cx18/cx18-mailbox.c
index 9605d54bd083..c07191e09fcb 100644
--- a/drivers/media/video/cx18/cx18-mailbox.c
+++ b/drivers/media/video/cx18/cx18-mailbox.c
@@ -81,6 +81,7 @@ static const struct cx18_api_info api_info[] = {
81 API_ENTRY(CPU, CX18_CPU_SET_SLICED_VBI_PARAM, 0), 81 API_ENTRY(CPU, CX18_CPU_SET_SLICED_VBI_PARAM, 0),
82 API_ENTRY(CPU, CX18_CPU_SET_USERDATA_PLACE_HOLDER, 0), 82 API_ENTRY(CPU, CX18_CPU_SET_USERDATA_PLACE_HOLDER, 0),
83 API_ENTRY(CPU, CX18_CPU_GET_ENC_PTS, 0), 83 API_ENTRY(CPU, CX18_CPU_GET_ENC_PTS, 0),
84 API_ENTRY(CPU, CX18_CPU_SET_VFC_PARAM, 0),
84 API_ENTRY(CPU, CX18_CPU_DE_SET_MDL_ACK, 0), 85 API_ENTRY(CPU, CX18_CPU_DE_SET_MDL_ACK, 0),
85 API_ENTRY(CPU, CX18_CPU_DE_SET_MDL, API_FAST), 86 API_ENTRY(CPU, CX18_CPU_DE_SET_MDL, API_FAST),
86 API_ENTRY(CPU, CX18_CPU_DE_RELEASE_MDL, API_SLOW), 87 API_ENTRY(CPU, CX18_CPU_DE_RELEASE_MDL, API_SLOW),
@@ -158,6 +159,60 @@ static void cx18_mdl_send_to_dvb(struct cx18_stream *s, struct cx18_mdl *mdl)
158 } 159 }
159} 160}
160 161
162static void cx18_mdl_send_to_videobuf(struct cx18_stream *s,
163 struct cx18_mdl *mdl)
164{
165 struct cx18_videobuf_buffer *vb_buf;
166 struct cx18_buffer *buf;
167 u8 *p;
168 u32 offset = 0;
169 int dispatch = 0;
170
171 if (mdl->bytesused == 0)
172 return;
173
174 /* Acquire a videobuf buffer, clone to and and release it */
175 spin_lock(&s->vb_lock);
176 if (list_empty(&s->vb_capture))
177 goto out;
178
179 vb_buf = list_first_entry(&s->vb_capture, struct cx18_videobuf_buffer,
180 vb.queue);
181
182 p = videobuf_to_vmalloc(&vb_buf->vb);
183 if (!p)
184 goto out;
185
186 offset = vb_buf->bytes_used;
187 list_for_each_entry(buf, &mdl->buf_list, list) {
188 if (buf->bytesused == 0)
189 break;
190
191 if ((offset + buf->bytesused) <= vb_buf->vb.bsize) {
192 memcpy(p + offset, buf->buf, buf->bytesused);
193 offset += buf->bytesused;
194 vb_buf->bytes_used += buf->bytesused;
195 }
196 }
197
198 /* If we've filled the buffer as per the callers res then dispatch it */
199 if (vb_buf->bytes_used >= (vb_buf->vb.width * vb_buf->vb.height * 2)) {
200 dispatch = 1;
201 vb_buf->bytes_used = 0;
202 }
203
204 if (dispatch) {
205 vb_buf->vb.ts = ktime_to_timeval(ktime_get());
206 list_del(&vb_buf->vb.queue);
207 vb_buf->vb.state = VIDEOBUF_DONE;
208 wake_up(&vb_buf->vb.done);
209 }
210
211 mod_timer(&s->vb_timeout, msecs_to_jiffies(2000) + jiffies);
212
213out:
214 spin_unlock(&s->vb_lock);
215}
161 216
162static void cx18_mdl_send_to_alsa(struct cx18 *cx, struct cx18_stream *s, 217static void cx18_mdl_send_to_alsa(struct cx18 *cx, struct cx18_stream *s,
163 struct cx18_mdl *mdl) 218 struct cx18_mdl *mdl)
@@ -263,6 +318,9 @@ static void epu_dma_done(struct cx18 *cx, struct cx18_in_work_order *order)
263 } else { 318 } else {
264 cx18_enqueue(s, mdl, &s->q_full); 319 cx18_enqueue(s, mdl, &s->q_full);
265 } 320 }
321 } else if (s->type == CX18_ENC_STREAM_TYPE_YUV) {
322 cx18_mdl_send_to_videobuf(s, mdl);
323 cx18_enqueue(s, mdl, &s->q_free);
266 } else { 324 } else {
267 cx18_enqueue(s, mdl, &s->q_full); 325 cx18_enqueue(s, mdl, &s->q_full);
268 if (s->type == CX18_ENC_STREAM_TYPE_IDX) 326 if (s->type == CX18_ENC_STREAM_TYPE_IDX)
diff --git a/drivers/media/video/cx18/cx18-streams.c b/drivers/media/video/cx18/cx18-streams.c
index 6fbc356113c1..852f420fd271 100644
--- a/drivers/media/video/cx18/cx18-streams.c
+++ b/drivers/media/video/cx18/cx18-streams.c
@@ -44,6 +44,7 @@ static struct v4l2_file_operations cx18_v4l2_enc_fops = {
44 .unlocked_ioctl = cx18_v4l2_ioctl, 44 .unlocked_ioctl = cx18_v4l2_ioctl,
45 .release = cx18_v4l2_close, 45 .release = cx18_v4l2_close,
46 .poll = cx18_v4l2_enc_poll, 46 .poll = cx18_v4l2_enc_poll,
47 .mmap = cx18_v4l2_mmap,
47}; 48};
48 49
49/* offset from 0 to register ts v4l2 minors on */ 50/* offset from 0 to register ts v4l2 minors on */
@@ -97,6 +98,141 @@ static struct {
97 }, 98 },
98}; 99};
99 100
101
102void cx18_dma_free(struct videobuf_queue *q,
103 struct cx18_stream *s, struct cx18_videobuf_buffer *buf)
104{
105 videobuf_waiton(q, &buf->vb, 0, 0);
106 videobuf_vmalloc_free(&buf->vb);
107 buf->vb.state = VIDEOBUF_NEEDS_INIT;
108}
109
110static int cx18_prepare_buffer(struct videobuf_queue *q,
111 struct cx18_stream *s,
112 struct cx18_videobuf_buffer *buf,
113 u32 pixelformat,
114 unsigned int width, unsigned int height,
115 enum v4l2_field field)
116{
117 struct cx18 *cx = s->cx;
118 int rc = 0;
119
120 /* check settings */
121 buf->bytes_used = 0;
122
123 if ((width < 48) || (height < 32))
124 return -EINVAL;
125
126 buf->vb.size = (width * height * 2);
127 if ((buf->vb.baddr != 0) && (buf->vb.bsize < buf->vb.size))
128 return -EINVAL;
129
130 /* alloc + fill struct (if changed) */
131 if (buf->vb.width != width || buf->vb.height != height ||
132 buf->vb.field != field || s->pixelformat != pixelformat ||
133 buf->tvnorm != cx->std) {
134
135 buf->vb.width = width;
136 buf->vb.height = height;
137 buf->vb.field = field;
138 buf->tvnorm = cx->std;
139 s->pixelformat = pixelformat;
140
141 cx18_dma_free(q, s, buf);
142 }
143
144 if ((buf->vb.baddr != 0) && (buf->vb.bsize < buf->vb.size))
145 return -EINVAL;
146
147 if (buf->vb.field == 0)
148 buf->vb.field = V4L2_FIELD_INTERLACED;
149
150 if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
151 buf->vb.width = width;
152 buf->vb.height = height;
153 buf->vb.field = field;
154 buf->tvnorm = cx->std;
155 s->pixelformat = pixelformat;
156
157 rc = videobuf_iolock(q, &buf->vb, NULL);
158 if (rc != 0)
159 goto fail;
160 }
161 buf->vb.state = VIDEOBUF_PREPARED;
162 return 0;
163
164fail:
165 cx18_dma_free(q, s, buf);
166 return rc;
167
168}
169
170/* VB_MIN_BUFSIZE is lcm(1440 * 480, 1440 * 576)
171 1440 is a single line of 4:2:2 YUV at 720 luma samples wide
172*/
173#define VB_MIN_BUFFERS 32
174#define VB_MIN_BUFSIZE 4147200
175
176static int buffer_setup(struct videobuf_queue *q,
177 unsigned int *count, unsigned int *size)
178{
179 struct cx18_stream *s = q->priv_data;
180 struct cx18 *cx = s->cx;
181
182 *size = 2 * cx->cxhdl.width * cx->cxhdl.height;
183 if (*count == 0)
184 *count = VB_MIN_BUFFERS;
185
186 while (*size * *count > VB_MIN_BUFFERS * VB_MIN_BUFSIZE)
187 (*count)--;
188
189 q->field = V4L2_FIELD_INTERLACED;
190 q->last = V4L2_FIELD_INTERLACED;
191
192 return 0;
193}
194
195static int buffer_prepare(struct videobuf_queue *q,
196 struct videobuf_buffer *vb,
197 enum v4l2_field field)
198{
199 struct cx18_videobuf_buffer *buf =
200 container_of(vb, struct cx18_videobuf_buffer, vb);
201 struct cx18_stream *s = q->priv_data;
202 struct cx18 *cx = s->cx;
203
204 return cx18_prepare_buffer(q, s, buf, s->pixelformat,
205 cx->cxhdl.width, cx->cxhdl.height, field);
206}
207
208static void buffer_release(struct videobuf_queue *q,
209 struct videobuf_buffer *vb)
210{
211 struct cx18_videobuf_buffer *buf =
212 container_of(vb, struct cx18_videobuf_buffer, vb);
213 struct cx18_stream *s = q->priv_data;
214
215 cx18_dma_free(q, s, buf);
216}
217
218static void buffer_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
219{
220 struct cx18_videobuf_buffer *buf =
221 container_of(vb, struct cx18_videobuf_buffer, vb);
222 struct cx18_stream *s = q->priv_data;
223
224 buf->vb.state = VIDEOBUF_QUEUED;
225
226 list_add_tail(&buf->vb.queue, &s->vb_capture);
227}
228
229static struct videobuf_queue_ops cx18_videobuf_qops = {
230 .buf_setup = buffer_setup,
231 .buf_prepare = buffer_prepare,
232 .buf_queue = buffer_queue,
233 .buf_release = buffer_release,
234};
235
100static void cx18_stream_init(struct cx18 *cx, int type) 236static void cx18_stream_init(struct cx18 *cx, int type)
101{ 237{
102 struct cx18_stream *s = &cx->streams[type]; 238 struct cx18_stream *s = &cx->streams[type];
@@ -132,6 +268,26 @@ static void cx18_stream_init(struct cx18 *cx, int type)
132 cx18_queue_init(&s->q_idle); 268 cx18_queue_init(&s->q_idle);
133 269
134 INIT_WORK(&s->out_work_order, cx18_out_work_handler); 270 INIT_WORK(&s->out_work_order, cx18_out_work_handler);
271
272 INIT_LIST_HEAD(&s->vb_capture);
273 s->vb_timeout.function = cx18_vb_timeout;
274 s->vb_timeout.data = (unsigned long)s;
275 init_timer(&s->vb_timeout);
276 spin_lock_init(&s->vb_lock);
277 if (type == CX18_ENC_STREAM_TYPE_YUV) {
278 spin_lock_init(&s->vbuf_q_lock);
279
280 s->vb_type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
281 videobuf_queue_vmalloc_init(&s->vbuf_q, &cx18_videobuf_qops,
282 &cx->pci_dev->dev, &s->vbuf_q_lock,
283 V4L2_BUF_TYPE_VIDEO_CAPTURE,
284 V4L2_FIELD_INTERLACED,
285 sizeof(struct cx18_videobuf_buffer),
286 s, &cx->serialize_lock);
287
288 /* Assume the previous pixel default */
289 s->pixelformat = V4L2_PIX_FMT_HM12;
290 }
135} 291}
136 292
137static int cx18_prep_dev(struct cx18 *cx, int type) 293static int cx18_prep_dev(struct cx18 *cx, int type)
@@ -372,6 +528,9 @@ void cx18_streams_cleanup(struct cx18 *cx, int unregister)
372 if (vdev == NULL) 528 if (vdev == NULL)
373 continue; 529 continue;
374 530
531 if (type == CX18_ENC_STREAM_TYPE_YUV)
532 videobuf_mmap_free(&cx->streams[type].vbuf_q);
533
375 cx18_stream_free(&cx->streams[type]); 534 cx18_stream_free(&cx->streams[type]);
376 535
377 /* Unregister or release device */ 536 /* Unregister or release device */
@@ -581,7 +740,10 @@ static void cx18_stream_configure_mdls(struct cx18_stream *s)
581 * Set the MDL size to the exact size needed for one frame. 740 * Set the MDL size to the exact size needed for one frame.
582 * Use enough buffers per MDL to cover the MDL size 741 * Use enough buffers per MDL to cover the MDL size
583 */ 742 */
584 s->mdl_size = 720 * s->cx->cxhdl.height * 3 / 2; 743 if (s->pixelformat == V4L2_PIX_FMT_HM12)
744 s->mdl_size = 720 * s->cx->cxhdl.height * 3 / 2;
745 else
746 s->mdl_size = 720 * s->cx->cxhdl.height * 2;
585 s->bufs_per_mdl = s->mdl_size / s->buf_size; 747 s->bufs_per_mdl = s->mdl_size / s->buf_size;
586 if (s->mdl_size % s->buf_size) 748 if (s->mdl_size % s->buf_size)
587 s->bufs_per_mdl++; 749 s->bufs_per_mdl++;
@@ -729,6 +891,19 @@ int cx18_start_v4l2_encode_stream(struct cx18_stream *s)
729 test_bit(CX18_F_I_RADIO_USER, &cx->i_flags)) 891 test_bit(CX18_F_I_RADIO_USER, &cx->i_flags))
730 cx18_vapi(cx, CX18_CPU_SET_VIDEO_MUTE, 2, s->handle, 892 cx18_vapi(cx, CX18_CPU_SET_VIDEO_MUTE, 2, s->handle,
731 (v4l2_ctrl_g_ctrl(cx->cxhdl.video_mute_yuv) << 8) | 1); 893 (v4l2_ctrl_g_ctrl(cx->cxhdl.video_mute_yuv) << 8) | 1);
894
895 /* Enable the Video Format Converter for UYVY 4:2:2 support,
896 * rather than the default HM12 Macroblovk 4:2:0 support.
897 */
898 if (captype == CAPTURE_CHANNEL_TYPE_YUV) {
899 if (s->pixelformat == V4L2_PIX_FMT_UYVY)
900 cx18_vapi(cx, CX18_CPU_SET_VFC_PARAM, 2,
901 s->handle, 1);
902 else
903 /* If in doubt, default to HM12 */
904 cx18_vapi(cx, CX18_CPU_SET_VFC_PARAM, 2,
905 s->handle, 0);
906 }
732 } 907 }
733 908
734 if (atomic_read(&cx->tot_capturing) == 0) { 909 if (atomic_read(&cx->tot_capturing) == 0) {
diff --git a/drivers/media/video/cx18/cx18-version.h b/drivers/media/video/cx18/cx18-version.h
index 3e1aec4bcfde..cd189b6bbe20 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 4 27#define CX18_DRIVER_VERSION_MINOR 5
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 935f557acbd0..767a8d23e3f2 100644
--- a/drivers/media/video/cx18/cx23418.h
+++ b/drivers/media/video/cx18/cx23418.h
@@ -342,6 +342,12 @@
342 ReturnCode */ 342 ReturnCode */
343#define CX18_CPU_GET_ENC_PTS (CPU_CMD_MASK_CAPTURE | 0x0022) 343#define CX18_CPU_GET_ENC_PTS (CPU_CMD_MASK_CAPTURE | 0x0022)
344 344
345/* Description: Set VFC parameters
346 IN[0] - task handle
347 IN[1] - VFC enable flag, 1 - enable, 0 - disable
348*/
349#define CX18_CPU_SET_VFC_PARAM (CPU_CMD_MASK_CAPTURE | 0x0023)
350
345/* Below is the list of commands related to the data exchange */ 351/* Below is the list of commands related to the data exchange */
346#define CPU_CMD_MASK_DE (CPU_CMD_MASK | 0x040000) 352#define CPU_CMD_MASK_DE (CPU_CMD_MASK | 0x040000)
347 353
diff --git a/drivers/media/video/cx231xx/cx231xx-cards.c b/drivers/media/video/cx231xx/cx231xx-cards.c
index f49230d170e6..22703815a31f 100644
--- a/drivers/media/video/cx231xx/cx231xx-cards.c
+++ b/drivers/media/video/cx231xx/cx231xx-cards.c
@@ -401,6 +401,44 @@ struct cx231xx_board cx231xx_boards[] = {
401 .gpio = NULL, 401 .gpio = NULL,
402 } }, 402 } },
403 }, 403 },
404 [CX231XX_BOARD_KWORLD_UB430_USB_HYBRID] = {
405 .name = "Kworld UB430 USB Hybrid",
406 .tuner_type = TUNER_NXP_TDA18271,
407 .tuner_addr = 0x60,
408 .decoder = CX231XX_AVDECODER,
409 .output_mode = OUT_MODE_VIP11,
410 .demod_xfer_mode = 0,
411 .ctl_pin_status_mask = 0xFFFFFFC4,
412 .agc_analog_digital_select_gpio = 0x11, /* According with PV cxPolaris.inf file */
413 .tuner_sif_gpio = -1,
414 .tuner_scl_gpio = -1,
415 .tuner_sda_gpio = -1,
416 .gpio_pin_status_mask = 0x4001000,
417 .tuner_i2c_master = 2,
418 .demod_i2c_master = 1,
419 .ir_i2c_master = 2,
420 .has_dvb = 1,
421 .demod_addr = 0x10,
422 .norm = V4L2_STD_PAL_M,
423 .input = {{
424 .type = CX231XX_VMUX_TELEVISION,
425 .vmux = CX231XX_VIN_3_1,
426 .amux = CX231XX_AMUX_VIDEO,
427 .gpio = NULL,
428 }, {
429 .type = CX231XX_VMUX_COMPOSITE1,
430 .vmux = CX231XX_VIN_2_1,
431 .amux = CX231XX_AMUX_LINE_IN,
432 .gpio = NULL,
433 }, {
434 .type = CX231XX_VMUX_SVIDEO,
435 .vmux = CX231XX_VIN_1_1 |
436 (CX231XX_VIN_1_2 << 8) |
437 CX25840_SVIDEO_ON,
438 .amux = CX231XX_AMUX_LINE_IN,
439 .gpio = NULL,
440 } },
441 },
404 [CX231XX_BOARD_PV_PLAYTV_USB_HYBRID] = { 442 [CX231XX_BOARD_PV_PLAYTV_USB_HYBRID] = {
405 .name = "Pixelview PlayTV USB Hybrid", 443 .name = "Pixelview PlayTV USB Hybrid",
406 .tuner_type = TUNER_NXP_TDA18271, 444 .tuner_type = TUNER_NXP_TDA18271,
@@ -469,6 +507,31 @@ struct cx231xx_board cx231xx_boards[] = {
469 } 507 }
470 }, 508 },
471 }, 509 },
510
511 [CX231XX_BOARD_ICONBIT_U100] = {
512 .name = "Iconbit Analog Stick U100 FM",
513 .tuner_type = TUNER_ABSENT,
514 .decoder = CX231XX_AVDECODER,
515 .output_mode = OUT_MODE_VIP11,
516 .demod_xfer_mode = 0,
517 .ctl_pin_status_mask = 0xFFFFFFC4,
518 .agc_analog_digital_select_gpio = 0x1C,
519 .gpio_pin_status_mask = 0x4001000,
520
521 .input = {{
522 .type = CX231XX_VMUX_COMPOSITE1,
523 .vmux = CX231XX_VIN_2_1,
524 .amux = CX231XX_AMUX_LINE_IN,
525 .gpio = NULL,
526 }, {
527 .type = CX231XX_VMUX_SVIDEO,
528 .vmux = CX231XX_VIN_1_1 |
529 (CX231XX_VIN_1_2 << 8) |
530 CX25840_SVIDEO_ON,
531 .amux = CX231XX_AMUX_LINE_IN,
532 .gpio = NULL,
533 } },
534 },
472}; 535};
473const unsigned int cx231xx_bcount = ARRAY_SIZE(cx231xx_boards); 536const unsigned int cx231xx_bcount = ARRAY_SIZE(cx231xx_boards);
474 537
@@ -500,6 +563,10 @@ struct usb_device_id cx231xx_id_table[] = {
500 .driver_info = CX231XX_BOARD_PV_PLAYTV_USB_HYBRID}, 563 .driver_info = CX231XX_BOARD_PV_PLAYTV_USB_HYBRID},
501 {USB_DEVICE(USB_VID_PIXELVIEW, 0x5014), 564 {USB_DEVICE(USB_VID_PIXELVIEW, 0x5014),
502 .driver_info = CX231XX_BOARD_PV_XCAPTURE_USB}, 565 .driver_info = CX231XX_BOARD_PV_XCAPTURE_USB},
566 {USB_DEVICE(0x1b80, 0xe424),
567 .driver_info = CX231XX_BOARD_KWORLD_UB430_USB_HYBRID},
568 {USB_DEVICE(0x1f4d, 0x0237),
569 .driver_info = CX231XX_BOARD_ICONBIT_U100},
503 {}, 570 {},
504}; 571};
505 572
diff --git a/drivers/media/video/cx231xx/cx231xx-dvb.c b/drivers/media/video/cx231xx/cx231xx-dvb.c
index 363aa6004221..da9a4a0aab79 100644
--- a/drivers/media/video/cx231xx/cx231xx-dvb.c
+++ b/drivers/media/video/cx231xx/cx231xx-dvb.c
@@ -704,6 +704,7 @@ static int dvb_init(struct cx231xx *dev)
704 break; 704 break;
705 705
706 case CX231XX_BOARD_PV_PLAYTV_USB_HYBRID: 706 case CX231XX_BOARD_PV_PLAYTV_USB_HYBRID:
707 case CX231XX_BOARD_KWORLD_UB430_USB_HYBRID:
707 708
708 printk(KERN_INFO "%s: looking for demod on i2c bus: %d\n", 709 printk(KERN_INFO "%s: looking for demod on i2c bus: %d\n",
709 __func__, i2c_adapter_id(&dev->i2c_bus[dev->board.tuner_i2c_master].i2c_adap)); 710 __func__, i2c_adapter_id(&dev->i2c_bus[dev->board.tuner_i2c_master].i2c_adap));
diff --git a/drivers/media/video/cx231xx/cx231xx.h b/drivers/media/video/cx231xx/cx231xx.h
index bd4a9cf29577..46dd84067816 100644
--- a/drivers/media/video/cx231xx/cx231xx.h
+++ b/drivers/media/video/cx231xx/cx231xx.h
@@ -65,6 +65,8 @@
65#define CX231XX_BOARD_HAUPPAUGE_USBLIVE2 9 65#define CX231XX_BOARD_HAUPPAUGE_USBLIVE2 9
66#define CX231XX_BOARD_PV_PLAYTV_USB_HYBRID 10 66#define CX231XX_BOARD_PV_PLAYTV_USB_HYBRID 10
67#define CX231XX_BOARD_PV_XCAPTURE_USB 11 67#define CX231XX_BOARD_PV_XCAPTURE_USB 11
68#define CX231XX_BOARD_KWORLD_UB430_USB_HYBRID 12
69#define CX231XX_BOARD_ICONBIT_U100 13
68 70
69/* Limits minimum and default number of buffers */ 71/* Limits minimum and default number of buffers */
70#define CX231XX_MIN_BUF 4 72#define CX231XX_MIN_BUF 4
diff --git a/drivers/media/video/cx23885/cx23885-cards.c b/drivers/media/video/cx23885/cx23885-cards.c
index ea88722cb4ab..2354336862cf 100644
--- a/drivers/media/video/cx23885/cx23885-cards.c
+++ b/drivers/media/video/cx23885/cx23885-cards.c
@@ -1399,6 +1399,7 @@ void cx23885_card_setup(struct cx23885_dev *dev)
1399 else 1399 else
1400 altera_init(&netup_config, fw); 1400 altera_init(&netup_config, fw);
1401 1401
1402 release_firmware(fw);
1402 break; 1403 break;
1403 } 1404 }
1404 } 1405 }
diff --git a/drivers/media/video/cx23885/cx23885-core.c b/drivers/media/video/cx23885/cx23885-core.c
index 9933810b4e33..64d9b2136ff6 100644
--- a/drivers/media/video/cx23885/cx23885-core.c
+++ b/drivers/media/video/cx23885/cx23885-core.c
@@ -2045,7 +2045,7 @@ static int __devinit cx23885_initdev(struct pci_dev *pci_dev,
2045 } 2045 }
2046 2046
2047 /* print pci info */ 2047 /* print pci info */
2048 pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &dev->pci_rev); 2048 dev->pci_rev = pci_dev->revision;
2049 pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &dev->pci_lat); 2049 pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &dev->pci_lat);
2050 printk(KERN_INFO "%s/0: found at %s, rev: %d, irq: %d, " 2050 printk(KERN_INFO "%s/0: found at %s, rev: %d, irq: %d, "
2051 "latency: %d, mmio: 0x%llx\n", dev->name, 2051 "latency: %d, mmio: 0x%llx\n", dev->name,
diff --git a/drivers/media/video/cx88/cx88-blackbird.c b/drivers/media/video/cx88/cx88-blackbird.c
index bca307eb1e24..11e49bbc4a66 100644
--- a/drivers/media/video/cx88/cx88-blackbird.c
+++ b/drivers/media/video/cx88/cx88-blackbird.c
@@ -1060,18 +1060,21 @@ static int mpeg_open(struct file *file)
1060 1060
1061 /* Make sure we can acquire the hardware */ 1061 /* Make sure we can acquire the hardware */
1062 drv = cx8802_get_driver(dev, CX88_MPEG_BLACKBIRD); 1062 drv = cx8802_get_driver(dev, CX88_MPEG_BLACKBIRD);
1063 if (drv) { 1063 if (!drv) {
1064 err = drv->request_acquire(drv); 1064 dprintk(1, "%s: blackbird driver is not loaded\n", __func__);
1065 if(err != 0) { 1065 mutex_unlock(&dev->core->lock);
1066 dprintk(1,"%s: Unable to acquire hardware, %d\n", __func__, err); 1066 return -ENODEV;
1067 mutex_unlock(&dev->core->lock); 1067 }
1068 return err; 1068
1069 } 1069 err = drv->request_acquire(drv);
1070 if (err != 0) {
1071 dprintk(1,"%s: Unable to acquire hardware, %d\n", __func__, err);
1072 mutex_unlock(&dev->core->lock);
1073 return err;
1070 } 1074 }
1071 1075
1072 if (!atomic_read(&dev->core->mpeg_users) && blackbird_initialize_codec(dev) < 0) { 1076 if (!dev->core->mpeg_users && blackbird_initialize_codec(dev) < 0) {
1073 if (drv) 1077 drv->request_release(drv);
1074 drv->request_release(drv);
1075 mutex_unlock(&dev->core->lock); 1078 mutex_unlock(&dev->core->lock);
1076 return -EINVAL; 1079 return -EINVAL;
1077 } 1080 }
@@ -1080,8 +1083,7 @@ static int mpeg_open(struct file *file)
1080 /* allocate + initialize per filehandle data */ 1083 /* allocate + initialize per filehandle data */
1081 fh = kzalloc(sizeof(*fh),GFP_KERNEL); 1084 fh = kzalloc(sizeof(*fh),GFP_KERNEL);
1082 if (NULL == fh) { 1085 if (NULL == fh) {
1083 if (drv) 1086 drv->request_release(drv);
1084 drv->request_release(drv);
1085 mutex_unlock(&dev->core->lock); 1087 mutex_unlock(&dev->core->lock);
1086 return -ENOMEM; 1088 return -ENOMEM;
1087 } 1089 }
@@ -1099,7 +1101,7 @@ static int mpeg_open(struct file *file)
1099 cx88_set_scale(dev->core, dev->width, dev->height, 1101 cx88_set_scale(dev->core, dev->width, dev->height,
1100 fh->mpegq.field); 1102 fh->mpegq.field);
1101 1103
1102 atomic_inc(&dev->core->mpeg_users); 1104 dev->core->mpeg_users++;
1103 mutex_unlock(&dev->core->lock); 1105 mutex_unlock(&dev->core->lock);
1104 return 0; 1106 return 0;
1105} 1107}
@@ -1110,7 +1112,9 @@ static int mpeg_release(struct file *file)
1110 struct cx8802_dev *dev = fh->dev; 1112 struct cx8802_dev *dev = fh->dev;
1111 struct cx8802_driver *drv = NULL; 1113 struct cx8802_driver *drv = NULL;
1112 1114
1113 if (dev->mpeg_active && atomic_read(&dev->core->mpeg_users) == 1) 1115 mutex_lock(&dev->core->lock);
1116
1117 if (dev->mpeg_active && dev->core->mpeg_users == 1)
1114 blackbird_stop_codec(dev); 1118 blackbird_stop_codec(dev);
1115 1119
1116 cx8802_cancel_buffers(fh->dev); 1120 cx8802_cancel_buffers(fh->dev);
@@ -1119,17 +1123,18 @@ static int mpeg_release(struct file *file)
1119 1123
1120 videobuf_mmap_free(&fh->mpegq); 1124 videobuf_mmap_free(&fh->mpegq);
1121 1125
1122 mutex_lock(&dev->core->lock);
1123 file->private_data = NULL; 1126 file->private_data = NULL;
1124 kfree(fh); 1127 kfree(fh);
1125 mutex_unlock(&dev->core->lock);
1126 1128
1127 /* Make sure we release the hardware */ 1129 /* Make sure we release the hardware */
1128 drv = cx8802_get_driver(dev, CX88_MPEG_BLACKBIRD); 1130 drv = cx8802_get_driver(dev, CX88_MPEG_BLACKBIRD);
1131 WARN_ON(!drv);
1129 if (drv) 1132 if (drv)
1130 drv->request_release(drv); 1133 drv->request_release(drv);
1131 1134
1132 atomic_dec(&dev->core->mpeg_users); 1135 dev->core->mpeg_users--;
1136
1137 mutex_unlock(&dev->core->lock);
1133 1138
1134 return 0; 1139 return 0;
1135} 1140}
@@ -1334,11 +1339,9 @@ static int cx8802_blackbird_probe(struct cx8802_driver *drv)
1334 blackbird_register_video(dev); 1339 blackbird_register_video(dev);
1335 1340
1336 /* initial device configuration: needed ? */ 1341 /* initial device configuration: needed ? */
1337 mutex_lock(&dev->core->lock);
1338// init_controls(core); 1342// init_controls(core);
1339 cx88_set_tvnorm(core,core->tvnorm); 1343 cx88_set_tvnorm(core,core->tvnorm);
1340 cx88_video_mux(core,0); 1344 cx88_video_mux(core,0);
1341 mutex_unlock(&dev->core->lock);
1342 1345
1343 return 0; 1346 return 0;
1344 1347
diff --git a/drivers/media/video/cx88/cx88-dvb.c b/drivers/media/video/cx88/cx88-dvb.c
index 7b8c9d3b6efc..c69df7ebb6a7 100644
--- a/drivers/media/video/cx88/cx88-dvb.c
+++ b/drivers/media/video/cx88/cx88-dvb.c
@@ -133,6 +133,7 @@ static int cx88_dvb_bus_ctrl(struct dvb_frontend* fe, int acquire)
133 return -EINVAL; 133 return -EINVAL;
134 } 134 }
135 135
136 mutex_lock(&dev->core->lock);
136 drv = cx8802_get_driver(dev, CX88_MPEG_DVB); 137 drv = cx8802_get_driver(dev, CX88_MPEG_DVB);
137 if (drv) { 138 if (drv) {
138 if (acquire){ 139 if (acquire){
@@ -143,6 +144,7 @@ static int cx88_dvb_bus_ctrl(struct dvb_frontend* fe, int acquire)
143 dev->frontends.active_fe_id = 0; 144 dev->frontends.active_fe_id = 0;
144 } 145 }
145 } 146 }
147 mutex_unlock(&dev->core->lock);
146 148
147 return ret; 149 return ret;
148} 150}
diff --git a/drivers/media/video/cx88/cx88-mpeg.c b/drivers/media/video/cx88/cx88-mpeg.c
index addf9545e9bf..1a7b983f8297 100644
--- a/drivers/media/video/cx88/cx88-mpeg.c
+++ b/drivers/media/video/cx88/cx88-mpeg.c
@@ -78,6 +78,7 @@ static void flush_request_modules(struct cx8802_dev *dev)
78 78
79 79
80static LIST_HEAD(cx8802_devlist); 80static LIST_HEAD(cx8802_devlist);
81static DEFINE_MUTEX(cx8802_mutex);
81/* ------------------------------------------------------------------ */ 82/* ------------------------------------------------------------------ */
82 83
83static int cx8802_start_dma(struct cx8802_dev *dev, 84static int cx8802_start_dma(struct cx8802_dev *dev,
@@ -474,7 +475,7 @@ static int cx8802_init_common(struct cx8802_dev *dev)
474 return -EIO; 475 return -EIO;
475 } 476 }
476 477
477 pci_read_config_byte(dev->pci, PCI_CLASS_REVISION, &dev->pci_rev); 478 dev->pci_rev = dev->pci->revision;
478 pci_read_config_byte(dev->pci, PCI_LATENCY_TIMER, &dev->pci_lat); 479 pci_read_config_byte(dev->pci, PCI_LATENCY_TIMER, &dev->pci_lat);
479 printk(KERN_INFO "%s/2: found at %s, rev: %d, irq: %d, " 480 printk(KERN_INFO "%s/2: found at %s, rev: %d, irq: %d, "
480 "latency: %d, mmio: 0x%llx\n", dev->core->name, 481 "latency: %d, mmio: 0x%llx\n", dev->core->name,
@@ -624,13 +625,11 @@ static int cx8802_request_acquire(struct cx8802_driver *drv)
624 625
625 if (drv->advise_acquire) 626 if (drv->advise_acquire)
626 { 627 {
627 mutex_lock(&drv->core->lock);
628 core->active_ref++; 628 core->active_ref++;
629 if (core->active_type_id == CX88_BOARD_NONE) { 629 if (core->active_type_id == CX88_BOARD_NONE) {
630 core->active_type_id = drv->type_id; 630 core->active_type_id = drv->type_id;
631 drv->advise_acquire(drv); 631 drv->advise_acquire(drv);
632 } 632 }
633 mutex_unlock(&drv->core->lock);
634 633
635 mpeg_dbg(1,"%s() Post acquire GPIO=%x\n", __func__, cx_read(MO_GP0_IO)); 634 mpeg_dbg(1,"%s() Post acquire GPIO=%x\n", __func__, cx_read(MO_GP0_IO));
636 } 635 }
@@ -643,14 +642,12 @@ static int cx8802_request_release(struct cx8802_driver *drv)
643{ 642{
644 struct cx88_core *core = drv->core; 643 struct cx88_core *core = drv->core;
645 644
646 mutex_lock(&drv->core->lock);
647 if (drv->advise_release && --core->active_ref == 0) 645 if (drv->advise_release && --core->active_ref == 0)
648 { 646 {
649 drv->advise_release(drv); 647 drv->advise_release(drv);
650 core->active_type_id = CX88_BOARD_NONE; 648 core->active_type_id = CX88_BOARD_NONE;
651 mpeg_dbg(1,"%s() Post release GPIO=%x\n", __func__, cx_read(MO_GP0_IO)); 649 mpeg_dbg(1,"%s() Post release GPIO=%x\n", __func__, cx_read(MO_GP0_IO));
652 } 650 }
653 mutex_unlock(&drv->core->lock);
654 651
655 return 0; 652 return 0;
656} 653}
@@ -693,6 +690,8 @@ int cx8802_register_driver(struct cx8802_driver *drv)
693 return err; 690 return err;
694 } 691 }
695 692
693 mutex_lock(&cx8802_mutex);
694
696 list_for_each_entry(dev, &cx8802_devlist, devlist) { 695 list_for_each_entry(dev, &cx8802_devlist, devlist) {
697 printk(KERN_INFO 696 printk(KERN_INFO
698 "%s/2: subsystem: %04x:%04x, board: %s [card=%d]\n", 697 "%s/2: subsystem: %04x:%04x, board: %s [card=%d]\n",
@@ -702,8 +701,10 @@ int cx8802_register_driver(struct cx8802_driver *drv)
702 701
703 /* Bring up a new struct for each driver instance */ 702 /* Bring up a new struct for each driver instance */
704 driver = kzalloc(sizeof(*drv),GFP_KERNEL); 703 driver = kzalloc(sizeof(*drv),GFP_KERNEL);
705 if (driver == NULL) 704 if (driver == NULL) {
706 return -ENOMEM; 705 err = -ENOMEM;
706 goto out;
707 }
707 708
708 /* Snapshot of the driver registration data */ 709 /* Snapshot of the driver registration data */
709 drv->core = dev->core; 710 drv->core = dev->core;
@@ -713,21 +714,23 @@ int cx8802_register_driver(struct cx8802_driver *drv)
713 drv->request_release = cx8802_request_release; 714 drv->request_release = cx8802_request_release;
714 memcpy(driver, drv, sizeof(*driver)); 715 memcpy(driver, drv, sizeof(*driver));
715 716
717 mutex_lock(&drv->core->lock);
716 err = drv->probe(driver); 718 err = drv->probe(driver);
717 if (err == 0) { 719 if (err == 0) {
718 i++; 720 i++;
719 mutex_lock(&drv->core->lock);
720 list_add_tail(&driver->drvlist, &dev->drvlist); 721 list_add_tail(&driver->drvlist, &dev->drvlist);
721 mutex_unlock(&drv->core->lock);
722 } else { 722 } else {
723 printk(KERN_ERR 723 printk(KERN_ERR
724 "%s/2: cx8802 probe failed, err = %d\n", 724 "%s/2: cx8802 probe failed, err = %d\n",
725 dev->core->name, err); 725 dev->core->name, err);
726 } 726 }
727 727 mutex_unlock(&drv->core->lock);
728 } 728 }
729 729
730 return i ? 0 : -ENODEV; 730 err = i ? 0 : -ENODEV;
731out:
732 mutex_unlock(&cx8802_mutex);
733 return err;
731} 734}
732 735
733int cx8802_unregister_driver(struct cx8802_driver *drv) 736int cx8802_unregister_driver(struct cx8802_driver *drv)
@@ -741,6 +744,8 @@ int cx8802_unregister_driver(struct cx8802_driver *drv)
741 drv->type_id == CX88_MPEG_DVB ? "dvb" : "blackbird", 744 drv->type_id == CX88_MPEG_DVB ? "dvb" : "blackbird",
742 drv->hw_access == CX8802_DRVCTL_SHARED ? "shared" : "exclusive"); 745 drv->hw_access == CX8802_DRVCTL_SHARED ? "shared" : "exclusive");
743 746
747 mutex_lock(&cx8802_mutex);
748
744 list_for_each_entry(dev, &cx8802_devlist, devlist) { 749 list_for_each_entry(dev, &cx8802_devlist, devlist) {
745 printk(KERN_INFO 750 printk(KERN_INFO
746 "%s/2: subsystem: %04x:%04x, board: %s [card=%d]\n", 751 "%s/2: subsystem: %04x:%04x, board: %s [card=%d]\n",
@@ -748,6 +753,8 @@ int cx8802_unregister_driver(struct cx8802_driver *drv)
748 dev->pci->subsystem_device, dev->core->board.name, 753 dev->pci->subsystem_device, dev->core->board.name,
749 dev->core->boardnr); 754 dev->core->boardnr);
750 755
756 mutex_lock(&dev->core->lock);
757
751 list_for_each_entry_safe(d, dtmp, &dev->drvlist, drvlist) { 758 list_for_each_entry_safe(d, dtmp, &dev->drvlist, drvlist) {
752 /* only unregister the correct driver type */ 759 /* only unregister the correct driver type */
753 if (d->type_id != drv->type_id) 760 if (d->type_id != drv->type_id)
@@ -755,17 +762,18 @@ int cx8802_unregister_driver(struct cx8802_driver *drv)
755 762
756 err = d->remove(d); 763 err = d->remove(d);
757 if (err == 0) { 764 if (err == 0) {
758 mutex_lock(&drv->core->lock);
759 list_del(&d->drvlist); 765 list_del(&d->drvlist);
760 mutex_unlock(&drv->core->lock);
761 kfree(d); 766 kfree(d);
762 } else 767 } else
763 printk(KERN_ERR "%s/2: cx8802 driver remove " 768 printk(KERN_ERR "%s/2: cx8802 driver remove "
764 "failed (%d)\n", dev->core->name, err); 769 "failed (%d)\n", dev->core->name, err);
765 } 770 }
766 771
772 mutex_unlock(&dev->core->lock);
767 } 773 }
768 774
775 mutex_unlock(&cx8802_mutex);
776
769 return err; 777 return err;
770} 778}
771 779
@@ -803,7 +811,9 @@ static int __devinit cx8802_probe(struct pci_dev *pci_dev,
803 goto fail_free; 811 goto fail_free;
804 812
805 INIT_LIST_HEAD(&dev->drvlist); 813 INIT_LIST_HEAD(&dev->drvlist);
814 mutex_lock(&cx8802_mutex);
806 list_add_tail(&dev->devlist,&cx8802_devlist); 815 list_add_tail(&dev->devlist,&cx8802_devlist);
816 mutex_unlock(&cx8802_mutex);
807 817
808 /* now autoload cx88-dvb or cx88-blackbird */ 818 /* now autoload cx88-dvb or cx88-blackbird */
809 request_modules(dev); 819 request_modules(dev);
@@ -827,6 +837,8 @@ static void __devexit cx8802_remove(struct pci_dev *pci_dev)
827 837
828 flush_request_modules(dev); 838 flush_request_modules(dev);
829 839
840 mutex_lock(&dev->core->lock);
841
830 if (!list_empty(&dev->drvlist)) { 842 if (!list_empty(&dev->drvlist)) {
831 struct cx8802_driver *drv, *tmp; 843 struct cx8802_driver *drv, *tmp;
832 int err; 844 int err;
@@ -838,9 +850,7 @@ static void __devexit cx8802_remove(struct pci_dev *pci_dev)
838 list_for_each_entry_safe(drv, tmp, &dev->drvlist, drvlist) { 850 list_for_each_entry_safe(drv, tmp, &dev->drvlist, drvlist) {
839 err = drv->remove(drv); 851 err = drv->remove(drv);
840 if (err == 0) { 852 if (err == 0) {
841 mutex_lock(&drv->core->lock);
842 list_del(&drv->drvlist); 853 list_del(&drv->drvlist);
843 mutex_unlock(&drv->core->lock);
844 } else 854 } else
845 printk(KERN_ERR "%s/2: cx8802 driver remove " 855 printk(KERN_ERR "%s/2: cx8802 driver remove "
846 "failed (%d)\n", dev->core->name, err); 856 "failed (%d)\n", dev->core->name, err);
@@ -848,6 +858,8 @@ static void __devexit cx8802_remove(struct pci_dev *pci_dev)
848 } 858 }
849 } 859 }
850 860
861 mutex_unlock(&dev->core->lock);
862
851 /* Destroy any 8802 reference. */ 863 /* Destroy any 8802 reference. */
852 dev->core->dvbdev = NULL; 864 dev->core->dvbdev = NULL;
853 865
diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c
index 287a41ee1c4f..cef4f282e5aa 100644
--- a/drivers/media/video/cx88/cx88-video.c
+++ b/drivers/media/video/cx88/cx88-video.c
@@ -824,7 +824,7 @@ static int video_open(struct file *file)
824 call_all(core, tuner, s_radio); 824 call_all(core, tuner, s_radio);
825 } 825 }
826 826
827 atomic_inc(&core->users); 827 core->users++;
828 mutex_unlock(&core->lock); 828 mutex_unlock(&core->lock);
829 829
830 return 0; 830 return 0;
@@ -922,7 +922,8 @@ static int video_release(struct file *file)
922 file->private_data = NULL; 922 file->private_data = NULL;
923 kfree(fh); 923 kfree(fh);
924 924
925 if(atomic_dec_and_test(&dev->core->users)) 925 dev->core->users--;
926 if (!dev->core->users)
926 call_all(dev->core, core, s_power, 0); 927 call_all(dev->core, core, s_power, 0);
927 mutex_unlock(&dev->core->lock); 928 mutex_unlock(&dev->core->lock);
928 929
@@ -1832,7 +1833,7 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev,
1832 dev->core = core; 1833 dev->core = core;
1833 1834
1834 /* print pci info */ 1835 /* print pci info */
1835 pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &dev->pci_rev); 1836 dev->pci_rev = pci_dev->revision;
1836 pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &dev->pci_lat); 1837 pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &dev->pci_lat);
1837 printk(KERN_INFO "%s/0: found at %s, rev: %d, irq: %d, " 1838 printk(KERN_INFO "%s/0: found at %s, rev: %d, irq: %d, "
1838 "latency: %d, mmio: 0x%llx\n", core->name, 1839 "latency: %d, mmio: 0x%llx\n", core->name,
diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h
index 9b3742a7746c..a399a8b086ba 100644
--- a/drivers/media/video/cx88/cx88.h
+++ b/drivers/media/video/cx88/cx88.h
@@ -389,8 +389,8 @@ struct cx88_core {
389 struct mutex lock; 389 struct mutex lock;
390 /* various v4l controls */ 390 /* various v4l controls */
391 u32 freq; 391 u32 freq;
392 atomic_t users; 392 int users;
393 atomic_t mpeg_users; 393 int mpeg_users;
394 394
395 /* cx88-video needs to access cx8802 for hybrid tuner pll access. */ 395 /* cx88-video needs to access cx8802 for hybrid tuner pll access. */
396 struct cx8802_dev *dvbdev; 396 struct cx8802_dev *dvbdev;
@@ -505,6 +505,8 @@ struct cx8802_driver {
505 int (*suspend)(struct pci_dev *pci_dev, pm_message_t state); 505 int (*suspend)(struct pci_dev *pci_dev, pm_message_t state);
506 int (*resume)(struct pci_dev *pci_dev); 506 int (*resume)(struct pci_dev *pci_dev);
507 507
508 /* Callers to the following functions must hold core->lock */
509
508 /* MPEG 8802 -> mini driver - Driver probe and configuration */ 510 /* MPEG 8802 -> mini driver - Driver probe and configuration */
509 int (*probe)(struct cx8802_driver *drv); 511 int (*probe)(struct cx8802_driver *drv);
510 int (*remove)(struct cx8802_driver *drv); 512 int (*remove)(struct cx8802_driver *drv);
@@ -561,8 +563,9 @@ struct cx8802_dev {
561 /* for switching modulation types */ 563 /* for switching modulation types */
562 unsigned char ts_gen_cntrl; 564 unsigned char ts_gen_cntrl;
563 565
564 /* List of attached drivers */ 566 /* List of attached drivers; must hold core->lock to access */
565 struct list_head drvlist; 567 struct list_head drvlist;
568
566 struct work_struct request_module_wk; 569 struct work_struct request_module_wk;
567}; 570};
568 571
@@ -685,6 +688,8 @@ int cx88_audio_thread(void *data);
685 688
686int cx8802_register_driver(struct cx8802_driver *drv); 689int cx8802_register_driver(struct cx8802_driver *drv);
687int cx8802_unregister_driver(struct cx8802_driver *drv); 690int cx8802_unregister_driver(struct cx8802_driver *drv);
691
692/* Caller must hold core->lock */
688struct cx8802_driver * cx8802_get_driver(struct cx8802_dev *dev, enum cx88_board_type btype); 693struct cx8802_driver * cx8802_get_driver(struct cx8802_dev *dev, enum cx88_board_type btype);
689 694
690/* ----------------------------------------------------------- */ 695/* ----------------------------------------------------------- */
diff --git a/drivers/media/video/em28xx/Kconfig b/drivers/media/video/em28xx/Kconfig
index 985100ea17a4..3cb78f26df90 100644
--- a/drivers/media/video/em28xx/Kconfig
+++ b/drivers/media/video/em28xx/Kconfig
@@ -38,6 +38,8 @@ config VIDEO_EM28XX_DVB
38 select DVB_ZL10353 if !DVB_FE_CUSTOMISE 38 select DVB_ZL10353 if !DVB_FE_CUSTOMISE
39 select DVB_TDA10023 if !DVB_FE_CUSTOMISE 39 select DVB_TDA10023 if !DVB_FE_CUSTOMISE
40 select DVB_S921 if !DVB_FE_CUSTOMISE 40 select DVB_S921 if !DVB_FE_CUSTOMISE
41 select DVB_DRXD if !DVB_FE_CUSTOMISE
42 select DVB_CXD2820R if !DVB_FE_CUSTOMISE
41 select VIDEOBUF_DVB 43 select VIDEOBUF_DVB
42 ---help--- 44 ---help---
43 This adds support for DVB cards based on the 45 This adds support for DVB cards based on the
diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c
index 69fcea82d01c..4e37375decf5 100644
--- a/drivers/media/video/em28xx/em28xx-cards.c
+++ b/drivers/media/video/em28xx/em28xx-cards.c
@@ -100,6 +100,13 @@ static struct em28xx_reg_seq hauppauge_wintv_hvr_900_digital[] = {
100 { -1, -1, -1, -1}, 100 { -1, -1, -1, -1},
101}; 101};
102 102
103/* Board Hauppauge WinTV HVR 900 (R2) digital */
104static struct em28xx_reg_seq hauppauge_wintv_hvr_900R2_digital[] = {
105 {EM28XX_R08_GPIO, 0x2e, ~EM_GPIO_4, 10},
106 {EM2880_R04_GPO, 0x0c, 0x0f, 10},
107 { -1, -1, -1, -1},
108};
109
103/* Boards - EM2880 MSI DIGIVOX AD and EM2880_BOARD_MSI_DIGIVOX_AD_II */ 110/* Boards - EM2880 MSI DIGIVOX AD and EM2880_BOARD_MSI_DIGIVOX_AD_II */
104static struct em28xx_reg_seq em2880_msi_digivox_ad_analog[] = { 111static struct em28xx_reg_seq em2880_msi_digivox_ad_analog[] = {
105 {EM28XX_R08_GPIO, 0x69, ~EM_GPIO_4, 10}, 112 {EM28XX_R08_GPIO, 0x69, ~EM_GPIO_4, 10},
@@ -282,6 +289,16 @@ static struct em28xx_reg_seq leadership_reset[] = {
282 { -1, -1, -1, -1}, 289 { -1, -1, -1, -1},
283}; 290};
284 291
292/* 2013:024f PCTV Systems nanoStick T2 290e
293 * GPIO_6 - demod reset
294 * GPIO_7 - LED
295 */
296static struct em28xx_reg_seq pctv_290e[] = {
297 {EM2874_R80_GPIO, 0x00, 0xff, 80},
298 {EM2874_R80_GPIO, 0x40, 0xff, 80}, /* GPIO_6 = 1 */
299 {EM2874_R80_GPIO, 0xc0, 0xff, 80}, /* GPIO_7 = 1 */
300 {-1, -1, -1, -1},
301};
285 302
286/* 303/*
287 * Board definitions 304 * Board definitions
@@ -859,6 +876,8 @@ struct em28xx_board em28xx_boards[] = {
859 .tuner_type = TUNER_XC2028, 876 .tuner_type = TUNER_XC2028,
860 .tuner_gpio = default_tuner_gpio, 877 .tuner_gpio = default_tuner_gpio,
861 .mts_firmware = 1, 878 .mts_firmware = 1,
879 .has_dvb = 1,
880 .dvb_gpio = hauppauge_wintv_hvr_900R2_digital,
862 .ir_codes = RC_MAP_HAUPPAUGE, 881 .ir_codes = RC_MAP_HAUPPAUGE,
863 .decoder = EM28XX_TVP5150, 882 .decoder = EM28XX_TVP5150,
864 .input = { { 883 .input = { {
@@ -1448,12 +1467,14 @@ struct em28xx_board em28xx_boards[] = {
1448 .gpio = pinnacle_hybrid_pro_analog, 1467 .gpio = pinnacle_hybrid_pro_analog,
1449 } }, 1468 } },
1450 }, 1469 },
1451 [EM2882_BOARD_PINNACLE_HYBRID_PRO] = { 1470 [EM2882_BOARD_PINNACLE_HYBRID_PRO_330E] = {
1452 .name = "Pinnacle Hybrid Pro (2)", 1471 .name = "Pinnacle Hybrid Pro (330e)",
1453 .valid = EM28XX_BOARD_NOT_VALIDATED,
1454 .tuner_type = TUNER_XC2028, 1472 .tuner_type = TUNER_XC2028,
1455 .tuner_gpio = default_tuner_gpio, 1473 .tuner_gpio = default_tuner_gpio,
1456 .mts_firmware = 1, 1474 .mts_firmware = 1,
1475 .has_dvb = 1,
1476 .dvb_gpio = hauppauge_wintv_hvr_900R2_digital,
1477 .ir_codes = RC_MAP_PINNACLE_PCTV_HD,
1457 .decoder = EM28XX_TVP5150, 1478 .decoder = EM28XX_TVP5150,
1458 .input = { { 1479 .input = { {
1459 .type = EM28XX_VMUX_TELEVISION, 1480 .type = EM28XX_VMUX_TELEVISION,
@@ -1749,6 +1770,17 @@ struct em28xx_board em28xx_boards[] = {
1749 .dvb_gpio = kworld_a340_digital, 1770 .dvb_gpio = kworld_a340_digital,
1750 .tuner_gpio = default_tuner_gpio, 1771 .tuner_gpio = default_tuner_gpio,
1751 }, 1772 },
1773 /* 2013:024f PCTV Systems nanoStick T2 290e.
1774 * Empia EM28174, Sony CXD2820R and NXP TDA18271HD/C2 */
1775 [EM28174_BOARD_PCTV_290E] = {
1776 .i2c_speed = EM2874_I2C_SECONDARY_BUS_SELECT |
1777 EM28XX_I2C_CLK_WAIT_ENABLE | EM28XX_I2C_FREQ_100_KHZ,
1778 .xclk = EM28XX_XCLK_FREQUENCY_12MHZ,
1779 .name = "PCTV Systems nanoStick T2 290e",
1780 .tuner_type = TUNER_ABSENT,
1781 .tuner_gpio = pctv_290e,
1782 .has_dvb = 1,
1783 },
1752}; 1784};
1753const unsigned int em28xx_bcount = ARRAY_SIZE(em28xx_boards); 1785const unsigned int em28xx_bcount = ARRAY_SIZE(em28xx_boards);
1754 1786
@@ -1863,7 +1895,7 @@ struct usb_device_id em28xx_id_table[] = {
1863 { USB_DEVICE(0x2304, 0x021a), 1895 { USB_DEVICE(0x2304, 0x021a),
1864 .driver_info = EM2820_BOARD_PINNACLE_DVC_90 }, 1896 .driver_info = EM2820_BOARD_PINNACLE_DVC_90 },
1865 { USB_DEVICE(0x2304, 0x0226), 1897 { USB_DEVICE(0x2304, 0x0226),
1866 .driver_info = EM2882_BOARD_PINNACLE_HYBRID_PRO }, 1898 .driver_info = EM2882_BOARD_PINNACLE_HYBRID_PRO_330E },
1867 { USB_DEVICE(0x2304, 0x0227), 1899 { USB_DEVICE(0x2304, 0x0227),
1868 .driver_info = EM2880_BOARD_PINNACLE_PCTV_HD_PRO }, 1900 .driver_info = EM2880_BOARD_PINNACLE_PCTV_HD_PRO },
1869 { USB_DEVICE(0x0413, 0x6023), 1901 { USB_DEVICE(0x0413, 0x6023),
@@ -1876,6 +1908,8 @@ struct usb_device_id em28xx_id_table[] = {
1876 .driver_info = EM2860_BOARD_GADMEI_UTV330 }, 1908 .driver_info = EM2860_BOARD_GADMEI_UTV330 },
1877 { USB_DEVICE(0x1b80, 0xa340), 1909 { USB_DEVICE(0x1b80, 0xa340),
1878 .driver_info = EM2870_BOARD_KWORLD_A340 }, 1910 .driver_info = EM2870_BOARD_KWORLD_A340 },
1911 { USB_DEVICE(0x2013, 0x024f),
1912 .driver_info = EM28174_BOARD_PCTV_290E },
1879 { }, 1913 { },
1880}; 1914};
1881MODULE_DEVICE_TABLE(usb, em28xx_id_table); 1915MODULE_DEVICE_TABLE(usb, em28xx_id_table);
@@ -2229,7 +2263,7 @@ static void em28xx_setup_xc3028(struct em28xx *dev, struct xc2028_ctrl *ctl)
2229 ctl->demod = XC3028_FE_ZARLINK456; 2263 ctl->demod = XC3028_FE_ZARLINK456;
2230 break; 2264 break;
2231 case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2: 2265 case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2:
2232 /* djh - Not sure which demod we need here */ 2266 case EM2882_BOARD_PINNACLE_HYBRID_PRO_330E:
2233 ctl->demod = XC3028_FE_DEFAULT; 2267 ctl->demod = XC3028_FE_DEFAULT;
2234 break; 2268 break;
2235 case EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600: 2269 case EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600:
@@ -2799,6 +2833,11 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
2799 dev->reg_gpio_num = EM2874_R80_GPIO; 2833 dev->reg_gpio_num = EM2874_R80_GPIO;
2800 dev->wait_after_write = 0; 2834 dev->wait_after_write = 0;
2801 break; 2835 break;
2836 case CHIP_ID_EM28174:
2837 em28xx_info("chip ID is em28174\n");
2838 dev->reg_gpio_num = EM2874_R80_GPIO;
2839 dev->wait_after_write = 0;
2840 break;
2802 case CHIP_ID_EM2883: 2841 case CHIP_ID_EM2883:
2803 em28xx_info("chip ID is em2882/em2883\n"); 2842 em28xx_info("chip ID is em2882/em2883\n");
2804 dev->wait_after_write = 0; 2843 dev->wait_after_write = 0;
diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c
index 44c63cbd6dda..e33f145d867a 100644
--- a/drivers/media/video/em28xx/em28xx-core.c
+++ b/drivers/media/video/em28xx/em28xx-core.c
@@ -489,7 +489,8 @@ int em28xx_audio_setup(struct em28xx *dev)
489 int vid1, vid2, feat, cfg; 489 int vid1, vid2, feat, cfg;
490 u32 vid; 490 u32 vid;
491 491
492 if (dev->chip_id == CHIP_ID_EM2870 || dev->chip_id == CHIP_ID_EM2874) { 492 if (dev->chip_id == CHIP_ID_EM2870 || dev->chip_id == CHIP_ID_EM2874
493 || dev->chip_id == CHIP_ID_EM28174) {
493 /* Digital only device - don't load any alsa module */ 494 /* Digital only device - don't load any alsa module */
494 dev->audio_mode.has_audio = 0; 495 dev->audio_mode.has_audio = 0;
495 dev->has_audio_class = 0; 496 dev->has_audio_class = 0;
@@ -614,7 +615,7 @@ int em28xx_capture_start(struct em28xx *dev, int start)
614{ 615{
615 int rc; 616 int rc;
616 617
617 if (dev->chip_id == CHIP_ID_EM2874) { 618 if (dev->chip_id == CHIP_ID_EM2874 || dev->chip_id == CHIP_ID_EM28174) {
618 /* The Transport Stream Enable Register moved in em2874 */ 619 /* The Transport Stream Enable Register moved in em2874 */
619 if (!start) { 620 if (!start) {
620 rc = em28xx_write_reg_bits(dev, EM2874_R5F_TS_ENABLE, 621 rc = em28xx_write_reg_bits(dev, EM2874_R5F_TS_ENABLE,
@@ -1111,6 +1112,10 @@ int em28xx_isoc_dvb_max_packetsize(struct em28xx *dev)
1111 /* FIXME - for now assume 564 like it was before, but the 1112 /* FIXME - for now assume 564 like it was before, but the
1112 em2874 code should be added to return the proper value... */ 1113 em2874 code should be added to return the proper value... */
1113 packet_size = 564; 1114 packet_size = 564;
1115 } else if (dev->chip_id == CHIP_ID_EM28174) {
1116 /* FIXME same as em2874. 564 was enough for 22 Mbit DVB-T
1117 but too much for 44 Mbit DVB-C. */
1118 packet_size = 752;
1114 } else { 1119 } else {
1115 /* TS max packet size stored in bits 1-0 of R01 */ 1120 /* TS max packet size stored in bits 1-0 of R01 */
1116 chip_cfg2 = em28xx_read_reg(dev, EM28XX_R01_CHIPCFG2); 1121 chip_cfg2 = em28xx_read_reg(dev, EM28XX_R01_CHIPCFG2);
diff --git a/drivers/media/video/em28xx/em28xx-dvb.c b/drivers/media/video/em28xx/em28xx-dvb.c
index c7c04bf712aa..7904ca4b6913 100644
--- a/drivers/media/video/em28xx/em28xx-dvb.c
+++ b/drivers/media/video/em28xx/em28xx-dvb.c
@@ -38,6 +38,8 @@
38#include "tda1002x.h" 38#include "tda1002x.h"
39#include "tda18271.h" 39#include "tda18271.h"
40#include "s921.h" 40#include "s921.h"
41#include "drxd.h"
42#include "cxd2820r.h"
41 43
42MODULE_DESCRIPTION("driver for em28xx based DVB cards"); 44MODULE_DESCRIPTION("driver for em28xx based DVB cards");
43MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>"); 45MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>");
@@ -58,7 +60,7 @@ if (debug >= level) \
58#define EM28XX_DVB_MAX_PACKETS 64 60#define EM28XX_DVB_MAX_PACKETS 64
59 61
60struct em28xx_dvb { 62struct em28xx_dvb {
61 struct dvb_frontend *frontend; 63 struct dvb_frontend *fe[2];
62 64
63 /* feed count management */ 65 /* feed count management */
64 struct mutex lock; 66 struct mutex lock;
@@ -285,12 +287,13 @@ static struct zl10353_config em28xx_zl10353_xc3028_no_i2c_gate = {
285 .if2 = 45600, 287 .if2 = 45600,
286}; 288};
287 289
288#ifdef EM28XX_DRX397XD_SUPPORT 290static struct drxd_config em28xx_drxd = {
289/* [TODO] djh - not sure yet what the device config needs to contain */ 291 .index = 0, .demod_address = 0x70, .demod_revision = 0xa2,
290static struct drx397xD_config em28xx_drx397xD_with_xc3028 = { 292 .demoda_address = 0x00, .pll_address = 0x00,
291 .demod_address = (0xe0 >> 1), 293 .pll_type = DRXD_PLL_NONE, .clock = 12000, .insert_rs_byte = 1,
294 .pll_set = NULL, .osc_deviation = NULL, .IF = 42800000,
295 .disable_i2c_gate_ctrl = 1,
292}; 296};
293#endif
294 297
295static int mt352_terratec_xs_init(struct dvb_frontend *fe) 298static int mt352_terratec_xs_init(struct dvb_frontend *fe)
296{ 299{
@@ -332,6 +335,26 @@ static struct tda10023_config em28xx_tda10023_config = {
332 .invert = 1, 335 .invert = 1,
333}; 336};
334 337
338static struct cxd2820r_config em28xx_cxd2820r_config = {
339 .i2c_address = (0xd8 >> 1),
340 .ts_mode = CXD2820R_TS_SERIAL,
341 .if_dvbt_6 = 3300,
342 .if_dvbt_7 = 3500,
343 .if_dvbt_8 = 4000,
344 .if_dvbt2_6 = 3300,
345 .if_dvbt2_7 = 3500,
346 .if_dvbt2_8 = 4000,
347 .if_dvbc = 5000,
348
349 /* enable LNA for DVB-T2 and DVB-C */
350 .gpio_dvbt2[0] = CXD2820R_GPIO_E | CXD2820R_GPIO_O | CXD2820R_GPIO_L,
351 .gpio_dvbc[0] = CXD2820R_GPIO_E | CXD2820R_GPIO_O | CXD2820R_GPIO_L,
352};
353
354static struct tda18271_config em28xx_cxd2820r_tda18271_config = {
355 .output_opt = TDA18271_OUTPUT_LT_OFF,
356};
357
335/* ------------------------------------------------------------------ */ 358/* ------------------------------------------------------------------ */
336 359
337static int attach_xc3028(u8 addr, struct em28xx *dev) 360static int attach_xc3028(u8 addr, struct em28xx *dev)
@@ -343,17 +366,17 @@ static int attach_xc3028(u8 addr, struct em28xx *dev)
343 cfg.i2c_adap = &dev->i2c_adap; 366 cfg.i2c_adap = &dev->i2c_adap;
344 cfg.i2c_addr = addr; 367 cfg.i2c_addr = addr;
345 368
346 if (!dev->dvb->frontend) { 369 if (!dev->dvb->fe[0]) {
347 em28xx_errdev("/2: dvb frontend not attached. " 370 em28xx_errdev("/2: dvb frontend not attached. "
348 "Can't attach xc3028\n"); 371 "Can't attach xc3028\n");
349 return -EINVAL; 372 return -EINVAL;
350 } 373 }
351 374
352 fe = dvb_attach(xc2028_attach, dev->dvb->frontend, &cfg); 375 fe = dvb_attach(xc2028_attach, dev->dvb->fe[0], &cfg);
353 if (!fe) { 376 if (!fe) {
354 em28xx_errdev("/2: xc3028 attach failed\n"); 377 em28xx_errdev("/2: xc3028 attach failed\n");
355 dvb_frontend_detach(dev->dvb->frontend); 378 dvb_frontend_detach(dev->dvb->fe[0]);
356 dev->dvb->frontend = NULL; 379 dev->dvb->fe[0] = NULL;
357 return -EINVAL; 380 return -EINVAL;
358 } 381 }
359 382
@@ -383,16 +406,28 @@ static int register_dvb(struct em28xx_dvb *dvb,
383 } 406 }
384 407
385 /* Ensure all frontends negotiate bus access */ 408 /* Ensure all frontends negotiate bus access */
386 dvb->frontend->ops.ts_bus_ctrl = em28xx_dvb_bus_ctrl; 409 dvb->fe[0]->ops.ts_bus_ctrl = em28xx_dvb_bus_ctrl;
410 if (dvb->fe[1])
411 dvb->fe[1]->ops.ts_bus_ctrl = em28xx_dvb_bus_ctrl;
387 412
388 dvb->adapter.priv = dev; 413 dvb->adapter.priv = dev;
389 414
390 /* register frontend */ 415 /* register frontend */
391 result = dvb_register_frontend(&dvb->adapter, dvb->frontend); 416 result = dvb_register_frontend(&dvb->adapter, dvb->fe[0]);
392 if (result < 0) { 417 if (result < 0) {
393 printk(KERN_WARNING "%s: dvb_register_frontend failed (errno = %d)\n", 418 printk(KERN_WARNING "%s: dvb_register_frontend failed (errno = %d)\n",
394 dev->name, result); 419 dev->name, result);
395 goto fail_frontend; 420 goto fail_frontend0;
421 }
422
423 /* register 2nd frontend */
424 if (dvb->fe[1]) {
425 result = dvb_register_frontend(&dvb->adapter, dvb->fe[1]);
426 if (result < 0) {
427 printk(KERN_WARNING "%s: 2nd dvb_register_frontend failed (errno = %d)\n",
428 dev->name, result);
429 goto fail_frontend1;
430 }
396 } 431 }
397 432
398 /* register demux stuff */ 433 /* register demux stuff */
@@ -458,9 +493,14 @@ fail_fe_hw:
458fail_dmxdev: 493fail_dmxdev:
459 dvb_dmx_release(&dvb->demux); 494 dvb_dmx_release(&dvb->demux);
460fail_dmx: 495fail_dmx:
461 dvb_unregister_frontend(dvb->frontend); 496 if (dvb->fe[1])
462fail_frontend: 497 dvb_unregister_frontend(dvb->fe[1]);
463 dvb_frontend_detach(dvb->frontend); 498 dvb_unregister_frontend(dvb->fe[0]);
499fail_frontend1:
500 if (dvb->fe[1])
501 dvb_frontend_detach(dvb->fe[1]);
502fail_frontend0:
503 dvb_frontend_detach(dvb->fe[0]);
464 dvb_unregister_adapter(&dvb->adapter); 504 dvb_unregister_adapter(&dvb->adapter);
465fail_adapter: 505fail_adapter:
466 return result; 506 return result;
@@ -473,12 +513,15 @@ static void unregister_dvb(struct em28xx_dvb *dvb)
473 dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_hw); 513 dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_hw);
474 dvb_dmxdev_release(&dvb->dmxdev); 514 dvb_dmxdev_release(&dvb->dmxdev);
475 dvb_dmx_release(&dvb->demux); 515 dvb_dmx_release(&dvb->demux);
476 dvb_unregister_frontend(dvb->frontend); 516 if (dvb->fe[1])
477 dvb_frontend_detach(dvb->frontend); 517 dvb_unregister_frontend(dvb->fe[1]);
518 dvb_unregister_frontend(dvb->fe[0]);
519 if (dvb->fe[1])
520 dvb_frontend_detach(dvb->fe[1]);
521 dvb_frontend_detach(dvb->fe[0]);
478 dvb_unregister_adapter(&dvb->adapter); 522 dvb_unregister_adapter(&dvb->adapter);
479} 523}
480 524
481
482static int dvb_init(struct em28xx *dev) 525static int dvb_init(struct em28xx *dev)
483{ 526{
484 int result = 0; 527 int result = 0;
@@ -497,16 +540,17 @@ static int dvb_init(struct em28xx *dev)
497 return -ENOMEM; 540 return -ENOMEM;
498 } 541 }
499 dev->dvb = dvb; 542 dev->dvb = dvb;
543 dvb->fe[0] = dvb->fe[1] = NULL;
500 544
501 mutex_lock(&dev->lock); 545 mutex_lock(&dev->lock);
502 em28xx_set_mode(dev, EM28XX_DIGITAL_MODE); 546 em28xx_set_mode(dev, EM28XX_DIGITAL_MODE);
503 /* init frontend */ 547 /* init frontend */
504 switch (dev->model) { 548 switch (dev->model) {
505 case EM2874_LEADERSHIP_ISDBT: 549 case EM2874_LEADERSHIP_ISDBT:
506 dvb->frontend = dvb_attach(s921_attach, 550 dvb->fe[0] = dvb_attach(s921_attach,
507 &sharp_isdbt, &dev->i2c_adap); 551 &sharp_isdbt, &dev->i2c_adap);
508 552
509 if (!dvb->frontend) { 553 if (!dvb->fe[0]) {
510 result = -EINVAL; 554 result = -EINVAL;
511 goto out_free; 555 goto out_free;
512 } 556 }
@@ -516,7 +560,7 @@ static int dvb_init(struct em28xx *dev)
516 case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950: 560 case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950:
517 case EM2880_BOARD_PINNACLE_PCTV_HD_PRO: 561 case EM2880_BOARD_PINNACLE_PCTV_HD_PRO:
518 case EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600: 562 case EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600:
519 dvb->frontend = dvb_attach(lgdt330x_attach, 563 dvb->fe[0] = dvb_attach(lgdt330x_attach,
520 &em2880_lgdt3303_dev, 564 &em2880_lgdt3303_dev,
521 &dev->i2c_adap); 565 &dev->i2c_adap);
522 if (attach_xc3028(0x61, dev) < 0) { 566 if (attach_xc3028(0x61, dev) < 0) {
@@ -525,7 +569,7 @@ static int dvb_init(struct em28xx *dev)
525 } 569 }
526 break; 570 break;
527 case EM2880_BOARD_KWORLD_DVB_310U: 571 case EM2880_BOARD_KWORLD_DVB_310U:
528 dvb->frontend = dvb_attach(zl10353_attach, 572 dvb->fe[0] = dvb_attach(zl10353_attach,
529 &em28xx_zl10353_with_xc3028, 573 &em28xx_zl10353_with_xc3028,
530 &dev->i2c_adap); 574 &dev->i2c_adap);
531 if (attach_xc3028(0x61, dev) < 0) { 575 if (attach_xc3028(0x61, dev) < 0) {
@@ -536,7 +580,7 @@ static int dvb_init(struct em28xx *dev)
536 case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900: 580 case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900:
537 case EM2882_BOARD_TERRATEC_HYBRID_XS: 581 case EM2882_BOARD_TERRATEC_HYBRID_XS:
538 case EM2880_BOARD_EMPIRE_DUAL_TV: 582 case EM2880_BOARD_EMPIRE_DUAL_TV:
539 dvb->frontend = dvb_attach(zl10353_attach, 583 dvb->fe[0] = dvb_attach(zl10353_attach,
540 &em28xx_zl10353_xc3028_no_i2c_gate, 584 &em28xx_zl10353_xc3028_no_i2c_gate,
541 &dev->i2c_adap); 585 &dev->i2c_adap);
542 if (attach_xc3028(0x61, dev) < 0) { 586 if (attach_xc3028(0x61, dev) < 0) {
@@ -549,13 +593,13 @@ static int dvb_init(struct em28xx *dev)
549 case EM2881_BOARD_PINNACLE_HYBRID_PRO: 593 case EM2881_BOARD_PINNACLE_HYBRID_PRO:
550 case EM2882_BOARD_DIKOM_DK300: 594 case EM2882_BOARD_DIKOM_DK300:
551 case EM2882_BOARD_KWORLD_VS_DVBT: 595 case EM2882_BOARD_KWORLD_VS_DVBT:
552 dvb->frontend = dvb_attach(zl10353_attach, 596 dvb->fe[0] = dvb_attach(zl10353_attach,
553 &em28xx_zl10353_xc3028_no_i2c_gate, 597 &em28xx_zl10353_xc3028_no_i2c_gate,
554 &dev->i2c_adap); 598 &dev->i2c_adap);
555 if (dvb->frontend == NULL) { 599 if (dvb->fe[0] == NULL) {
556 /* This board could have either a zl10353 or a mt352. 600 /* This board could have either a zl10353 or a mt352.
557 If the chip id isn't for zl10353, try mt352 */ 601 If the chip id isn't for zl10353, try mt352 */
558 dvb->frontend = dvb_attach(mt352_attach, 602 dvb->fe[0] = dvb_attach(mt352_attach,
559 &terratec_xs_mt352_cfg, 603 &terratec_xs_mt352_cfg,
560 &dev->i2c_adap); 604 &dev->i2c_adap);
561 } 605 }
@@ -567,7 +611,7 @@ static int dvb_init(struct em28xx *dev)
567 break; 611 break;
568 case EM2883_BOARD_KWORLD_HYBRID_330U: 612 case EM2883_BOARD_KWORLD_HYBRID_330U:
569 case EM2882_BOARD_EVGA_INDTUBE: 613 case EM2882_BOARD_EVGA_INDTUBE:
570 dvb->frontend = dvb_attach(s5h1409_attach, 614 dvb->fe[0] = dvb_attach(s5h1409_attach,
571 &em28xx_s5h1409_with_xc3028, 615 &em28xx_s5h1409_with_xc3028,
572 &dev->i2c_adap); 616 &dev->i2c_adap);
573 if (attach_xc3028(0x61, dev) < 0) { 617 if (attach_xc3028(0x61, dev) < 0) {
@@ -576,11 +620,11 @@ static int dvb_init(struct em28xx *dev)
576 } 620 }
577 break; 621 break;
578 case EM2882_BOARD_KWORLD_ATSC_315U: 622 case EM2882_BOARD_KWORLD_ATSC_315U:
579 dvb->frontend = dvb_attach(lgdt330x_attach, 623 dvb->fe[0] = dvb_attach(lgdt330x_attach,
580 &em2880_lgdt3303_dev, 624 &em2880_lgdt3303_dev,
581 &dev->i2c_adap); 625 &dev->i2c_adap);
582 if (dvb->frontend != NULL) { 626 if (dvb->fe[0] != NULL) {
583 if (!dvb_attach(simple_tuner_attach, dvb->frontend, 627 if (!dvb_attach(simple_tuner_attach, dvb->fe[0],
584 &dev->i2c_adap, 0x61, TUNER_THOMSON_DTT761X)) { 628 &dev->i2c_adap, 0x61, TUNER_THOMSON_DTT761X)) {
585 result = -EINVAL; 629 result = -EINVAL;
586 goto out_free; 630 goto out_free;
@@ -588,25 +632,21 @@ static int dvb_init(struct em28xx *dev)
588 } 632 }
589 break; 633 break;
590 case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2: 634 case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2:
591#ifdef EM28XX_DRX397XD_SUPPORT 635 case EM2882_BOARD_PINNACLE_HYBRID_PRO_330E:
592 /* We don't have the config structure properly populated, so 636 dvb->fe[0] = dvb_attach(drxd_attach, &em28xx_drxd, NULL,
593 this is commented out for now */ 637 &dev->i2c_adap, &dev->udev->dev);
594 dvb->frontend = dvb_attach(drx397xD_attach,
595 &em28xx_drx397xD_with_xc3028,
596 &dev->i2c_adap);
597 if (attach_xc3028(0x61, dev) < 0) { 638 if (attach_xc3028(0x61, dev) < 0) {
598 result = -EINVAL; 639 result = -EINVAL;
599 goto out_free; 640 goto out_free;
600 } 641 }
601 break; 642 break;
602#endif
603 case EM2870_BOARD_REDDO_DVB_C_USB_BOX: 643 case EM2870_BOARD_REDDO_DVB_C_USB_BOX:
604 /* Philips CU1216L NIM (Philips TDA10023 + Infineon TUA6034) */ 644 /* Philips CU1216L NIM (Philips TDA10023 + Infineon TUA6034) */
605 dvb->frontend = dvb_attach(tda10023_attach, 645 dvb->fe[0] = dvb_attach(tda10023_attach,
606 &em28xx_tda10023_config, 646 &em28xx_tda10023_config,
607 &dev->i2c_adap, 0x48); 647 &dev->i2c_adap, 0x48);
608 if (dvb->frontend) { 648 if (dvb->fe[0]) {
609 if (!dvb_attach(simple_tuner_attach, dvb->frontend, 649 if (!dvb_attach(simple_tuner_attach, dvb->fe[0],
610 &dev->i2c_adap, 0x60, TUNER_PHILIPS_CU1216L)) { 650 &dev->i2c_adap, 0x60, TUNER_PHILIPS_CU1216L)) {
611 result = -EINVAL; 651 result = -EINVAL;
612 goto out_free; 652 goto out_free;
@@ -614,25 +654,53 @@ static int dvb_init(struct em28xx *dev)
614 } 654 }
615 break; 655 break;
616 case EM2870_BOARD_KWORLD_A340: 656 case EM2870_BOARD_KWORLD_A340:
617 dvb->frontend = dvb_attach(lgdt3305_attach, 657 dvb->fe[0] = dvb_attach(lgdt3305_attach,
618 &em2870_lgdt3304_dev, 658 &em2870_lgdt3304_dev,
619 &dev->i2c_adap); 659 &dev->i2c_adap);
620 if (dvb->frontend != NULL) 660 if (dvb->fe[0] != NULL)
621 dvb_attach(tda18271_attach, dvb->frontend, 0x60, 661 dvb_attach(tda18271_attach, dvb->fe[0], 0x60,
622 &dev->i2c_adap, &kworld_a340_config); 662 &dev->i2c_adap, &kworld_a340_config);
623 break; 663 break;
664 case EM28174_BOARD_PCTV_290E:
665 /* MFE
666 * FE 0 = DVB-T/T2 + FE 1 = DVB-C, both sharing same tuner. */
667 /* FE 0 */
668 dvb->fe[0] = dvb_attach(cxd2820r_attach,
669 &em28xx_cxd2820r_config, &dev->i2c_adap, NULL);
670 if (dvb->fe[0]) {
671 struct i2c_adapter *i2c_tuner;
672 i2c_tuner = cxd2820r_get_tuner_i2c_adapter(dvb->fe[0]);
673 /* FE 0 attach tuner */
674 if (!dvb_attach(tda18271_attach, dvb->fe[0], 0x60,
675 i2c_tuner, &em28xx_cxd2820r_tda18271_config)) {
676 dvb_frontend_detach(dvb->fe[0]);
677 result = -EINVAL;
678 goto out_free;
679 }
680 /* FE 1. This dvb_attach() cannot fail. */
681 dvb->fe[1] = dvb_attach(cxd2820r_attach, NULL, NULL,
682 dvb->fe[0]);
683 dvb->fe[1]->id = 1;
684 /* FE 1 attach tuner */
685 if (!dvb_attach(tda18271_attach, dvb->fe[1], 0x60,
686 i2c_tuner, &em28xx_cxd2820r_tda18271_config)) {
687 dvb_frontend_detach(dvb->fe[1]);
688 /* leave FE 0 still active */
689 }
690 }
691 break;
624 default: 692 default:
625 em28xx_errdev("/2: The frontend of your DVB/ATSC card" 693 em28xx_errdev("/2: The frontend of your DVB/ATSC card"
626 " isn't supported yet\n"); 694 " isn't supported yet\n");
627 break; 695 break;
628 } 696 }
629 if (NULL == dvb->frontend) { 697 if (NULL == dvb->fe[0]) {
630 em28xx_errdev("/2: frontend initialization failed\n"); 698 em28xx_errdev("/2: frontend initialization failed\n");
631 result = -EINVAL; 699 result = -EINVAL;
632 goto out_free; 700 goto out_free;
633 } 701 }
634 /* define general-purpose callback pointer */ 702 /* define general-purpose callback pointer */
635 dvb->frontend->callback = em28xx_tuner_callback; 703 dvb->fe[0]->callback = em28xx_tuner_callback;
636 704
637 /* register everything */ 705 /* register everything */
638 result = register_dvb(dvb, THIS_MODULE, dev, &dev->udev->dev); 706 result = register_dvb(dvb, THIS_MODULE, dev, &dev->udev->dev);
diff --git a/drivers/media/video/em28xx/em28xx-i2c.c b/drivers/media/video/em28xx/em28xx-i2c.c
index 71474d31e155..4739fc7e6eb3 100644
--- a/drivers/media/video/em28xx/em28xx-i2c.c
+++ b/drivers/media/video/em28xx/em28xx-i2c.c
@@ -332,7 +332,7 @@ static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned char *eedata, int len)
332 struct em28xx_eeprom *em_eeprom = (void *)eedata; 332 struct em28xx_eeprom *em_eeprom = (void *)eedata;
333 int i, err, size = len, block; 333 int i, err, size = len, block;
334 334
335 if (dev->chip_id == CHIP_ID_EM2874) { 335 if (dev->chip_id == CHIP_ID_EM2874 || dev->chip_id == CHIP_ID_EM28174) {
336 /* Empia switched to a 16-bit addressable eeprom in newer 336 /* Empia switched to a 16-bit addressable eeprom in newer
337 devices. While we could certainly write a routine to read 337 devices. While we could certainly write a routine to read
338 the eeprom, there is nothing of use in there that cannot be 338 the eeprom, there is nothing of use in there that cannot be
diff --git a/drivers/media/video/em28xx/em28xx-reg.h b/drivers/media/video/em28xx/em28xx-reg.h
index 91e90559642b..e92a28ede434 100644
--- a/drivers/media/video/em28xx/em28xx-reg.h
+++ b/drivers/media/video/em28xx/em28xx-reg.h
@@ -201,6 +201,7 @@ enum em28xx_chip_id {
201 CHIP_ID_EM2870 = 35, 201 CHIP_ID_EM2870 = 35,
202 CHIP_ID_EM2883 = 36, 202 CHIP_ID_EM2883 = 36,
203 CHIP_ID_EM2874 = 65, 203 CHIP_ID_EM2874 = 65,
204 CHIP_ID_EM28174 = 113,
204}; 205};
205 206
206/* 207/*
diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h
index 6f2795a3d4b7..3cca33122450 100644
--- a/drivers/media/video/em28xx/em28xx.h
+++ b/drivers/media/video/em28xx/em28xx.h
@@ -97,7 +97,7 @@
97#define EM2881_BOARD_PINNACLE_HYBRID_PRO 53 97#define EM2881_BOARD_PINNACLE_HYBRID_PRO 53
98#define EM2882_BOARD_KWORLD_VS_DVBT 54 98#define EM2882_BOARD_KWORLD_VS_DVBT 54
99#define EM2882_BOARD_TERRATEC_HYBRID_XS 55 99#define EM2882_BOARD_TERRATEC_HYBRID_XS 55
100#define EM2882_BOARD_PINNACLE_HYBRID_PRO 56 100#define EM2882_BOARD_PINNACLE_HYBRID_PRO_330E 56
101#define EM2883_BOARD_KWORLD_HYBRID_330U 57 101#define EM2883_BOARD_KWORLD_HYBRID_330U 57
102#define EM2820_BOARD_COMPRO_VIDEOMATE_FORYOU 58 102#define EM2820_BOARD_COMPRO_VIDEOMATE_FORYOU 58
103#define EM2883_BOARD_HAUPPAUGE_WINTV_HVR_850 60 103#define EM2883_BOARD_HAUPPAUGE_WINTV_HVR_850 60
@@ -118,6 +118,7 @@
118#define EM2882_BOARD_DIKOM_DK300 75 118#define EM2882_BOARD_DIKOM_DK300 75
119#define EM2870_BOARD_KWORLD_A340 76 119#define EM2870_BOARD_KWORLD_A340 76
120#define EM2874_LEADERSHIP_ISDBT 77 120#define EM2874_LEADERSHIP_ISDBT 77
121#define EM28174_BOARD_PCTV_290E 78
121 122
122 123
123/* Limits minimum and default number of buffers */ 124/* Limits minimum and default number of buffers */
diff --git a/drivers/media/video/fsl-viu.c b/drivers/media/video/fsl-viu.c
index 031af1610154..908d7012c3f2 100644
--- a/drivers/media/video/fsl-viu.c
+++ b/drivers/media/video/fsl-viu.c
@@ -766,7 +766,7 @@ inline void viu_activate_overlay(struct viu_reg *viu_reg)
766 out_be32(&vr->picture_count, reg_val.picture_count); 766 out_be32(&vr->picture_count, reg_val.picture_count);
767} 767}
768 768
769static int viu_start_preview(struct viu_dev *dev, struct viu_fh *fh) 769static int viu_setup_preview(struct viu_dev *dev, struct viu_fh *fh)
770{ 770{
771 int bpp; 771 int bpp;
772 772
@@ -805,11 +805,6 @@ static int viu_start_preview(struct viu_dev *dev, struct viu_fh *fh)
805 /* setup the base address of the overlay buffer */ 805 /* setup the base address of the overlay buffer */
806 reg_val.field_base_addr = (u32)dev->ovbuf.base; 806 reg_val.field_base_addr = (u32)dev->ovbuf.base;
807 807
808 dev->ovenable = 1;
809 viu_activate_overlay(dev->vr);
810
811 /* start dma */
812 viu_start_dma(dev);
813 return 0; 808 return 0;
814} 809}
815 810
@@ -825,13 +820,11 @@ static int vidioc_s_fmt_overlay(struct file *file, void *priv,
825 if (err) 820 if (err)
826 return err; 821 return err;
827 822
828 mutex_lock(&dev->lock);
829 fh->win = f->fmt.win; 823 fh->win = f->fmt.win;
830 824
831 spin_lock_irqsave(&dev->slock, flags); 825 spin_lock_irqsave(&dev->slock, flags);
832 viu_start_preview(dev, fh); 826 viu_setup_preview(dev, fh);
833 spin_unlock_irqrestore(&dev->slock, flags); 827 spin_unlock_irqrestore(&dev->slock, flags);
834 mutex_unlock(&dev->lock);
835 return 0; 828 return 0;
836} 829}
837 830
@@ -841,6 +834,28 @@ static int vidioc_try_fmt_overlay(struct file *file, void *priv,
841 return 0; 834 return 0;
842} 835}
843 836
837static int vidioc_overlay(struct file *file, void *priv, unsigned int on)
838{
839 struct viu_fh *fh = priv;
840 struct viu_dev *dev = (struct viu_dev *)fh->dev;
841 unsigned long flags;
842
843 if (on) {
844 spin_lock_irqsave(&dev->slock, flags);
845 viu_activate_overlay(dev->vr);
846 dev->ovenable = 1;
847
848 /* start dma */
849 viu_start_dma(dev);
850 spin_unlock_irqrestore(&dev->slock, flags);
851 } else {
852 viu_stop_dma(dev);
853 dev->ovenable = 0;
854 }
855
856 return 0;
857}
858
844int vidioc_g_fbuf(struct file *file, void *priv, struct v4l2_framebuffer *arg) 859int vidioc_g_fbuf(struct file *file, void *priv, struct v4l2_framebuffer *arg)
845{ 860{
846 struct viu_fh *fh = priv; 861 struct viu_fh *fh = priv;
@@ -911,12 +926,16 @@ static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
911static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i) 926static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
912{ 927{
913 struct viu_fh *fh = priv; 928 struct viu_fh *fh = priv;
929 struct viu_dev *dev = fh->dev;
914 930
915 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 931 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
916 return -EINVAL; 932 return -EINVAL;
917 if (fh->type != i) 933 if (fh->type != i)
918 return -EINVAL; 934 return -EINVAL;
919 935
936 if (dev->ovenable)
937 dev->ovenable = 0;
938
920 viu_start_dma(fh->dev); 939 viu_start_dma(fh->dev);
921 940
922 return videobuf_streamon(&fh->vb_vidq); 941 return videobuf_streamon(&fh->vb_vidq);
@@ -1311,7 +1330,8 @@ static int viu_open(struct file *file)
1311 videobuf_queue_dma_contig_init(&fh->vb_vidq, &viu_video_qops, 1330 videobuf_queue_dma_contig_init(&fh->vb_vidq, &viu_video_qops,
1312 dev->dev, &fh->vbq_lock, 1331 dev->dev, &fh->vbq_lock,
1313 fh->type, V4L2_FIELD_INTERLACED, 1332 fh->type, V4L2_FIELD_INTERLACED,
1314 sizeof(struct viu_buf), fh, NULL); 1333 sizeof(struct viu_buf), fh,
1334 &fh->dev->lock);
1315 return 0; 1335 return 0;
1316} 1336}
1317 1337
@@ -1401,7 +1421,7 @@ static struct v4l2_file_operations viu_fops = {
1401 .release = viu_release, 1421 .release = viu_release,
1402 .read = viu_read, 1422 .read = viu_read,
1403 .poll = viu_poll, 1423 .poll = viu_poll,
1404 .ioctl = video_ioctl2, /* V4L2 ioctl handler */ 1424 .unlocked_ioctl = video_ioctl2, /* V4L2 ioctl handler */
1405 .mmap = viu_mmap, 1425 .mmap = viu_mmap,
1406}; 1426};
1407 1427
@@ -1415,6 +1435,7 @@ static const struct v4l2_ioctl_ops viu_ioctl_ops = {
1415 .vidioc_g_fmt_vid_overlay = vidioc_g_fmt_overlay, 1435 .vidioc_g_fmt_vid_overlay = vidioc_g_fmt_overlay,
1416 .vidioc_try_fmt_vid_overlay = vidioc_try_fmt_overlay, 1436 .vidioc_try_fmt_vid_overlay = vidioc_try_fmt_overlay,
1417 .vidioc_s_fmt_vid_overlay = vidioc_s_fmt_overlay, 1437 .vidioc_s_fmt_vid_overlay = vidioc_s_fmt_overlay,
1438 .vidioc_overlay = vidioc_overlay,
1418 .vidioc_g_fbuf = vidioc_g_fbuf, 1439 .vidioc_g_fbuf = vidioc_g_fbuf,
1419 .vidioc_s_fbuf = vidioc_s_fbuf, 1440 .vidioc_s_fbuf = vidioc_s_fbuf,
1420 .vidioc_reqbufs = vidioc_reqbufs, 1441 .vidioc_reqbufs = vidioc_reqbufs,
@@ -1498,9 +1519,6 @@ static int __devinit viu_of_probe(struct platform_device *op)
1498 INIT_LIST_HEAD(&viu_dev->vidq.active); 1519 INIT_LIST_HEAD(&viu_dev->vidq.active);
1499 INIT_LIST_HEAD(&viu_dev->vidq.queued); 1520 INIT_LIST_HEAD(&viu_dev->vidq.queued);
1500 1521
1501 /* initialize locks */
1502 mutex_init(&viu_dev->lock);
1503
1504 snprintf(viu_dev->v4l2_dev.name, 1522 snprintf(viu_dev->v4l2_dev.name,
1505 sizeof(viu_dev->v4l2_dev.name), "%s", "VIU"); 1523 sizeof(viu_dev->v4l2_dev.name), "%s", "VIU");
1506 ret = v4l2_device_register(viu_dev->dev, &viu_dev->v4l2_dev); 1524 ret = v4l2_device_register(viu_dev->dev, &viu_dev->v4l2_dev);
@@ -1531,8 +1549,15 @@ static int __devinit viu_of_probe(struct platform_device *op)
1531 1549
1532 viu_dev->vdev = vdev; 1550 viu_dev->vdev = vdev;
1533 1551
1552 /* initialize locks */
1553 mutex_init(&viu_dev->lock);
1554 viu_dev->vdev->lock = &viu_dev->lock;
1555 spin_lock_init(&viu_dev->slock);
1556
1534 video_set_drvdata(viu_dev->vdev, viu_dev); 1557 video_set_drvdata(viu_dev->vdev, viu_dev);
1535 1558
1559 mutex_lock(&viu_dev->lock);
1560
1536 ret = video_register_device(viu_dev->vdev, VFL_TYPE_GRABBER, -1); 1561 ret = video_register_device(viu_dev->vdev, VFL_TYPE_GRABBER, -1);
1537 if (ret < 0) { 1562 if (ret < 0) {
1538 video_device_release(viu_dev->vdev); 1563 video_device_release(viu_dev->vdev);
@@ -1559,6 +1584,8 @@ static int __devinit viu_of_probe(struct platform_device *op)
1559 goto err_irq; 1584 goto err_irq;
1560 } 1585 }
1561 1586
1587 mutex_unlock(&viu_dev->lock);
1588
1562 dev_info(&op->dev, "Freescale VIU Video Capture Board\n"); 1589 dev_info(&op->dev, "Freescale VIU Video Capture Board\n");
1563 return ret; 1590 return ret;
1564 1591
@@ -1568,6 +1595,7 @@ err_irq:
1568err_clk: 1595err_clk:
1569 video_unregister_device(viu_dev->vdev); 1596 video_unregister_device(viu_dev->vdev);
1570err_vdev: 1597err_vdev:
1598 mutex_unlock(&viu_dev->lock);
1571 i2c_put_adapter(ad); 1599 i2c_put_adapter(ad);
1572 v4l2_device_unregister(&viu_dev->v4l2_dev); 1600 v4l2_device_unregister(&viu_dev->v4l2_dev);
1573err: 1601err:
diff --git a/drivers/media/video/gspca/Kconfig b/drivers/media/video/gspca/Kconfig
index eb04e8b59989..34ae2c299799 100644
--- a/drivers/media/video/gspca/Kconfig
+++ b/drivers/media/video/gspca/Kconfig
@@ -77,6 +77,15 @@ config USB_GSPCA_JEILINJ
77 To compile this driver as a module, choose M here: the 77 To compile this driver as a module, choose M here: the
78 module will be called gspca_jeilinj. 78 module will be called gspca_jeilinj.
79 79
80config USB_GSPCA_KINECT
81 tristate "Kinect sensor device USB Camera Driver"
82 depends on VIDEO_V4L2 && USB_GSPCA
83 help
84 Say Y here if you want support for the Microsoft Kinect sensor device.
85
86 To compile this driver as a module, choose M here: the
87 module will be called gspca_kinect.
88
80config USB_GSPCA_KONICA 89config USB_GSPCA_KONICA
81 tristate "Konica USB Camera V4L2 driver" 90 tristate "Konica USB Camera V4L2 driver"
82 depends on VIDEO_V4L2 && USB_GSPCA 91 depends on VIDEO_V4L2 && USB_GSPCA
diff --git a/drivers/media/video/gspca/Makefile b/drivers/media/video/gspca/Makefile
index 855fbc8c9c47..802fbe1bff4a 100644
--- a/drivers/media/video/gspca/Makefile
+++ b/drivers/media/video/gspca/Makefile
@@ -5,6 +5,7 @@ obj-$(CONFIG_USB_GSPCA_CPIA1) += gspca_cpia1.o
5obj-$(CONFIG_USB_GSPCA_ETOMS) += gspca_etoms.o 5obj-$(CONFIG_USB_GSPCA_ETOMS) += gspca_etoms.o
6obj-$(CONFIG_USB_GSPCA_FINEPIX) += gspca_finepix.o 6obj-$(CONFIG_USB_GSPCA_FINEPIX) += gspca_finepix.o
7obj-$(CONFIG_USB_GSPCA_JEILINJ) += gspca_jeilinj.o 7obj-$(CONFIG_USB_GSPCA_JEILINJ) += gspca_jeilinj.o
8obj-$(CONFIG_USB_GSPCA_KINECT) += gspca_kinect.o
8obj-$(CONFIG_USB_GSPCA_KONICA) += gspca_konica.o 9obj-$(CONFIG_USB_GSPCA_KONICA) += gspca_konica.o
9obj-$(CONFIG_USB_GSPCA_MARS) += gspca_mars.o 10obj-$(CONFIG_USB_GSPCA_MARS) += gspca_mars.o
10obj-$(CONFIG_USB_GSPCA_MR97310A) += gspca_mr97310a.o 11obj-$(CONFIG_USB_GSPCA_MR97310A) += gspca_mr97310a.o
@@ -46,6 +47,7 @@ gspca_cpia1-objs := cpia1.o
46gspca_etoms-objs := etoms.o 47gspca_etoms-objs := etoms.o
47gspca_finepix-objs := finepix.o 48gspca_finepix-objs := finepix.o
48gspca_jeilinj-objs := jeilinj.o 49gspca_jeilinj-objs := jeilinj.o
50gspca_kinect-objs := kinect.o
49gspca_konica-objs := konica.o 51gspca_konica-objs := konica.o
50gspca_mars-objs := mars.o 52gspca_mars-objs := mars.o
51gspca_mr97310a-objs := mr97310a.o 53gspca_mr97310a-objs := mr97310a.o
diff --git a/drivers/media/video/gspca/cpia1.c b/drivers/media/video/gspca/cpia1.c
index 9ddbac680663..f2a9451eea19 100644
--- a/drivers/media/video/gspca/cpia1.c
+++ b/drivers/media/video/gspca/cpia1.c
@@ -1262,7 +1262,7 @@ static int set_flicker(struct gspca_dev *gspca_dev, int on, int apply)
1262static void monitor_exposure(struct gspca_dev *gspca_dev) 1262static void monitor_exposure(struct gspca_dev *gspca_dev)
1263{ 1263{
1264 struct sd *sd = (struct sd *) gspca_dev; 1264 struct sd *sd = (struct sd *) gspca_dev;
1265 u8 exp_acc, bcomp, gain, coarseL, cmd[8]; 1265 u8 exp_acc, bcomp, cmd[8];
1266 int ret, light_exp, dark_exp, very_dark_exp; 1266 int ret, light_exp, dark_exp, very_dark_exp;
1267 int old_exposure, new_exposure, framerate; 1267 int old_exposure, new_exposure, framerate;
1268 int setfps = 0, setexp = 0, setflicker = 0; 1268 int setfps = 0, setexp = 0, setflicker = 0;
@@ -1284,8 +1284,6 @@ static void monitor_exposure(struct gspca_dev *gspca_dev)
1284 } 1284 }
1285 exp_acc = gspca_dev->usb_buf[0]; 1285 exp_acc = gspca_dev->usb_buf[0];
1286 bcomp = gspca_dev->usb_buf[1]; 1286 bcomp = gspca_dev->usb_buf[1];
1287 gain = gspca_dev->usb_buf[2];
1288 coarseL = gspca_dev->usb_buf[3];
1289 1287
1290 light_exp = sd->params.colourParams.brightness + 1288 light_exp = sd->params.colourParams.brightness +
1291 TC - 50 + EXP_ACC_LIGHT; 1289 TC - 50 + EXP_ACC_LIGHT;
@@ -1772,9 +1770,7 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
1772/* this function is called at probe and resume time */ 1770/* this function is called at probe and resume time */
1773static int sd_init(struct gspca_dev *gspca_dev) 1771static int sd_init(struct gspca_dev *gspca_dev)
1774{ 1772{
1775#ifdef GSPCA_DEBUG
1776 struct sd *sd = (struct sd *) gspca_dev; 1773 struct sd *sd = (struct sd *) gspca_dev;
1777#endif
1778 int ret; 1774 int ret;
1779 1775
1780 /* Start / Stop the camera to make sure we are talking to 1776 /* Start / Stop the camera to make sure we are talking to
diff --git a/drivers/media/video/gspca/gl860/gl860.c b/drivers/media/video/gspca/gl860/gl860.c
index 99083038cec3..e8e071aa212f 100644
--- a/drivers/media/video/gspca/gl860/gl860.c
+++ b/drivers/media/video/gspca/gl860/gl860.c
@@ -499,21 +499,8 @@ MODULE_DEVICE_TABLE(usb, device_table);
499static int sd_probe(struct usb_interface *intf, 499static int sd_probe(struct usb_interface *intf,
500 const struct usb_device_id *id) 500 const struct usb_device_id *id)
501{ 501{
502 struct gspca_dev *gspca_dev; 502 return gspca_dev_probe(intf, id,
503 s32 ret;
504
505 ret = gspca_dev_probe(intf, id,
506 &sd_desc_mi1320, sizeof(struct sd), THIS_MODULE); 503 &sd_desc_mi1320, sizeof(struct sd), THIS_MODULE);
507
508 if (ret >= 0) {
509 gspca_dev = usb_get_intfdata(intf);
510
511 PDEBUG(D_PROBE,
512 "Camera is now controlling video device %s",
513 video_device_node_name(&gspca_dev->vdev));
514 }
515
516 return ret;
517} 504}
518 505
519static void sd_disconnect(struct usb_interface *intf) 506static void sd_disconnect(struct usb_interface *intf)
diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c
index e526aa3dedaf..08ce9948d99b 100644
--- a/drivers/media/video/gspca/gspca.c
+++ b/drivers/media/video/gspca/gspca.c
@@ -55,7 +55,7 @@ MODULE_AUTHOR("Jean-François Moine <http://moinejf.free.fr>");
55MODULE_DESCRIPTION("GSPCA USB Camera Driver"); 55MODULE_DESCRIPTION("GSPCA USB Camera Driver");
56MODULE_LICENSE("GPL"); 56MODULE_LICENSE("GPL");
57 57
58#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 12, 0) 58#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 13, 0)
59 59
60#ifdef GSPCA_DEBUG 60#ifdef GSPCA_DEBUG
61int gspca_debug = D_ERR | D_PROBE; 61int gspca_debug = D_ERR | D_PROBE;
@@ -2495,6 +2495,6 @@ module_exit(gspca_exit);
2495module_param_named(debug, gspca_debug, int, 0644); 2495module_param_named(debug, gspca_debug, int, 0644);
2496MODULE_PARM_DESC(debug, 2496MODULE_PARM_DESC(debug,
2497 "Debug (bit) 0x01:error 0x02:probe 0x04:config" 2497 "Debug (bit) 0x01:error 0x02:probe 0x04:config"
2498 " 0x08:stream 0x10:frame 0x20:packet 0x40:USBin 0x80:USBout" 2498 " 0x08:stream 0x10:frame 0x20:packet"
2499 " 0x0100: v4l2"); 2499 " 0x0100: v4l2");
2500#endif 2500#endif
diff --git a/drivers/media/video/gspca/gspca.h b/drivers/media/video/gspca/gspca.h
index 41755226d389..49e2fcbe81fb 100644
--- a/drivers/media/video/gspca/gspca.h
+++ b/drivers/media/video/gspca/gspca.h
@@ -9,7 +9,7 @@
9#include <linux/mutex.h> 9#include <linux/mutex.h>
10 10
11/* compilation option */ 11/* compilation option */
12#define GSPCA_DEBUG 1 12/*#define GSPCA_DEBUG 1*/
13 13
14#ifdef GSPCA_DEBUG 14#ifdef GSPCA_DEBUG
15/* GSPCA our debug messages */ 15/* GSPCA our debug messages */
@@ -25,8 +25,8 @@ extern int gspca_debug;
25#define D_STREAM 0x08 25#define D_STREAM 0x08
26#define D_FRAM 0x10 26#define D_FRAM 0x10
27#define D_PACK 0x20 27#define D_PACK 0x20
28#define D_USBI 0x40 28#define D_USBI 0x00
29#define D_USBO 0x80 29#define D_USBO 0x00
30#define D_V4L2 0x0100 30#define D_V4L2 0x0100
31#else 31#else
32#define PDEBUG(level, fmt, args...) 32#define PDEBUG(level, fmt, args...)
diff --git a/drivers/media/video/gspca/jeilinj.c b/drivers/media/video/gspca/jeilinj.c
index 36dae38b1e38..1bd9c4b542dd 100644
--- a/drivers/media/video/gspca/jeilinj.c
+++ b/drivers/media/video/gspca/jeilinj.c
@@ -6,6 +6,9 @@
6 * 6 *
7 * Copyright (C) 2009 Theodore Kilgore 7 * Copyright (C) 2009 Theodore Kilgore
8 * 8 *
9 * Sportscam DV15 support and control settings are
10 * Copyright (C) 2011 Patrice Chotard
11 *
9 * This program is free software; you can redistribute it and/or modify 12 * 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 13 * 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 14 * the Free Software Foundation; either version 2 of the License, or
@@ -23,7 +26,6 @@
23 26
24#define MODULE_NAME "jeilinj" 27#define MODULE_NAME "jeilinj"
25 28
26#include <linux/workqueue.h>
27#include <linux/slab.h> 29#include <linux/slab.h>
28#include "gspca.h" 30#include "gspca.h"
29#include "jpeg.h" 31#include "jpeg.h"
@@ -34,29 +36,51 @@ MODULE_LICENSE("GPL");
34 36
35/* Default timeouts, in ms */ 37/* Default timeouts, in ms */
36#define JEILINJ_CMD_TIMEOUT 500 38#define JEILINJ_CMD_TIMEOUT 500
39#define JEILINJ_CMD_DELAY 160
37#define JEILINJ_DATA_TIMEOUT 1000 40#define JEILINJ_DATA_TIMEOUT 1000
38 41
39/* Maximum transfer size to use. */ 42/* Maximum transfer size to use. */
40#define JEILINJ_MAX_TRANSFER 0x200 43#define JEILINJ_MAX_TRANSFER 0x200
41
42#define FRAME_HEADER_LEN 0x10 44#define FRAME_HEADER_LEN 0x10
45#define FRAME_START 0xFFFFFFFF
46
47enum {
48 SAKAR_57379,
49 SPORTSCAM_DV15,
50};
51
52#define CAMQUALITY_MIN 0 /* highest cam quality */
53#define CAMQUALITY_MAX 97 /* lowest cam quality */
54
55enum e_ctrl {
56 LIGHTFREQ,
57 AUTOGAIN,
58 RED,
59 GREEN,
60 BLUE,
61 NCTRLS /* number of controls */
62};
43 63
44/* Structure to hold all of our device specific stuff */ 64/* Structure to hold all of our device specific stuff */
45struct sd { 65struct sd {
46 struct gspca_dev gspca_dev; /* !! must be the first item */ 66 struct gspca_dev gspca_dev; /* !! must be the first item */
67 struct gspca_ctrl ctrls[NCTRLS];
68 int blocks_left;
47 const struct v4l2_pix_format *cap_mode; 69 const struct v4l2_pix_format *cap_mode;
48 /* Driver stuff */ 70 /* Driver stuff */
49 struct work_struct work_struct; 71 u8 type;
50 struct workqueue_struct *work_thread;
51 u8 quality; /* image quality */ 72 u8 quality; /* image quality */
52 u8 jpegqual; /* webcam quality */ 73#define QUALITY_MIN 35
74#define QUALITY_MAX 85
75#define QUALITY_DEF 85
53 u8 jpeg_hdr[JPEG_HDR_SZ]; 76 u8 jpeg_hdr[JPEG_HDR_SZ];
54}; 77};
55 78
56 struct jlj_command { 79struct jlj_command {
57 unsigned char instruction[2]; 80 unsigned char instruction[2];
58 unsigned char ack_wanted; 81 unsigned char ack_wanted;
59 }; 82 unsigned char delay;
83};
60 84
61/* AFAICT these cameras will only do 320x240. */ 85/* AFAICT these cameras will only do 320x240. */
62static struct v4l2_pix_format jlj_mode[] = { 86static struct v4l2_pix_format jlj_mode[] = {
@@ -64,6 +88,11 @@ static struct v4l2_pix_format jlj_mode[] = {
64 .bytesperline = 320, 88 .bytesperline = 320,
65 .sizeimage = 320 * 240, 89 .sizeimage = 320 * 240,
66 .colorspace = V4L2_COLORSPACE_JPEG, 90 .colorspace = V4L2_COLORSPACE_JPEG,
91 .priv = 0},
92 { 640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
93 .bytesperline = 640,
94 .sizeimage = 640 * 480,
95 .colorspace = V4L2_COLORSPACE_JPEG,
67 .priv = 0} 96 .priv = 0}
68}; 97};
69 98
@@ -73,178 +102,295 @@ static struct v4l2_pix_format jlj_mode[] = {
73 */ 102 */
74 103
75/* All commands are two bytes only */ 104/* All commands are two bytes only */
76static int jlj_write2(struct gspca_dev *gspca_dev, unsigned char *command) 105static void jlj_write2(struct gspca_dev *gspca_dev, unsigned char *command)
77{ 106{
78 int retval; 107 int retval;
79 108
109 if (gspca_dev->usb_err < 0)
110 return;
80 memcpy(gspca_dev->usb_buf, command, 2); 111 memcpy(gspca_dev->usb_buf, command, 2);
81 retval = usb_bulk_msg(gspca_dev->dev, 112 retval = usb_bulk_msg(gspca_dev->dev,
82 usb_sndbulkpipe(gspca_dev->dev, 3), 113 usb_sndbulkpipe(gspca_dev->dev, 3),
83 gspca_dev->usb_buf, 2, NULL, 500); 114 gspca_dev->usb_buf, 2, NULL, 500);
84 if (retval < 0) 115 if (retval < 0) {
85 err("command write [%02x] error %d", 116 err("command write [%02x] error %d",
86 gspca_dev->usb_buf[0], retval); 117 gspca_dev->usb_buf[0], retval);
87 return retval; 118 gspca_dev->usb_err = retval;
119 }
88} 120}
89 121
90/* Responses are one byte only */ 122/* Responses are one byte only */
91static int jlj_read1(struct gspca_dev *gspca_dev, unsigned char response) 123static void jlj_read1(struct gspca_dev *gspca_dev, unsigned char response)
92{ 124{
93 int retval; 125 int retval;
94 126
127 if (gspca_dev->usb_err < 0)
128 return;
95 retval = usb_bulk_msg(gspca_dev->dev, 129 retval = usb_bulk_msg(gspca_dev->dev,
96 usb_rcvbulkpipe(gspca_dev->dev, 0x84), 130 usb_rcvbulkpipe(gspca_dev->dev, 0x84),
97 gspca_dev->usb_buf, 1, NULL, 500); 131 gspca_dev->usb_buf, 1, NULL, 500);
98 response = gspca_dev->usb_buf[0]; 132 response = gspca_dev->usb_buf[0];
99 if (retval < 0) 133 if (retval < 0) {
100 err("read command [%02x] error %d", 134 err("read command [%02x] error %d",
101 gspca_dev->usb_buf[0], retval); 135 gspca_dev->usb_buf[0], retval);
102 return retval; 136 gspca_dev->usb_err = retval;
137 }
103} 138}
104 139
105static int jlj_start(struct gspca_dev *gspca_dev) 140static void setfreq(struct gspca_dev *gspca_dev)
106{ 141{
107 int i; 142 struct sd *sd = (struct sd *) gspca_dev;
108 int retval = -1; 143 u8 freq_commands[][2] = {
109 u8 response = 0xff; 144 {0x71, 0x80},
110 struct jlj_command start_commands[] = { 145 {0x70, 0x07}
111 {{0x71, 0x81}, 0},
112 {{0x70, 0x05}, 0},
113 {{0x95, 0x70}, 1},
114 {{0x71, 0x81}, 0},
115 {{0x70, 0x04}, 0},
116 {{0x95, 0x70}, 1},
117 {{0x71, 0x00}, 0},
118 {{0x70, 0x08}, 0},
119 {{0x95, 0x70}, 1},
120 {{0x94, 0x02}, 0},
121 {{0xde, 0x24}, 0},
122 {{0x94, 0x02}, 0},
123 {{0xdd, 0xf0}, 0},
124 {{0x94, 0x02}, 0},
125 {{0xe3, 0x2c}, 0},
126 {{0x94, 0x02}, 0},
127 {{0xe4, 0x00}, 0},
128 {{0x94, 0x02}, 0},
129 {{0xe5, 0x00}, 0},
130 {{0x94, 0x02}, 0},
131 {{0xe6, 0x2c}, 0},
132 {{0x94, 0x03}, 0},
133 {{0xaa, 0x00}, 0},
134 {{0x71, 0x1e}, 0},
135 {{0x70, 0x06}, 0},
136 {{0x71, 0x80}, 0},
137 {{0x70, 0x07}, 0}
138 }; 146 };
139 for (i = 0; i < ARRAY_SIZE(start_commands); i++) { 147
140 retval = jlj_write2(gspca_dev, start_commands[i].instruction); 148 freq_commands[0][1] |= (sd->ctrls[LIGHTFREQ].val >> 1);
141 if (retval < 0) 149
142 return retval; 150 jlj_write2(gspca_dev, freq_commands[0]);
143 if (start_commands[i].ack_wanted) 151 jlj_write2(gspca_dev, freq_commands[1]);
144 retval = jlj_read1(gspca_dev, response);
145 if (retval < 0)
146 return retval;
147 }
148 PDEBUG(D_ERR, "jlj_start retval is %d", retval);
149 return retval;
150} 152}
151 153
152static int jlj_stop(struct gspca_dev *gspca_dev) 154static void setcamquality(struct gspca_dev *gspca_dev)
155{
156 struct sd *sd = (struct sd *) gspca_dev;
157 u8 quality_commands[][2] = {
158 {0x71, 0x1E},
159 {0x70, 0x06}
160 };
161 u8 camquality;
162
163 /* adapt camera quality from jpeg quality */
164 camquality = ((QUALITY_MAX - sd->quality) * CAMQUALITY_MAX)
165 / (QUALITY_MAX - QUALITY_MIN);
166 quality_commands[0][1] += camquality;
167
168 jlj_write2(gspca_dev, quality_commands[0]);
169 jlj_write2(gspca_dev, quality_commands[1]);
170}
171
172static void setautogain(struct gspca_dev *gspca_dev)
173{
174 struct sd *sd = (struct sd *) gspca_dev;
175 u8 autogain_commands[][2] = {
176 {0x94, 0x02},
177 {0xcf, 0x00}
178 };
179
180 autogain_commands[1][1] = (sd->ctrls[AUTOGAIN].val << 4);
181
182 jlj_write2(gspca_dev, autogain_commands[0]);
183 jlj_write2(gspca_dev, autogain_commands[1]);
184}
185
186static void setred(struct gspca_dev *gspca_dev)
187{
188 struct sd *sd = (struct sd *) gspca_dev;
189 u8 setred_commands[][2] = {
190 {0x94, 0x02},
191 {0xe6, 0x00}
192 };
193
194 setred_commands[1][1] = sd->ctrls[RED].val;
195
196 jlj_write2(gspca_dev, setred_commands[0]);
197 jlj_write2(gspca_dev, setred_commands[1]);
198}
199
200static void setgreen(struct gspca_dev *gspca_dev)
201{
202 struct sd *sd = (struct sd *) gspca_dev;
203 u8 setgreen_commands[][2] = {
204 {0x94, 0x02},
205 {0xe7, 0x00}
206 };
207
208 setgreen_commands[1][1] = sd->ctrls[GREEN].val;
209
210 jlj_write2(gspca_dev, setgreen_commands[0]);
211 jlj_write2(gspca_dev, setgreen_commands[1]);
212}
213
214static void setblue(struct gspca_dev *gspca_dev)
215{
216 struct sd *sd = (struct sd *) gspca_dev;
217 u8 setblue_commands[][2] = {
218 {0x94, 0x02},
219 {0xe9, 0x00}
220 };
221
222 setblue_commands[1][1] = sd->ctrls[BLUE].val;
223
224 jlj_write2(gspca_dev, setblue_commands[0]);
225 jlj_write2(gspca_dev, setblue_commands[1]);
226}
227
228static const struct ctrl sd_ctrls[NCTRLS] = {
229[LIGHTFREQ] = {
230 {
231 .id = V4L2_CID_POWER_LINE_FREQUENCY,
232 .type = V4L2_CTRL_TYPE_MENU,
233 .name = "Light frequency filter",
234 .minimum = V4L2_CID_POWER_LINE_FREQUENCY_DISABLED, /* 1 */
235 .maximum = V4L2_CID_POWER_LINE_FREQUENCY_60HZ, /* 2 */
236 .step = 1,
237 .default_value = V4L2_CID_POWER_LINE_FREQUENCY_60HZ,
238 },
239 .set_control = setfreq
240 },
241[AUTOGAIN] = {
242 {
243 .id = V4L2_CID_AUTOGAIN,
244 .type = V4L2_CTRL_TYPE_INTEGER,
245 .name = "Automatic Gain (and Exposure)",
246 .minimum = 0,
247 .maximum = 3,
248 .step = 1,
249#define AUTOGAIN_DEF 0
250 .default_value = AUTOGAIN_DEF,
251 },
252 .set_control = setautogain
253 },
254[RED] = {
255 {
256 .id = V4L2_CID_RED_BALANCE,
257 .type = V4L2_CTRL_TYPE_INTEGER,
258 .name = "red balance",
259 .minimum = 0,
260 .maximum = 3,
261 .step = 1,
262#define RED_BALANCE_DEF 2
263 .default_value = RED_BALANCE_DEF,
264 },
265 .set_control = setred
266 },
267
268[GREEN] = {
269 {
270 .id = V4L2_CID_GAIN,
271 .type = V4L2_CTRL_TYPE_INTEGER,
272 .name = "green balance",
273 .minimum = 0,
274 .maximum = 3,
275 .step = 1,
276#define GREEN_BALANCE_DEF 2
277 .default_value = GREEN_BALANCE_DEF,
278 },
279 .set_control = setgreen
280 },
281[BLUE] = {
282 {
283 .id = V4L2_CID_BLUE_BALANCE,
284 .type = V4L2_CTRL_TYPE_INTEGER,
285 .name = "blue balance",
286 .minimum = 0,
287 .maximum = 3,
288 .step = 1,
289#define BLUE_BALANCE_DEF 2
290 .default_value = BLUE_BALANCE_DEF,
291 },
292 .set_control = setblue
293 },
294};
295
296static int jlj_start(struct gspca_dev *gspca_dev)
153{ 297{
154 int i; 298 int i;
155 int retval; 299 int start_commands_size;
156 struct jlj_command stop_commands[] = { 300 u8 response = 0xff;
157 {{0x71, 0x00}, 0}, 301 struct sd *sd = (struct sd *) gspca_dev;
158 {{0x70, 0x09}, 0}, 302 struct jlj_command start_commands[] = {
159 {{0x71, 0x80}, 0}, 303 {{0x71, 0x81}, 0, 0},
160 {{0x70, 0x05}, 0} 304 {{0x70, 0x05}, 0, JEILINJ_CMD_DELAY},
305 {{0x95, 0x70}, 1, 0},
306 {{0x71, 0x81 - gspca_dev->curr_mode}, 0, 0},
307 {{0x70, 0x04}, 0, JEILINJ_CMD_DELAY},
308 {{0x95, 0x70}, 1, 0},
309 {{0x71, 0x00}, 0, 0}, /* start streaming ??*/
310 {{0x70, 0x08}, 0, JEILINJ_CMD_DELAY},
311 {{0x95, 0x70}, 1, 0},
312#define SPORTSCAM_DV15_CMD_SIZE 9
313 {{0x94, 0x02}, 0, 0},
314 {{0xde, 0x24}, 0, 0},
315 {{0x94, 0x02}, 0, 0},
316 {{0xdd, 0xf0}, 0, 0},
317 {{0x94, 0x02}, 0, 0},
318 {{0xe3, 0x2c}, 0, 0},
319 {{0x94, 0x02}, 0, 0},
320 {{0xe4, 0x00}, 0, 0},
321 {{0x94, 0x02}, 0, 0},
322 {{0xe5, 0x00}, 0, 0},
323 {{0x94, 0x02}, 0, 0},
324 {{0xe6, 0x2c}, 0, 0},
325 {{0x94, 0x03}, 0, 0},
326 {{0xaa, 0x00}, 0, 0}
161 }; 327 };
162 for (i = 0; i < ARRAY_SIZE(stop_commands); i++) { 328
163 retval = jlj_write2(gspca_dev, stop_commands[i].instruction); 329 sd->blocks_left = 0;
164 if (retval < 0) 330 /* Under Windows, USB spy shows that only the 9 first start
165 return retval; 331 * commands are used for SPORTSCAM_DV15 webcam
332 */
333 if (sd->type == SPORTSCAM_DV15)
334 start_commands_size = SPORTSCAM_DV15_CMD_SIZE;
335 else
336 start_commands_size = ARRAY_SIZE(start_commands);
337
338 for (i = 0; i < start_commands_size; i++) {
339 jlj_write2(gspca_dev, start_commands[i].instruction);
340 if (start_commands[i].delay)
341 msleep(start_commands[i].delay);
342 if (start_commands[i].ack_wanted)
343 jlj_read1(gspca_dev, response);
166 } 344 }
167 return retval; 345 setcamquality(gspca_dev);
346 msleep(2);
347 setfreq(gspca_dev);
348 if (gspca_dev->usb_err < 0)
349 PDEBUG(D_ERR, "Start streaming command failed");
350 return gspca_dev->usb_err;
168} 351}
169 352
170/* This function is called as a workqueue function and runs whenever the camera 353static void sd_pkt_scan(struct gspca_dev *gspca_dev,
171 * is streaming data. Because it is a workqueue function it is allowed to sleep 354 u8 *data, int len)
172 * so we can use synchronous USB calls. To avoid possible collisions with other
173 * threads attempting to use the camera's USB interface the gspca usb_lock is
174 * used when performing the one USB control operation inside the workqueue,
175 * which tells the camera to close the stream. In practice the only thing
176 * which needs to be protected against is the usb_set_interface call that
177 * gspca makes during stream_off. Otherwise the camera doesn't provide any
178 * controls that the user could try to change.
179 */
180
181static void jlj_dostream(struct work_struct *work)
182{ 355{
183 struct sd *dev = container_of(work, struct sd, work_struct); 356 struct sd *sd = (struct sd *) gspca_dev;
184 struct gspca_dev *gspca_dev = &dev->gspca_dev;
185 int blocks_left; /* 0x200-sized blocks remaining in current frame. */
186 int act_len;
187 int packet_type; 357 int packet_type;
188 int ret; 358 u32 header_marker;
189 u8 *buffer;
190 359
191 buffer = kmalloc(JEILINJ_MAX_TRANSFER, GFP_KERNEL | GFP_DMA); 360 PDEBUG(D_STREAM, "Got %d bytes out of %d for Block 0",
192 if (!buffer) { 361 len, JEILINJ_MAX_TRANSFER);
193 err("Couldn't allocate USB buffer"); 362 if (len != JEILINJ_MAX_TRANSFER) {
194 goto quit_stream; 363 PDEBUG(D_PACK, "bad length");
364 goto discard;
195 } 365 }
196 while (gspca_dev->present && gspca_dev->streaming) { 366 /* check if it's start of frame */
197 /* 367 header_marker = ((u32 *)data)[0];
198 * Now request data block 0. Line 0 reports the size 368 if (header_marker == FRAME_START) {
199 * to download, in blocks of size 0x200, and also tells the 369 sd->blocks_left = data[0x0a] - 1;
200 * "actual" data size, in bytes, which seems best to ignore. 370 PDEBUG(D_STREAM, "blocks_left = 0x%x", sd->blocks_left);
201 */
202 ret = usb_bulk_msg(gspca_dev->dev,
203 usb_rcvbulkpipe(gspca_dev->dev, 0x82),
204 buffer, JEILINJ_MAX_TRANSFER, &act_len,
205 JEILINJ_DATA_TIMEOUT);
206 PDEBUG(D_STREAM,
207 "Got %d bytes out of %d for Block 0",
208 act_len, JEILINJ_MAX_TRANSFER);
209 if (ret < 0 || act_len < FRAME_HEADER_LEN)
210 goto quit_stream;
211 blocks_left = buffer[0x0a] - 1;
212 PDEBUG(D_STREAM, "blocks_left = 0x%x", blocks_left);
213
214 /* Start a new frame, and add the JPEG header, first thing */ 371 /* Start a new frame, and add the JPEG header, first thing */
215 gspca_frame_add(gspca_dev, FIRST_PACKET, 372 gspca_frame_add(gspca_dev, FIRST_PACKET,
216 dev->jpeg_hdr, JPEG_HDR_SZ); 373 sd->jpeg_hdr, JPEG_HDR_SZ);
217 /* Toss line 0 of data block 0, keep the rest. */ 374 /* Toss line 0 of data block 0, keep the rest. */
218 gspca_frame_add(gspca_dev, INTER_PACKET, 375 gspca_frame_add(gspca_dev, INTER_PACKET,
219 buffer + FRAME_HEADER_LEN, 376 data + FRAME_HEADER_LEN,
220 JEILINJ_MAX_TRANSFER - FRAME_HEADER_LEN); 377 JEILINJ_MAX_TRANSFER - FRAME_HEADER_LEN);
221 378 } else if (sd->blocks_left > 0) {
222 while (blocks_left > 0) { 379 PDEBUG(D_STREAM, "%d blocks remaining for frame",
223 if (!gspca_dev->present) 380 sd->blocks_left);
224 goto quit_stream; 381 sd->blocks_left -= 1;
225 ret = usb_bulk_msg(gspca_dev->dev, 382 if (sd->blocks_left == 0)
226 usb_rcvbulkpipe(gspca_dev->dev, 0x82), 383 packet_type = LAST_PACKET;
227 buffer, JEILINJ_MAX_TRANSFER, &act_len, 384 else
228 JEILINJ_DATA_TIMEOUT); 385 packet_type = INTER_PACKET;
229 if (ret < 0 || act_len < JEILINJ_MAX_TRANSFER) 386 gspca_frame_add(gspca_dev, packet_type,
230 goto quit_stream; 387 data, JEILINJ_MAX_TRANSFER);
231 PDEBUG(D_STREAM, 388 } else
232 "%d blocks remaining for frame", blocks_left); 389 goto discard;
233 blocks_left -= 1; 390 return;
234 if (blocks_left == 0) 391discard:
235 packet_type = LAST_PACKET; 392 /* Discard data until a new frame starts. */
236 else 393 gspca_dev->last_packet_type = DISCARD_PACKET;
237 packet_type = INTER_PACKET;
238 gspca_frame_add(gspca_dev, packet_type,
239 buffer, JEILINJ_MAX_TRANSFER);
240 }
241 }
242quit_stream:
243 mutex_lock(&gspca_dev->usb_lock);
244 if (gspca_dev->present)
245 jlj_stop(gspca_dev);
246 mutex_unlock(&gspca_dev->usb_lock);
247 kfree(buffer);
248} 394}
249 395
250/* This function is called at probe time just before sd_init */ 396/* This function is called at probe time just before sd_init */
@@ -254,78 +400,169 @@ static int sd_config(struct gspca_dev *gspca_dev,
254 struct cam *cam = &gspca_dev->cam; 400 struct cam *cam = &gspca_dev->cam;
255 struct sd *dev = (struct sd *) gspca_dev; 401 struct sd *dev = (struct sd *) gspca_dev;
256 402
257 dev->quality = 85; 403 dev->type = id->driver_info;
258 dev->jpegqual = 85; 404 gspca_dev->cam.ctrls = dev->ctrls;
405 dev->quality = QUALITY_DEF;
406 dev->ctrls[LIGHTFREQ].def = V4L2_CID_POWER_LINE_FREQUENCY_60HZ;
407 dev->ctrls[RED].def = RED_BALANCE_DEF;
408 dev->ctrls[GREEN].def = GREEN_BALANCE_DEF;
409 dev->ctrls[BLUE].def = BLUE_BALANCE_DEF;
259 PDEBUG(D_PROBE, 410 PDEBUG(D_PROBE,
260 "JEILINJ camera detected" 411 "JEILINJ camera detected"
261 " (vid/pid 0x%04X:0x%04X)", id->idVendor, id->idProduct); 412 " (vid/pid 0x%04X:0x%04X)", id->idVendor, id->idProduct);
262 cam->cam_mode = jlj_mode; 413 cam->cam_mode = jlj_mode;
263 cam->nmodes = 1; 414 cam->nmodes = ARRAY_SIZE(jlj_mode);
264 cam->bulk = 1; 415 cam->bulk = 1;
265 /* We don't use the buffer gspca allocates so make it small. */ 416 cam->bulk_nurbs = 1;
266 cam->bulk_size = 32; 417 cam->bulk_size = JEILINJ_MAX_TRANSFER;
267 INIT_WORK(&dev->work_struct, jlj_dostream);
268 return 0; 418 return 0;
269} 419}
270 420
271/* called on streamoff with alt==0 and on disconnect */ 421static void sd_stopN(struct gspca_dev *gspca_dev)
272/* the usb_lock is held at entry - restore on exit */
273static void sd_stop0(struct gspca_dev *gspca_dev)
274{ 422{
275 struct sd *dev = (struct sd *) gspca_dev; 423 int i;
424 u8 *buf;
425 u8 stop_commands[][2] = {
426 {0x71, 0x00},
427 {0x70, 0x09},
428 {0x71, 0x80},
429 {0x70, 0x05}
430 };
431
432 for (;;) {
433 /* get the image remaining blocks */
434 usb_bulk_msg(gspca_dev->dev,
435 gspca_dev->urb[0]->pipe,
436 gspca_dev->urb[0]->transfer_buffer,
437 JEILINJ_MAX_TRANSFER, NULL,
438 JEILINJ_DATA_TIMEOUT);
439
440 /* search for 0xff 0xd9 (EOF for JPEG) */
441 i = 0;
442 buf = gspca_dev->urb[0]->transfer_buffer;
443 while ((i < (JEILINJ_MAX_TRANSFER - 1)) &&
444 ((buf[i] != 0xff) || (buf[i+1] != 0xd9)))
445 i++;
276 446
277 /* wait for the work queue to terminate */ 447 if (i != (JEILINJ_MAX_TRANSFER - 1))
278 mutex_unlock(&gspca_dev->usb_lock); 448 /* last remaining block found */
279 /* This waits for jlj_dostream to finish */ 449 break;
280 destroy_workqueue(dev->work_thread); 450 }
281 dev->work_thread = NULL; 451
282 mutex_lock(&gspca_dev->usb_lock); 452 for (i = 0; i < ARRAY_SIZE(stop_commands); i++)
453 jlj_write2(gspca_dev, stop_commands[i]);
283} 454}
284 455
285/* this function is called at probe and resume time */ 456/* this function is called at probe and resume time */
286static int sd_init(struct gspca_dev *gspca_dev) 457static int sd_init(struct gspca_dev *gspca_dev)
287{ 458{
288 return 0; 459 return gspca_dev->usb_err;
289} 460}
290 461
291/* Set up for getting frames. */ 462/* Set up for getting frames. */
292static int sd_start(struct gspca_dev *gspca_dev) 463static int sd_start(struct gspca_dev *gspca_dev)
293{ 464{
294 struct sd *dev = (struct sd *) gspca_dev; 465 struct sd *dev = (struct sd *) gspca_dev;
295 int ret;
296 466
297 /* create the JPEG header */ 467 /* create the JPEG header */
298 jpeg_define(dev->jpeg_hdr, gspca_dev->height, gspca_dev->width, 468 jpeg_define(dev->jpeg_hdr, gspca_dev->height, gspca_dev->width,
299 0x21); /* JPEG 422 */ 469 0x21); /* JPEG 422 */
300 jpeg_set_qual(dev->jpeg_hdr, dev->quality); 470 jpeg_set_qual(dev->jpeg_hdr, dev->quality);
301 PDEBUG(D_STREAM, "Start streaming at 320x240"); 471 PDEBUG(D_STREAM, "Start streaming at %dx%d",
302 ret = jlj_start(gspca_dev); 472 gspca_dev->height, gspca_dev->width);
303 if (ret < 0) { 473 jlj_start(gspca_dev);
304 PDEBUG(D_ERR, "Start streaming command failed"); 474 return gspca_dev->usb_err;
305 return ret;
306 }
307 /* Start the workqueue function to do the streaming */
308 dev->work_thread = create_singlethread_workqueue(MODULE_NAME);
309 queue_work(dev->work_thread, &dev->work_struct);
310
311 return 0;
312} 475}
313 476
314/* Table of supported USB devices */ 477/* Table of supported USB devices */
315static const struct usb_device_id device_table[] = { 478static const struct usb_device_id device_table[] = {
316 {USB_DEVICE(0x0979, 0x0280)}, 479 {USB_DEVICE(0x0979, 0x0280), .driver_info = SAKAR_57379},
480 {USB_DEVICE(0x0979, 0x0270), .driver_info = SPORTSCAM_DV15},
317 {} 481 {}
318}; 482};
319 483
320MODULE_DEVICE_TABLE(usb, device_table); 484MODULE_DEVICE_TABLE(usb, device_table);
321 485
486static int sd_querymenu(struct gspca_dev *gspca_dev,
487 struct v4l2_querymenu *menu)
488{
489 switch (menu->id) {
490 case V4L2_CID_POWER_LINE_FREQUENCY:
491 switch (menu->index) {
492 case 0: /* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */
493 strcpy((char *) menu->name, "disable");
494 return 0;
495 case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
496 strcpy((char *) menu->name, "50 Hz");
497 return 0;
498 case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
499 strcpy((char *) menu->name, "60 Hz");
500 return 0;
501 }
502 break;
503 }
504 return -EINVAL;
505}
506
507static int sd_set_jcomp(struct gspca_dev *gspca_dev,
508 struct v4l2_jpegcompression *jcomp)
509{
510 struct sd *sd = (struct sd *) gspca_dev;
511
512 if (jcomp->quality < QUALITY_MIN)
513 sd->quality = QUALITY_MIN;
514 else if (jcomp->quality > QUALITY_MAX)
515 sd->quality = QUALITY_MAX;
516 else
517 sd->quality = jcomp->quality;
518 if (gspca_dev->streaming) {
519 jpeg_set_qual(sd->jpeg_hdr, sd->quality);
520 setcamquality(gspca_dev);
521 }
522 return 0;
523}
524
525static int sd_get_jcomp(struct gspca_dev *gspca_dev,
526 struct v4l2_jpegcompression *jcomp)
527{
528 struct sd *sd = (struct sd *) gspca_dev;
529
530 memset(jcomp, 0, sizeof *jcomp);
531 jcomp->quality = sd->quality;
532 jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT
533 | V4L2_JPEG_MARKER_DQT;
534 return 0;
535}
536
537
322/* sub-driver description */ 538/* sub-driver description */
323static const struct sd_desc sd_desc = { 539static const struct sd_desc sd_desc_sakar_57379 = {
324 .name = MODULE_NAME, 540 .name = MODULE_NAME,
325 .config = sd_config, 541 .config = sd_config,
326 .init = sd_init, 542 .init = sd_init,
327 .start = sd_start, 543 .start = sd_start,
328 .stop0 = sd_stop0, 544 .stopN = sd_stopN,
545 .pkt_scan = sd_pkt_scan,
546};
547
548/* sub-driver description */
549static const struct sd_desc sd_desc_sportscam_dv15 = {
550 .name = MODULE_NAME,
551 .config = sd_config,
552 .init = sd_init,
553 .start = sd_start,
554 .stopN = sd_stopN,
555 .pkt_scan = sd_pkt_scan,
556 .ctrls = sd_ctrls,
557 .nctrls = ARRAY_SIZE(sd_ctrls),
558 .querymenu = sd_querymenu,
559 .get_jcomp = sd_get_jcomp,
560 .set_jcomp = sd_set_jcomp,
561};
562
563static const struct sd_desc *sd_desc[2] = {
564 &sd_desc_sakar_57379,
565 &sd_desc_sportscam_dv15
329}; 566};
330 567
331/* -- device connect -- */ 568/* -- device connect -- */
@@ -333,7 +570,7 @@ static int sd_probe(struct usb_interface *intf,
333 const struct usb_device_id *id) 570 const struct usb_device_id *id)
334{ 571{
335 return gspca_dev_probe(intf, id, 572 return gspca_dev_probe(intf, id,
336 &sd_desc, 573 sd_desc[id->driver_info],
337 sizeof(struct sd), 574 sizeof(struct sd),
338 THIS_MODULE); 575 THIS_MODULE);
339} 576}
diff --git a/drivers/media/video/gspca/kinect.c b/drivers/media/video/gspca/kinect.c
new file mode 100644
index 000000000000..66671a4092e4
--- /dev/null
+++ b/drivers/media/video/gspca/kinect.c
@@ -0,0 +1,429 @@
1/*
2 * kinect sensor device camera, gspca driver
3 *
4 * Copyright (C) 2011 Antonio Ospite <ospite@studenti.unina.it>
5 *
6 * Based on the OpenKinect project and libfreenect
7 * http://openkinect.org/wiki/Init_Analysis
8 *
9 * Special thanks to Steven Toth and kernellabs.com for sponsoring a Kinect
10 * sensor device which I tested the driver on.
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 */
26
27#define MODULE_NAME "kinect"
28
29#include "gspca.h"
30
31#define CTRL_TIMEOUT 500
32
33MODULE_AUTHOR("Antonio Ospite <ospite@studenti.unina.it>");
34MODULE_DESCRIPTION("GSPCA/Kinect Sensor Device USB Camera Driver");
35MODULE_LICENSE("GPL");
36
37#ifdef DEBUG
38int gspca_debug = D_ERR | D_PROBE | D_CONF | D_STREAM | D_FRAM | D_PACK |
39 D_USBI | D_USBO | D_V4L2;
40#endif
41
42struct pkt_hdr {
43 uint8_t magic[2];
44 uint8_t pad;
45 uint8_t flag;
46 uint8_t unk1;
47 uint8_t seq;
48 uint8_t unk2;
49 uint8_t unk3;
50 uint32_t timestamp;
51};
52
53struct cam_hdr {
54 uint8_t magic[2];
55 uint16_t len;
56 uint16_t cmd;
57 uint16_t tag;
58};
59
60/* specific webcam descriptor */
61struct sd {
62 struct gspca_dev gspca_dev; /* !! must be the first item */
63 uint16_t cam_tag; /* a sequence number for packets */
64 uint8_t stream_flag; /* to identify different stream types */
65 uint8_t obuf[0x400]; /* output buffer for control commands */
66 uint8_t ibuf[0x200]; /* input buffer for control commands */
67};
68
69/* V4L2 controls supported by the driver */
70/* controls prototypes here */
71
72static const struct ctrl sd_ctrls[] = {
73};
74
75#define MODE_640x480 0x0001
76#define MODE_640x488 0x0002
77#define MODE_1280x1024 0x0004
78
79#define FORMAT_BAYER 0x0010
80#define FORMAT_UYVY 0x0020
81#define FORMAT_Y10B 0x0040
82
83#define FPS_HIGH 0x0100
84
85static const struct v4l2_pix_format video_camera_mode[] = {
86 {640, 480, V4L2_PIX_FMT_SGRBG8, V4L2_FIELD_NONE,
87 .bytesperline = 640,
88 .sizeimage = 640 * 480,
89 .colorspace = V4L2_COLORSPACE_SRGB,
90 .priv = MODE_640x480 | FORMAT_BAYER | FPS_HIGH},
91 {640, 480, V4L2_PIX_FMT_UYVY, V4L2_FIELD_NONE,
92 .bytesperline = 640 * 2,
93 .sizeimage = 640 * 480 * 2,
94 .colorspace = V4L2_COLORSPACE_SRGB,
95 .priv = MODE_640x480 | FORMAT_UYVY},
96 {1280, 1024, V4L2_PIX_FMT_SGRBG8, V4L2_FIELD_NONE,
97 .bytesperline = 1280,
98 .sizeimage = 1280 * 1024,
99 .colorspace = V4L2_COLORSPACE_SRGB,
100 .priv = MODE_1280x1024 | FORMAT_BAYER},
101 {640, 488, V4L2_PIX_FMT_Y10BPACK, V4L2_FIELD_NONE,
102 .bytesperline = 640 * 10 / 8,
103 .sizeimage = 640 * 488 * 10 / 8,
104 .colorspace = V4L2_COLORSPACE_SRGB,
105 .priv = MODE_640x488 | FORMAT_Y10B | FPS_HIGH},
106 {1280, 1024, V4L2_PIX_FMT_Y10BPACK, V4L2_FIELD_NONE,
107 .bytesperline = 1280 * 10 / 8,
108 .sizeimage = 1280 * 1024 * 10 / 8,
109 .colorspace = V4L2_COLORSPACE_SRGB,
110 .priv = MODE_1280x1024 | FORMAT_Y10B},
111};
112
113static int kinect_write(struct usb_device *udev, uint8_t *data,
114 uint16_t wLength)
115{
116 return usb_control_msg(udev,
117 usb_sndctrlpipe(udev, 0),
118 0x00,
119 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
120 0, 0, data, wLength, CTRL_TIMEOUT);
121}
122
123static int kinect_read(struct usb_device *udev, uint8_t *data, uint16_t wLength)
124{
125 return usb_control_msg(udev,
126 usb_rcvctrlpipe(udev, 0),
127 0x00,
128 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
129 0, 0, data, wLength, CTRL_TIMEOUT);
130}
131
132static int send_cmd(struct gspca_dev *gspca_dev, uint16_t cmd, void *cmdbuf,
133 unsigned int cmd_len, void *replybuf, unsigned int reply_len)
134{
135 struct sd *sd = (struct sd *) gspca_dev;
136 struct usb_device *udev = gspca_dev->dev;
137 int res, actual_len;
138 uint8_t *obuf = sd->obuf;
139 uint8_t *ibuf = sd->ibuf;
140 struct cam_hdr *chdr = (void *)obuf;
141 struct cam_hdr *rhdr = (void *)ibuf;
142
143 if (cmd_len & 1 || cmd_len > (0x400 - sizeof(*chdr))) {
144 err("send_cmd: Invalid command length (0x%x)", cmd_len);
145 return -1;
146 }
147
148 chdr->magic[0] = 0x47;
149 chdr->magic[1] = 0x4d;
150 chdr->cmd = cpu_to_le16(cmd);
151 chdr->tag = cpu_to_le16(sd->cam_tag);
152 chdr->len = cpu_to_le16(cmd_len / 2);
153
154 memcpy(obuf+sizeof(*chdr), cmdbuf, cmd_len);
155
156 res = kinect_write(udev, obuf, cmd_len + sizeof(*chdr));
157 PDEBUG(D_USBO, "Control cmd=%04x tag=%04x len=%04x: %d", cmd,
158 sd->cam_tag, cmd_len, res);
159 if (res < 0) {
160 err("send_cmd: Output control transfer failed (%d)", res);
161 return res;
162 }
163
164 do {
165 actual_len = kinect_read(udev, ibuf, 0x200);
166 } while (actual_len == 0);
167 PDEBUG(D_USBO, "Control reply: %d", res);
168 if (actual_len < sizeof(*rhdr)) {
169 err("send_cmd: Input control transfer failed (%d)", res);
170 return res;
171 }
172 actual_len -= sizeof(*rhdr);
173
174 if (rhdr->magic[0] != 0x52 || rhdr->magic[1] != 0x42) {
175 err("send_cmd: Bad magic %02x %02x", rhdr->magic[0],
176 rhdr->magic[1]);
177 return -1;
178 }
179 if (rhdr->cmd != chdr->cmd) {
180 err("send_cmd: Bad cmd %02x != %02x", rhdr->cmd, chdr->cmd);
181 return -1;
182 }
183 if (rhdr->tag != chdr->tag) {
184 err("send_cmd: Bad tag %04x != %04x", rhdr->tag, chdr->tag);
185 return -1;
186 }
187 if (cpu_to_le16(rhdr->len) != (actual_len/2)) {
188 err("send_cmd: Bad len %04x != %04x",
189 cpu_to_le16(rhdr->len), (int)(actual_len/2));
190 return -1;
191 }
192
193 if (actual_len > reply_len) {
194 warn("send_cmd: Data buffer is %d bytes long, but got %d bytes",
195 reply_len, actual_len);
196 memcpy(replybuf, ibuf+sizeof(*rhdr), reply_len);
197 } else {
198 memcpy(replybuf, ibuf+sizeof(*rhdr), actual_len);
199 }
200
201 sd->cam_tag++;
202
203 return actual_len;
204}
205
206static int write_register(struct gspca_dev *gspca_dev, uint16_t reg,
207 uint16_t data)
208{
209 uint16_t reply[2];
210 uint16_t cmd[2];
211 int res;
212
213 cmd[0] = cpu_to_le16(reg);
214 cmd[1] = cpu_to_le16(data);
215
216 PDEBUG(D_USBO, "Write Reg 0x%04x <= 0x%02x", reg, data);
217 res = send_cmd(gspca_dev, 0x03, cmd, 4, reply, 4);
218 if (res < 0)
219 return res;
220 if (res != 2) {
221 warn("send_cmd returned %d [%04x %04x], 0000 expected",
222 res, reply[0], reply[1]);
223 }
224 return 0;
225}
226
227/* this function is called at probe time */
228static int sd_config(struct gspca_dev *gspca_dev,
229 const struct usb_device_id *id)
230{
231 struct sd *sd = (struct sd *) gspca_dev;
232 struct cam *cam;
233
234 sd->cam_tag = 0;
235
236 /* Only video stream is supported for now,
237 * which has stream flag = 0x80 */
238 sd->stream_flag = 0x80;
239
240 cam = &gspca_dev->cam;
241
242 cam->cam_mode = video_camera_mode;
243 cam->nmodes = ARRAY_SIZE(video_camera_mode);
244
245#if 0
246 /* Setting those values is not needed for video stream */
247 cam->npkt = 15;
248 gspca_dev->pkt_size = 960 * 2;
249#endif
250
251 return 0;
252}
253
254/* this function is called at probe and resume time */
255static int sd_init(struct gspca_dev *gspca_dev)
256{
257 PDEBUG(D_PROBE, "Kinect Camera device.");
258
259 return 0;
260}
261
262static int sd_start(struct gspca_dev *gspca_dev)
263{
264 int mode;
265 uint8_t fmt_reg, fmt_val;
266 uint8_t res_reg, res_val;
267 uint8_t fps_reg, fps_val;
268 uint8_t mode_val;
269
270 mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
271
272 if (mode & FORMAT_Y10B) {
273 fmt_reg = 0x19;
274 res_reg = 0x1a;
275 fps_reg = 0x1b;
276 mode_val = 0x03;
277 } else {
278 fmt_reg = 0x0c;
279 res_reg = 0x0d;
280 fps_reg = 0x0e;
281 mode_val = 0x01;
282 }
283
284 /* format */
285 if (mode & FORMAT_UYVY)
286 fmt_val = 0x05;
287 else
288 fmt_val = 0x00;
289
290 if (mode & MODE_1280x1024)
291 res_val = 0x02;
292 else
293 res_val = 0x01;
294
295 if (mode & FPS_HIGH)
296 fps_val = 0x1e;
297 else
298 fps_val = 0x0f;
299
300
301 /* turn off IR-reset function */
302 write_register(gspca_dev, 0x105, 0x00);
303
304 /* Reset video stream */
305 write_register(gspca_dev, 0x05, 0x00);
306
307 /* Due to some ridiculous condition in the firmware, we have to start
308 * and stop the depth stream before the camera will hand us 1280x1024
309 * IR. This is a stupid workaround, but we've yet to find a better
310 * solution.
311 *
312 * Thanks to Drew Fisher for figuring this out.
313 */
314 if (mode & (FORMAT_Y10B | MODE_1280x1024)) {
315 write_register(gspca_dev, 0x13, 0x01);
316 write_register(gspca_dev, 0x14, 0x1e);
317 write_register(gspca_dev, 0x06, 0x02);
318 write_register(gspca_dev, 0x06, 0x00);
319 }
320
321 write_register(gspca_dev, fmt_reg, fmt_val);
322 write_register(gspca_dev, res_reg, res_val);
323 write_register(gspca_dev, fps_reg, fps_val);
324
325 /* Start video stream */
326 write_register(gspca_dev, 0x05, mode_val);
327
328 /* disable Hflip */
329 write_register(gspca_dev, 0x47, 0x00);
330
331 return 0;
332}
333
334static void sd_stopN(struct gspca_dev *gspca_dev)
335{
336 /* reset video stream */
337 write_register(gspca_dev, 0x05, 0x00);
338}
339
340static void sd_pkt_scan(struct gspca_dev *gspca_dev, u8 *__data, int len)
341{
342 struct sd *sd = (struct sd *) gspca_dev;
343
344 struct pkt_hdr *hdr = (void *)__data;
345 uint8_t *data = __data + sizeof(*hdr);
346 int datalen = len - sizeof(*hdr);
347
348 uint8_t sof = sd->stream_flag | 1;
349 uint8_t mof = sd->stream_flag | 2;
350 uint8_t eof = sd->stream_flag | 5;
351
352 if (len < 12)
353 return;
354
355 if (hdr->magic[0] != 'R' || hdr->magic[1] != 'B') {
356 warn("[Stream %02x] Invalid magic %02x%02x", sd->stream_flag,
357 hdr->magic[0], hdr->magic[1]);
358 return;
359 }
360
361 if (hdr->flag == sof)
362 gspca_frame_add(gspca_dev, FIRST_PACKET, data, datalen);
363
364 else if (hdr->flag == mof)
365 gspca_frame_add(gspca_dev, INTER_PACKET, data, datalen);
366
367 else if (hdr->flag == eof)
368 gspca_frame_add(gspca_dev, LAST_PACKET, data, datalen);
369
370 else
371 warn("Packet type not recognized...");
372}
373
374/* sub-driver description */
375static const struct sd_desc sd_desc = {
376 .name = MODULE_NAME,
377 .ctrls = sd_ctrls,
378 .nctrls = ARRAY_SIZE(sd_ctrls),
379 .config = sd_config,
380 .init = sd_init,
381 .start = sd_start,
382 .stopN = sd_stopN,
383 .pkt_scan = sd_pkt_scan,
384 /*
385 .querymenu = sd_querymenu,
386 .get_streamparm = sd_get_streamparm,
387 .set_streamparm = sd_set_streamparm,
388 */
389};
390
391/* -- module initialisation -- */
392static const struct usb_device_id device_table[] = {
393 {USB_DEVICE(0x045e, 0x02ae)},
394 {}
395};
396
397MODULE_DEVICE_TABLE(usb, device_table);
398
399/* -- device connect -- */
400static int sd_probe(struct usb_interface *intf, const struct usb_device_id *id)
401{
402 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
403 THIS_MODULE);
404}
405
406static struct usb_driver sd_driver = {
407 .name = MODULE_NAME,
408 .id_table = device_table,
409 .probe = sd_probe,
410 .disconnect = gspca_disconnect,
411#ifdef CONFIG_PM
412 .suspend = gspca_suspend,
413 .resume = gspca_resume,
414#endif
415};
416
417/* -- module insert / remove -- */
418static int __init sd_mod_init(void)
419{
420 return usb_register(&sd_driver);
421}
422
423static void __exit sd_mod_exit(void)
424{
425 usb_deregister(&sd_driver);
426}
427
428module_init(sd_mod_init);
429module_exit(sd_mod_exit);
diff --git a/drivers/media/video/gspca/spca508.c b/drivers/media/video/gspca/spca508.c
index 41dce49fb43d..9d0b46027b93 100644
--- a/drivers/media/video/gspca/spca508.c
+++ b/drivers/media/video/gspca/spca508.c
@@ -1375,7 +1375,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
1375{ 1375{
1376 struct sd *sd = (struct sd *) gspca_dev; 1376 struct sd *sd = (struct sd *) gspca_dev;
1377 struct cam *cam; 1377 struct cam *cam;
1378 int data1, data2;
1379 const u16 (*init_data)[2]; 1378 const u16 (*init_data)[2];
1380 static const u16 (*(init_data_tb[]))[2] = { 1379 static const u16 (*(init_data_tb[]))[2] = {
1381 spca508_vista_init_data, /* CreativeVista 0 */ 1380 spca508_vista_init_data, /* CreativeVista 0 */
@@ -1386,6 +1385,9 @@ static int sd_config(struct gspca_dev *gspca_dev,
1386 spca508_init_data, /* ViewQuestVQ110 5 */ 1385 spca508_init_data, /* ViewQuestVQ110 5 */
1387 }; 1386 };
1388 1387
1388#ifdef GSPCA_DEBUG
1389 int data1, data2;
1390
1389 /* Read from global register the USB product and vendor IDs, just to 1391 /* Read from global register the USB product and vendor IDs, just to
1390 * prove that we can communicate with the device. This works, which 1392 * prove that we can communicate with the device. This works, which
1391 * confirms at we are communicating properly and that the device 1393 * confirms at we are communicating properly and that the device
@@ -1400,6 +1402,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
1400 1402
1401 data1 = reg_read(gspca_dev, 0x8621); 1403 data1 = reg_read(gspca_dev, 0x8621);
1402 PDEBUG(D_PROBE, "Window 1 average luminance: %d", data1); 1404 PDEBUG(D_PROBE, "Window 1 average luminance: %d", data1);
1405#endif
1403 1406
1404 cam = &gspca_dev->cam; 1407 cam = &gspca_dev->cam;
1405 cam->cam_mode = sif_mode; 1408 cam->cam_mode = sif_mode;
diff --git a/drivers/media/video/gspca/stk014.c b/drivers/media/video/gspca/stk014.c
index 87be52b5e1e3..763747700f10 100644
--- a/drivers/media/video/gspca/stk014.c
+++ b/drivers/media/video/gspca/stk014.c
@@ -436,17 +436,14 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
436static int sd_querymenu(struct gspca_dev *gspca_dev, 436static int sd_querymenu(struct gspca_dev *gspca_dev,
437 struct v4l2_querymenu *menu) 437 struct v4l2_querymenu *menu)
438{ 438{
439 static const char *freq_nm[3] = {"NoFliker", "50 Hz", "60 Hz"};
440
439 switch (menu->id) { 441 switch (menu->id) {
440 case V4L2_CID_POWER_LINE_FREQUENCY: 442 case V4L2_CID_POWER_LINE_FREQUENCY:
441 switch (menu->index) { 443 if ((unsigned) menu->index >= ARRAY_SIZE(freq_nm))
442 case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */ 444 break;
443 strcpy((char *) menu->name, "50 Hz"); 445 strcpy((char *) menu->name, freq_nm[menu->index]);
444 return 0; 446 return 0;
445 case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
446 strcpy((char *) menu->name, "60 Hz");
447 return 0;
448 }
449 break;
450 } 447 }
451 return -EINVAL; 448 return -EINVAL;
452} 449}
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.c b/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.c
index ac47b4c94388..75a5b9c2f15f 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.c
+++ b/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.c
@@ -217,6 +217,8 @@ static int pb0100_start(struct sd *sd)
217 217
218 intf = usb_ifnum_to_if(sd->gspca_dev.dev, sd->gspca_dev.iface); 218 intf = usb_ifnum_to_if(sd->gspca_dev.dev, sd->gspca_dev.iface);
219 alt = usb_altnum_to_altsetting(intf, sd->gspca_dev.alt); 219 alt = usb_altnum_to_altsetting(intf, sd->gspca_dev.alt);
220 if (!alt)
221 return -ENODEV;
220 packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize); 222 packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize);
221 223
222 /* If we don't have enough bandwidth use a lower framerate */ 224 /* If we don't have enough bandwidth use a lower framerate */
diff --git a/drivers/media/video/gspca/sunplus.c b/drivers/media/video/gspca/sunplus.c
index 543542af2720..b089c0d3ee9f 100644
--- a/drivers/media/video/gspca/sunplus.c
+++ b/drivers/media/video/gspca/sunplus.c
@@ -396,57 +396,6 @@ static void reg_w_riv(struct gspca_dev *gspca_dev,
396 req, index, value); 396 req, index, value);
397} 397}
398 398
399/* read 1 byte */
400static u8 reg_r_1(struct gspca_dev *gspca_dev,
401 u16 value) /* wValue */
402{
403 int ret;
404
405 if (gspca_dev->usb_err < 0)
406 return 0;
407 ret = usb_control_msg(gspca_dev->dev,
408 usb_rcvctrlpipe(gspca_dev->dev, 0),
409 0x20, /* request */
410 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
411 value,
412 0, /* index */
413 gspca_dev->usb_buf, 1,
414 500); /* timeout */
415 if (ret < 0) {
416 err("reg_r_1 err %d", ret);
417 gspca_dev->usb_err = ret;
418 return 0;
419 }
420 return gspca_dev->usb_buf[0];
421}
422
423/* read 1 or 2 bytes */
424static u16 reg_r_12(struct gspca_dev *gspca_dev,
425 u8 req, /* bRequest */
426 u16 index, /* wIndex */
427 u16 length) /* wLength (1 or 2 only) */
428{
429 int ret;
430
431 if (gspca_dev->usb_err < 0)
432 return 0;
433 gspca_dev->usb_buf[1] = 0;
434 ret = usb_control_msg(gspca_dev->dev,
435 usb_rcvctrlpipe(gspca_dev->dev, 0),
436 req,
437 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
438 0, /* value */
439 index,
440 gspca_dev->usb_buf, length,
441 500);
442 if (ret < 0) {
443 err("reg_r_12 err %d", ret);
444 gspca_dev->usb_err = ret;
445 return 0;
446 }
447 return (gspca_dev->usb_buf[1] << 8) + gspca_dev->usb_buf[0];
448}
449
450static void write_vector(struct gspca_dev *gspca_dev, 399static void write_vector(struct gspca_dev *gspca_dev,
451 const struct cmd *data, int ncmds) 400 const struct cmd *data, int ncmds)
452{ 401{
@@ -473,44 +422,46 @@ static void setup_qtable(struct gspca_dev *gspca_dev,
473static void spca504_acknowledged_command(struct gspca_dev *gspca_dev, 422static void spca504_acknowledged_command(struct gspca_dev *gspca_dev,
474 u8 req, u16 idx, u16 val) 423 u8 req, u16 idx, u16 val)
475{ 424{
476 u16 notdone;
477
478 reg_w_riv(gspca_dev, req, idx, val); 425 reg_w_riv(gspca_dev, req, idx, val);
479 notdone = reg_r_12(gspca_dev, 0x01, 0x0001, 1); 426 reg_r(gspca_dev, 0x01, 0x0001, 1);
427 PDEBUG(D_FRAM, "before wait 0x%04x", gspca_dev->usb_buf[0]);
480 reg_w_riv(gspca_dev, req, idx, val); 428 reg_w_riv(gspca_dev, req, idx, val);
481 429
482 PDEBUG(D_FRAM, "before wait 0x%04x", notdone);
483
484 msleep(200); 430 msleep(200);
485 notdone = reg_r_12(gspca_dev, 0x01, 0x0001, 1); 431 reg_r(gspca_dev, 0x01, 0x0001, 1);
486 PDEBUG(D_FRAM, "after wait 0x%04x", notdone); 432 PDEBUG(D_FRAM, "after wait 0x%04x", gspca_dev->usb_buf[0]);
487} 433}
488 434
435#ifdef GSPCA_DEBUG
489static void spca504_read_info(struct gspca_dev *gspca_dev) 436static void spca504_read_info(struct gspca_dev *gspca_dev)
490{ 437{
491 int i; 438 int i;
492 u8 info[6]; 439 u8 info[6];
493 440
494 for (i = 0; i < 6; i++) 441 for (i = 0; i < 6; i++) {
495 info[i] = reg_r_1(gspca_dev, i); 442 reg_r(gspca_dev, 0, i, 1);
443 info[i] = gspca_dev->usb_buf[0];
444 }
496 PDEBUG(D_STREAM, 445 PDEBUG(D_STREAM,
497 "Read info: %d %d %d %d %d %d." 446 "Read info: %d %d %d %d %d %d."
498 " Should be 1,0,2,2,0,0", 447 " Should be 1,0,2,2,0,0",
499 info[0], info[1], info[2], 448 info[0], info[1], info[2],
500 info[3], info[4], info[5]); 449 info[3], info[4], info[5]);
501} 450}
451#endif
502 452
503static void spca504A_acknowledged_command(struct gspca_dev *gspca_dev, 453static void spca504A_acknowledged_command(struct gspca_dev *gspca_dev,
504 u8 req, 454 u8 req,
505 u16 idx, u16 val, u16 endcode, u8 count) 455 u16 idx, u16 val, u8 endcode, u8 count)
506{ 456{
507 u16 status; 457 u16 status;
508 458
509 reg_w_riv(gspca_dev, req, idx, val); 459 reg_w_riv(gspca_dev, req, idx, val);
510 status = reg_r_12(gspca_dev, 0x01, 0x0001, 1); 460 reg_r(gspca_dev, 0x01, 0x0001, 1);
511 if (gspca_dev->usb_err < 0) 461 if (gspca_dev->usb_err < 0)
512 return; 462 return;
513 PDEBUG(D_FRAM, "Status 0x%04x Need 0x%04x", status, endcode); 463 PDEBUG(D_FRAM, "Status 0x%02x Need 0x%02x",
464 gspca_dev->usb_buf[0], endcode);
514 if (!count) 465 if (!count)
515 return; 466 return;
516 count = 200; 467 count = 200;
@@ -518,7 +469,8 @@ static void spca504A_acknowledged_command(struct gspca_dev *gspca_dev,
518 msleep(10); 469 msleep(10);
519 /* gsmart mini2 write a each wait setting 1 ms is enough */ 470 /* gsmart mini2 write a each wait setting 1 ms is enough */
520/* reg_w_riv(gspca_dev, req, idx, val); */ 471/* reg_w_riv(gspca_dev, req, idx, val); */
521 status = reg_r_12(gspca_dev, 0x01, 0x0001, 1); 472 reg_r(gspca_dev, 0x01, 0x0001, 1);
473 status = gspca_dev->usb_buf[0];
522 if (status == endcode) { 474 if (status == endcode) {
523 PDEBUG(D_FRAM, "status 0x%04x after wait %d", 475 PDEBUG(D_FRAM, "status 0x%04x after wait %d",
524 status, 200 - count); 476 status, 200 - count);
@@ -555,17 +507,19 @@ static void spca504B_WaitCmdStatus(struct gspca_dev *gspca_dev)
555 } 507 }
556} 508}
557 509
510#ifdef GSPCA_DEBUG
558static void spca50x_GetFirmware(struct gspca_dev *gspca_dev) 511static void spca50x_GetFirmware(struct gspca_dev *gspca_dev)
559{ 512{
560 u8 *data; 513 u8 *data;
561 514
562 data = gspca_dev->usb_buf; 515 data = gspca_dev->usb_buf;
563 reg_r(gspca_dev, 0x20, 0, 5); 516 reg_r(gspca_dev, 0x20, 0, 5);
564 PDEBUG(D_STREAM, "FirmWare : %d %d %d %d %d ", 517 PDEBUG(D_STREAM, "FirmWare: %d %d %d %d %d",
565 data[0], data[1], data[2], data[3], data[4]); 518 data[0], data[1], data[2], data[3], data[4]);
566 reg_r(gspca_dev, 0x23, 0, 64); 519 reg_r(gspca_dev, 0x23, 0, 64);
567 reg_r(gspca_dev, 0x23, 1, 64); 520 reg_r(gspca_dev, 0x23, 1, 64);
568} 521}
522#endif
569 523
570static void spca504B_SetSizeType(struct gspca_dev *gspca_dev) 524static void spca504B_SetSizeType(struct gspca_dev *gspca_dev)
571{ 525{
@@ -578,7 +532,9 @@ static void spca504B_SetSizeType(struct gspca_dev *gspca_dev)
578 reg_w_riv(gspca_dev, 0x31, 0, 0); 532 reg_w_riv(gspca_dev, 0x31, 0, 0);
579 spca504B_WaitCmdStatus(gspca_dev); 533 spca504B_WaitCmdStatus(gspca_dev);
580 spca504B_PollingDataReady(gspca_dev); 534 spca504B_PollingDataReady(gspca_dev);
535#ifdef GSPCA_DEBUG
581 spca50x_GetFirmware(gspca_dev); 536 spca50x_GetFirmware(gspca_dev);
537#endif
582 reg_w_1(gspca_dev, 0x24, 0, 8, 2); /* type */ 538 reg_w_1(gspca_dev, 0x24, 0, 8, 2); /* type */
583 reg_r(gspca_dev, 0x24, 8, 1); 539 reg_r(gspca_dev, 0x24, 8, 1);
584 540
@@ -628,7 +584,8 @@ static void spca504_wait_status(struct gspca_dev *gspca_dev)
628 cnt = 256; 584 cnt = 256;
629 while (--cnt > 0) { 585 while (--cnt > 0) {
630 /* With this we get the status, when return 0 it's all ok */ 586 /* With this we get the status, when return 0 it's all ok */
631 if (reg_r_12(gspca_dev, 0x06, 0x00, 1) == 0) 587 reg_r(gspca_dev, 0x06, 0x00, 1);
588 if (gspca_dev->usb_buf[0] == 0)
632 return; 589 return;
633 msleep(10); 590 msleep(10);
634 } 591 }
@@ -772,10 +729,14 @@ static int sd_init(struct gspca_dev *gspca_dev)
772 /* fall thru */ 729 /* fall thru */
773 case BRIDGE_SPCA533: 730 case BRIDGE_SPCA533:
774 spca504B_PollingDataReady(gspca_dev); 731 spca504B_PollingDataReady(gspca_dev);
732#ifdef GSPCA_DEBUG
775 spca50x_GetFirmware(gspca_dev); 733 spca50x_GetFirmware(gspca_dev);
734#endif
776 break; 735 break;
777 case BRIDGE_SPCA536: 736 case BRIDGE_SPCA536:
737#ifdef GSPCA_DEBUG
778 spca50x_GetFirmware(gspca_dev); 738 spca50x_GetFirmware(gspca_dev);
739#endif
779 reg_r(gspca_dev, 0x00, 0x5002, 1); 740 reg_r(gspca_dev, 0x00, 0x5002, 1);
780 reg_w_1(gspca_dev, 0x24, 0, 0, 0); 741 reg_w_1(gspca_dev, 0x24, 0, 0, 0);
781 reg_r(gspca_dev, 0x24, 0, 1); 742 reg_r(gspca_dev, 0x24, 0, 1);
@@ -801,7 +762,9 @@ static int sd_init(struct gspca_dev *gspca_dev)
801/* case BRIDGE_SPCA504: */ 762/* case BRIDGE_SPCA504: */
802 PDEBUG(D_STREAM, "Opening SPCA504"); 763 PDEBUG(D_STREAM, "Opening SPCA504");
803 if (sd->subtype == AiptekMiniPenCam13) { 764 if (sd->subtype == AiptekMiniPenCam13) {
765#ifdef GSPCA_DEBUG
804 spca504_read_info(gspca_dev); 766 spca504_read_info(gspca_dev);
767#endif
805 768
806 /* Set AE AWB Banding Type 3-> 50Hz 2-> 60Hz */ 769 /* Set AE AWB Banding Type 3-> 50Hz 2-> 60Hz */
807 spca504A_acknowledged_command(gspca_dev, 0x24, 770 spca504A_acknowledged_command(gspca_dev, 0x24,
@@ -873,7 +836,9 @@ static int sd_start(struct gspca_dev *gspca_dev)
873 break; 836 break;
874 case BRIDGE_SPCA504: 837 case BRIDGE_SPCA504:
875 if (sd->subtype == AiptekMiniPenCam13) { 838 if (sd->subtype == AiptekMiniPenCam13) {
839#ifdef GSPCA_DEBUG
876 spca504_read_info(gspca_dev); 840 spca504_read_info(gspca_dev);
841#endif
877 842
878 /* Set AE AWB Banding Type 3-> 50Hz 2-> 60Hz */ 843 /* Set AE AWB Banding Type 3-> 50Hz 2-> 60Hz */
879 spca504A_acknowledged_command(gspca_dev, 0x24, 844 spca504A_acknowledged_command(gspca_dev, 0x24,
@@ -885,7 +850,9 @@ static int sd_start(struct gspca_dev *gspca_dev)
885 0, 0, 0x9d, 1); 850 0, 0, 0x9d, 1);
886 } else { 851 } else {
887 spca504_acknowledged_command(gspca_dev, 0x24, 8, 3); 852 spca504_acknowledged_command(gspca_dev, 0x24, 8, 3);
853#ifdef GSPCA_DEBUG
888 spca504_read_info(gspca_dev); 854 spca504_read_info(gspca_dev);
855#endif
889 spca504_acknowledged_command(gspca_dev, 0x24, 8, 3); 856 spca504_acknowledged_command(gspca_dev, 0x24, 8, 3);
890 spca504_acknowledged_command(gspca_dev, 0x24, 0, 0); 857 spca504_acknowledged_command(gspca_dev, 0x24, 0, 0);
891 } 858 }
diff --git a/drivers/media/video/gspca/t613.c b/drivers/media/video/gspca/t613.c
index a3eccd815766..7e762d551099 100644
--- a/drivers/media/video/gspca/t613.c
+++ b/drivers/media/video/gspca/t613.c
@@ -92,8 +92,6 @@ static int sd_setmirror(struct gspca_dev *gspca_dev, __s32 val);
92static int sd_getmirror(struct gspca_dev *gspca_dev, __s32 *val); 92static int sd_getmirror(struct gspca_dev *gspca_dev, __s32 *val);
93static int sd_seteffect(struct gspca_dev *gspca_dev, __s32 val); 93static int sd_seteffect(struct gspca_dev *gspca_dev, __s32 val);
94static int sd_geteffect(struct gspca_dev *gspca_dev, __s32 *val); 94static int sd_geteffect(struct gspca_dev *gspca_dev, __s32 *val);
95static int sd_querymenu(struct gspca_dev *gspca_dev,
96 struct v4l2_querymenu *menu);
97 95
98static const struct ctrl sd_ctrls[] = { 96static const struct ctrl sd_ctrls[] = {
99 { 97 {
@@ -1379,17 +1377,14 @@ static int sd_getlowlight(struct gspca_dev *gspca_dev, __s32 *val)
1379static int sd_querymenu(struct gspca_dev *gspca_dev, 1377static int sd_querymenu(struct gspca_dev *gspca_dev,
1380 struct v4l2_querymenu *menu) 1378 struct v4l2_querymenu *menu)
1381{ 1379{
1380 static const char *freq_nm[3] = {"NoFliker", "50 Hz", "60 Hz"};
1381
1382 switch (menu->id) { 1382 switch (menu->id) {
1383 case V4L2_CID_POWER_LINE_FREQUENCY: 1383 case V4L2_CID_POWER_LINE_FREQUENCY:
1384 switch (menu->index) { 1384 if ((unsigned) menu->index >= ARRAY_SIZE(freq_nm))
1385 case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */ 1385 break;
1386 strcpy((char *) menu->name, "50 Hz"); 1386 strcpy((char *) menu->name, freq_nm[menu->index]);
1387 return 0; 1387 return 0;
1388 case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
1389 strcpy((char *) menu->name, "60 Hz");
1390 return 0;
1391 }
1392 break;
1393 case V4L2_CID_EFFECTS: 1388 case V4L2_CID_EFFECTS:
1394 if ((unsigned) menu->index < ARRAY_SIZE(effects_control)) { 1389 if ((unsigned) menu->index < ARRAY_SIZE(effects_control)) {
1395 strncpy((char *) menu->name, 1390 strncpy((char *) menu->name,
diff --git a/drivers/media/video/gspca/zc3xx.c b/drivers/media/video/gspca/zc3xx.c
index fa164e861cde..61cdd56a74a9 100644
--- a/drivers/media/video/gspca/zc3xx.c
+++ b/drivers/media/video/gspca/zc3xx.c
@@ -3065,15 +3065,10 @@ static const struct usb_action mc501cb_InitialScale[] = { /* 320x240 */
3065 {0xaa, 0x55, 0x0010}, /* 00,55,10,aa */ 3065 {0xaa, 0x55, 0x0010}, /* 00,55,10,aa */
3066 {0xa0, 0xf0, 0x0199}, /* 01,99,F0,cc */ 3066 {0xa0, 0xf0, 0x0199}, /* 01,99,F0,cc */
3067 {0xa0, 0x80, 0x019a}, /* 01,9A,80,cc */ 3067 {0xa0, 0x80, 0x019a}, /* 01,9A,80,cc */
3068 {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */
3069 {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */
3070 {0xaa, 0x36, 0x001d}, /* 00,36,1D,aa */
3071 {0xaa, 0x37, 0x004c}, /* 00,37,4C,aa */
3072 {0xaa, 0x3b, 0x001d}, /* 00,3B,1D,aa */
3073 {} 3068 {}
3074}; 3069};
3075 3070
3076static const struct usb_action mc501cb_50HZScale[] = { 3071static const struct usb_action mc501cb_50HZ[] = {
3077 {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */ 3072 {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */
3078 {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */ 3073 {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */
3079 {0xaa, 0x36, 0x001d}, /* 00,36,1D,aa */ 3074 {0xaa, 0x36, 0x001d}, /* 00,36,1D,aa */
@@ -3082,15 +3077,10 @@ static const struct usb_action mc501cb_50HZScale[] = {
3082 {0xaa, 0x3c, 0x004c}, /* 00,3C,4C,aa */ 3077 {0xaa, 0x3c, 0x004c}, /* 00,3C,4C,aa */
3083 {0xaa, 0x3d, 0x001d}, /* 00,3D,1D,aa */ 3078 {0xaa, 0x3d, 0x001d}, /* 00,3D,1D,aa */
3084 {0xaa, 0x3e, 0x004c}, /* 00,3E,4C,aa */ 3079 {0xaa, 0x3e, 0x004c}, /* 00,3E,4C,aa */
3085 {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */
3086 {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */
3087 {0xaa, 0x36, 0x003a}, /* 00,36,3A,aa */
3088 {0xaa, 0x37, 0x0098}, /* 00,37,98,aa */
3089 {0xaa, 0x3b, 0x003a}, /* 00,3B,3A,aa */
3090 {} 3080 {}
3091}; 3081};
3092 3082
3093static const struct usb_action mc501cb_50HZ[] = { 3083static const struct usb_action mc501cb_50HZScale[] = {
3094 {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */ 3084 {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */
3095 {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */ 3085 {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */
3096 {0xaa, 0x36, 0x003a}, /* 00,36,3A,aa */ 3086 {0xaa, 0x36, 0x003a}, /* 00,36,3A,aa */
@@ -3099,15 +3089,10 @@ static const struct usb_action mc501cb_50HZ[] = {
3099 {0xaa, 0x3c, 0x0098}, /* 00,3C,98,aa */ 3089 {0xaa, 0x3c, 0x0098}, /* 00,3C,98,aa */
3100 {0xaa, 0x3d, 0x003a}, /* 00,3D,3A,aa */ 3090 {0xaa, 0x3d, 0x003a}, /* 00,3D,3A,aa */
3101 {0xaa, 0x3e, 0x0098}, /* 00,3E,98,aa */ 3091 {0xaa, 0x3e, 0x0098}, /* 00,3E,98,aa */
3102 {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */
3103 {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */
3104 {0xaa, 0x36, 0x0018}, /* 00,36,18,aa */
3105 {0xaa, 0x37, 0x006a}, /* 00,37,6A,aa */
3106 {0xaa, 0x3d, 0x0018}, /* 00,3D,18,aa */
3107 {} 3092 {}
3108}; 3093};
3109 3094
3110static const struct usb_action mc501cb_60HZScale[] = { 3095static const struct usb_action mc501cb_60HZ[] = {
3111 {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */ 3096 {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */
3112 {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */ 3097 {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */
3113 {0xaa, 0x36, 0x0018}, /* 00,36,18,aa */ 3098 {0xaa, 0x36, 0x0018}, /* 00,36,18,aa */
@@ -3116,15 +3101,10 @@ static const struct usb_action mc501cb_60HZScale[] = {
3116 {0xaa, 0x3e, 0x006a}, /* 00,3E,6A,aa */ 3101 {0xaa, 0x3e, 0x006a}, /* 00,3E,6A,aa */
3117 {0xaa, 0x3b, 0x0018}, /* 00,3B,18,aa */ 3102 {0xaa, 0x3b, 0x0018}, /* 00,3B,18,aa */
3118 {0xaa, 0x3c, 0x006a}, /* 00,3C,6A,aa */ 3103 {0xaa, 0x3c, 0x006a}, /* 00,3C,6A,aa */
3119 {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */
3120 {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */
3121 {0xaa, 0x36, 0x0030}, /* 00,36,30,aa */
3122 {0xaa, 0x37, 0x00d4}, /* 00,37,D4,aa */
3123 {0xaa, 0x3d, 0x0030}, /* 00,3D,30,aa */
3124 {} 3104 {}
3125}; 3105};
3126 3106
3127static const struct usb_action mc501cb_60HZ[] = { 3107static const struct usb_action mc501cb_60HZScale[] = {
3128 {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */ 3108 {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */
3129 {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */ 3109 {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */
3130 {0xaa, 0x36, 0x0030}, /* 00,36,30,aa */ 3110 {0xaa, 0x36, 0x0030}, /* 00,36,30,aa */
@@ -3133,15 +3113,10 @@ static const struct usb_action mc501cb_60HZ[] = {
3133 {0xaa, 0x3e, 0x00d4}, /* 00,3E,D4,aa */ 3113 {0xaa, 0x3e, 0x00d4}, /* 00,3E,D4,aa */
3134 {0xaa, 0x3b, 0x0030}, /* 00,3B,30,aa */ 3114 {0xaa, 0x3b, 0x0030}, /* 00,3B,30,aa */
3135 {0xaa, 0x3c, 0x00d4}, /* 00,3C,D4,aa */ 3115 {0xaa, 0x3c, 0x00d4}, /* 00,3C,D4,aa */
3136 {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */
3137 {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */
3138 {0xaa, 0x36, 0x0018}, /* 00,36,18,aa */
3139 {0xaa, 0x37, 0x006a}, /* 00,37,6A,aa */
3140 {0xaa, 0x3d, 0x0018}, /* 00,3D,18,aa */
3141 {} 3116 {}
3142}; 3117};
3143 3118
3144static const struct usb_action mc501cb_NoFlikerScale[] = { 3119static const struct usb_action mc501cb_NoFliker[] = {
3145 {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */ 3120 {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */
3146 {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */ 3121 {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */
3147 {0xaa, 0x36, 0x0018}, /* 00,36,18,aa */ 3122 {0xaa, 0x36, 0x0018}, /* 00,36,18,aa */
@@ -3150,15 +3125,10 @@ static const struct usb_action mc501cb_NoFlikerScale[] = {
3150 {0xaa, 0x3e, 0x006a}, /* 00,3E,6A,aa */ 3125 {0xaa, 0x3e, 0x006a}, /* 00,3E,6A,aa */
3151 {0xaa, 0x3b, 0x0018}, /* 00,3B,18,aa */ 3126 {0xaa, 0x3b, 0x0018}, /* 00,3B,18,aa */
3152 {0xaa, 0x3c, 0x006a}, /* 00,3C,6A,aa */ 3127 {0xaa, 0x3c, 0x006a}, /* 00,3C,6A,aa */
3153 {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */
3154 {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */
3155 {0xaa, 0x36, 0x0030}, /* 00,36,30,aa */
3156 {0xaa, 0x37, 0x00d4}, /* 00,37,D4,aa */
3157 {0xaa, 0x3d, 0x0030}, /* 00,3D,30,aa */
3158 {} 3128 {}
3159}; 3129};
3160 3130
3161static const struct usb_action mc501cb_NoFliker[] = { 3131static const struct usb_action mc501cb_NoFlikerScale[] = {
3162 {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */ 3132 {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */
3163 {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */ 3133 {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */
3164 {0xaa, 0x36, 0x0030}, /* 00,36,30,aa */ 3134 {0xaa, 0x36, 0x0030}, /* 00,36,30,aa */
@@ -6296,7 +6266,6 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev)
6296{ 6266{
6297 struct sd *sd = (struct sd *) gspca_dev; 6267 struct sd *sd = (struct sd *) gspca_dev;
6298 int i; 6268 int i;
6299 u8 retbyte;
6300 u16 retword; 6269 u16 retword;
6301 6270
6302/*fixme: lack of 8b=b3 (11,12)-> 10, 8b=e0 (14,15,16)-> 12 found in gspcav1*/ 6271/*fixme: lack of 8b=b3 (11,12)-> 10, 8b=e0 (14,15,16)-> 12 found in gspcav1*/
@@ -6389,8 +6358,12 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev)
6389 retword |= i2c_read(gspca_dev, 0x01); /* ID 1 */ 6358 retword |= i2c_read(gspca_dev, 0x01); /* ID 1 */
6390 PDEBUG(D_PROBE, "probe 3wr vga 2 0x%04x", retword); 6359 PDEBUG(D_PROBE, "probe 3wr vga 2 0x%04x", retword);
6391 if (retword == 0x2030) { 6360 if (retword == 0x2030) {
6361#ifdef GSPCA_DEBUG
6362 u8 retbyte;
6363
6392 retbyte = i2c_read(gspca_dev, 0x02); /* revision number */ 6364 retbyte = i2c_read(gspca_dev, 0x02); /* revision number */
6393 PDEBUG(D_PROBE, "sensor PO2030 rev 0x%02x", retbyte); 6365 PDEBUG(D_PROBE, "sensor PO2030 rev 0x%02x", retbyte);
6366#endif
6394 send_unknown(gspca_dev, SENSOR_PO2030); 6367 send_unknown(gspca_dev, SENSOR_PO2030);
6395 return retword; 6368 return retword;
6396 } 6369 }
diff --git a/drivers/media/video/ivtv/ivtv-driver.c b/drivers/media/video/ivtv/ivtv-driver.c
index 39946420b301..a4e4dfdbc2f2 100644
--- a/drivers/media/video/ivtv/ivtv-driver.c
+++ b/drivers/media/video/ivtv/ivtv-driver.c
@@ -810,7 +810,6 @@ static int ivtv_setup_pci(struct ivtv *itv, struct pci_dev *pdev,
810 const struct pci_device_id *pci_id) 810 const struct pci_device_id *pci_id)
811{ 811{
812 u16 cmd; 812 u16 cmd;
813 u8 card_rev;
814 unsigned char pci_latency; 813 unsigned char pci_latency;
815 814
816 IVTV_DEBUG_INFO("Enabling pci device\n"); 815 IVTV_DEBUG_INFO("Enabling pci device\n");
@@ -857,7 +856,6 @@ static int ivtv_setup_pci(struct ivtv *itv, struct pci_dev *pdev,
857 } 856 }
858 IVTV_DEBUG_INFO("Bus Mastering Enabled.\n"); 857 IVTV_DEBUG_INFO("Bus Mastering Enabled.\n");
859 858
860 pci_read_config_byte(pdev, PCI_CLASS_REVISION, &card_rev);
861 pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &pci_latency); 859 pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &pci_latency);
862 860
863 if (pci_latency < 64 && ivtv_pci_latency) { 861 if (pci_latency < 64 && ivtv_pci_latency) {
@@ -874,7 +872,7 @@ static int ivtv_setup_pci(struct ivtv *itv, struct pci_dev *pdev,
874 872
875 IVTV_DEBUG_INFO("%d (rev %d) at %02x:%02x.%x, " 873 IVTV_DEBUG_INFO("%d (rev %d) at %02x:%02x.%x, "
876 "irq: %d, latency: %d, memory: 0x%lx\n", 874 "irq: %d, latency: %d, memory: 0x%lx\n",
877 pdev->device, card_rev, pdev->bus->number, 875 pdev->device, pdev->revision, pdev->bus->number,
878 PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn), 876 PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn),
879 pdev->irq, pci_latency, (unsigned long)itv->base_addr); 877 pdev->irq, pci_latency, (unsigned long)itv->base_addr);
880 878
diff --git a/drivers/media/video/mt9m111.c b/drivers/media/video/mt9m111.c
index 53fa2a7bf156..ebebed929627 100644
--- a/drivers/media/video/mt9m111.c
+++ b/drivers/media/video/mt9m111.c
@@ -315,10 +315,20 @@ static int mt9m111_setup_rect(struct i2c_client *client,
315static int mt9m111_setup_pixfmt(struct i2c_client *client, u16 outfmt) 315static int mt9m111_setup_pixfmt(struct i2c_client *client, u16 outfmt)
316{ 316{
317 int ret; 317 int ret;
318 u16 mask = MT9M111_OUTFMT_PROCESSED_BAYER | MT9M111_OUTFMT_RGB |
319 MT9M111_OUTFMT_BYPASS_IFP | MT9M111_OUTFMT_SWAP_RGB_EVEN |
320 MT9M111_OUTFMT_RGB565 | MT9M111_OUTFMT_RGB555 |
321 MT9M111_OUTFMT_SWAP_YCbCr_Cb_Cr |
322 MT9M111_OUTFMT_SWAP_YCbCr_C_Y;
318 323
319 ret = reg_write(OUTPUT_FORMAT_CTRL2_A, outfmt); 324 ret = reg_read(OUTPUT_FORMAT_CTRL2_A);
325 if (ret >= 0)
326 ret = reg_write(OUTPUT_FORMAT_CTRL2_A, (ret & ~mask) | outfmt);
320 if (!ret) 327 if (!ret)
321 ret = reg_write(OUTPUT_FORMAT_CTRL2_B, outfmt); 328 ret = reg_read(OUTPUT_FORMAT_CTRL2_B);
329 if (ret >= 0)
330 ret = reg_write(OUTPUT_FORMAT_CTRL2_B, (ret & ~mask) | outfmt);
331
322 return ret; 332 return ret;
323} 333}
324 334
diff --git a/drivers/media/video/mt9v022.c b/drivers/media/video/mt9v022.c
index e313d8390092..fc76ed1c08e5 100644
--- a/drivers/media/video/mt9v022.c
+++ b/drivers/media/video/mt9v022.c
@@ -228,7 +228,7 @@ static int mt9v022_set_bus_param(struct soc_camera_device *icd,
228 228
229 flags = soc_camera_apply_sensor_flags(icl, flags); 229 flags = soc_camera_apply_sensor_flags(icl, flags);
230 230
231 if (flags & SOCAM_PCLK_SAMPLE_RISING) 231 if (flags & SOCAM_PCLK_SAMPLE_FALLING)
232 pixclk |= 0x10; 232 pixclk |= 0x10;
233 233
234 if (!(flags & SOCAM_HSYNC_ACTIVE_HIGH)) 234 if (!(flags & SOCAM_HSYNC_ACTIVE_HIGH))
diff --git a/drivers/media/video/mt9v032.c b/drivers/media/video/mt9v032.c
new file mode 100644
index 000000000000..1319c2c48aff
--- /dev/null
+++ b/drivers/media/video/mt9v032.c
@@ -0,0 +1,773 @@
1/*
2 * Driver for MT9V032 CMOS Image Sensor from Micron
3 *
4 * Copyright (C) 2010, Laurent Pinchart <laurent.pinchart@ideasonboard.com>
5 *
6 * Based on the MT9M001 driver,
7 *
8 * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 */
14
15#include <linux/delay.h>
16#include <linux/i2c.h>
17#include <linux/log2.h>
18#include <linux/mutex.h>
19#include <linux/slab.h>
20#include <linux/videodev2.h>
21#include <linux/v4l2-mediabus.h>
22
23#include <media/mt9v032.h>
24#include <media/v4l2-ctrls.h>
25#include <media/v4l2-device.h>
26#include <media/v4l2-subdev.h>
27
28#define MT9V032_PIXEL_ARRAY_HEIGHT 492
29#define MT9V032_PIXEL_ARRAY_WIDTH 782
30
31#define MT9V032_CHIP_VERSION 0x00
32#define MT9V032_CHIP_ID_REV1 0x1311
33#define MT9V032_CHIP_ID_REV3 0x1313
34#define MT9V032_ROW_START 0x01
35#define MT9V032_ROW_START_MIN 4
36#define MT9V032_ROW_START_DEF 10
37#define MT9V032_ROW_START_MAX 482
38#define MT9V032_COLUMN_START 0x02
39#define MT9V032_COLUMN_START_MIN 1
40#define MT9V032_COLUMN_START_DEF 2
41#define MT9V032_COLUMN_START_MAX 752
42#define MT9V032_WINDOW_HEIGHT 0x03
43#define MT9V032_WINDOW_HEIGHT_MIN 1
44#define MT9V032_WINDOW_HEIGHT_DEF 480
45#define MT9V032_WINDOW_HEIGHT_MAX 480
46#define MT9V032_WINDOW_WIDTH 0x04
47#define MT9V032_WINDOW_WIDTH_MIN 1
48#define MT9V032_WINDOW_WIDTH_DEF 752
49#define MT9V032_WINDOW_WIDTH_MAX 752
50#define MT9V032_HORIZONTAL_BLANKING 0x05
51#define MT9V032_HORIZONTAL_BLANKING_MIN 43
52#define MT9V032_HORIZONTAL_BLANKING_MAX 1023
53#define MT9V032_VERTICAL_BLANKING 0x06
54#define MT9V032_VERTICAL_BLANKING_MIN 4
55#define MT9V032_VERTICAL_BLANKING_MAX 3000
56#define MT9V032_CHIP_CONTROL 0x07
57#define MT9V032_CHIP_CONTROL_MASTER_MODE (1 << 3)
58#define MT9V032_CHIP_CONTROL_DOUT_ENABLE (1 << 7)
59#define MT9V032_CHIP_CONTROL_SEQUENTIAL (1 << 8)
60#define MT9V032_SHUTTER_WIDTH1 0x08
61#define MT9V032_SHUTTER_WIDTH2 0x09
62#define MT9V032_SHUTTER_WIDTH_CONTROL 0x0a
63#define MT9V032_TOTAL_SHUTTER_WIDTH 0x0b
64#define MT9V032_TOTAL_SHUTTER_WIDTH_MIN 1
65#define MT9V032_TOTAL_SHUTTER_WIDTH_DEF 480
66#define MT9V032_TOTAL_SHUTTER_WIDTH_MAX 32767
67#define MT9V032_RESET 0x0c
68#define MT9V032_READ_MODE 0x0d
69#define MT9V032_READ_MODE_ROW_BIN_MASK (3 << 0)
70#define MT9V032_READ_MODE_ROW_BIN_SHIFT 0
71#define MT9V032_READ_MODE_COLUMN_BIN_MASK (3 << 2)
72#define MT9V032_READ_MODE_COLUMN_BIN_SHIFT 2
73#define MT9V032_READ_MODE_ROW_FLIP (1 << 4)
74#define MT9V032_READ_MODE_COLUMN_FLIP (1 << 5)
75#define MT9V032_READ_MODE_DARK_COLUMNS (1 << 6)
76#define MT9V032_READ_MODE_DARK_ROWS (1 << 7)
77#define MT9V032_PIXEL_OPERATION_MODE 0x0f
78#define MT9V032_PIXEL_OPERATION_MODE_COLOR (1 << 2)
79#define MT9V032_PIXEL_OPERATION_MODE_HDR (1 << 6)
80#define MT9V032_ANALOG_GAIN 0x35
81#define MT9V032_ANALOG_GAIN_MIN 16
82#define MT9V032_ANALOG_GAIN_DEF 16
83#define MT9V032_ANALOG_GAIN_MAX 64
84#define MT9V032_MAX_ANALOG_GAIN 0x36
85#define MT9V032_MAX_ANALOG_GAIN_MAX 127
86#define MT9V032_FRAME_DARK_AVERAGE 0x42
87#define MT9V032_DARK_AVG_THRESH 0x46
88#define MT9V032_DARK_AVG_LOW_THRESH_MASK (255 << 0)
89#define MT9V032_DARK_AVG_LOW_THRESH_SHIFT 0
90#define MT9V032_DARK_AVG_HIGH_THRESH_MASK (255 << 8)
91#define MT9V032_DARK_AVG_HIGH_THRESH_SHIFT 8
92#define MT9V032_ROW_NOISE_CORR_CONTROL 0x70
93#define MT9V032_ROW_NOISE_CORR_ENABLE (1 << 5)
94#define MT9V032_ROW_NOISE_CORR_USE_BLK_AVG (1 << 7)
95#define MT9V032_PIXEL_CLOCK 0x74
96#define MT9V032_PIXEL_CLOCK_INV_LINE (1 << 0)
97#define MT9V032_PIXEL_CLOCK_INV_FRAME (1 << 1)
98#define MT9V032_PIXEL_CLOCK_XOR_LINE (1 << 2)
99#define MT9V032_PIXEL_CLOCK_CONT_LINE (1 << 3)
100#define MT9V032_PIXEL_CLOCK_INV_PXL_CLK (1 << 4)
101#define MT9V032_TEST_PATTERN 0x7f
102#define MT9V032_TEST_PATTERN_DATA_MASK (1023 << 0)
103#define MT9V032_TEST_PATTERN_DATA_SHIFT 0
104#define MT9V032_TEST_PATTERN_USE_DATA (1 << 10)
105#define MT9V032_TEST_PATTERN_GRAY_MASK (3 << 11)
106#define MT9V032_TEST_PATTERN_GRAY_NONE (0 << 11)
107#define MT9V032_TEST_PATTERN_GRAY_VERTICAL (1 << 11)
108#define MT9V032_TEST_PATTERN_GRAY_HORIZONTAL (2 << 11)
109#define MT9V032_TEST_PATTERN_GRAY_DIAGONAL (3 << 11)
110#define MT9V032_TEST_PATTERN_ENABLE (1 << 13)
111#define MT9V032_TEST_PATTERN_FLIP (1 << 14)
112#define MT9V032_AEC_AGC_ENABLE 0xaf
113#define MT9V032_AEC_ENABLE (1 << 0)
114#define MT9V032_AGC_ENABLE (1 << 1)
115#define MT9V032_THERMAL_INFO 0xc1
116
117struct mt9v032 {
118 struct v4l2_subdev subdev;
119 struct media_pad pad;
120
121 struct v4l2_mbus_framefmt format;
122 struct v4l2_rect crop;
123
124 struct v4l2_ctrl_handler ctrls;
125
126 struct mutex power_lock;
127 int power_count;
128
129 struct mt9v032_platform_data *pdata;
130 u16 chip_control;
131 u16 aec_agc;
132};
133
134static struct mt9v032 *to_mt9v032(struct v4l2_subdev *sd)
135{
136 return container_of(sd, struct mt9v032, subdev);
137}
138
139static int mt9v032_read(struct i2c_client *client, const u8 reg)
140{
141 s32 data = i2c_smbus_read_word_data(client, reg);
142 dev_dbg(&client->dev, "%s: read 0x%04x from 0x%02x\n", __func__,
143 swab16(data), reg);
144 return data < 0 ? data : swab16(data);
145}
146
147static int mt9v032_write(struct i2c_client *client, const u8 reg,
148 const u16 data)
149{
150 dev_dbg(&client->dev, "%s: writing 0x%04x to 0x%02x\n", __func__,
151 data, reg);
152 return i2c_smbus_write_word_data(client, reg, swab16(data));
153}
154
155static int mt9v032_set_chip_control(struct mt9v032 *mt9v032, u16 clear, u16 set)
156{
157 struct i2c_client *client = v4l2_get_subdevdata(&mt9v032->subdev);
158 u16 value = (mt9v032->chip_control & ~clear) | set;
159 int ret;
160
161 ret = mt9v032_write(client, MT9V032_CHIP_CONTROL, value);
162 if (ret < 0)
163 return ret;
164
165 mt9v032->chip_control = value;
166 return 0;
167}
168
169static int
170mt9v032_update_aec_agc(struct mt9v032 *mt9v032, u16 which, int enable)
171{
172 struct i2c_client *client = v4l2_get_subdevdata(&mt9v032->subdev);
173 u16 value = mt9v032->aec_agc;
174 int ret;
175
176 if (enable)
177 value |= which;
178 else
179 value &= ~which;
180
181 ret = mt9v032_write(client, MT9V032_AEC_AGC_ENABLE, value);
182 if (ret < 0)
183 return ret;
184
185 mt9v032->aec_agc = value;
186 return 0;
187}
188
189static int mt9v032_power_on(struct mt9v032 *mt9v032)
190{
191 struct i2c_client *client = v4l2_get_subdevdata(&mt9v032->subdev);
192 int ret;
193
194 if (mt9v032->pdata->set_clock) {
195 mt9v032->pdata->set_clock(&mt9v032->subdev, 25000000);
196 udelay(1);
197 }
198
199 /* Reset the chip and stop data read out */
200 ret = mt9v032_write(client, MT9V032_RESET, 1);
201 if (ret < 0)
202 return ret;
203
204 ret = mt9v032_write(client, MT9V032_RESET, 0);
205 if (ret < 0)
206 return ret;
207
208 return mt9v032_write(client, MT9V032_CHIP_CONTROL, 0);
209}
210
211static void mt9v032_power_off(struct mt9v032 *mt9v032)
212{
213 if (mt9v032->pdata->set_clock)
214 mt9v032->pdata->set_clock(&mt9v032->subdev, 0);
215}
216
217static int __mt9v032_set_power(struct mt9v032 *mt9v032, bool on)
218{
219 struct i2c_client *client = v4l2_get_subdevdata(&mt9v032->subdev);
220 int ret;
221
222 if (!on) {
223 mt9v032_power_off(mt9v032);
224 return 0;
225 }
226
227 ret = mt9v032_power_on(mt9v032);
228 if (ret < 0)
229 return ret;
230
231 /* Configure the pixel clock polarity */
232 if (mt9v032->pdata && mt9v032->pdata->clk_pol) {
233 ret = mt9v032_write(client, MT9V032_PIXEL_CLOCK,
234 MT9V032_PIXEL_CLOCK_INV_PXL_CLK);
235 if (ret < 0)
236 return ret;
237 }
238
239 /* Disable the noise correction algorithm and restore the controls. */
240 ret = mt9v032_write(client, MT9V032_ROW_NOISE_CORR_CONTROL, 0);
241 if (ret < 0)
242 return ret;
243
244 return v4l2_ctrl_handler_setup(&mt9v032->ctrls);
245}
246
247/* -----------------------------------------------------------------------------
248 * V4L2 subdev video operations
249 */
250
251static struct v4l2_mbus_framefmt *
252__mt9v032_get_pad_format(struct mt9v032 *mt9v032, struct v4l2_subdev_fh *fh,
253 unsigned int pad, enum v4l2_subdev_format_whence which)
254{
255 switch (which) {
256 case V4L2_SUBDEV_FORMAT_TRY:
257 return v4l2_subdev_get_try_format(fh, pad);
258 case V4L2_SUBDEV_FORMAT_ACTIVE:
259 return &mt9v032->format;
260 default:
261 return NULL;
262 }
263}
264
265static struct v4l2_rect *
266__mt9v032_get_pad_crop(struct mt9v032 *mt9v032, struct v4l2_subdev_fh *fh,
267 unsigned int pad, enum v4l2_subdev_format_whence which)
268{
269 switch (which) {
270 case V4L2_SUBDEV_FORMAT_TRY:
271 return v4l2_subdev_get_try_crop(fh, pad);
272 case V4L2_SUBDEV_FORMAT_ACTIVE:
273 return &mt9v032->crop;
274 default:
275 return NULL;
276 }
277}
278
279static int mt9v032_s_stream(struct v4l2_subdev *subdev, int enable)
280{
281 const u16 mode = MT9V032_CHIP_CONTROL_MASTER_MODE
282 | MT9V032_CHIP_CONTROL_DOUT_ENABLE
283 | MT9V032_CHIP_CONTROL_SEQUENTIAL;
284 struct i2c_client *client = v4l2_get_subdevdata(subdev);
285 struct mt9v032 *mt9v032 = to_mt9v032(subdev);
286 struct v4l2_mbus_framefmt *format = &mt9v032->format;
287 struct v4l2_rect *crop = &mt9v032->crop;
288 unsigned int hratio;
289 unsigned int vratio;
290 int ret;
291
292 if (!enable)
293 return mt9v032_set_chip_control(mt9v032, mode, 0);
294
295 /* Configure the window size and row/column bin */
296 hratio = DIV_ROUND_CLOSEST(crop->width, format->width);
297 vratio = DIV_ROUND_CLOSEST(crop->height, format->height);
298
299 ret = mt9v032_write(client, MT9V032_READ_MODE,
300 (hratio - 1) << MT9V032_READ_MODE_ROW_BIN_SHIFT |
301 (vratio - 1) << MT9V032_READ_MODE_COLUMN_BIN_SHIFT);
302 if (ret < 0)
303 return ret;
304
305 ret = mt9v032_write(client, MT9V032_COLUMN_START, crop->left);
306 if (ret < 0)
307 return ret;
308
309 ret = mt9v032_write(client, MT9V032_ROW_START, crop->top);
310 if (ret < 0)
311 return ret;
312
313 ret = mt9v032_write(client, MT9V032_WINDOW_WIDTH, crop->width);
314 if (ret < 0)
315 return ret;
316
317 ret = mt9v032_write(client, MT9V032_WINDOW_HEIGHT, crop->height);
318 if (ret < 0)
319 return ret;
320
321 ret = mt9v032_write(client, MT9V032_HORIZONTAL_BLANKING,
322 max(43, 660 - crop->width));
323 if (ret < 0)
324 return ret;
325
326 /* Switch to master "normal" mode */
327 return mt9v032_set_chip_control(mt9v032, 0, mode);
328}
329
330static int mt9v032_enum_mbus_code(struct v4l2_subdev *subdev,
331 struct v4l2_subdev_fh *fh,
332 struct v4l2_subdev_mbus_code_enum *code)
333{
334 if (code->index > 0)
335 return -EINVAL;
336
337 code->code = V4L2_MBUS_FMT_SGRBG10_1X10;
338 return 0;
339}
340
341static int mt9v032_enum_frame_size(struct v4l2_subdev *subdev,
342 struct v4l2_subdev_fh *fh,
343 struct v4l2_subdev_frame_size_enum *fse)
344{
345 if (fse->index >= 8 || fse->code != V4L2_MBUS_FMT_SGRBG10_1X10)
346 return -EINVAL;
347
348 fse->min_width = MT9V032_WINDOW_WIDTH_DEF / fse->index;
349 fse->max_width = fse->min_width;
350 fse->min_height = MT9V032_WINDOW_HEIGHT_DEF / fse->index;
351 fse->max_height = fse->min_height;
352
353 return 0;
354}
355
356static int mt9v032_get_format(struct v4l2_subdev *subdev,
357 struct v4l2_subdev_fh *fh,
358 struct v4l2_subdev_format *format)
359{
360 struct mt9v032 *mt9v032 = to_mt9v032(subdev);
361
362 format->format = *__mt9v032_get_pad_format(mt9v032, fh, format->pad,
363 format->which);
364 return 0;
365}
366
367static int mt9v032_set_format(struct v4l2_subdev *subdev,
368 struct v4l2_subdev_fh *fh,
369 struct v4l2_subdev_format *format)
370{
371 struct mt9v032 *mt9v032 = to_mt9v032(subdev);
372 struct v4l2_mbus_framefmt *__format;
373 struct v4l2_rect *__crop;
374 unsigned int width;
375 unsigned int height;
376 unsigned int hratio;
377 unsigned int vratio;
378
379 __crop = __mt9v032_get_pad_crop(mt9v032, fh, format->pad,
380 format->which);
381
382 /* Clamp the width and height to avoid dividing by zero. */
383 width = clamp_t(unsigned int, ALIGN(format->format.width, 2),
384 max(__crop->width / 8, MT9V032_WINDOW_WIDTH_MIN),
385 __crop->width);
386 height = clamp_t(unsigned int, ALIGN(format->format.height, 2),
387 max(__crop->height / 8, MT9V032_WINDOW_HEIGHT_MIN),
388 __crop->height);
389
390 hratio = DIV_ROUND_CLOSEST(__crop->width, width);
391 vratio = DIV_ROUND_CLOSEST(__crop->height, height);
392
393 __format = __mt9v032_get_pad_format(mt9v032, fh, format->pad,
394 format->which);
395 __format->width = __crop->width / hratio;
396 __format->height = __crop->height / vratio;
397
398 format->format = *__format;
399
400 return 0;
401}
402
403static int mt9v032_get_crop(struct v4l2_subdev *subdev,
404 struct v4l2_subdev_fh *fh,
405 struct v4l2_subdev_crop *crop)
406{
407 struct mt9v032 *mt9v032 = to_mt9v032(subdev);
408
409 crop->rect = *__mt9v032_get_pad_crop(mt9v032, fh, crop->pad,
410 crop->which);
411 return 0;
412}
413
414static int mt9v032_set_crop(struct v4l2_subdev *subdev,
415 struct v4l2_subdev_fh *fh,
416 struct v4l2_subdev_crop *crop)
417{
418 struct mt9v032 *mt9v032 = to_mt9v032(subdev);
419 struct v4l2_mbus_framefmt *__format;
420 struct v4l2_rect *__crop;
421 struct v4l2_rect rect;
422
423 /* Clamp the crop rectangle boundaries and align them to a multiple of 2
424 * pixels.
425 */
426 rect.left = clamp(ALIGN(crop->rect.left, 2),
427 MT9V032_COLUMN_START_MIN,
428 MT9V032_COLUMN_START_MAX);
429 rect.top = clamp(ALIGN(crop->rect.top, 2),
430 MT9V032_ROW_START_MIN,
431 MT9V032_ROW_START_MAX);
432 rect.width = clamp(ALIGN(crop->rect.width, 2),
433 MT9V032_WINDOW_WIDTH_MIN,
434 MT9V032_WINDOW_WIDTH_MAX);
435 rect.height = clamp(ALIGN(crop->rect.height, 2),
436 MT9V032_WINDOW_HEIGHT_MIN,
437 MT9V032_WINDOW_HEIGHT_MAX);
438
439 rect.width = min(rect.width, MT9V032_PIXEL_ARRAY_WIDTH - rect.left);
440 rect.height = min(rect.height, MT9V032_PIXEL_ARRAY_HEIGHT - rect.top);
441
442 __crop = __mt9v032_get_pad_crop(mt9v032, fh, crop->pad, crop->which);
443
444 if (rect.width != __crop->width || rect.height != __crop->height) {
445 /* Reset the output image size if the crop rectangle size has
446 * been modified.
447 */
448 __format = __mt9v032_get_pad_format(mt9v032, fh, crop->pad,
449 crop->which);
450 __format->width = rect.width;
451 __format->height = rect.height;
452 }
453
454 *__crop = rect;
455 crop->rect = rect;
456
457 return 0;
458}
459
460/* -----------------------------------------------------------------------------
461 * V4L2 subdev control operations
462 */
463
464#define V4L2_CID_TEST_PATTERN (V4L2_CID_USER_BASE | 0x1001)
465
466static int mt9v032_s_ctrl(struct v4l2_ctrl *ctrl)
467{
468 struct mt9v032 *mt9v032 =
469 container_of(ctrl->handler, struct mt9v032, ctrls);
470 struct i2c_client *client = v4l2_get_subdevdata(&mt9v032->subdev);
471 u16 data;
472
473 switch (ctrl->id) {
474 case V4L2_CID_AUTOGAIN:
475 return mt9v032_update_aec_agc(mt9v032, MT9V032_AGC_ENABLE,
476 ctrl->val);
477
478 case V4L2_CID_GAIN:
479 return mt9v032_write(client, MT9V032_ANALOG_GAIN, ctrl->val);
480
481 case V4L2_CID_EXPOSURE_AUTO:
482 return mt9v032_update_aec_agc(mt9v032, MT9V032_AEC_ENABLE,
483 ctrl->val);
484
485 case V4L2_CID_EXPOSURE:
486 return mt9v032_write(client, MT9V032_TOTAL_SHUTTER_WIDTH,
487 ctrl->val);
488
489 case V4L2_CID_TEST_PATTERN:
490 switch (ctrl->val) {
491 case 0:
492 data = 0;
493 break;
494 case 1:
495 data = MT9V032_TEST_PATTERN_GRAY_VERTICAL
496 | MT9V032_TEST_PATTERN_ENABLE;
497 break;
498 case 2:
499 data = MT9V032_TEST_PATTERN_GRAY_HORIZONTAL
500 | MT9V032_TEST_PATTERN_ENABLE;
501 break;
502 case 3:
503 data = MT9V032_TEST_PATTERN_GRAY_DIAGONAL
504 | MT9V032_TEST_PATTERN_ENABLE;
505 break;
506 default:
507 data = (ctrl->val << MT9V032_TEST_PATTERN_DATA_SHIFT)
508 | MT9V032_TEST_PATTERN_USE_DATA
509 | MT9V032_TEST_PATTERN_ENABLE
510 | MT9V032_TEST_PATTERN_FLIP;
511 break;
512 }
513
514 return mt9v032_write(client, MT9V032_TEST_PATTERN, data);
515 }
516
517 return 0;
518}
519
520static struct v4l2_ctrl_ops mt9v032_ctrl_ops = {
521 .s_ctrl = mt9v032_s_ctrl,
522};
523
524static const struct v4l2_ctrl_config mt9v032_ctrls[] = {
525 {
526 .ops = &mt9v032_ctrl_ops,
527 .id = V4L2_CID_TEST_PATTERN,
528 .type = V4L2_CTRL_TYPE_INTEGER,
529 .name = "Test pattern",
530 .min = 0,
531 .max = 1023,
532 .step = 1,
533 .def = 0,
534 .flags = 0,
535 }
536};
537
538/* -----------------------------------------------------------------------------
539 * V4L2 subdev core operations
540 */
541
542static int mt9v032_set_power(struct v4l2_subdev *subdev, int on)
543{
544 struct mt9v032 *mt9v032 = to_mt9v032(subdev);
545 int ret = 0;
546
547 mutex_lock(&mt9v032->power_lock);
548
549 /* If the power count is modified from 0 to != 0 or from != 0 to 0,
550 * update the power state.
551 */
552 if (mt9v032->power_count == !on) {
553 ret = __mt9v032_set_power(mt9v032, !!on);
554 if (ret < 0)
555 goto done;
556 }
557
558 /* Update the power count. */
559 mt9v032->power_count += on ? 1 : -1;
560 WARN_ON(mt9v032->power_count < 0);
561
562done:
563 mutex_unlock(&mt9v032->power_lock);
564 return ret;
565}
566
567/* -----------------------------------------------------------------------------
568 * V4L2 subdev internal operations
569 */
570
571static int mt9v032_registered(struct v4l2_subdev *subdev)
572{
573 struct i2c_client *client = v4l2_get_subdevdata(subdev);
574 struct mt9v032 *mt9v032 = to_mt9v032(subdev);
575 s32 data;
576 int ret;
577
578 dev_info(&client->dev, "Probing MT9V032 at address 0x%02x\n",
579 client->addr);
580
581 ret = mt9v032_power_on(mt9v032);
582 if (ret < 0) {
583 dev_err(&client->dev, "MT9V032 power up failed\n");
584 return ret;
585 }
586
587 /* Read and check the sensor version */
588 data = mt9v032_read(client, MT9V032_CHIP_VERSION);
589 if (data != MT9V032_CHIP_ID_REV1 && data != MT9V032_CHIP_ID_REV3) {
590 dev_err(&client->dev, "MT9V032 not detected, wrong version "
591 "0x%04x\n", data);
592 return -ENODEV;
593 }
594
595 mt9v032_power_off(mt9v032);
596
597 dev_info(&client->dev, "MT9V032 detected at address 0x%02x\n",
598 client->addr);
599
600 return ret;
601}
602
603static int mt9v032_open(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh)
604{
605 struct v4l2_mbus_framefmt *format;
606 struct v4l2_rect *crop;
607
608 crop = v4l2_subdev_get_try_crop(fh, 0);
609 crop->left = MT9V032_COLUMN_START_DEF;
610 crop->top = MT9V032_ROW_START_DEF;
611 crop->width = MT9V032_WINDOW_WIDTH_DEF;
612 crop->height = MT9V032_WINDOW_HEIGHT_DEF;
613
614 format = v4l2_subdev_get_try_format(fh, 0);
615 format->code = V4L2_MBUS_FMT_SGRBG10_1X10;
616 format->width = MT9V032_WINDOW_WIDTH_DEF;
617 format->height = MT9V032_WINDOW_HEIGHT_DEF;
618 format->field = V4L2_FIELD_NONE;
619 format->colorspace = V4L2_COLORSPACE_SRGB;
620
621 return mt9v032_set_power(subdev, 1);
622}
623
624static int mt9v032_close(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh)
625{
626 return mt9v032_set_power(subdev, 0);
627}
628
629static struct v4l2_subdev_core_ops mt9v032_subdev_core_ops = {
630 .s_power = mt9v032_set_power,
631};
632
633static struct v4l2_subdev_video_ops mt9v032_subdev_video_ops = {
634 .s_stream = mt9v032_s_stream,
635};
636
637static struct v4l2_subdev_pad_ops mt9v032_subdev_pad_ops = {
638 .enum_mbus_code = mt9v032_enum_mbus_code,
639 .enum_frame_size = mt9v032_enum_frame_size,
640 .get_fmt = mt9v032_get_format,
641 .set_fmt = mt9v032_set_format,
642 .get_crop = mt9v032_get_crop,
643 .set_crop = mt9v032_set_crop,
644};
645
646static struct v4l2_subdev_ops mt9v032_subdev_ops = {
647 .core = &mt9v032_subdev_core_ops,
648 .video = &mt9v032_subdev_video_ops,
649 .pad = &mt9v032_subdev_pad_ops,
650};
651
652static const struct v4l2_subdev_internal_ops mt9v032_subdev_internal_ops = {
653 .registered = mt9v032_registered,
654 .open = mt9v032_open,
655 .close = mt9v032_close,
656};
657
658/* -----------------------------------------------------------------------------
659 * Driver initialization and probing
660 */
661
662static int mt9v032_probe(struct i2c_client *client,
663 const struct i2c_device_id *did)
664{
665 struct mt9v032 *mt9v032;
666 unsigned int i;
667 int ret;
668
669 if (!i2c_check_functionality(client->adapter,
670 I2C_FUNC_SMBUS_WORD_DATA)) {
671 dev_warn(&client->adapter->dev,
672 "I2C-Adapter doesn't support I2C_FUNC_SMBUS_WORD\n");
673 return -EIO;
674 }
675
676 mt9v032 = kzalloc(sizeof(*mt9v032), GFP_KERNEL);
677 if (!mt9v032)
678 return -ENOMEM;
679
680 mutex_init(&mt9v032->power_lock);
681 mt9v032->pdata = client->dev.platform_data;
682
683 v4l2_ctrl_handler_init(&mt9v032->ctrls, ARRAY_SIZE(mt9v032_ctrls) + 4);
684
685 v4l2_ctrl_new_std(&mt9v032->ctrls, &mt9v032_ctrl_ops,
686 V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
687 v4l2_ctrl_new_std(&mt9v032->ctrls, &mt9v032_ctrl_ops,
688 V4L2_CID_GAIN, MT9V032_ANALOG_GAIN_MIN,
689 MT9V032_ANALOG_GAIN_MAX, 1, MT9V032_ANALOG_GAIN_DEF);
690 v4l2_ctrl_new_std_menu(&mt9v032->ctrls, &mt9v032_ctrl_ops,
691 V4L2_CID_EXPOSURE_AUTO, V4L2_EXPOSURE_MANUAL, 0,
692 V4L2_EXPOSURE_AUTO);
693 v4l2_ctrl_new_std(&mt9v032->ctrls, &mt9v032_ctrl_ops,
694 V4L2_CID_EXPOSURE, MT9V032_TOTAL_SHUTTER_WIDTH_MIN,
695 MT9V032_TOTAL_SHUTTER_WIDTH_MAX, 1,
696 MT9V032_TOTAL_SHUTTER_WIDTH_DEF);
697
698 for (i = 0; i < ARRAY_SIZE(mt9v032_ctrls); ++i)
699 v4l2_ctrl_new_custom(&mt9v032->ctrls, &mt9v032_ctrls[i], NULL);
700
701 mt9v032->subdev.ctrl_handler = &mt9v032->ctrls;
702
703 if (mt9v032->ctrls.error)
704 printk(KERN_INFO "%s: control initialization error %d\n",
705 __func__, mt9v032->ctrls.error);
706
707 mt9v032->crop.left = MT9V032_COLUMN_START_DEF;
708 mt9v032->crop.top = MT9V032_ROW_START_DEF;
709 mt9v032->crop.width = MT9V032_WINDOW_WIDTH_DEF;
710 mt9v032->crop.height = MT9V032_WINDOW_HEIGHT_DEF;
711
712 mt9v032->format.code = V4L2_MBUS_FMT_SGRBG10_1X10;
713 mt9v032->format.width = MT9V032_WINDOW_WIDTH_DEF;
714 mt9v032->format.height = MT9V032_WINDOW_HEIGHT_DEF;
715 mt9v032->format.field = V4L2_FIELD_NONE;
716 mt9v032->format.colorspace = V4L2_COLORSPACE_SRGB;
717
718 mt9v032->aec_agc = MT9V032_AEC_ENABLE | MT9V032_AGC_ENABLE;
719
720 v4l2_i2c_subdev_init(&mt9v032->subdev, client, &mt9v032_subdev_ops);
721 mt9v032->subdev.internal_ops = &mt9v032_subdev_internal_ops;
722 mt9v032->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
723
724 mt9v032->pad.flags = MEDIA_PAD_FL_SOURCE;
725 ret = media_entity_init(&mt9v032->subdev.entity, 1, &mt9v032->pad, 0);
726 if (ret < 0)
727 kfree(mt9v032);
728
729 return ret;
730}
731
732static int mt9v032_remove(struct i2c_client *client)
733{
734 struct v4l2_subdev *subdev = i2c_get_clientdata(client);
735 struct mt9v032 *mt9v032 = to_mt9v032(subdev);
736
737 v4l2_device_unregister_subdev(subdev);
738 media_entity_cleanup(&subdev->entity);
739 kfree(mt9v032);
740 return 0;
741}
742
743static const struct i2c_device_id mt9v032_id[] = {
744 { "mt9v032", 0 },
745 { }
746};
747MODULE_DEVICE_TABLE(i2c, mt9v032_id);
748
749static struct i2c_driver mt9v032_driver = {
750 .driver = {
751 .name = "mt9v032",
752 },
753 .probe = mt9v032_probe,
754 .remove = mt9v032_remove,
755 .id_table = mt9v032_id,
756};
757
758static int __init mt9v032_init(void)
759{
760 return i2c_add_driver(&mt9v032_driver);
761}
762
763static void __exit mt9v032_exit(void)
764{
765 i2c_del_driver(&mt9v032_driver);
766}
767
768module_init(mt9v032_init);
769module_exit(mt9v032_exit);
770
771MODULE_DESCRIPTION("Aptina MT9V032 Camera driver");
772MODULE_AUTHOR("Laurent Pinchart <laurent.pinchart@ideasonboard.com>");
773MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/mx3_camera.c b/drivers/media/video/mx3_camera.c
index 502e2a40964c..c7680eb83664 100644
--- a/drivers/media/video/mx3_camera.c
+++ b/drivers/media/video/mx3_camera.c
@@ -400,6 +400,35 @@ static int mx3_videobuf_init(struct vb2_buffer *vb)
400 return 0; 400 return 0;
401} 401}
402 402
403static int mx3_stop_streaming(struct vb2_queue *q)
404{
405 struct soc_camera_device *icd = soc_camera_from_vb2q(q);
406 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
407 struct mx3_camera_dev *mx3_cam = ici->priv;
408 struct idmac_channel *ichan = mx3_cam->idmac_channel[0];
409 struct dma_chan *chan;
410 struct mx3_camera_buffer *buf, *tmp;
411 unsigned long flags;
412
413 if (ichan) {
414 chan = &ichan->dma_chan;
415 chan->device->device_control(chan, DMA_TERMINATE_ALL, 0);
416 }
417
418 spin_lock_irqsave(&mx3_cam->lock, flags);
419
420 mx3_cam->active = NULL;
421
422 list_for_each_entry_safe(buf, tmp, &mx3_cam->capture, queue) {
423 buf->state = CSI_BUF_NEEDS_INIT;
424 list_del_init(&buf->queue);
425 }
426
427 spin_unlock_irqrestore(&mx3_cam->lock, flags);
428
429 return 0;
430}
431
403static struct vb2_ops mx3_videobuf_ops = { 432static struct vb2_ops mx3_videobuf_ops = {
404 .queue_setup = mx3_videobuf_setup, 433 .queue_setup = mx3_videobuf_setup,
405 .buf_prepare = mx3_videobuf_prepare, 434 .buf_prepare = mx3_videobuf_prepare,
@@ -408,6 +437,7 @@ static struct vb2_ops mx3_videobuf_ops = {
408 .buf_init = mx3_videobuf_init, 437 .buf_init = mx3_videobuf_init,
409 .wait_prepare = soc_camera_unlock, 438 .wait_prepare = soc_camera_unlock,
410 .wait_finish = soc_camera_lock, 439 .wait_finish = soc_camera_lock,
440 .stop_streaming = mx3_stop_streaming,
411}; 441};
412 442
413static int mx3_camera_init_videobuf(struct vb2_queue *q, 443static int mx3_camera_init_videobuf(struct vb2_queue *q,
@@ -658,8 +688,8 @@ static int mx3_camera_get_formats(struct soc_camera_device *icd, unsigned int id
658 688
659 fmt = soc_mbus_get_fmtdesc(code); 689 fmt = soc_mbus_get_fmtdesc(code);
660 if (!fmt) { 690 if (!fmt) {
661 dev_err(icd->dev.parent, 691 dev_warn(icd->dev.parent,
662 "Invalid format code #%u: %d\n", idx, code); 692 "Unsupported format code #%u: %d\n", idx, code);
663 return 0; 693 return 0;
664 } 694 }
665 695
@@ -712,13 +742,9 @@ static int mx3_camera_get_formats(struct soc_camera_device *icd, unsigned int id
712 742
713static void configure_geometry(struct mx3_camera_dev *mx3_cam, 743static void configure_geometry(struct mx3_camera_dev *mx3_cam,
714 unsigned int width, unsigned int height, 744 unsigned int width, unsigned int height,
715 enum v4l2_mbus_pixelcode code) 745 const struct soc_mbus_pixelfmt *fmt)
716{ 746{
717 u32 ctrl, width_field, height_field; 747 u32 ctrl, width_field, height_field;
718 const struct soc_mbus_pixelfmt *fmt;
719
720 fmt = soc_mbus_get_fmtdesc(code);
721 BUG_ON(!fmt);
722 748
723 if (fourcc_to_ipu_pix(fmt->fourcc) == IPU_PIX_FMT_GENERIC) { 749 if (fourcc_to_ipu_pix(fmt->fourcc) == IPU_PIX_FMT_GENERIC) {
724 /* 750 /*
@@ -726,8 +752,10 @@ static void configure_geometry(struct mx3_camera_dev *mx3_cam,
726 * the width parameter count the number of samples to 752 * the width parameter count the number of samples to
727 * capture to complete the whole image width. 753 * capture to complete the whole image width.
728 */ 754 */
729 width *= soc_mbus_samples_per_pixel(fmt); 755 unsigned int num, den;
730 BUG_ON(width < 0); 756 int ret = soc_mbus_samples_per_pixel(fmt, &num, &den);
757 BUG_ON(ret < 0);
758 width = width * num / den;
731 } 759 }
732 760
733 /* Setup frame size - this cannot be changed on-the-fly... */ 761 /* Setup frame size - this cannot be changed on-the-fly... */
@@ -774,8 +802,8 @@ static int acquire_dma_channel(struct mx3_camera_dev *mx3_cam)
774 */ 802 */
775static inline void stride_align(__u32 *width) 803static inline void stride_align(__u32 *width)
776{ 804{
777 if (((*width + 7) & ~7) < 4096) 805 if (ALIGN(*width, 8) < 4096)
778 *width = (*width + 7) & ~7; 806 *width = ALIGN(*width, 8);
779 else 807 else
780 *width = *width & ~7; 808 *width = *width & ~7;
781} 809}
@@ -801,11 +829,14 @@ static int mx3_camera_set_crop(struct soc_camera_device *icd,
801 if (ret < 0) 829 if (ret < 0)
802 return ret; 830 return ret;
803 831
804 /* The capture device might have changed its output */ 832 /* The capture device might have changed its output sizes */
805 ret = v4l2_subdev_call(sd, video, g_mbus_fmt, &mf); 833 ret = v4l2_subdev_call(sd, video, g_mbus_fmt, &mf);
806 if (ret < 0) 834 if (ret < 0)
807 return ret; 835 return ret;
808 836
837 if (mf.code != icd->current_fmt->code)
838 return -EINVAL;
839
809 if (mf.width & 7) { 840 if (mf.width & 7) {
810 /* Ouch! We can only handle 8-byte aligned width... */ 841 /* Ouch! We can only handle 8-byte aligned width... */
811 stride_align(&mf.width); 842 stride_align(&mf.width);
@@ -815,7 +846,8 @@ static int mx3_camera_set_crop(struct soc_camera_device *icd,
815 } 846 }
816 847
817 if (mf.width != icd->user_width || mf.height != icd->user_height) 848 if (mf.width != icd->user_width || mf.height != icd->user_height)
818 configure_geometry(mx3_cam, mf.width, mf.height, mf.code); 849 configure_geometry(mx3_cam, mf.width, mf.height,
850 icd->current_fmt->host_fmt);
819 851
820 dev_dbg(icd->dev.parent, "Sensor cropped %dx%d\n", 852 dev_dbg(icd->dev.parent, "Sensor cropped %dx%d\n",
821 mf.width, mf.height); 853 mf.width, mf.height);
@@ -853,7 +885,7 @@ static int mx3_camera_set_fmt(struct soc_camera_device *icd,
853 * mxc_v4l2_s_fmt() 885 * mxc_v4l2_s_fmt()
854 */ 886 */
855 887
856 configure_geometry(mx3_cam, pix->width, pix->height, xlate->code); 888 configure_geometry(mx3_cam, pix->width, pix->height, xlate->host_fmt);
857 889
858 mf.width = pix->width; 890 mf.width = pix->width;
859 mf.height = pix->height; 891 mf.height = pix->height;
diff --git a/drivers/media/video/omap1_camera.c b/drivers/media/video/omap1_camera.c
index 5954b9306630..e7cfc85b0a1c 100644
--- a/drivers/media/video/omap1_camera.c
+++ b/drivers/media/video/omap1_camera.c
@@ -990,63 +990,80 @@ static void omap1_cam_remove_device(struct soc_camera_device *icd)
990} 990}
991 991
992/* Duplicate standard formats based on host capability of byte swapping */ 992/* Duplicate standard formats based on host capability of byte swapping */
993static const struct soc_mbus_pixelfmt omap1_cam_formats[] = { 993static const struct soc_mbus_lookup omap1_cam_formats[] = {
994 [V4L2_MBUS_FMT_UYVY8_2X8] = { 994{
995 .code = V4L2_MBUS_FMT_UYVY8_2X8,
996 .fmt = {
995 .fourcc = V4L2_PIX_FMT_YUYV, 997 .fourcc = V4L2_PIX_FMT_YUYV,
996 .name = "YUYV", 998 .name = "YUYV",
997 .bits_per_sample = 8, 999 .bits_per_sample = 8,
998 .packing = SOC_MBUS_PACKING_2X8_PADHI, 1000 .packing = SOC_MBUS_PACKING_2X8_PADHI,
999 .order = SOC_MBUS_ORDER_BE, 1001 .order = SOC_MBUS_ORDER_BE,
1000 }, 1002 },
1001 [V4L2_MBUS_FMT_VYUY8_2X8] = { 1003}, {
1004 .code = V4L2_MBUS_FMT_VYUY8_2X8,
1005 .fmt = {
1002 .fourcc = V4L2_PIX_FMT_YVYU, 1006 .fourcc = V4L2_PIX_FMT_YVYU,
1003 .name = "YVYU", 1007 .name = "YVYU",
1004 .bits_per_sample = 8, 1008 .bits_per_sample = 8,
1005 .packing = SOC_MBUS_PACKING_2X8_PADHI, 1009 .packing = SOC_MBUS_PACKING_2X8_PADHI,
1006 .order = SOC_MBUS_ORDER_BE, 1010 .order = SOC_MBUS_ORDER_BE,
1007 }, 1011 },
1008 [V4L2_MBUS_FMT_YUYV8_2X8] = { 1012}, {
1013 .code = V4L2_MBUS_FMT_YUYV8_2X8,
1014 .fmt = {
1009 .fourcc = V4L2_PIX_FMT_UYVY, 1015 .fourcc = V4L2_PIX_FMT_UYVY,
1010 .name = "UYVY", 1016 .name = "UYVY",
1011 .bits_per_sample = 8, 1017 .bits_per_sample = 8,
1012 .packing = SOC_MBUS_PACKING_2X8_PADHI, 1018 .packing = SOC_MBUS_PACKING_2X8_PADHI,
1013 .order = SOC_MBUS_ORDER_BE, 1019 .order = SOC_MBUS_ORDER_BE,
1014 }, 1020 },
1015 [V4L2_MBUS_FMT_YVYU8_2X8] = { 1021}, {
1022 .code = V4L2_MBUS_FMT_YVYU8_2X8,
1023 .fmt = {
1016 .fourcc = V4L2_PIX_FMT_VYUY, 1024 .fourcc = V4L2_PIX_FMT_VYUY,
1017 .name = "VYUY", 1025 .name = "VYUY",
1018 .bits_per_sample = 8, 1026 .bits_per_sample = 8,
1019 .packing = SOC_MBUS_PACKING_2X8_PADHI, 1027 .packing = SOC_MBUS_PACKING_2X8_PADHI,
1020 .order = SOC_MBUS_ORDER_BE, 1028 .order = SOC_MBUS_ORDER_BE,
1021 }, 1029 },
1022 [V4L2_MBUS_FMT_RGB555_2X8_PADHI_BE] = { 1030}, {
1031 .code = V4L2_MBUS_FMT_RGB555_2X8_PADHI_BE,
1032 .fmt = {
1023 .fourcc = V4L2_PIX_FMT_RGB555, 1033 .fourcc = V4L2_PIX_FMT_RGB555,
1024 .name = "RGB555", 1034 .name = "RGB555",
1025 .bits_per_sample = 8, 1035 .bits_per_sample = 8,
1026 .packing = SOC_MBUS_PACKING_2X8_PADHI, 1036 .packing = SOC_MBUS_PACKING_2X8_PADHI,
1027 .order = SOC_MBUS_ORDER_BE, 1037 .order = SOC_MBUS_ORDER_BE,
1028 }, 1038 },
1029 [V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE] = { 1039}, {
1040 .code = V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE,
1041 .fmt = {
1030 .fourcc = V4L2_PIX_FMT_RGB555X, 1042 .fourcc = V4L2_PIX_FMT_RGB555X,
1031 .name = "RGB555X", 1043 .name = "RGB555X",
1032 .bits_per_sample = 8, 1044 .bits_per_sample = 8,
1033 .packing = SOC_MBUS_PACKING_2X8_PADHI, 1045 .packing = SOC_MBUS_PACKING_2X8_PADHI,
1034 .order = SOC_MBUS_ORDER_BE, 1046 .order = SOC_MBUS_ORDER_BE,
1035 }, 1047 },
1036 [V4L2_MBUS_FMT_RGB565_2X8_BE] = { 1048}, {
1049 .code = V4L2_MBUS_FMT_RGB565_2X8_BE,
1050 .fmt = {
1037 .fourcc = V4L2_PIX_FMT_RGB565, 1051 .fourcc = V4L2_PIX_FMT_RGB565,
1038 .name = "RGB565", 1052 .name = "RGB565",
1039 .bits_per_sample = 8, 1053 .bits_per_sample = 8,
1040 .packing = SOC_MBUS_PACKING_2X8_PADHI, 1054 .packing = SOC_MBUS_PACKING_2X8_PADHI,
1041 .order = SOC_MBUS_ORDER_BE, 1055 .order = SOC_MBUS_ORDER_BE,
1042 }, 1056 },
1043 [V4L2_MBUS_FMT_RGB565_2X8_LE] = { 1057}, {
1058 .code = V4L2_MBUS_FMT_RGB565_2X8_LE,
1059 .fmt = {
1044 .fourcc = V4L2_PIX_FMT_RGB565X, 1060 .fourcc = V4L2_PIX_FMT_RGB565X,
1045 .name = "RGB565X", 1061 .name = "RGB565X",
1046 .bits_per_sample = 8, 1062 .bits_per_sample = 8,
1047 .packing = SOC_MBUS_PACKING_2X8_PADHI, 1063 .packing = SOC_MBUS_PACKING_2X8_PADHI,
1048 .order = SOC_MBUS_ORDER_BE, 1064 .order = SOC_MBUS_ORDER_BE,
1049 }, 1065 },
1066},
1050}; 1067};
1051 1068
1052static int omap1_cam_get_formats(struct soc_camera_device *icd, 1069static int omap1_cam_get_formats(struct soc_camera_device *icd,
@@ -1065,7 +1082,7 @@ static int omap1_cam_get_formats(struct soc_camera_device *icd,
1065 1082
1066 fmt = soc_mbus_get_fmtdesc(code); 1083 fmt = soc_mbus_get_fmtdesc(code);
1067 if (!fmt) { 1084 if (!fmt) {
1068 dev_err(dev, "%s: invalid format code #%d: %d\n", __func__, 1085 dev_warn(dev, "%s: unsupported format code #%d: %d\n", __func__,
1069 idx, code); 1086 idx, code);
1070 return 0; 1087 return 0;
1071 } 1088 }
@@ -1085,12 +1102,14 @@ static int omap1_cam_get_formats(struct soc_camera_device *icd,
1085 case V4L2_MBUS_FMT_RGB565_2X8_LE: 1102 case V4L2_MBUS_FMT_RGB565_2X8_LE:
1086 formats++; 1103 formats++;
1087 if (xlate) { 1104 if (xlate) {
1088 xlate->host_fmt = &omap1_cam_formats[code]; 1105 xlate->host_fmt = soc_mbus_find_fmtdesc(code,
1106 omap1_cam_formats,
1107 ARRAY_SIZE(omap1_cam_formats));
1089 xlate->code = code; 1108 xlate->code = code;
1090 xlate++; 1109 xlate++;
1091 dev_dbg(dev, 1110 dev_dbg(dev,
1092 "%s: providing format %s as byte swapped code #%d\n", 1111 "%s: providing format %s as byte swapped code #%d\n",
1093 __func__, omap1_cam_formats[code].name, code); 1112 __func__, xlate->host_fmt->name, code);
1094 } 1113 }
1095 default: 1114 default:
1096 if (xlate) 1115 if (xlate)
diff --git a/drivers/media/video/pvrusb2/pvrusb2-std.c b/drivers/media/video/pvrusb2/pvrusb2-std.c
index ca9f83a85ca5..453627b07833 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-std.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-std.c
@@ -278,12 +278,10 @@ static struct v4l2_standard generic_standards[] = {
278 } 278 }
279}; 279};
280 280
281#define generic_standards_cnt ARRAY_SIZE(generic_standards)
282
283static struct v4l2_standard *match_std(v4l2_std_id id) 281static struct v4l2_standard *match_std(v4l2_std_id id)
284{ 282{
285 unsigned int idx; 283 unsigned int idx;
286 for (idx = 0; idx < generic_standards_cnt; idx++) { 284 for (idx = 0; idx < ARRAY_SIZE(generic_standards); idx++) {
287 if (generic_standards[idx].id & id) { 285 if (generic_standards[idx].id & id) {
288 return generic_standards + idx; 286 return generic_standards + idx;
289 } 287 }
@@ -370,7 +368,11 @@ struct v4l2_standard *pvr2_std_create_enum(unsigned int *countptr,
370 368
371 stddefs = kzalloc(sizeof(struct v4l2_standard) * std_cnt, 369 stddefs = kzalloc(sizeof(struct v4l2_standard) * std_cnt,
372 GFP_KERNEL); 370 GFP_KERNEL);
373 for (idx = 0; idx < std_cnt; idx++) stddefs[idx].index = idx; 371 if (!stddefs)
372 return NULL;
373
374 for (idx = 0; idx < std_cnt; idx++)
375 stddefs[idx].index = idx;
374 376
375 idx = 0; 377 idx = 0;
376 378
diff --git a/drivers/media/video/pwc/pwc-if.c b/drivers/media/video/pwc/pwc-if.c
index 780af5f81642..356cd42b593b 100644
--- a/drivers/media/video/pwc/pwc-if.c
+++ b/drivers/media/video/pwc/pwc-if.c
@@ -1850,7 +1850,6 @@ static void usb_pwc_disconnect(struct usb_interface *intf)
1850 } else { 1850 } else {
1851 /* Device is closed, so we can safely unregister it */ 1851 /* Device is closed, so we can safely unregister it */
1852 PWC_DEBUG_PROBE("Unregistering video device in disconnect().\n"); 1852 PWC_DEBUG_PROBE("Unregistering video device in disconnect().\n");
1853 pwc_cleanup(pdev);
1854 1853
1855disconnect_out: 1854disconnect_out:
1856 /* search device_hint[] table if we occupy a slot, by any chance */ 1855 /* search device_hint[] table if we occupy a slot, by any chance */
@@ -1860,6 +1859,7 @@ disconnect_out:
1860 } 1859 }
1861 1860
1862 mutex_unlock(&pdev->modlock); 1861 mutex_unlock(&pdev->modlock);
1862 pwc_cleanup(pdev);
1863} 1863}
1864 1864
1865 1865
diff --git a/drivers/media/video/pwc/pwc-v4l.c b/drivers/media/video/pwc/pwc-v4l.c
index aa87e462a958..f85c51249c7b 100644
--- a/drivers/media/video/pwc/pwc-v4l.c
+++ b/drivers/media/video/pwc/pwc-v4l.c
@@ -379,8 +379,27 @@ static int pwc_s_input(struct file *file, void *fh, unsigned int i)
379 379
380static int pwc_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *c) 380static int pwc_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *c)
381{ 381{
382 int i; 382 int i, idx;
383 383 u32 id;
384
385 id = c->id;
386 if (id & V4L2_CTRL_FLAG_NEXT_CTRL) {
387 id &= V4L2_CTRL_ID_MASK;
388 id++;
389 idx = -1;
390 for (i = 0; i < ARRAY_SIZE(pwc_controls); i++) {
391 if (pwc_controls[i].id < id)
392 continue;
393 if (idx >= 0
394 && pwc_controls[i].id > pwc_controls[idx].id)
395 continue;
396 idx = i;
397 }
398 if (idx < 0)
399 return -EINVAL;
400 memcpy(c, &pwc_controls[idx], sizeof pwc_controls[0]);
401 return 0;
402 }
384 for (i = 0; i < sizeof(pwc_controls) / sizeof(struct v4l2_queryctrl); i++) { 403 for (i = 0; i < sizeof(pwc_controls) / sizeof(struct v4l2_queryctrl); i++) {
385 if (pwc_controls[i].id == c->id) { 404 if (pwc_controls[i].id == c->id) {
386 PWC_DEBUG_IOCTL("ioctl(VIDIOC_QUERYCTRL) found\n"); 405 PWC_DEBUG_IOCTL("ioctl(VIDIOC_QUERYCTRL) found\n");
diff --git a/drivers/media/video/pxa_camera.c b/drivers/media/video/pxa_camera.c
index c1ee09a043ba..b42bfa5ccdf2 100644
--- a/drivers/media/video/pxa_camera.c
+++ b/drivers/media/video/pxa_camera.c
@@ -1155,15 +1155,11 @@ static int pxa_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
1155 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 1155 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
1156 struct pxa_camera_dev *pcdev = ici->priv; 1156 struct pxa_camera_dev *pcdev = ici->priv;
1157 unsigned long bus_flags, camera_flags, common_flags; 1157 unsigned long bus_flags, camera_flags, common_flags;
1158 const struct soc_mbus_pixelfmt *fmt;
1159 int ret; 1158 int ret;
1160 struct pxa_cam *cam = icd->host_priv; 1159 struct pxa_cam *cam = icd->host_priv;
1161 1160
1162 fmt = soc_mbus_get_fmtdesc(icd->current_fmt->code); 1161 ret = test_platform_param(pcdev, icd->current_fmt->host_fmt->bits_per_sample,
1163 if (!fmt) 1162 &bus_flags);
1164 return -EINVAL;
1165
1166 ret = test_platform_param(pcdev, fmt->bits_per_sample, &bus_flags);
1167 if (ret < 0) 1163 if (ret < 0)
1168 return ret; 1164 return ret;
1169 1165
diff --git a/drivers/media/video/s2255drv.c b/drivers/media/video/s2255drv.c
index 561909b65ce6..5b9dce85645c 100644
--- a/drivers/media/video/s2255drv.c
+++ b/drivers/media/video/s2255drv.c
@@ -394,12 +394,17 @@ static unsigned int vid_limit = 16; /* Video memory limit, in Mb */
394/* start video number */ 394/* start video number */
395static int video_nr = -1; /* /dev/videoN, -1 for autodetect */ 395static int video_nr = -1; /* /dev/videoN, -1 for autodetect */
396 396
397/* Enable jpeg capture. */
398static int jpeg_enable = 1;
399
397module_param(debug, int, 0644); 400module_param(debug, int, 0644);
398MODULE_PARM_DESC(debug, "Debug level(0-100) default 0"); 401MODULE_PARM_DESC(debug, "Debug level(0-100) default 0");
399module_param(vid_limit, int, 0644); 402module_param(vid_limit, int, 0644);
400MODULE_PARM_DESC(vid_limit, "video memory limit(Mb)"); 403MODULE_PARM_DESC(vid_limit, "video memory limit(Mb)");
401module_param(video_nr, int, 0644); 404module_param(video_nr, int, 0644);
402MODULE_PARM_DESC(video_nr, "start video minor(-1 default autodetect)"); 405MODULE_PARM_DESC(video_nr, "start video minor(-1 default autodetect)");
406module_param(jpeg_enable, int, 0644);
407MODULE_PARM_DESC(jpeg_enable, "Jpeg enable(1-on 0-off) default 1");
403 408
404/* USB device table */ 409/* USB device table */
405#define USB_SENSORAY_VID 0x1943 410#define USB_SENSORAY_VID 0x1943
@@ -413,6 +418,7 @@ MODULE_DEVICE_TABLE(usb, s2255_table);
413#define BUFFER_TIMEOUT msecs_to_jiffies(400) 418#define BUFFER_TIMEOUT msecs_to_jiffies(400)
414 419
415/* image formats. */ 420/* image formats. */
421/* JPEG formats must be defined last to support jpeg_enable parameter */
416static const struct s2255_fmt formats[] = { 422static const struct s2255_fmt formats[] = {
417 { 423 {
418 .name = "4:2:2, planar, YUV422P", 424 .name = "4:2:2, planar, YUV422P",
@@ -429,13 +435,17 @@ static const struct s2255_fmt formats[] = {
429 .fourcc = V4L2_PIX_FMT_UYVY, 435 .fourcc = V4L2_PIX_FMT_UYVY,
430 .depth = 16 436 .depth = 16
431 }, { 437 }, {
438 .name = "8bpp GREY",
439 .fourcc = V4L2_PIX_FMT_GREY,
440 .depth = 8
441 }, {
432 .name = "JPG", 442 .name = "JPG",
433 .fourcc = V4L2_PIX_FMT_JPEG, 443 .fourcc = V4L2_PIX_FMT_JPEG,
434 .depth = 24 444 .depth = 24
435 }, { 445 }, {
436 .name = "8bpp GREY", 446 .name = "MJPG",
437 .fourcc = V4L2_PIX_FMT_GREY, 447 .fourcc = V4L2_PIX_FMT_MJPEG,
438 .depth = 8 448 .depth = 24
439 } 449 }
440}; 450};
441 451
@@ -610,6 +620,9 @@ static const struct s2255_fmt *format_by_fourcc(int fourcc)
610 for (i = 0; i < ARRAY_SIZE(formats); i++) { 620 for (i = 0; i < ARRAY_SIZE(formats); i++) {
611 if (-1 == formats[i].fourcc) 621 if (-1 == formats[i].fourcc)
612 continue; 622 continue;
623 if (!jpeg_enable && ((formats[i].fourcc == V4L2_PIX_FMT_JPEG) ||
624 (formats[i].fourcc == V4L2_PIX_FMT_MJPEG)))
625 continue;
613 if (formats[i].fourcc == fourcc) 626 if (formats[i].fourcc == fourcc)
614 return formats + i; 627 return formats + i;
615 } 628 }
@@ -653,6 +666,7 @@ static void s2255_fillbuff(struct s2255_channel *channel,
653 memcpy(vbuf, tmpbuf, buf->vb.width * buf->vb.height); 666 memcpy(vbuf, tmpbuf, buf->vb.width * buf->vb.height);
654 break; 667 break;
655 case V4L2_PIX_FMT_JPEG: 668 case V4L2_PIX_FMT_JPEG:
669 case V4L2_PIX_FMT_MJPEG:
656 buf->vb.size = jpgsize; 670 buf->vb.size = jpgsize;
657 memcpy(vbuf, tmpbuf, buf->vb.size); 671 memcpy(vbuf, tmpbuf, buf->vb.size);
658 break; 672 break;
@@ -856,7 +870,9 @@ static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
856 870
857 if (index >= ARRAY_SIZE(formats)) 871 if (index >= ARRAY_SIZE(formats))
858 return -EINVAL; 872 return -EINVAL;
859 873 if (!jpeg_enable && ((formats[index].fourcc == V4L2_PIX_FMT_JPEG) ||
874 (formats[index].fourcc == V4L2_PIX_FMT_MJPEG)))
875 return -EINVAL;
860 dprintk(4, "name %s\n", formats[index].name); 876 dprintk(4, "name %s\n", formats[index].name);
861 strlcpy(f->description, formats[index].name, sizeof(f->description)); 877 strlcpy(f->description, formats[index].name, sizeof(f->description));
862 f->pixelformat = formats[index].fourcc; 878 f->pixelformat = formats[index].fourcc;
@@ -1037,6 +1053,7 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
1037 mode.color |= COLOR_Y8; 1053 mode.color |= COLOR_Y8;
1038 break; 1054 break;
1039 case V4L2_PIX_FMT_JPEG: 1055 case V4L2_PIX_FMT_JPEG:
1056 case V4L2_PIX_FMT_MJPEG:
1040 mode.color &= ~MASK_COLOR; 1057 mode.color &= ~MASK_COLOR;
1041 mode.color |= COLOR_JPG; 1058 mode.color |= COLOR_JPG;
1042 mode.color |= (channel->jc.quality << 8); 1059 mode.color |= (channel->jc.quality << 8);
@@ -2382,7 +2399,7 @@ static void read_pipe_completion(struct urb *purb)
2382 read_pipe_completion, pipe_info); 2399 read_pipe_completion, pipe_info);
2383 2400
2384 if (pipe_info->state != 0) { 2401 if (pipe_info->state != 0) {
2385 if (usb_submit_urb(pipe_info->stream_urb, GFP_KERNEL)) { 2402 if (usb_submit_urb(pipe_info->stream_urb, GFP_ATOMIC)) {
2386 dev_err(&dev->udev->dev, "error submitting urb\n"); 2403 dev_err(&dev->udev->dev, "error submitting urb\n");
2387 } 2404 }
2388 } else { 2405 } else {
diff --git a/drivers/media/video/s5p-fimc/Makefile b/drivers/media/video/s5p-fimc/Makefile
index 7ea1b1403b1e..df6954ab1d99 100644
--- a/drivers/media/video/s5p-fimc/Makefile
+++ b/drivers/media/video/s5p-fimc/Makefile
@@ -1,3 +1,5 @@
1s5p-fimc-objs := fimc-core.o fimc-reg.o fimc-capture.o
2s5p-csis-objs := mipi-csis.o
1 3
2obj-$(CONFIG_VIDEO_SAMSUNG_S5P_FIMC) := s5p-fimc.o 4obj-$(CONFIG_VIDEO_S5P_MIPI_CSIS) += s5p-csis.o
3s5p-fimc-y := fimc-core.o fimc-reg.o fimc-capture.o 5obj-$(CONFIG_VIDEO_SAMSUNG_S5P_FIMC) += s5p-fimc.o
diff --git a/drivers/media/video/s5p-fimc/mipi-csis.c b/drivers/media/video/s5p-fimc/mipi-csis.c
new file mode 100644
index 000000000000..ef056d6605ca
--- /dev/null
+++ b/drivers/media/video/s5p-fimc/mipi-csis.c
@@ -0,0 +1,724 @@
1/*
2 * Samsung S5P/EXYNOS4 SoC series MIPI-CSI receiver driver
3 *
4 * Copyright (C) 2011 Samsung Electronics Co., Ltd.
5 * Contact: Sylwester Nawrocki, <s.nawrocki@samsung.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <linux/clk.h>
13#include <linux/delay.h>
14#include <linux/device.h>
15#include <linux/errno.h>
16#include <linux/interrupt.h>
17#include <linux/io.h>
18#include <linux/irq.h>
19#include <linux/kernel.h>
20#include <linux/memory.h>
21#include <linux/module.h>
22#include <linux/platform_device.h>
23#include <linux/pm_runtime.h>
24#include <linux/regulator/consumer.h>
25#include <linux/slab.h>
26#include <linux/spinlock.h>
27#include <linux/videodev2.h>
28#include <media/v4l2-subdev.h>
29#include <plat/mipi_csis.h>
30#include "mipi-csis.h"
31
32static int debug;
33module_param(debug, int, 0644);
34MODULE_PARM_DESC(debug, "Debug level (0-1)");
35
36/* Register map definition */
37
38/* CSIS global control */
39#define S5PCSIS_CTRL 0x00
40#define S5PCSIS_CTRL_DPDN_DEFAULT (0 << 31)
41#define S5PCSIS_CTRL_DPDN_SWAP (1 << 31)
42#define S5PCSIS_CTRL_ALIGN_32BIT (1 << 20)
43#define S5PCSIS_CTRL_UPDATE_SHADOW (1 << 16)
44#define S5PCSIS_CTRL_WCLK_EXTCLK (1 << 8)
45#define S5PCSIS_CTRL_RESET (1 << 4)
46#define S5PCSIS_CTRL_ENABLE (1 << 0)
47
48/* D-PHY control */
49#define S5PCSIS_DPHYCTRL 0x04
50#define S5PCSIS_DPHYCTRL_HSS_MASK (0x1f << 27)
51#define S5PCSIS_DPHYCTRL_ENABLE (0x1f << 0)
52
53#define S5PCSIS_CONFIG 0x08
54#define S5PCSIS_CFG_FMT_YCBCR422_8BIT (0x1e << 2)
55#define S5PCSIS_CFG_FMT_RAW8 (0x2a << 2)
56#define S5PCSIS_CFG_FMT_RAW10 (0x2b << 2)
57#define S5PCSIS_CFG_FMT_RAW12 (0x2c << 2)
58/* User defined formats, x = 1...4 */
59#define S5PCSIS_CFG_FMT_USER(x) ((0x30 + x - 1) << 2)
60#define S5PCSIS_CFG_FMT_MASK (0x3f << 2)
61#define S5PCSIS_CFG_NR_LANE_MASK 3
62
63/* Interrupt mask. */
64#define S5PCSIS_INTMSK 0x10
65#define S5PCSIS_INTMSK_EN_ALL 0xf000003f
66#define S5PCSIS_INTSRC 0x14
67
68/* Pixel resolution */
69#define S5PCSIS_RESOL 0x2c
70#define CSIS_MAX_PIX_WIDTH 0xffff
71#define CSIS_MAX_PIX_HEIGHT 0xffff
72
73enum {
74 CSIS_CLK_MUX,
75 CSIS_CLK_GATE,
76};
77
78static char *csi_clock_name[] = {
79 [CSIS_CLK_MUX] = "sclk_csis",
80 [CSIS_CLK_GATE] = "csis",
81};
82#define NUM_CSIS_CLOCKS ARRAY_SIZE(csi_clock_name)
83
84enum {
85 ST_POWERED = 1,
86 ST_STREAMING = 2,
87 ST_SUSPENDED = 4,
88};
89
90/**
91 * struct csis_state - the driver's internal state data structure
92 * @lock: mutex serializing the subdev and power management operations,
93 * protecting @format and @flags members
94 * @pads: CSIS pads array
95 * @sd: v4l2_subdev associated with CSIS device instance
96 * @pdev: CSIS platform device
97 * @regs_res: requested I/O register memory resource
98 * @regs: mmaped I/O registers memory
99 * @clock: CSIS clocks
100 * @irq: requested s5p-mipi-csis irq number
101 * @flags: the state variable for power and streaming control
102 * @csis_fmt: current CSIS pixel format
103 * @format: common media bus format for the source and sink pad
104 */
105struct csis_state {
106 struct mutex lock;
107 struct media_pad pads[CSIS_PADS_NUM];
108 struct v4l2_subdev sd;
109 struct platform_device *pdev;
110 struct resource *regs_res;
111 void __iomem *regs;
112 struct clk *clock[NUM_CSIS_CLOCKS];
113 int irq;
114 struct regulator *supply;
115 u32 flags;
116 const struct csis_pix_format *csis_fmt;
117 struct v4l2_mbus_framefmt format;
118};
119
120/**
121 * struct csis_pix_format - CSIS pixel format description
122 * @pix_width_alignment: horizontal pixel alignment, width will be
123 * multiple of 2^pix_width_alignment
124 * @code: corresponding media bus code
125 * @fmt_reg: S5PCSIS_CONFIG register value
126 */
127struct csis_pix_format {
128 unsigned int pix_width_alignment;
129 enum v4l2_mbus_pixelcode code;
130 u32 fmt_reg;
131};
132
133static const struct csis_pix_format s5pcsis_formats[] = {
134 {
135 .code = V4L2_MBUS_FMT_VYUY8_2X8,
136 .fmt_reg = S5PCSIS_CFG_FMT_YCBCR422_8BIT,
137 }, {
138 .code = V4L2_MBUS_FMT_JPEG_1X8,
139 .fmt_reg = S5PCSIS_CFG_FMT_USER(1),
140 },
141};
142
143#define s5pcsis_write(__csis, __r, __v) writel(__v, __csis->regs + __r)
144#define s5pcsis_read(__csis, __r) readl(__csis->regs + __r)
145
146static struct csis_state *sd_to_csis_state(struct v4l2_subdev *sdev)
147{
148 return container_of(sdev, struct csis_state, sd);
149}
150
151static const struct csis_pix_format *find_csis_format(
152 struct v4l2_mbus_framefmt *mf)
153{
154 int i;
155
156 for (i = 0; i < ARRAY_SIZE(s5pcsis_formats); i++)
157 if (mf->code == s5pcsis_formats[i].code)
158 return &s5pcsis_formats[i];
159 return NULL;
160}
161
162static void s5pcsis_enable_interrupts(struct csis_state *state, bool on)
163{
164 u32 val = s5pcsis_read(state, S5PCSIS_INTMSK);
165
166 val = on ? val | S5PCSIS_INTMSK_EN_ALL :
167 val & ~S5PCSIS_INTMSK_EN_ALL;
168 s5pcsis_write(state, S5PCSIS_INTMSK, val);
169}
170
171static void s5pcsis_reset(struct csis_state *state)
172{
173 u32 val = s5pcsis_read(state, S5PCSIS_CTRL);
174
175 s5pcsis_write(state, S5PCSIS_CTRL, val | S5PCSIS_CTRL_RESET);
176 udelay(10);
177}
178
179static void s5pcsis_system_enable(struct csis_state *state, int on)
180{
181 u32 val;
182
183 val = s5pcsis_read(state, S5PCSIS_CTRL);
184 if (on)
185 val |= S5PCSIS_CTRL_ENABLE;
186 else
187 val &= ~S5PCSIS_CTRL_ENABLE;
188 s5pcsis_write(state, S5PCSIS_CTRL, val);
189
190 val = s5pcsis_read(state, S5PCSIS_DPHYCTRL);
191 if (on)
192 val |= S5PCSIS_DPHYCTRL_ENABLE;
193 else
194 val &= ~S5PCSIS_DPHYCTRL_ENABLE;
195 s5pcsis_write(state, S5PCSIS_DPHYCTRL, val);
196}
197
198/* Called with the state.lock mutex held */
199static void __s5pcsis_set_format(struct csis_state *state)
200{
201 struct v4l2_mbus_framefmt *mf = &state->format;
202 u32 val;
203
204 v4l2_dbg(1, debug, &state->sd, "fmt: %d, %d x %d\n",
205 mf->code, mf->width, mf->height);
206
207 /* Color format */
208 val = s5pcsis_read(state, S5PCSIS_CONFIG);
209 val = (val & ~S5PCSIS_CFG_FMT_MASK) | state->csis_fmt->fmt_reg;
210 s5pcsis_write(state, S5PCSIS_CONFIG, val);
211
212 /* Pixel resolution */
213 val = (mf->width << 16) | mf->height;
214 s5pcsis_write(state, S5PCSIS_RESOL, val);
215}
216
217static void s5pcsis_set_hsync_settle(struct csis_state *state, int settle)
218{
219 u32 val = s5pcsis_read(state, S5PCSIS_DPHYCTRL);
220
221 val = (val & ~S5PCSIS_DPHYCTRL_HSS_MASK) | (settle << 27);
222 s5pcsis_write(state, S5PCSIS_DPHYCTRL, val);
223}
224
225static void s5pcsis_set_params(struct csis_state *state)
226{
227 struct s5p_platform_mipi_csis *pdata = state->pdev->dev.platform_data;
228 u32 val;
229
230 val = s5pcsis_read(state, S5PCSIS_CONFIG);
231 val = (val & ~S5PCSIS_CFG_NR_LANE_MASK) | (pdata->lanes - 1);
232 s5pcsis_write(state, S5PCSIS_CONFIG, val);
233
234 __s5pcsis_set_format(state);
235 s5pcsis_set_hsync_settle(state, pdata->hs_settle);
236
237 val = s5pcsis_read(state, S5PCSIS_CTRL);
238 if (pdata->alignment == 32)
239 val |= S5PCSIS_CTRL_ALIGN_32BIT;
240 else /* 24-bits */
241 val &= ~S5PCSIS_CTRL_ALIGN_32BIT;
242 /* Not using external clock. */
243 val &= ~S5PCSIS_CTRL_WCLK_EXTCLK;
244 s5pcsis_write(state, S5PCSIS_CTRL, val);
245
246 /* Update the shadow register. */
247 val = s5pcsis_read(state, S5PCSIS_CTRL);
248 s5pcsis_write(state, S5PCSIS_CTRL, val | S5PCSIS_CTRL_UPDATE_SHADOW);
249}
250
251static void s5pcsis_clk_put(struct csis_state *state)
252{
253 int i;
254
255 for (i = 0; i < NUM_CSIS_CLOCKS; i++)
256 if (!IS_ERR_OR_NULL(state->clock[i]))
257 clk_put(state->clock[i]);
258}
259
260static int s5pcsis_clk_get(struct csis_state *state)
261{
262 struct device *dev = &state->pdev->dev;
263 int i;
264
265 for (i = 0; i < NUM_CSIS_CLOCKS; i++) {
266 state->clock[i] = clk_get(dev, csi_clock_name[i]);
267 if (IS_ERR(state->clock[i])) {
268 s5pcsis_clk_put(state);
269 dev_err(dev, "failed to get clock: %s\n",
270 csi_clock_name[i]);
271 return -ENXIO;
272 }
273 }
274 return 0;
275}
276
277static int s5pcsis_s_power(struct v4l2_subdev *sd, int on)
278{
279 struct csis_state *state = sd_to_csis_state(sd);
280 struct device *dev = &state->pdev->dev;
281
282 if (on)
283 return pm_runtime_get_sync(dev);
284
285 return pm_runtime_put_sync(dev);
286}
287
288static void s5pcsis_start_stream(struct csis_state *state)
289{
290 s5pcsis_reset(state);
291 s5pcsis_set_params(state);
292 s5pcsis_system_enable(state, true);
293 s5pcsis_enable_interrupts(state, true);
294}
295
296static void s5pcsis_stop_stream(struct csis_state *state)
297{
298 s5pcsis_enable_interrupts(state, false);
299 s5pcsis_system_enable(state, false);
300}
301
302/* v4l2_subdev operations */
303static int s5pcsis_s_stream(struct v4l2_subdev *sd, int enable)
304{
305 struct csis_state *state = sd_to_csis_state(sd);
306 int ret = 0;
307
308 v4l2_dbg(1, debug, sd, "%s: %d, state: 0x%x\n",
309 __func__, enable, state->flags);
310
311 if (enable) {
312 ret = pm_runtime_get_sync(&state->pdev->dev);
313 if (ret && ret != 1)
314 return ret;
315 }
316 mutex_lock(&state->lock);
317 if (enable) {
318 if (state->flags & ST_SUSPENDED) {
319 ret = -EBUSY;
320 goto unlock;
321 }
322 s5pcsis_start_stream(state);
323 state->flags |= ST_STREAMING;
324 } else {
325 s5pcsis_stop_stream(state);
326 state->flags &= ~ST_STREAMING;
327 }
328unlock:
329 mutex_unlock(&state->lock);
330 if (!enable)
331 pm_runtime_put(&state->pdev->dev);
332
333 return ret == 1 ? 0 : ret;
334}
335
336static int s5pcsis_enum_mbus_code(struct v4l2_subdev *sd,
337 struct v4l2_subdev_fh *fh,
338 struct v4l2_subdev_mbus_code_enum *code)
339{
340 if (code->index >= ARRAY_SIZE(s5pcsis_formats))
341 return -EINVAL;
342
343 code->code = s5pcsis_formats[code->index].code;
344 return 0;
345}
346
347static struct csis_pix_format const *s5pcsis_try_format(
348 struct v4l2_mbus_framefmt *mf)
349{
350 struct csis_pix_format const *csis_fmt;
351
352 csis_fmt = find_csis_format(mf);
353 if (csis_fmt == NULL)
354 csis_fmt = &s5pcsis_formats[0];
355
356 mf->code = csis_fmt->code;
357 v4l_bound_align_image(&mf->width, 1, CSIS_MAX_PIX_WIDTH,
358 csis_fmt->pix_width_alignment,
359 &mf->height, 1, CSIS_MAX_PIX_HEIGHT, 1,
360 0);
361 return csis_fmt;
362}
363
364static struct v4l2_mbus_framefmt *__s5pcsis_get_format(
365 struct csis_state *state, struct v4l2_subdev_fh *fh,
366 u32 pad, enum v4l2_subdev_format_whence which)
367{
368 if (which == V4L2_SUBDEV_FORMAT_TRY)
369 return fh ? v4l2_subdev_get_try_format(fh, pad) : NULL;
370
371 return &state->format;
372}
373
374static int s5pcsis_set_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
375 struct v4l2_subdev_format *fmt)
376{
377 struct csis_state *state = sd_to_csis_state(sd);
378 struct csis_pix_format const *csis_fmt;
379 struct v4l2_mbus_framefmt *mf;
380
381 if (fmt->pad != CSIS_PAD_SOURCE && fmt->pad != CSIS_PAD_SINK)
382 return -EINVAL;
383
384 mf = __s5pcsis_get_format(state, fh, fmt->pad, fmt->which);
385
386 if (fmt->pad == CSIS_PAD_SOURCE) {
387 if (mf) {
388 mutex_lock(&state->lock);
389 fmt->format = *mf;
390 mutex_unlock(&state->lock);
391 }
392 return 0;
393 }
394 csis_fmt = s5pcsis_try_format(&fmt->format);
395 if (mf) {
396 mutex_lock(&state->lock);
397 *mf = fmt->format;
398 if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE)
399 state->csis_fmt = csis_fmt;
400 mutex_unlock(&state->lock);
401 }
402 return 0;
403}
404
405static int s5pcsis_get_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
406 struct v4l2_subdev_format *fmt)
407{
408 struct csis_state *state = sd_to_csis_state(sd);
409 struct v4l2_mbus_framefmt *mf;
410
411 if (fmt->pad != CSIS_PAD_SOURCE && fmt->pad != CSIS_PAD_SINK)
412 return -EINVAL;
413
414 mf = __s5pcsis_get_format(state, fh, fmt->pad, fmt->which);
415 if (!mf)
416 return -EINVAL;
417
418 mutex_lock(&state->lock);
419 fmt->format = *mf;
420 mutex_unlock(&state->lock);
421 return 0;
422}
423
424static struct v4l2_subdev_core_ops s5pcsis_core_ops = {
425 .s_power = s5pcsis_s_power,
426};
427
428static struct v4l2_subdev_pad_ops s5pcsis_pad_ops = {
429 .enum_mbus_code = s5pcsis_enum_mbus_code,
430 .get_fmt = s5pcsis_get_fmt,
431 .set_fmt = s5pcsis_set_fmt,
432};
433
434static struct v4l2_subdev_video_ops s5pcsis_video_ops = {
435 .s_stream = s5pcsis_s_stream,
436};
437
438static struct v4l2_subdev_ops s5pcsis_subdev_ops = {
439 .core = &s5pcsis_core_ops,
440 .pad = &s5pcsis_pad_ops,
441 .video = &s5pcsis_video_ops,
442};
443
444static irqreturn_t s5pcsis_irq_handler(int irq, void *dev_id)
445{
446 struct csis_state *state = dev_id;
447 u32 val;
448
449 /* Just clear the interrupt pending bits. */
450 val = s5pcsis_read(state, S5PCSIS_INTSRC);
451 s5pcsis_write(state, S5PCSIS_INTSRC, val);
452
453 return IRQ_HANDLED;
454}
455
456static int __devinit s5pcsis_probe(struct platform_device *pdev)
457{
458 struct s5p_platform_mipi_csis *pdata;
459 struct resource *mem_res;
460 struct resource *regs_res;
461 struct csis_state *state;
462 int ret = -ENOMEM;
463
464 state = kzalloc(sizeof(*state), GFP_KERNEL);
465 if (!state)
466 return -ENOMEM;
467
468 mutex_init(&state->lock);
469 state->pdev = pdev;
470
471 pdata = pdev->dev.platform_data;
472 if (pdata == NULL || pdata->phy_enable == NULL) {
473 dev_err(&pdev->dev, "Platform data not fully specified\n");
474 goto e_free;
475 }
476
477 if ((pdev->id == 1 && pdata->lanes > CSIS1_MAX_LANES) ||
478 pdata->lanes > CSIS0_MAX_LANES) {
479 ret = -EINVAL;
480 dev_err(&pdev->dev, "Unsupported number of data lanes: %d\n",
481 pdata->lanes);
482 goto e_free;
483 }
484
485 mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
486 if (!mem_res) {
487 dev_err(&pdev->dev, "Failed to get IO memory region\n");
488 goto e_free;
489 }
490
491 regs_res = request_mem_region(mem_res->start, resource_size(mem_res),
492 pdev->name);
493 if (!regs_res) {
494 dev_err(&pdev->dev, "Failed to request IO memory region\n");
495 goto e_free;
496 }
497 state->regs_res = regs_res;
498
499 state->regs = ioremap(mem_res->start, resource_size(mem_res));
500 if (!state->regs) {
501 dev_err(&pdev->dev, "Failed to remap IO region\n");
502 goto e_reqmem;
503 }
504
505 ret = s5pcsis_clk_get(state);
506 if (ret)
507 goto e_unmap;
508
509 clk_enable(state->clock[CSIS_CLK_MUX]);
510 if (pdata->clk_rate)
511 clk_set_rate(state->clock[CSIS_CLK_MUX], pdata->clk_rate);
512 else
513 dev_WARN(&pdev->dev, "No clock frequency specified!\n");
514
515 state->irq = platform_get_irq(pdev, 0);
516 if (state->irq < 0) {
517 ret = state->irq;
518 dev_err(&pdev->dev, "Failed to get irq\n");
519 goto e_clkput;
520 }
521
522 if (!pdata->fixed_phy_vdd) {
523 state->supply = regulator_get(&pdev->dev, "vdd");
524 if (IS_ERR(state->supply)) {
525 ret = PTR_ERR(state->supply);
526 state->supply = NULL;
527 goto e_clkput;
528 }
529 }
530
531 ret = request_irq(state->irq, s5pcsis_irq_handler, 0,
532 dev_name(&pdev->dev), state);
533 if (ret) {
534 dev_err(&pdev->dev, "request_irq failed\n");
535 goto e_regput;
536 }
537
538 v4l2_subdev_init(&state->sd, &s5pcsis_subdev_ops);
539 state->sd.owner = THIS_MODULE;
540 strlcpy(state->sd.name, dev_name(&pdev->dev), sizeof(state->sd.name));
541 state->csis_fmt = &s5pcsis_formats[0];
542
543 state->pads[CSIS_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
544 state->pads[CSIS_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
545 ret = media_entity_init(&state->sd.entity,
546 CSIS_PADS_NUM, state->pads, 0);
547 if (ret < 0)
548 goto e_irqfree;
549
550 /* This allows to retrieve the platform device id by the host driver */
551 v4l2_set_subdevdata(&state->sd, pdev);
552
553 /* .. and a pointer to the subdev. */
554 platform_set_drvdata(pdev, &state->sd);
555
556 state->flags = ST_SUSPENDED;
557 pm_runtime_enable(&pdev->dev);
558
559 return 0;
560
561e_irqfree:
562 free_irq(state->irq, state);
563e_regput:
564 if (state->supply)
565 regulator_put(state->supply);
566e_clkput:
567 clk_disable(state->clock[CSIS_CLK_MUX]);
568 s5pcsis_clk_put(state);
569e_unmap:
570 iounmap(state->regs);
571e_reqmem:
572 release_mem_region(regs_res->start, resource_size(regs_res));
573e_free:
574 kfree(state);
575 return ret;
576}
577
578static int s5pcsis_suspend(struct device *dev)
579{
580 struct s5p_platform_mipi_csis *pdata = dev->platform_data;
581 struct platform_device *pdev = to_platform_device(dev);
582 struct v4l2_subdev *sd = platform_get_drvdata(pdev);
583 struct csis_state *state = sd_to_csis_state(sd);
584 int ret = 0;
585
586 v4l2_dbg(1, debug, sd, "%s: flags: 0x%x\n",
587 __func__, state->flags);
588
589 mutex_lock(&state->lock);
590 if (state->flags & ST_POWERED) {
591 s5pcsis_stop_stream(state);
592 ret = pdata->phy_enable(state->pdev, false);
593 if (ret)
594 goto unlock;
595 if (state->supply) {
596 ret = regulator_disable(state->supply);
597 if (ret)
598 goto unlock;
599 }
600 clk_disable(state->clock[CSIS_CLK_GATE]);
601 state->flags &= ~ST_POWERED;
602 }
603 state->flags |= ST_SUSPENDED;
604 unlock:
605 mutex_unlock(&state->lock);
606 return ret ? -EAGAIN : 0;
607}
608
609static int s5pcsis_resume(struct device *dev)
610{
611 struct s5p_platform_mipi_csis *pdata = dev->platform_data;
612 struct platform_device *pdev = to_platform_device(dev);
613 struct v4l2_subdev *sd = platform_get_drvdata(pdev);
614 struct csis_state *state = sd_to_csis_state(sd);
615 int ret = 0;
616
617 v4l2_dbg(1, debug, sd, "%s: flags: 0x%x\n",
618 __func__, state->flags);
619
620 mutex_lock(&state->lock);
621 if (!(state->flags & ST_SUSPENDED))
622 goto unlock;
623
624 if (!(state->flags & ST_POWERED)) {
625 if (state->supply)
626 ret = regulator_enable(state->supply);
627 if (ret)
628 goto unlock;
629
630 ret = pdata->phy_enable(state->pdev, true);
631 if (!ret) {
632 state->flags |= ST_POWERED;
633 } else if (state->supply) {
634 regulator_disable(state->supply);
635 goto unlock;
636 }
637 clk_enable(state->clock[CSIS_CLK_GATE]);
638 }
639 if (state->flags & ST_STREAMING)
640 s5pcsis_start_stream(state);
641
642 state->flags &= ~ST_SUSPENDED;
643 unlock:
644 mutex_unlock(&state->lock);
645 return ret ? -EAGAIN : 0;
646}
647
648#ifdef CONFIG_PM_SLEEP
649static int s5pcsis_pm_suspend(struct device *dev)
650{
651 return s5pcsis_suspend(dev);
652}
653
654static int s5pcsis_pm_resume(struct device *dev)
655{
656 int ret;
657
658 ret = s5pcsis_resume(dev);
659
660 if (!ret) {
661 pm_runtime_disable(dev);
662 ret = pm_runtime_set_active(dev);
663 pm_runtime_enable(dev);
664 }
665
666 return ret;
667}
668#endif
669
670static int __devexit s5pcsis_remove(struct platform_device *pdev)
671{
672 struct v4l2_subdev *sd = platform_get_drvdata(pdev);
673 struct csis_state *state = sd_to_csis_state(sd);
674 struct resource *res = state->regs_res;
675
676 pm_runtime_disable(&pdev->dev);
677 s5pcsis_suspend(&pdev->dev);
678 clk_disable(state->clock[CSIS_CLK_MUX]);
679 pm_runtime_set_suspended(&pdev->dev);
680
681 s5pcsis_clk_put(state);
682 if (state->supply)
683 regulator_put(state->supply);
684
685 media_entity_cleanup(&state->sd.entity);
686 free_irq(state->irq, state);
687 iounmap(state->regs);
688 release_mem_region(res->start, resource_size(res));
689 kfree(state);
690
691 return 0;
692}
693
694static const struct dev_pm_ops s5pcsis_pm_ops = {
695 SET_RUNTIME_PM_OPS(s5pcsis_suspend, s5pcsis_resume, NULL)
696 SET_SYSTEM_SLEEP_PM_OPS(s5pcsis_pm_suspend, s5pcsis_pm_resume)
697};
698
699static struct platform_driver s5pcsis_driver = {
700 .probe = s5pcsis_probe,
701 .remove = __devexit_p(s5pcsis_remove),
702 .driver = {
703 .name = CSIS_DRIVER_NAME,
704 .owner = THIS_MODULE,
705 .pm = &s5pcsis_pm_ops,
706 },
707};
708
709static int __init s5pcsis_init(void)
710{
711 return platform_driver_probe(&s5pcsis_driver, s5pcsis_probe);
712}
713
714static void __exit s5pcsis_exit(void)
715{
716 platform_driver_unregister(&s5pcsis_driver);
717}
718
719module_init(s5pcsis_init);
720module_exit(s5pcsis_exit);
721
722MODULE_AUTHOR("Sylwester Nawrocki <s.nawrocki@samsung.com>");
723MODULE_DESCRIPTION("S5P/EXYNOS4 MIPI CSI receiver driver");
724MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/s5p-fimc/mipi-csis.h b/drivers/media/video/s5p-fimc/mipi-csis.h
new file mode 100644
index 000000000000..f5691336dd5c
--- /dev/null
+++ b/drivers/media/video/s5p-fimc/mipi-csis.h
@@ -0,0 +1,22 @@
1/*
2 * Samsung S5P/EXYNOS4 SoC series MIPI-CSI receiver driver
3 *
4 * Copyright (C) 2011 Samsung Electronics Co., Ltd.
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#ifndef S5P_MIPI_CSIS_H_
11#define S5P_MIPI_CSIS_H_
12
13#define CSIS_DRIVER_NAME "s5p-mipi-csis"
14#define CSIS_MAX_ENTITIES 2
15#define CSIS0_MAX_LANES 4
16#define CSIS1_MAX_LANES 2
17
18#define CSIS_PAD_SINK 0
19#define CSIS_PAD_SOURCE 1
20#define CSIS_PADS_NUM 2
21
22#endif
diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c
index 50f1be05ebd3..e2062b240e32 100644
--- a/drivers/media/video/saa7134/saa7134-cards.c
+++ b/drivers/media/video/saa7134/saa7134-cards.c
@@ -5591,6 +5591,105 @@ struct saa7134_board saa7134_boards[] = {
5591 .amux = TV, 5591 .amux = TV,
5592 }, 5592 },
5593 }, 5593 },
5594 [SAA7134_BOARD_MAGICPRO_PROHDTV_PRO2] = {
5595 /* Timothy Lee <timothy.lee@siriushk.com> */
5596 .name = "MagicPro ProHDTV Pro2 DMB-TH/Hybrid",
5597 .audio_clock = 0x00187de7,
5598 .tuner_type = TUNER_PHILIPS_TDA8290,
5599 .radio_type = UNSET,
5600 .tuner_config = 3,
5601 .tuner_addr = ADDR_UNSET,
5602 .radio_addr = ADDR_UNSET,
5603 .gpiomask = 0x02050000,
5604 .mpeg = SAA7134_MPEG_DVB,
5605 .ts_type = SAA7134_MPEG_TS_PARALLEL,
5606 .inputs = { {
5607 .name = name_tv,
5608 .vmux = 1,
5609 .amux = TV,
5610 .tv = 1,
5611 .gpio = 0x00050000,
5612 }, {
5613 .name = name_comp1,
5614 .vmux = 3,
5615 .amux = LINE1,
5616 .gpio = 0x00050000,
5617 }, {
5618 .name = name_svideo,
5619 .vmux = 8,
5620 .amux = LINE1,
5621 .gpio = 0x00050000,
5622 } },
5623 .radio = {
5624 .name = name_radio,
5625 .amux = TV,
5626 .gpio = 0x00050000,
5627 },
5628 .mute = {
5629 .name = name_mute,
5630 .vmux = 0,
5631 .amux = TV,
5632 .gpio = 0x00050000,
5633 },
5634 },
5635 [SAA7134_BOARD_BEHOLD_501] = {
5636 /* Beholder Intl. Ltd. 2010 */
5637 /* Dmitry Belimov <d.belimov@gmail.com> */
5638 .name = "Beholder BeholdTV 501",
5639 .audio_clock = 0x00200000,
5640 .tuner_type = TUNER_ABSENT,
5641 .radio_type = UNSET,
5642 .tuner_addr = ADDR_UNSET,
5643 .radio_addr = ADDR_UNSET,
5644 .gpiomask = 0x00008000,
5645 .inputs = { {
5646 .name = name_tv,
5647 .vmux = 3,
5648 .amux = LINE2,
5649 .tv = 1,
5650 }, {
5651 .name = name_comp1,
5652 .vmux = 1,
5653 .amux = LINE1,
5654 }, {
5655 .name = name_svideo,
5656 .vmux = 8,
5657 .amux = LINE1,
5658 } },
5659 .mute = {
5660 .name = name_mute,
5661 .amux = LINE1,
5662 },
5663 },
5664 [SAA7134_BOARD_BEHOLD_503FM] = {
5665 /* Beholder Intl. Ltd. 2010 */
5666 /* Dmitry Belimov <d.belimov@gmail.com> */
5667 .name = "Beholder BeholdTV 503 FM",
5668 .audio_clock = 0x00200000,
5669 .tuner_type = TUNER_ABSENT,
5670 .radio_type = UNSET,
5671 .tuner_addr = ADDR_UNSET,
5672 .radio_addr = ADDR_UNSET,
5673 .gpiomask = 0x00008000,
5674 .inputs = { {
5675 .name = name_tv,
5676 .vmux = 3,
5677 .amux = LINE2,
5678 .tv = 1,
5679 }, {
5680 .name = name_comp1,
5681 .vmux = 1,
5682 .amux = LINE1,
5683 }, {
5684 .name = name_svideo,
5685 .vmux = 8,
5686 .amux = LINE1,
5687 } },
5688 .mute = {
5689 .name = name_mute,
5690 .amux = LINE1,
5691 },
5692 },
5594 5693
5595}; 5694};
5596 5695
@@ -6796,6 +6895,24 @@ struct pci_device_id saa7134_pci_tbl[] = {
6796 .subdevice = 0xc900, 6895 .subdevice = 0xc900,
6797 .driver_data = SAA7134_BOARD_VIDEOMATE_M1F, 6896 .driver_data = SAA7134_BOARD_VIDEOMATE_M1F,
6798 }, { 6897 }, {
6898 .vendor = PCI_VENDOR_ID_PHILIPS,
6899 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
6900 .subvendor = 0x5ace,
6901 .subdevice = 0x5030,
6902 .driver_data = SAA7134_BOARD_BEHOLD_503FM,
6903 }, {
6904 .vendor = PCI_VENDOR_ID_PHILIPS,
6905 .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
6906 .subvendor = 0x5ace,
6907 .subdevice = 0x5010,
6908 .driver_data = SAA7134_BOARD_BEHOLD_501,
6909 }, {
6910 .vendor = PCI_VENDOR_ID_PHILIPS,
6911 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
6912 .subvendor = 0x17de,
6913 .subdevice = 0xd136,
6914 .driver_data = SAA7134_BOARD_MAGICPRO_PROHDTV_PRO2,
6915 }, {
6799 /* --- boards without eeprom + subsystem ID --- */ 6916 /* --- boards without eeprom + subsystem ID --- */
6800 .vendor = PCI_VENDOR_ID_PHILIPS, 6917 .vendor = PCI_VENDOR_ID_PHILIPS,
6801 .device = PCI_DEVICE_ID_PHILIPS_SAA7134, 6918 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
@@ -6988,6 +7105,7 @@ static int saa7134_tda8290_18271_callback(struct saa7134_dev *dev,
6988 switch (dev->board) { 7105 switch (dev->board) {
6989 case SAA7134_BOARD_HAUPPAUGE_HVR1150: 7106 case SAA7134_BOARD_HAUPPAUGE_HVR1150:
6990 case SAA7134_BOARD_HAUPPAUGE_HVR1120: 7107 case SAA7134_BOARD_HAUPPAUGE_HVR1120:
7108 case SAA7134_BOARD_MAGICPRO_PROHDTV_PRO2:
6991 ret = saa7134_tda18271_hvr11x0_toggle_agc(dev, arg); 7109 ret = saa7134_tda18271_hvr11x0_toggle_agc(dev, arg);
6992 break; 7110 break;
6993 case SAA7134_BOARD_KWORLD_PCI_SBTVD_FULLSEG: 7111 case SAA7134_BOARD_KWORLD_PCI_SBTVD_FULLSEG:
@@ -7014,6 +7132,7 @@ static int saa7134_tda8290_callback(struct saa7134_dev *dev,
7014 case SAA7134_BOARD_HAUPPAUGE_HVR1120: 7132 case SAA7134_BOARD_HAUPPAUGE_HVR1120:
7015 case SAA7134_BOARD_AVERMEDIA_M733A: 7133 case SAA7134_BOARD_AVERMEDIA_M733A:
7016 case SAA7134_BOARD_KWORLD_PCI_SBTVD_FULLSEG: 7134 case SAA7134_BOARD_KWORLD_PCI_SBTVD_FULLSEG:
7135 case SAA7134_BOARD_MAGICPRO_PROHDTV_PRO2:
7017 /* tda8290 + tda18271 */ 7136 /* tda8290 + tda18271 */
7018 ret = saa7134_tda8290_18271_callback(dev, command, arg); 7137 ret = saa7134_tda8290_18271_callback(dev, command, arg);
7019 break; 7138 break;
@@ -7264,6 +7383,7 @@ int saa7134_board_init1(struct saa7134_dev *dev)
7264 break; 7383 break;
7265 case SAA7134_BOARD_HAUPPAUGE_HVR1150: 7384 case SAA7134_BOARD_HAUPPAUGE_HVR1150:
7266 case SAA7134_BOARD_HAUPPAUGE_HVR1120: 7385 case SAA7134_BOARD_HAUPPAUGE_HVR1120:
7386 dev->has_remote = SAA7134_REMOTE_GPIO;
7267 /* GPIO 26 high for digital, low for analog */ 7387 /* GPIO 26 high for digital, low for analog */
7268 saa7134_set_gpio(dev, 26, 0); 7388 saa7134_set_gpio(dev, 26, 0);
7269 msleep(1); 7389 msleep(1);
@@ -7326,6 +7446,11 @@ int saa7134_board_init1(struct saa7134_dev *dev)
7326 saa7134_set_gpio(dev, 1, 1); 7446 saa7134_set_gpio(dev, 1, 1);
7327 dev->has_remote = SAA7134_REMOTE_GPIO; 7447 dev->has_remote = SAA7134_REMOTE_GPIO;
7328 break; 7448 break;
7449 case SAA7134_BOARD_MAGICPRO_PROHDTV_PRO2:
7450 /* enable LGS-8G75 */
7451 saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x0e050000, 0x0c050000);
7452 saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x0e050000, 0x0c050000);
7453 break;
7329 } 7454 }
7330 return 0; 7455 return 0;
7331} 7456}
diff --git a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c
index 41f836fc93ec..f9be737ba6f4 100644
--- a/drivers/media/video/saa7134/saa7134-core.c
+++ b/drivers/media/video/saa7134/saa7134-core.c
@@ -927,7 +927,7 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
927 } 927 }
928 928
929 /* print pci info */ 929 /* print pci info */
930 pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &dev->pci_rev); 930 dev->pci_rev = pci_dev->revision;
931 pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &dev->pci_lat); 931 pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &dev->pci_lat);
932 printk(KERN_INFO "%s: found at %s, rev: %d, irq: %d, " 932 printk(KERN_INFO "%s: found at %s, rev: %d, irq: %d, "
933 "latency: %d, mmio: 0x%llx\n", dev->name, 933 "latency: %d, mmio: 0x%llx\n", dev->name,
diff --git a/drivers/media/video/saa7134/saa7134-dvb.c b/drivers/media/video/saa7134/saa7134-dvb.c
index f65cad287b83..996a206c6d79 100644
--- a/drivers/media/video/saa7134/saa7134-dvb.c
+++ b/drivers/media/video/saa7134/saa7134-dvb.c
@@ -53,6 +53,7 @@
53#include "lgdt3305.h" 53#include "lgdt3305.h"
54#include "tda8290.h" 54#include "tda8290.h"
55#include "mb86a20s.h" 55#include "mb86a20s.h"
56#include "lgs8gxx.h"
56 57
57#include "zl10353.h" 58#include "zl10353.h"
58 59
@@ -1123,6 +1124,26 @@ static struct tda18271_config dtv1000s_tda18271_config = {
1123 .gate = TDA18271_GATE_ANALOG, 1124 .gate = TDA18271_GATE_ANALOG,
1124}; 1125};
1125 1126
1127static struct lgs8gxx_config prohdtv_pro2_lgs8g75_config = {
1128 .prod = LGS8GXX_PROD_LGS8G75,
1129 .demod_address = 0x1d,
1130 .serial_ts = 0,
1131 .ts_clk_pol = 1,
1132 .ts_clk_gated = 0,
1133 .if_clk_freq = 30400, /* 30.4 MHz */
1134 .if_freq = 4000, /* 4.00 MHz */
1135 .if_neg_center = 0,
1136 .ext_adc = 0,
1137 .adc_signed = 1,
1138 .adc_vpp = 3, /* 2.0 Vpp */
1139 .if_neg_edge = 1,
1140};
1141
1142static struct tda18271_config prohdtv_pro2_tda18271_config = {
1143 .gate = TDA18271_GATE_ANALOG,
1144 .output_opt = TDA18271_OUTPUT_LT_OFF,
1145};
1146
1126/* ================================================================== 1147/* ==================================================================
1127 * Core code 1148 * Core code
1128 */ 1149 */
@@ -1674,6 +1695,19 @@ static int dvb_init(struct saa7134_dev *dev)
1674 1695
1675 /* mb86a20s need to use the I2C gateway */ 1696 /* mb86a20s need to use the I2C gateway */
1676 break; 1697 break;
1698 case SAA7134_BOARD_MAGICPRO_PROHDTV_PRO2:
1699 fe0->dvb.frontend = dvb_attach(lgs8gxx_attach,
1700 &prohdtv_pro2_lgs8g75_config,
1701 &dev->i2c_adap);
1702 if (fe0->dvb.frontend != NULL) {
1703 dvb_attach(tda829x_attach, fe0->dvb.frontend,
1704 &dev->i2c_adap, 0x4b,
1705 &tda829x_no_probe);
1706 dvb_attach(tda18271_attach, fe0->dvb.frontend,
1707 0x60, &dev->i2c_adap,
1708 &prohdtv_pro2_tda18271_config);
1709 }
1710 break;
1677 default: 1711 default:
1678 wprintk("Huh? unknown DVB card?\n"); 1712 wprintk("Huh? unknown DVB card?\n");
1679 break; 1713 break;
diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c
index be1c2a2de27c..ff6c0e97563e 100644
--- a/drivers/media/video/saa7134/saa7134-input.c
+++ b/drivers/media/video/saa7134/saa7134-input.c
@@ -756,6 +756,14 @@ int saa7134_input_init1(struct saa7134_dev *dev)
756 mask_keycode = 0x0ff00; 756 mask_keycode = 0x0ff00;
757 mask_keyup = 0x040000; 757 mask_keyup = 0x040000;
758 break; 758 break;
759 case SAA7134_BOARD_HAUPPAUGE_HVR1150:
760 case SAA7134_BOARD_HAUPPAUGE_HVR1120:
761 ir_codes = RC_MAP_HAUPPAUGE;
762 mask_keydown = 0x0040000; /* Enable GPIO18 line on both edges */
763 mask_keyup = 0x0040000;
764 mask_keycode = 0xffff;
765 raw_decode = true;
766 break;
759 } 767 }
760 if (NULL == ir_codes) { 768 if (NULL == ir_codes) {
761 printk("%s: Oops: IR config error [card=%d]\n", 769 printk("%s: Oops: IR config error [card=%d]\n",
diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h
index f96cd5d761f9..28eb10398323 100644
--- a/drivers/media/video/saa7134/saa7134.h
+++ b/drivers/media/video/saa7134/saa7134.h
@@ -328,6 +328,9 @@ struct saa7134_card_ir {
328#define SAA7134_BOARD_KWORLD_PCI_SBTVD_FULLSEG 182 328#define SAA7134_BOARD_KWORLD_PCI_SBTVD_FULLSEG 182
329#define SAA7134_BOARD_VIDEOMATE_M1F 183 329#define SAA7134_BOARD_VIDEOMATE_M1F 183
330#define SAA7134_BOARD_ENCORE_ENLTV_FM3 184 330#define SAA7134_BOARD_ENCORE_ENLTV_FM3 184
331#define SAA7134_BOARD_MAGICPRO_PROHDTV_PRO2 185
332#define SAA7134_BOARD_BEHOLD_501 186
333#define SAA7134_BOARD_BEHOLD_503FM 187
331 334
332#define SAA7134_MAXBOARDS 32 335#define SAA7134_MAXBOARDS 32
333#define SAA7134_INPUT_MAX 8 336#define SAA7134_INPUT_MAX 8
diff --git a/drivers/media/video/saa7164/saa7164-core.c b/drivers/media/video/saa7164/saa7164-core.c
index b813aec1e456..3b7d7b4e3034 100644
--- a/drivers/media/video/saa7164/saa7164-core.c
+++ b/drivers/media/video/saa7164/saa7164-core.c
@@ -1247,7 +1247,7 @@ static int __devinit saa7164_initdev(struct pci_dev *pci_dev,
1247 } 1247 }
1248 1248
1249 /* print pci info */ 1249 /* print pci info */
1250 pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &dev->pci_rev); 1250 dev->pci_rev = pci_dev->revision;
1251 pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &dev->pci_lat); 1251 pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &dev->pci_lat);
1252 printk(KERN_INFO "%s/0: found at %s, rev: %d, irq: %d, " 1252 printk(KERN_INFO "%s/0: found at %s, rev: %d, irq: %d, "
1253 "latency: %d, mmio: 0x%llx\n", dev->name, 1253 "latency: %d, mmio: 0x%llx\n", dev->name,
diff --git a/drivers/media/video/sh_mobile_ceu_camera.c b/drivers/media/video/sh_mobile_ceu_camera.c
index 134e86bf6d97..3ae5c9c58cba 100644
--- a/drivers/media/video/sh_mobile_ceu_camera.c
+++ b/drivers/media/video/sh_mobile_ceu_camera.c
@@ -17,6 +17,7 @@
17#include <linux/init.h> 17#include <linux/init.h>
18#include <linux/module.h> 18#include <linux/module.h>
19#include <linux/io.h> 19#include <linux/io.h>
20#include <linux/completion.h>
20#include <linux/delay.h> 21#include <linux/delay.h>
21#include <linux/dma-mapping.h> 22#include <linux/dma-mapping.h>
22#include <linux/errno.h> 23#include <linux/errno.h>
@@ -106,6 +107,7 @@ struct sh_mobile_ceu_dev {
106 struct vb2_alloc_ctx *alloc_ctx; 107 struct vb2_alloc_ctx *alloc_ctx;
107 108
108 struct sh_mobile_ceu_info *pdata; 109 struct sh_mobile_ceu_info *pdata;
110 struct completion complete;
109 111
110 u32 cflcr; 112 u32 cflcr;
111 113
@@ -114,6 +116,7 @@ struct sh_mobile_ceu_dev {
114 116
115 unsigned int image_mode:1; 117 unsigned int image_mode:1;
116 unsigned int is_16bit:1; 118 unsigned int is_16bit:1;
119 unsigned int frozen:1;
117}; 120};
118 121
119struct sh_mobile_ceu_cam { 122struct sh_mobile_ceu_cam {
@@ -273,7 +276,8 @@ static int sh_mobile_ceu_capture(struct sh_mobile_ceu_dev *pcdev)
273 ceu_write(pcdev, CEIER, ceu_read(pcdev, CEIER) & ~CEU_CEIER_MASK); 276 ceu_write(pcdev, CEIER, ceu_read(pcdev, CEIER) & ~CEU_CEIER_MASK);
274 status = ceu_read(pcdev, CETCR); 277 status = ceu_read(pcdev, CETCR);
275 ceu_write(pcdev, CETCR, ~status & CEU_CETCR_MAGIC); 278 ceu_write(pcdev, CETCR, ~status & CEU_CETCR_MAGIC);
276 ceu_write(pcdev, CEIER, ceu_read(pcdev, CEIER) | CEU_CEIER_MASK); 279 if (!pcdev->frozen)
280 ceu_write(pcdev, CEIER, ceu_read(pcdev, CEIER) | CEU_CEIER_MASK);
277 ceu_write(pcdev, CAPCR, ceu_read(pcdev, CAPCR) & ~CEU_CAPCR_CTNCP); 281 ceu_write(pcdev, CAPCR, ceu_read(pcdev, CAPCR) & ~CEU_CAPCR_CTNCP);
278 ceu_write(pcdev, CETCR, CEU_CETCR_MAGIC ^ CEU_CETCR_IGRW); 282 ceu_write(pcdev, CETCR, CEU_CETCR_MAGIC ^ CEU_CETCR_IGRW);
279 283
@@ -287,6 +291,11 @@ static int sh_mobile_ceu_capture(struct sh_mobile_ceu_dev *pcdev)
287 ret = -EIO; 291 ret = -EIO;
288 } 292 }
289 293
294 if (pcdev->frozen) {
295 complete(&pcdev->complete);
296 return ret;
297 }
298
290 if (!pcdev->active) 299 if (!pcdev->active)
291 return ret; 300 return ret;
292 301
@@ -378,12 +387,11 @@ static void sh_mobile_ceu_videobuf_queue(struct vb2_buffer *vb)
378 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 387 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
379 struct sh_mobile_ceu_dev *pcdev = ici->priv; 388 struct sh_mobile_ceu_dev *pcdev = ici->priv;
380 struct sh_mobile_ceu_buffer *buf = to_ceu_vb(vb); 389 struct sh_mobile_ceu_buffer *buf = to_ceu_vb(vb);
381 unsigned long flags;
382 390
383 dev_dbg(icd->dev.parent, "%s (vb=0x%p) 0x%p %lu\n", __func__, 391 dev_dbg(icd->dev.parent, "%s (vb=0x%p) 0x%p %lu\n", __func__,
384 vb, vb2_plane_vaddr(vb, 0), vb2_get_plane_payload(vb, 0)); 392 vb, vb2_plane_vaddr(vb, 0), vb2_get_plane_payload(vb, 0));
385 393
386 spin_lock_irqsave(&pcdev->lock, flags); 394 spin_lock_irq(&pcdev->lock);
387 list_add_tail(&buf->queue, &pcdev->capture); 395 list_add_tail(&buf->queue, &pcdev->capture);
388 396
389 if (!pcdev->active) { 397 if (!pcdev->active) {
@@ -395,7 +403,7 @@ static void sh_mobile_ceu_videobuf_queue(struct vb2_buffer *vb)
395 pcdev->active = vb; 403 pcdev->active = vb;
396 sh_mobile_ceu_capture(pcdev); 404 sh_mobile_ceu_capture(pcdev);
397 } 405 }
398 spin_unlock_irqrestore(&pcdev->lock, flags); 406 spin_unlock_irq(&pcdev->lock);
399} 407}
400 408
401static void sh_mobile_ceu_videobuf_release(struct vb2_buffer *vb) 409static void sh_mobile_ceu_videobuf_release(struct vb2_buffer *vb)
@@ -404,9 +412,8 @@ static void sh_mobile_ceu_videobuf_release(struct vb2_buffer *vb)
404 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 412 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
405 struct sh_mobile_ceu_buffer *buf = to_ceu_vb(vb); 413 struct sh_mobile_ceu_buffer *buf = to_ceu_vb(vb);
406 struct sh_mobile_ceu_dev *pcdev = ici->priv; 414 struct sh_mobile_ceu_dev *pcdev = ici->priv;
407 unsigned long flags;
408 415
409 spin_lock_irqsave(&pcdev->lock, flags); 416 spin_lock_irq(&pcdev->lock);
410 417
411 if (pcdev->active == vb) { 418 if (pcdev->active == vb) {
412 /* disable capture (release DMA buffer), reset */ 419 /* disable capture (release DMA buffer), reset */
@@ -417,7 +424,7 @@ static void sh_mobile_ceu_videobuf_release(struct vb2_buffer *vb)
417 /* Doesn't hurt also if the list is empty */ 424 /* Doesn't hurt also if the list is empty */
418 list_del_init(&buf->queue); 425 list_del_init(&buf->queue);
419 426
420 spin_unlock_irqrestore(&pcdev->lock, flags); 427 spin_unlock_irq(&pcdev->lock);
421} 428}
422 429
423static int sh_mobile_ceu_videobuf_init(struct vb2_buffer *vb) 430static int sh_mobile_ceu_videobuf_init(struct vb2_buffer *vb)
@@ -427,6 +434,25 @@ static int sh_mobile_ceu_videobuf_init(struct vb2_buffer *vb)
427 return 0; 434 return 0;
428} 435}
429 436
437static int sh_mobile_ceu_stop_streaming(struct vb2_queue *q)
438{
439 struct soc_camera_device *icd = container_of(q, struct soc_camera_device, vb2_vidq);
440 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
441 struct sh_mobile_ceu_dev *pcdev = ici->priv;
442 struct list_head *buf_head, *tmp;
443
444 spin_lock_irq(&pcdev->lock);
445
446 pcdev->active = NULL;
447
448 list_for_each_safe(buf_head, tmp, &pcdev->capture)
449 list_del_init(buf_head);
450
451 spin_unlock_irq(&pcdev->lock);
452
453 return sh_mobile_ceu_soft_reset(pcdev);
454}
455
430static struct vb2_ops sh_mobile_ceu_videobuf_ops = { 456static struct vb2_ops sh_mobile_ceu_videobuf_ops = {
431 .queue_setup = sh_mobile_ceu_videobuf_setup, 457 .queue_setup = sh_mobile_ceu_videobuf_setup,
432 .buf_prepare = sh_mobile_ceu_videobuf_prepare, 458 .buf_prepare = sh_mobile_ceu_videobuf_prepare,
@@ -435,6 +461,7 @@ static struct vb2_ops sh_mobile_ceu_videobuf_ops = {
435 .buf_init = sh_mobile_ceu_videobuf_init, 461 .buf_init = sh_mobile_ceu_videobuf_init,
436 .wait_prepare = soc_camera_unlock, 462 .wait_prepare = soc_camera_unlock,
437 .wait_finish = soc_camera_lock, 463 .wait_finish = soc_camera_lock,
464 .stop_streaming = sh_mobile_ceu_stop_streaming,
438}; 465};
439 466
440static irqreturn_t sh_mobile_ceu_irq(int irq, void *data) 467static irqreturn_t sh_mobile_ceu_irq(int irq, void *data)
@@ -500,7 +527,6 @@ static void sh_mobile_ceu_remove_device(struct soc_camera_device *icd)
500{ 527{
501 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 528 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
502 struct sh_mobile_ceu_dev *pcdev = ici->priv; 529 struct sh_mobile_ceu_dev *pcdev = ici->priv;
503 unsigned long flags;
504 530
505 BUG_ON(icd != pcdev->icd); 531 BUG_ON(icd != pcdev->icd);
506 532
@@ -509,13 +535,13 @@ static void sh_mobile_ceu_remove_device(struct soc_camera_device *icd)
509 sh_mobile_ceu_soft_reset(pcdev); 535 sh_mobile_ceu_soft_reset(pcdev);
510 536
511 /* make sure active buffer is canceled */ 537 /* make sure active buffer is canceled */
512 spin_lock_irqsave(&pcdev->lock, flags); 538 spin_lock_irq(&pcdev->lock);
513 if (pcdev->active) { 539 if (pcdev->active) {
514 list_del_init(&to_ceu_vb(pcdev->active)->queue); 540 list_del_init(&to_ceu_vb(pcdev->active)->queue);
515 vb2_buffer_done(pcdev->active, VB2_BUF_STATE_ERROR); 541 vb2_buffer_done(pcdev->active, VB2_BUF_STATE_ERROR);
516 pcdev->active = NULL; 542 pcdev->active = NULL;
517 } 543 }
518 spin_unlock_irqrestore(&pcdev->lock, flags); 544 spin_unlock_irq(&pcdev->lock);
519 545
520 pm_runtime_put_sync(ici->v4l2_dev.dev); 546 pm_runtime_put_sync(ici->v4l2_dev.dev);
521 547
@@ -891,8 +917,8 @@ static int sh_mobile_ceu_get_formats(struct soc_camera_device *icd, unsigned int
891 917
892 fmt = soc_mbus_get_fmtdesc(code); 918 fmt = soc_mbus_get_fmtdesc(code);
893 if (!fmt) { 919 if (!fmt) {
894 dev_err(dev, "Invalid format code #%u: %d\n", idx, code); 920 dev_warn(dev, "unsupported format code #%u: %d\n", idx, code);
895 return -EINVAL; 921 return 0;
896 } 922 }
897 923
898 if (!pcdev->pdata->csi2_dev) { 924 if (!pcdev->pdata->csi2_dev) {
@@ -1330,7 +1356,7 @@ static int client_scale(struct soc_camera_device *icd,
1330/* 1356/*
1331 * CEU can scale and crop, but we don't want to waste bandwidth and kill the 1357 * CEU can scale and crop, but we don't want to waste bandwidth and kill the
1332 * framerate by always requesting the maximum image from the client. See 1358 * framerate by always requesting the maximum image from the client. See
1333 * Documentation/video4linux/sh_mobile_camera_ceu.txt for a description of 1359 * Documentation/video4linux/sh_mobile_ceu_camera.txt for a description of
1334 * scaling and cropping algorithms and for the meaning of referenced here steps. 1360 * scaling and cropping algorithms and for the meaning of referenced here steps.
1335 */ 1361 */
1336static int sh_mobile_ceu_set_crop(struct soc_camera_device *icd, 1362static int sh_mobile_ceu_set_crop(struct soc_camera_device *icd,
@@ -1377,10 +1403,6 @@ static int sh_mobile_ceu_set_crop(struct soc_camera_device *icd,
1377 if (mf.width > 2560 || mf.height > 1920) 1403 if (mf.width > 2560 || mf.height > 1920)
1378 return -EINVAL; 1404 return -EINVAL;
1379 1405
1380 /* Cache camera output window */
1381 cam->width = mf.width;
1382 cam->height = mf.height;
1383
1384 /* 4. Calculate camera scales */ 1406 /* 4. Calculate camera scales */
1385 scale_cam_h = calc_generic_scale(cam_rect->width, mf.width); 1407 scale_cam_h = calc_generic_scale(cam_rect->width, mf.width);
1386 scale_cam_v = calc_generic_scale(cam_rect->height, mf.height); 1408 scale_cam_v = calc_generic_scale(cam_rect->height, mf.height);
@@ -1389,6 +1411,39 @@ static int sh_mobile_ceu_set_crop(struct soc_camera_device *icd,
1389 interm_width = scale_down(rect->width, scale_cam_h); 1411 interm_width = scale_down(rect->width, scale_cam_h);
1390 interm_height = scale_down(rect->height, scale_cam_v); 1412 interm_height = scale_down(rect->height, scale_cam_v);
1391 1413
1414 if (interm_width < icd->user_width) {
1415 u32 new_scale_h;
1416
1417 new_scale_h = calc_generic_scale(rect->width, icd->user_width);
1418
1419 mf.width = scale_down(cam_rect->width, new_scale_h);
1420 }
1421
1422 if (interm_height < icd->user_height) {
1423 u32 new_scale_v;
1424
1425 new_scale_v = calc_generic_scale(rect->height, icd->user_height);
1426
1427 mf.height = scale_down(cam_rect->height, new_scale_v);
1428 }
1429
1430 if (interm_width < icd->user_width || interm_height < icd->user_height) {
1431 ret = v4l2_device_call_until_err(sd->v4l2_dev, (int)icd, video,
1432 s_mbus_fmt, &mf);
1433 if (ret < 0)
1434 return ret;
1435
1436 dev_geo(dev, "New camera output %ux%u\n", mf.width, mf.height);
1437 scale_cam_h = calc_generic_scale(cam_rect->width, mf.width);
1438 scale_cam_v = calc_generic_scale(cam_rect->height, mf.height);
1439 interm_width = scale_down(rect->width, scale_cam_h);
1440 interm_height = scale_down(rect->height, scale_cam_v);
1441 }
1442
1443 /* Cache camera output window */
1444 cam->width = mf.width;
1445 cam->height = mf.height;
1446
1392 if (pcdev->image_mode) { 1447 if (pcdev->image_mode) {
1393 out_width = min(interm_width, icd->user_width); 1448 out_width = min(interm_width, icd->user_width);
1394 out_height = min(interm_height, icd->user_height); 1449 out_height = min(interm_height, icd->user_height);
@@ -1704,6 +1759,63 @@ static int sh_mobile_ceu_try_fmt(struct soc_camera_device *icd,
1704 return ret; 1759 return ret;
1705} 1760}
1706 1761
1762static int sh_mobile_ceu_set_livecrop(struct soc_camera_device *icd,
1763 struct v4l2_crop *a)
1764{
1765 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1766 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
1767 struct sh_mobile_ceu_dev *pcdev = ici->priv;
1768 u32 out_width = icd->user_width, out_height = icd->user_height;
1769 int ret;
1770
1771 /* Freeze queue */
1772 pcdev->frozen = 1;
1773 /* Wait for frame */
1774 ret = wait_for_completion_interruptible(&pcdev->complete);
1775 /* Stop the client */
1776 ret = v4l2_subdev_call(sd, video, s_stream, 0);
1777 if (ret < 0)
1778 dev_warn(icd->dev.parent,
1779 "Client failed to stop the stream: %d\n", ret);
1780 else
1781 /* Do the crop, if it fails, there's nothing more we can do */
1782 sh_mobile_ceu_set_crop(icd, a);
1783
1784 dev_geo(icd->dev.parent, "Output after crop: %ux%u\n", icd->user_width, icd->user_height);
1785
1786 if (icd->user_width != out_width || icd->user_height != out_height) {
1787 struct v4l2_format f = {
1788 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
1789 .fmt.pix = {
1790 .width = out_width,
1791 .height = out_height,
1792 .pixelformat = icd->current_fmt->host_fmt->fourcc,
1793 .field = pcdev->field,
1794 .colorspace = icd->colorspace,
1795 },
1796 };
1797 ret = sh_mobile_ceu_set_fmt(icd, &f);
1798 if (!ret && (out_width != f.fmt.pix.width ||
1799 out_height != f.fmt.pix.height))
1800 ret = -EINVAL;
1801 if (!ret) {
1802 icd->user_width = out_width;
1803 icd->user_height = out_height;
1804 ret = sh_mobile_ceu_set_bus_param(icd,
1805 icd->current_fmt->host_fmt->fourcc);
1806 }
1807 }
1808
1809 /* Thaw the queue */
1810 pcdev->frozen = 0;
1811 spin_lock_irq(&pcdev->lock);
1812 sh_mobile_ceu_capture(pcdev);
1813 spin_unlock_irq(&pcdev->lock);
1814 /* Start the client */
1815 ret = v4l2_subdev_call(sd, video, s_stream, 1);
1816 return ret;
1817}
1818
1707static unsigned int sh_mobile_ceu_poll(struct file *file, poll_table *pt) 1819static unsigned int sh_mobile_ceu_poll(struct file *file, poll_table *pt)
1708{ 1820{
1709 struct soc_camera_device *icd = file->private_data; 1821 struct soc_camera_device *icd = file->private_data;
@@ -1790,6 +1902,7 @@ static struct soc_camera_host_ops sh_mobile_ceu_host_ops = {
1790 .put_formats = sh_mobile_ceu_put_formats, 1902 .put_formats = sh_mobile_ceu_put_formats,
1791 .get_crop = sh_mobile_ceu_get_crop, 1903 .get_crop = sh_mobile_ceu_get_crop,
1792 .set_crop = sh_mobile_ceu_set_crop, 1904 .set_crop = sh_mobile_ceu_set_crop,
1905 .set_livecrop = sh_mobile_ceu_set_livecrop,
1793 .set_fmt = sh_mobile_ceu_set_fmt, 1906 .set_fmt = sh_mobile_ceu_set_fmt,
1794 .try_fmt = sh_mobile_ceu_try_fmt, 1907 .try_fmt = sh_mobile_ceu_try_fmt,
1795 .set_ctrl = sh_mobile_ceu_set_ctrl, 1908 .set_ctrl = sh_mobile_ceu_set_ctrl,
@@ -1856,6 +1969,7 @@ static int __devinit sh_mobile_ceu_probe(struct platform_device *pdev)
1856 1969
1857 INIT_LIST_HEAD(&pcdev->capture); 1970 INIT_LIST_HEAD(&pcdev->capture);
1858 spin_lock_init(&pcdev->lock); 1971 spin_lock_init(&pcdev->lock);
1972 init_completion(&pcdev->complete);
1859 1973
1860 pcdev->pdata = pdev->dev.platform_data; 1974 pcdev->pdata = pdev->dev.platform_data;
1861 if (!pcdev->pdata) { 1975 if (!pcdev->pdata) {
diff --git a/drivers/media/video/soc_camera.c b/drivers/media/video/soc_camera.c
index ddb4c091dedc..398864370267 100644
--- a/drivers/media/video/soc_camera.c
+++ b/drivers/media/video/soc_camera.c
@@ -41,6 +41,11 @@
41#define DEFAULT_WIDTH 640 41#define DEFAULT_WIDTH 640
42#define DEFAULT_HEIGHT 480 42#define DEFAULT_HEIGHT 480
43 43
44#define is_streaming(ici, icd) \
45 (((ici)->ops->init_videobuf) ? \
46 (icd)->vb_vidq.streaming : \
47 vb2_is_streaming(&(icd)->vb2_vidq))
48
44static LIST_HEAD(hosts); 49static LIST_HEAD(hosts);
45static LIST_HEAD(devices); 50static LIST_HEAD(devices);
46static DEFINE_MUTEX(list_lock); /* Protects the list of hosts */ 51static DEFINE_MUTEX(list_lock); /* Protects the list of hosts */
@@ -358,8 +363,6 @@ static int soc_camera_init_user_formats(struct soc_camera_device *icd)
358 if (!icd->user_formats) 363 if (!icd->user_formats)
359 return -ENOMEM; 364 return -ENOMEM;
360 365
361 icd->num_user_formats = fmts;
362
363 dev_dbg(&icd->dev, "Found %d supported formats.\n", fmts); 366 dev_dbg(&icd->dev, "Found %d supported formats.\n", fmts);
364 367
365 /* Second pass - actually fill data formats */ 368 /* Second pass - actually fill data formats */
@@ -367,9 +370,10 @@ static int soc_camera_init_user_formats(struct soc_camera_device *icd)
367 for (i = 0; i < raw_fmts; i++) 370 for (i = 0; i < raw_fmts; i++)
368 if (!ici->ops->get_formats) { 371 if (!ici->ops->get_formats) {
369 v4l2_subdev_call(sd, video, enum_mbus_fmt, i, &code); 372 v4l2_subdev_call(sd, video, enum_mbus_fmt, i, &code);
370 icd->user_formats[i].host_fmt = 373 icd->user_formats[fmts].host_fmt =
371 soc_mbus_get_fmtdesc(code); 374 soc_mbus_get_fmtdesc(code);
372 icd->user_formats[i].code = code; 375 if (icd->user_formats[fmts].host_fmt)
376 icd->user_formats[fmts++].code = code;
373 } else { 377 } else {
374 ret = ici->ops->get_formats(icd, i, 378 ret = ici->ops->get_formats(icd, i,
375 &icd->user_formats[fmts]); 379 &icd->user_formats[fmts]);
@@ -378,12 +382,12 @@ static int soc_camera_init_user_formats(struct soc_camera_device *icd)
378 fmts += ret; 382 fmts += ret;
379 } 383 }
380 384
385 icd->num_user_formats = fmts;
381 icd->current_fmt = &icd->user_formats[0]; 386 icd->current_fmt = &icd->user_formats[0];
382 387
383 return 0; 388 return 0;
384 389
385egfmt: 390egfmt:
386 icd->num_user_formats = 0;
387 vfree(icd->user_formats); 391 vfree(icd->user_formats);
388 return ret; 392 return ret;
389} 393}
@@ -662,7 +666,7 @@ static int soc_camera_s_fmt_vid_cap(struct file *file, void *priv,
662 if (icd->streamer && icd->streamer != file) 666 if (icd->streamer && icd->streamer != file)
663 return -EBUSY; 667 return -EBUSY;
664 668
665 if (icd->vb_vidq.bufs[0]) { 669 if (is_streaming(to_soc_camera_host(icd->dev.parent), icd)) {
666 dev_err(&icd->dev, "S_FMT denied: queue initialised\n"); 670 dev_err(&icd->dev, "S_FMT denied: queue initialised\n");
667 return -EBUSY; 671 return -EBUSY;
668 } 672 }
@@ -903,14 +907,17 @@ static int soc_camera_s_crop(struct file *file, void *fh,
903 if (ret < 0) { 907 if (ret < 0) {
904 dev_err(&icd->dev, 908 dev_err(&icd->dev,
905 "S_CROP denied: getting current crop failed\n"); 909 "S_CROP denied: getting current crop failed\n");
906 } else if (icd->vb_vidq.bufs[0] && 910 } else if ((a->c.width == current_crop.c.width &&
907 (a->c.width != current_crop.c.width || 911 a->c.height == current_crop.c.height) ||
908 a->c.height != current_crop.c.height)) { 912 !is_streaming(ici, icd)) {
913 /* same size or not streaming - use .set_crop() */
914 ret = ici->ops->set_crop(icd, a);
915 } else if (ici->ops->set_livecrop) {
916 ret = ici->ops->set_livecrop(icd, a);
917 } else {
909 dev_err(&icd->dev, 918 dev_err(&icd->dev,
910 "S_CROP denied: queue initialised and sizes differ\n"); 919 "S_CROP denied: queue initialised and sizes differ\n");
911 ret = -EBUSY; 920 ret = -EBUSY;
912 } else {
913 ret = ici->ops->set_crop(icd, a);
914 } 921 }
915 922
916 return ret; 923 return ret;
diff --git a/drivers/media/video/soc_mediabus.c b/drivers/media/video/soc_mediabus.c
index ed77aa055b63..bea7c9cf4f88 100644
--- a/drivers/media/video/soc_mediabus.c
+++ b/drivers/media/video/soc_mediabus.c
@@ -15,132 +15,329 @@
15#include <media/v4l2-mediabus.h> 15#include <media/v4l2-mediabus.h>
16#include <media/soc_mediabus.h> 16#include <media/soc_mediabus.h>
17 17
18#define MBUS_IDX(f) (V4L2_MBUS_FMT_ ## f - V4L2_MBUS_FMT_FIXED - 1) 18static const struct soc_mbus_lookup mbus_fmt[] = {
19 19{
20static const struct soc_mbus_pixelfmt mbus_fmt[] = { 20 .code = V4L2_MBUS_FMT_YUYV8_2X8,
21 [MBUS_IDX(YUYV8_2X8)] = { 21 .fmt = {
22 .fourcc = V4L2_PIX_FMT_YUYV, 22 .fourcc = V4L2_PIX_FMT_YUYV,
23 .name = "YUYV", 23 .name = "YUYV",
24 .bits_per_sample = 8, 24 .bits_per_sample = 8,
25 .packing = SOC_MBUS_PACKING_2X8_PADHI, 25 .packing = SOC_MBUS_PACKING_2X8_PADHI,
26 .order = SOC_MBUS_ORDER_LE, 26 .order = SOC_MBUS_ORDER_LE,
27 }, 27 },
28 [MBUS_IDX(YVYU8_2X8)] = { 28}, {
29 .code = V4L2_MBUS_FMT_YVYU8_2X8,
30 .fmt = {
29 .fourcc = V4L2_PIX_FMT_YVYU, 31 .fourcc = V4L2_PIX_FMT_YVYU,
30 .name = "YVYU", 32 .name = "YVYU",
31 .bits_per_sample = 8, 33 .bits_per_sample = 8,
32 .packing = SOC_MBUS_PACKING_2X8_PADHI, 34 .packing = SOC_MBUS_PACKING_2X8_PADHI,
33 .order = SOC_MBUS_ORDER_LE, 35 .order = SOC_MBUS_ORDER_LE,
34 }, 36 },
35 [MBUS_IDX(UYVY8_2X8)] = { 37}, {
38 .code = V4L2_MBUS_FMT_UYVY8_2X8,
39 .fmt = {
36 .fourcc = V4L2_PIX_FMT_UYVY, 40 .fourcc = V4L2_PIX_FMT_UYVY,
37 .name = "UYVY", 41 .name = "UYVY",
38 .bits_per_sample = 8, 42 .bits_per_sample = 8,
39 .packing = SOC_MBUS_PACKING_2X8_PADHI, 43 .packing = SOC_MBUS_PACKING_2X8_PADHI,
40 .order = SOC_MBUS_ORDER_LE, 44 .order = SOC_MBUS_ORDER_LE,
41 }, 45 },
42 [MBUS_IDX(VYUY8_2X8)] = { 46}, {
47 .code = V4L2_MBUS_FMT_VYUY8_2X8,
48 .fmt = {
43 .fourcc = V4L2_PIX_FMT_VYUY, 49 .fourcc = V4L2_PIX_FMT_VYUY,
44 .name = "VYUY", 50 .name = "VYUY",
45 .bits_per_sample = 8, 51 .bits_per_sample = 8,
46 .packing = SOC_MBUS_PACKING_2X8_PADHI, 52 .packing = SOC_MBUS_PACKING_2X8_PADHI,
47 .order = SOC_MBUS_ORDER_LE, 53 .order = SOC_MBUS_ORDER_LE,
48 }, 54 },
49 [MBUS_IDX(RGB555_2X8_PADHI_LE)] = { 55}, {
56 .code = V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE,
57 .fmt = {
50 .fourcc = V4L2_PIX_FMT_RGB555, 58 .fourcc = V4L2_PIX_FMT_RGB555,
51 .name = "RGB555", 59 .name = "RGB555",
52 .bits_per_sample = 8, 60 .bits_per_sample = 8,
53 .packing = SOC_MBUS_PACKING_2X8_PADHI, 61 .packing = SOC_MBUS_PACKING_2X8_PADHI,
54 .order = SOC_MBUS_ORDER_LE, 62 .order = SOC_MBUS_ORDER_LE,
55 }, 63 },
56 [MBUS_IDX(RGB555_2X8_PADHI_BE)] = { 64}, {
65 .code = V4L2_MBUS_FMT_RGB555_2X8_PADHI_BE,
66 .fmt = {
57 .fourcc = V4L2_PIX_FMT_RGB555X, 67 .fourcc = V4L2_PIX_FMT_RGB555X,
58 .name = "RGB555X", 68 .name = "RGB555X",
59 .bits_per_sample = 8, 69 .bits_per_sample = 8,
60 .packing = SOC_MBUS_PACKING_2X8_PADHI, 70 .packing = SOC_MBUS_PACKING_2X8_PADHI,
61 .order = SOC_MBUS_ORDER_LE, 71 .order = SOC_MBUS_ORDER_LE,
62 }, 72 },
63 [MBUS_IDX(RGB565_2X8_LE)] = { 73}, {
74 .code = V4L2_MBUS_FMT_RGB565_2X8_LE,
75 .fmt = {
64 .fourcc = V4L2_PIX_FMT_RGB565, 76 .fourcc = V4L2_PIX_FMT_RGB565,
65 .name = "RGB565", 77 .name = "RGB565",
66 .bits_per_sample = 8, 78 .bits_per_sample = 8,
67 .packing = SOC_MBUS_PACKING_2X8_PADHI, 79 .packing = SOC_MBUS_PACKING_2X8_PADHI,
68 .order = SOC_MBUS_ORDER_LE, 80 .order = SOC_MBUS_ORDER_LE,
69 }, 81 },
70 [MBUS_IDX(RGB565_2X8_BE)] = { 82}, {
83 .code = V4L2_MBUS_FMT_RGB565_2X8_BE,
84 .fmt = {
71 .fourcc = V4L2_PIX_FMT_RGB565X, 85 .fourcc = V4L2_PIX_FMT_RGB565X,
72 .name = "RGB565X", 86 .name = "RGB565X",
73 .bits_per_sample = 8, 87 .bits_per_sample = 8,
74 .packing = SOC_MBUS_PACKING_2X8_PADHI, 88 .packing = SOC_MBUS_PACKING_2X8_PADHI,
75 .order = SOC_MBUS_ORDER_LE, 89 .order = SOC_MBUS_ORDER_LE,
76 }, 90 },
77 [MBUS_IDX(SBGGR8_1X8)] = { 91}, {
92 .code = V4L2_MBUS_FMT_SBGGR8_1X8,
93 .fmt = {
78 .fourcc = V4L2_PIX_FMT_SBGGR8, 94 .fourcc = V4L2_PIX_FMT_SBGGR8,
79 .name = "Bayer 8 BGGR", 95 .name = "Bayer 8 BGGR",
80 .bits_per_sample = 8, 96 .bits_per_sample = 8,
81 .packing = SOC_MBUS_PACKING_NONE, 97 .packing = SOC_MBUS_PACKING_NONE,
82 .order = SOC_MBUS_ORDER_LE, 98 .order = SOC_MBUS_ORDER_LE,
83 }, 99 },
84 [MBUS_IDX(SBGGR10_1X10)] = { 100}, {
101 .code = V4L2_MBUS_FMT_SBGGR10_1X10,
102 .fmt = {
85 .fourcc = V4L2_PIX_FMT_SBGGR10, 103 .fourcc = V4L2_PIX_FMT_SBGGR10,
86 .name = "Bayer 10 BGGR", 104 .name = "Bayer 10 BGGR",
87 .bits_per_sample = 10, 105 .bits_per_sample = 10,
88 .packing = SOC_MBUS_PACKING_EXTEND16, 106 .packing = SOC_MBUS_PACKING_EXTEND16,
89 .order = SOC_MBUS_ORDER_LE, 107 .order = SOC_MBUS_ORDER_LE,
90 }, 108 },
91 [MBUS_IDX(Y8_1X8)] = { 109}, {
110 .code = V4L2_MBUS_FMT_Y8_1X8,
111 .fmt = {
92 .fourcc = V4L2_PIX_FMT_GREY, 112 .fourcc = V4L2_PIX_FMT_GREY,
93 .name = "Grey", 113 .name = "Grey",
94 .bits_per_sample = 8, 114 .bits_per_sample = 8,
95 .packing = SOC_MBUS_PACKING_NONE, 115 .packing = SOC_MBUS_PACKING_NONE,
96 .order = SOC_MBUS_ORDER_LE, 116 .order = SOC_MBUS_ORDER_LE,
97 }, 117 },
98 [MBUS_IDX(Y10_1X10)] = { 118}, {
119 .code = V4L2_MBUS_FMT_Y10_1X10,
120 .fmt = {
99 .fourcc = V4L2_PIX_FMT_Y10, 121 .fourcc = V4L2_PIX_FMT_Y10,
100 .name = "Grey 10bit", 122 .name = "Grey 10bit",
101 .bits_per_sample = 10, 123 .bits_per_sample = 10,
102 .packing = SOC_MBUS_PACKING_EXTEND16, 124 .packing = SOC_MBUS_PACKING_EXTEND16,
103 .order = SOC_MBUS_ORDER_LE, 125 .order = SOC_MBUS_ORDER_LE,
104 }, 126 },
105 [MBUS_IDX(SBGGR10_2X8_PADHI_LE)] = { 127}, {
128 .code = V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_LE,
129 .fmt = {
106 .fourcc = V4L2_PIX_FMT_SBGGR10, 130 .fourcc = V4L2_PIX_FMT_SBGGR10,
107 .name = "Bayer 10 BGGR", 131 .name = "Bayer 10 BGGR",
108 .bits_per_sample = 8, 132 .bits_per_sample = 8,
109 .packing = SOC_MBUS_PACKING_2X8_PADHI, 133 .packing = SOC_MBUS_PACKING_2X8_PADHI,
110 .order = SOC_MBUS_ORDER_LE, 134 .order = SOC_MBUS_ORDER_LE,
111 }, 135 },
112 [MBUS_IDX(SBGGR10_2X8_PADLO_LE)] = { 136}, {
137 .code = V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_LE,
138 .fmt = {
113 .fourcc = V4L2_PIX_FMT_SBGGR10, 139 .fourcc = V4L2_PIX_FMT_SBGGR10,
114 .name = "Bayer 10 BGGR", 140 .name = "Bayer 10 BGGR",
115 .bits_per_sample = 8, 141 .bits_per_sample = 8,
116 .packing = SOC_MBUS_PACKING_2X8_PADLO, 142 .packing = SOC_MBUS_PACKING_2X8_PADLO,
117 .order = SOC_MBUS_ORDER_LE, 143 .order = SOC_MBUS_ORDER_LE,
118 }, 144 },
119 [MBUS_IDX(SBGGR10_2X8_PADHI_BE)] = { 145}, {
146 .code = V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_BE,
147 .fmt = {
120 .fourcc = V4L2_PIX_FMT_SBGGR10, 148 .fourcc = V4L2_PIX_FMT_SBGGR10,
121 .name = "Bayer 10 BGGR", 149 .name = "Bayer 10 BGGR",
122 .bits_per_sample = 8, 150 .bits_per_sample = 8,
123 .packing = SOC_MBUS_PACKING_2X8_PADHI, 151 .packing = SOC_MBUS_PACKING_2X8_PADHI,
124 .order = SOC_MBUS_ORDER_BE, 152 .order = SOC_MBUS_ORDER_BE,
125 }, 153 },
126 [MBUS_IDX(SBGGR10_2X8_PADLO_BE)] = { 154}, {
155 .code = V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_BE,
156 .fmt = {
127 .fourcc = V4L2_PIX_FMT_SBGGR10, 157 .fourcc = V4L2_PIX_FMT_SBGGR10,
128 .name = "Bayer 10 BGGR", 158 .name = "Bayer 10 BGGR",
129 .bits_per_sample = 8, 159 .bits_per_sample = 8,
130 .packing = SOC_MBUS_PACKING_2X8_PADLO, 160 .packing = SOC_MBUS_PACKING_2X8_PADLO,
131 .order = SOC_MBUS_ORDER_BE, 161 .order = SOC_MBUS_ORDER_BE,
132 }, 162 },
163}, {
164 .code = V4L2_MBUS_FMT_JPEG_1X8,
165 .fmt = {
166 .fourcc = V4L2_PIX_FMT_JPEG,
167 .name = "JPEG",
168 .bits_per_sample = 8,
169 .packing = SOC_MBUS_PACKING_VARIABLE,
170 .order = SOC_MBUS_ORDER_LE,
171 },
172}, {
173 .code = V4L2_MBUS_FMT_RGB444_2X8_PADHI_BE,
174 .fmt = {
175 .fourcc = V4L2_PIX_FMT_RGB444,
176 .name = "RGB444",
177 .bits_per_sample = 8,
178 .packing = SOC_MBUS_PACKING_2X8_PADHI,
179 .order = SOC_MBUS_ORDER_BE,
180 },
181}, {
182 .code = V4L2_MBUS_FMT_YUYV8_1_5X8,
183 .fmt = {
184 .fourcc = V4L2_PIX_FMT_YUV420,
185 .name = "YUYV 4:2:0",
186 .bits_per_sample = 8,
187 .packing = SOC_MBUS_PACKING_1_5X8,
188 .order = SOC_MBUS_ORDER_LE,
189 },
190}, {
191 .code = V4L2_MBUS_FMT_YVYU8_1_5X8,
192 .fmt = {
193 .fourcc = V4L2_PIX_FMT_YVU420,
194 .name = "YVYU 4:2:0",
195 .bits_per_sample = 8,
196 .packing = SOC_MBUS_PACKING_1_5X8,
197 .order = SOC_MBUS_ORDER_LE,
198 },
199}, {
200 .code = V4L2_MBUS_FMT_UYVY8_1X16,
201 .fmt = {
202 .fourcc = V4L2_PIX_FMT_UYVY,
203 .name = "UYVY 16bit",
204 .bits_per_sample = 16,
205 .packing = SOC_MBUS_PACKING_EXTEND16,
206 .order = SOC_MBUS_ORDER_LE,
207 },
208}, {
209 .code = V4L2_MBUS_FMT_VYUY8_1X16,
210 .fmt = {
211 .fourcc = V4L2_PIX_FMT_VYUY,
212 .name = "VYUY 16bit",
213 .bits_per_sample = 16,
214 .packing = SOC_MBUS_PACKING_EXTEND16,
215 .order = SOC_MBUS_ORDER_LE,
216 },
217}, {
218 .code = V4L2_MBUS_FMT_YUYV8_1X16,
219 .fmt = {
220 .fourcc = V4L2_PIX_FMT_YUYV,
221 .name = "YUYV 16bit",
222 .bits_per_sample = 16,
223 .packing = SOC_MBUS_PACKING_EXTEND16,
224 .order = SOC_MBUS_ORDER_LE,
225 },
226}, {
227 .code = V4L2_MBUS_FMT_YVYU8_1X16,
228 .fmt = {
229 .fourcc = V4L2_PIX_FMT_YVYU,
230 .name = "YVYU 16bit",
231 .bits_per_sample = 16,
232 .packing = SOC_MBUS_PACKING_EXTEND16,
233 .order = SOC_MBUS_ORDER_LE,
234 },
235}, {
236 .code = V4L2_MBUS_FMT_SGRBG8_1X8,
237 .fmt = {
238 .fourcc = V4L2_PIX_FMT_SGRBG8,
239 .name = "Bayer 8 GRBG",
240 .bits_per_sample = 8,
241 .packing = SOC_MBUS_PACKING_NONE,
242 .order = SOC_MBUS_ORDER_LE,
243 },
244}, {
245 .code = V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8,
246 .fmt = {
247 .fourcc = V4L2_PIX_FMT_SGRBG10DPCM8,
248 .name = "Bayer 10 BGGR DPCM 8",
249 .bits_per_sample = 8,
250 .packing = SOC_MBUS_PACKING_NONE,
251 .order = SOC_MBUS_ORDER_LE,
252 },
253}, {
254 .code = V4L2_MBUS_FMT_SGBRG10_1X10,
255 .fmt = {
256 .fourcc = V4L2_PIX_FMT_SGBRG10,
257 .name = "Bayer 10 GBRG",
258 .bits_per_sample = 10,
259 .packing = SOC_MBUS_PACKING_EXTEND16,
260 .order = SOC_MBUS_ORDER_LE,
261 },
262}, {
263 .code = V4L2_MBUS_FMT_SGRBG10_1X10,
264 .fmt = {
265 .fourcc = V4L2_PIX_FMT_SGRBG10,
266 .name = "Bayer 10 GRBG",
267 .bits_per_sample = 10,
268 .packing = SOC_MBUS_PACKING_EXTEND16,
269 .order = SOC_MBUS_ORDER_LE,
270 },
271}, {
272 .code = V4L2_MBUS_FMT_SRGGB10_1X10,
273 .fmt = {
274 .fourcc = V4L2_PIX_FMT_SRGGB10,
275 .name = "Bayer 10 RGGB",
276 .bits_per_sample = 10,
277 .packing = SOC_MBUS_PACKING_EXTEND16,
278 .order = SOC_MBUS_ORDER_LE,
279 },
280}, {
281 .code = V4L2_MBUS_FMT_SBGGR12_1X12,
282 .fmt = {
283 .fourcc = V4L2_PIX_FMT_SBGGR12,
284 .name = "Bayer 12 BGGR",
285 .bits_per_sample = 12,
286 .packing = SOC_MBUS_PACKING_EXTEND16,
287 .order = SOC_MBUS_ORDER_LE,
288 },
289}, {
290 .code = V4L2_MBUS_FMT_SGBRG12_1X12,
291 .fmt = {
292 .fourcc = V4L2_PIX_FMT_SGBRG12,
293 .name = "Bayer 12 GBRG",
294 .bits_per_sample = 12,
295 .packing = SOC_MBUS_PACKING_EXTEND16,
296 .order = SOC_MBUS_ORDER_LE,
297 },
298}, {
299 .code = V4L2_MBUS_FMT_SGRBG12_1X12,
300 .fmt = {
301 .fourcc = V4L2_PIX_FMT_SGRBG12,
302 .name = "Bayer 12 GRBG",
303 .bits_per_sample = 12,
304 .packing = SOC_MBUS_PACKING_EXTEND16,
305 .order = SOC_MBUS_ORDER_LE,
306 },
307}, {
308 .code = V4L2_MBUS_FMT_SRGGB12_1X12,
309 .fmt = {
310 .fourcc = V4L2_PIX_FMT_SRGGB12,
311 .name = "Bayer 12 RGGB",
312 .bits_per_sample = 12,
313 .packing = SOC_MBUS_PACKING_EXTEND16,
314 .order = SOC_MBUS_ORDER_LE,
315 },
316},
133}; 317};
134 318
135int soc_mbus_samples_per_pixel(const struct soc_mbus_pixelfmt *mf) 319int soc_mbus_samples_per_pixel(const struct soc_mbus_pixelfmt *mf,
320 unsigned int *numerator, unsigned int *denominator)
136{ 321{
137 switch (mf->packing) { 322 switch (mf->packing) {
138 case SOC_MBUS_PACKING_NONE: 323 case SOC_MBUS_PACKING_NONE:
139 case SOC_MBUS_PACKING_EXTEND16: 324 case SOC_MBUS_PACKING_EXTEND16:
140 return 1; 325 *numerator = 1;
326 *denominator = 1;
327 return 0;
141 case SOC_MBUS_PACKING_2X8_PADHI: 328 case SOC_MBUS_PACKING_2X8_PADHI:
142 case SOC_MBUS_PACKING_2X8_PADLO: 329 case SOC_MBUS_PACKING_2X8_PADLO:
143 return 2; 330 *numerator = 2;
331 *denominator = 1;
332 return 0;
333 case SOC_MBUS_PACKING_1_5X8:
334 *numerator = 3;
335 *denominator = 2;
336 return 0;
337 case SOC_MBUS_PACKING_VARIABLE:
338 *numerator = 0;
339 *denominator = 1;
340 return 0;
144 } 341 }
145 return -EINVAL; 342 return -EINVAL;
146} 343}
@@ -155,18 +352,34 @@ s32 soc_mbus_bytes_per_line(u32 width, const struct soc_mbus_pixelfmt *mf)
155 case SOC_MBUS_PACKING_2X8_PADLO: 352 case SOC_MBUS_PACKING_2X8_PADLO:
156 case SOC_MBUS_PACKING_EXTEND16: 353 case SOC_MBUS_PACKING_EXTEND16:
157 return width * 2; 354 return width * 2;
355 case SOC_MBUS_PACKING_1_5X8:
356 return width * 3 / 2;
357 case SOC_MBUS_PACKING_VARIABLE:
358 return 0;
158 } 359 }
159 return -EINVAL; 360 return -EINVAL;
160} 361}
161EXPORT_SYMBOL(soc_mbus_bytes_per_line); 362EXPORT_SYMBOL(soc_mbus_bytes_per_line);
162 363
364const struct soc_mbus_pixelfmt *soc_mbus_find_fmtdesc(
365 enum v4l2_mbus_pixelcode code,
366 const struct soc_mbus_lookup *lookup,
367 int n)
368{
369 int i;
370
371 for (i = 0; i < n; i++)
372 if (lookup[i].code == code)
373 return &lookup[i].fmt;
374
375 return NULL;
376}
377EXPORT_SYMBOL(soc_mbus_find_fmtdesc);
378
163const struct soc_mbus_pixelfmt *soc_mbus_get_fmtdesc( 379const struct soc_mbus_pixelfmt *soc_mbus_get_fmtdesc(
164 enum v4l2_mbus_pixelcode code) 380 enum v4l2_mbus_pixelcode code)
165{ 381{
166 if (code - V4L2_MBUS_FMT_FIXED > ARRAY_SIZE(mbus_fmt) || 382 return soc_mbus_find_fmtdesc(code, mbus_fmt, ARRAY_SIZE(mbus_fmt));
167 code <= V4L2_MBUS_FMT_FIXED)
168 return NULL;
169 return mbus_fmt + code - V4L2_MBUS_FMT_FIXED - 1;
170} 383}
171EXPORT_SYMBOL(soc_mbus_get_fmtdesc); 384EXPORT_SYMBOL(soc_mbus_get_fmtdesc);
172 385
diff --git a/drivers/media/video/tveeprom.c b/drivers/media/video/tveeprom.c
index 07fabdd9b465..6103d1b1081e 100644
--- a/drivers/media/video/tveeprom.c
+++ b/drivers/media/video/tveeprom.c
@@ -267,21 +267,27 @@ hauppauge_tuner[] =
267 { TUNER_ABSENT, "Xceive XC4000"}, 267 { TUNER_ABSENT, "Xceive XC4000"},
268 { TUNER_ABSENT, "Dibcom 7070"}, 268 { TUNER_ABSENT, "Dibcom 7070"},
269 { TUNER_PHILIPS_TDA8290, "NXP 18271C2"}, 269 { TUNER_PHILIPS_TDA8290, "NXP 18271C2"},
270 { TUNER_ABSENT, "unknown"}, 270 { TUNER_ABSENT, "Siano SMS1010"},
271 { TUNER_ABSENT, "unknown"}, 271 { TUNER_ABSENT, "Siano SMS1150"},
272 { TUNER_ABSENT, "unknown"}, 272 { TUNER_ABSENT, "MaxLinear 5007"},
273 { TUNER_ABSENT, "unknown"}, 273 { TUNER_ABSENT, "TCL M09WPP_2P_E"},
274 /* 160-169 */ 274 /* 160-169 */
275 { TUNER_ABSENT, "unknown"}, 275 { TUNER_ABSENT, "Siano SMS1180"},
276 { TUNER_ABSENT, "unknown"}, 276 { TUNER_ABSENT, "Maxim_MAX2165"},
277 { TUNER_ABSENT, "unknown"}, 277 { TUNER_ABSENT, "Siano SMS1140"},
278 { TUNER_ABSENT, "unknown"}, 278 { TUNER_ABSENT, "Siano SMS1150 B1"},
279 { TUNER_ABSENT, "unknown"}, 279 { TUNER_ABSENT, "MaxLinear 111"},
280 { TUNER_ABSENT, "unknown"}, 280 { TUNER_ABSENT, "Dibcom 7770"},
281 { TUNER_ABSENT, "unknown"}, 281 { TUNER_ABSENT, "Siano SMS1180VNS"},
282 { TUNER_ABSENT, "unknown"}, 282 { TUNER_ABSENT, "Siano SMS1184"},
283 { TUNER_PHILIPS_FQ1236_MK5, "TCL M30WTP-4N-E"}, 283 { TUNER_PHILIPS_FQ1236_MK5, "TCL M30WTP-4N-E"},
284 { TUNER_ABSENT, "unknown"}, 284 { TUNER_ABSENT, "TCL_M11WPP_2PN_E"},
285 /* 170-179 */
286 { TUNER_ABSENT, "MaxLinear 301"},
287 { TUNER_ABSENT, "Mirics MSi001"},
288 { TUNER_ABSENT, "MaxLinear MxL241SF"},
289 { TUNER_ABSENT, "Xceive XC5000C"},
290 { TUNER_ABSENT, "Montage M68TS2020"},
285}; 291};
286 292
287/* Use V4L2_IDENT_AMBIGUOUS for those audio 'chips' that are 293/* Use V4L2_IDENT_AMBIGUOUS for those audio 'chips' that are
diff --git a/drivers/media/video/usbvision/usbvision-cards.c b/drivers/media/video/usbvision/usbvision-cards.c
index 68b998bd203f..8f5266157f15 100644
--- a/drivers/media/video/usbvision/usbvision-cards.c
+++ b/drivers/media/video/usbvision/usbvision-cards.c
@@ -1025,6 +1025,34 @@ struct usbvision_device_data_st usbvision_device_data[] = {
1025 .y_offset = -1, 1025 .y_offset = -1,
1026 .model_string = "Hauppauge WinTv-USB", 1026 .model_string = "Hauppauge WinTv-USB",
1027 }, 1027 },
1028 [MICROCAM_NTSC] = {
1029 .interface = -1,
1030 .codec = CODEC_WEBCAM,
1031 .video_channels = 1,
1032 .video_norm = V4L2_STD_NTSC,
1033 .audio_channels = 0,
1034 .radio = 0,
1035 .vbi = 0,
1036 .tuner = 0,
1037 .tuner_type = 0,
1038 .x_offset = 71,
1039 .y_offset = 15,
1040 .model_string = "Nogatech USB MicroCam NTSC (NV3000N)",
1041 },
1042 [MICROCAM_PAL] = {
1043 .interface = -1,
1044 .codec = CODEC_WEBCAM,
1045 .video_channels = 1,
1046 .video_norm = V4L2_STD_PAL,
1047 .audio_channels = 0,
1048 .radio = 0,
1049 .vbi = 0,
1050 .tuner = 0,
1051 .tuner_type = 0,
1052 .x_offset = 71,
1053 .y_offset = 18,
1054 .model_string = "Nogatech USB MicroCam PAL (NV3001P)",
1055 },
1028}; 1056};
1029const int usbvision_device_data_size = ARRAY_SIZE(usbvision_device_data); 1057const int usbvision_device_data_size = ARRAY_SIZE(usbvision_device_data);
1030 1058
@@ -1042,6 +1070,8 @@ struct usb_device_id usbvision_table[] = {
1042 { USB_DEVICE(0x0573, 0x2d00), .driver_info = HPG_WINTV_LIVE_PAL_BG }, 1070 { USB_DEVICE(0x0573, 0x2d00), .driver_info = HPG_WINTV_LIVE_PAL_BG },
1043 { USB_DEVICE(0x0573, 0x2d01), .driver_info = HPG_WINTV_LIVE_PRO_NTSC_MN }, 1071 { USB_DEVICE(0x0573, 0x2d01), .driver_info = HPG_WINTV_LIVE_PRO_NTSC_MN },
1044 { USB_DEVICE(0x0573, 0x2101), .driver_info = ZORAN_PMD_NOGATECH }, 1072 { USB_DEVICE(0x0573, 0x2101), .driver_info = ZORAN_PMD_NOGATECH },
1073 { USB_DEVICE(0x0573, 0x3000), .driver_info = MICROCAM_NTSC },
1074 { USB_DEVICE(0x0573, 0x3001), .driver_info = MICROCAM_PAL },
1045 { USB_DEVICE(0x0573, 0x4100), .driver_info = NOGATECH_USB_TV_NTSC_FM }, 1075 { USB_DEVICE(0x0573, 0x4100), .driver_info = NOGATECH_USB_TV_NTSC_FM },
1046 { USB_DEVICE(0x0573, 0x4110), .driver_info = PNY_USB_TV_NTSC_FM }, 1076 { USB_DEVICE(0x0573, 0x4110), .driver_info = PNY_USB_TV_NTSC_FM },
1047 { USB_DEVICE(0x0573, 0x4450), .driver_info = PV_PLAYTV_USB_PRO_PAL_FM }, 1077 { USB_DEVICE(0x0573, 0x4450), .driver_info = PV_PLAYTV_USB_PRO_PAL_FM },
@@ -1088,8 +1118,7 @@ struct usb_device_id usbvision_table[] = {
1088 { USB_DEVICE(0x2304, 0x0110), .driver_info = PINNA_PCTV_USB_PAL_FM }, 1118 { USB_DEVICE(0x2304, 0x0110), .driver_info = PINNA_PCTV_USB_PAL_FM },
1089 { USB_DEVICE(0x2304, 0x0111), .driver_info = MIRO_PCTV_USB }, 1119 { USB_DEVICE(0x2304, 0x0111), .driver_info = MIRO_PCTV_USB },
1090 { USB_DEVICE(0x2304, 0x0112), .driver_info = PINNA_PCTV_USB_NTSC_FM }, 1120 { USB_DEVICE(0x2304, 0x0112), .driver_info = PINNA_PCTV_USB_NTSC_FM },
1091 { USB_DEVICE(0x2304, 0x0113), 1121 { USB_DEVICE(0x2304, 0x0113), .driver_info = PINNA_PCTV_USB_NTSC_FM_V3 },
1092 .driver_info = PINNA_PCTV_USB_NTSC_FM_V3 },
1093 { USB_DEVICE(0x2304, 0x0210), .driver_info = PINNA_PCTV_USB_PAL_FM_V2 }, 1122 { USB_DEVICE(0x2304, 0x0210), .driver_info = PINNA_PCTV_USB_PAL_FM_V2 },
1094 { USB_DEVICE(0x2304, 0x0212), .driver_info = PINNA_PCTV_USB_NTSC_FM_V2 }, 1123 { USB_DEVICE(0x2304, 0x0212), .driver_info = PINNA_PCTV_USB_NTSC_FM_V2 },
1095 { USB_DEVICE(0x2304, 0x0214), .driver_info = PINNA_PCTV_USB_PAL_FM_V3 }, 1124 { USB_DEVICE(0x2304, 0x0214), .driver_info = PINNA_PCTV_USB_PAL_FM_V3 },
diff --git a/drivers/media/video/usbvision/usbvision-cards.h b/drivers/media/video/usbvision/usbvision-cards.h
index 9c6ad22960d8..a51cc1185cce 100644
--- a/drivers/media/video/usbvision/usbvision-cards.h
+++ b/drivers/media/video/usbvision/usbvision-cards.h
@@ -63,5 +63,7 @@
63#define PINNA_PCTV_BUNGEE_PAL_FM 62 63#define PINNA_PCTV_BUNGEE_PAL_FM 62
64#define HPG_WINTV 63 64#define HPG_WINTV 63
65#define PINNA_PCTV_USB_NTSC_FM_V3 64 65#define PINNA_PCTV_USB_NTSC_FM_V3 64
66#define MICROCAM_NTSC 65
67#define MICROCAM_PAL 66
66 68
67extern const int usbvision_device_data_size; 69extern const int usbvision_device_data_size;
diff --git a/drivers/media/video/usbvision/usbvision-core.c b/drivers/media/video/usbvision/usbvision-core.c
index c8feb0d6fccf..f344411a4578 100644
--- a/drivers/media/video/usbvision/usbvision-core.c
+++ b/drivers/media/video/usbvision/usbvision-core.c
@@ -49,10 +49,6 @@ static unsigned int core_debug;
49module_param(core_debug, int, 0644); 49module_param(core_debug, int, 0644);
50MODULE_PARM_DESC(core_debug, "enable debug messages [core]"); 50MODULE_PARM_DESC(core_debug, "enable debug messages [core]");
51 51
52static unsigned int force_testpattern;
53module_param(force_testpattern, int, 0644);
54MODULE_PARM_DESC(force_testpattern, "enable test pattern display [core]");
55
56static int adjust_compression = 1; /* Set the compression to be adaptive */ 52static int adjust_compression = 1; /* Set the compression to be adaptive */
57module_param(adjust_compression, int, 0444); 53module_param(adjust_compression, int, 0444);
58MODULE_PARM_DESC(adjust_compression, " Set the ADPCM compression for the device. Default: 1 (On)"); 54MODULE_PARM_DESC(adjust_compression, " Set the ADPCM compression for the device. Default: 1 (On)");
@@ -388,90 +384,6 @@ void usbvision_scratch_free(struct usb_usbvision *usbvision)
388} 384}
389 385
390/* 386/*
391 * usbvision_testpattern()
392 *
393 * Procedure forms a test pattern (yellow grid on blue background).
394 *
395 * Parameters:
396 * fullframe: if TRUE then entire frame is filled, otherwise the procedure
397 * continues from the current scanline.
398 * pmode 0: fill the frame with solid blue color (like on VCR or TV)
399 * 1: Draw a colored grid
400 *
401 */
402static void usbvision_testpattern(struct usb_usbvision *usbvision,
403 int fullframe, int pmode)
404{
405 static const char proc[] = "usbvision_testpattern";
406 struct usbvision_frame *frame;
407 unsigned char *f;
408 int num_cell = 0;
409 int scan_length = 0;
410 static int num_pass;
411
412 if (usbvision == NULL) {
413 printk(KERN_ERR "%s: usbvision == NULL\n", proc);
414 return;
415 }
416 if (usbvision->cur_frame == NULL) {
417 printk(KERN_ERR "%s: usbvision->cur_frame is NULL.\n", proc);
418 return;
419 }
420
421 /* Grab the current frame */
422 frame = usbvision->cur_frame;
423
424 /* Optionally start at the beginning */
425 if (fullframe) {
426 frame->curline = 0;
427 frame->scanlength = 0;
428 }
429
430 /* Form every scan line */
431 for (; frame->curline < frame->frmheight; frame->curline++) {
432 int i;
433
434 f = frame->data + (usbvision->curwidth * 3 * frame->curline);
435 for (i = 0; i < usbvision->curwidth; i++) {
436 unsigned char cb = 0x80;
437 unsigned char cg = 0;
438 unsigned char cr = 0;
439
440 if (pmode == 1) {
441 if (frame->curline % 32 == 0)
442 cb = 0, cg = cr = 0xFF;
443 else if (i % 32 == 0) {
444 if (frame->curline % 32 == 1)
445 num_cell++;
446 cb = 0, cg = cr = 0xFF;
447 } else {
448 cb =
449 ((num_cell * 7) +
450 num_pass) & 0xFF;
451 cg =
452 ((num_cell * 5) +
453 num_pass * 2) & 0xFF;
454 cr =
455 ((num_cell * 3) +
456 num_pass * 3) & 0xFF;
457 }
458 } else {
459 /* Just the blue screen */
460 }
461
462 *f++ = cb;
463 *f++ = cg;
464 *f++ = cr;
465 scan_length += 3;
466 }
467 }
468
469 frame->grabstate = frame_state_done;
470 frame->scanlength += scan_length;
471 ++num_pass;
472}
473
474/*
475 * usbvision_decompress_alloc() 387 * usbvision_decompress_alloc()
476 * 388 *
477 * allocates intermediate buffer for decompression 389 * allocates intermediate buffer for decompression
@@ -571,10 +483,6 @@ static enum parse_state usbvision_find_header(struct usb_usbvision *usbvision)
571 frame->scanstate = scan_state_lines; 483 frame->scanstate = scan_state_lines;
572 frame->curline = 0; 484 frame->curline = 0;
573 485
574 if (force_testpattern) {
575 usbvision_testpattern(usbvision, 1, 1);
576 return parse_state_next_frame;
577 }
578 return parse_state_continue; 486 return parse_state_continue;
579} 487}
580 488
@@ -1679,6 +1587,55 @@ int usbvision_power_off(struct usb_usbvision *usbvision)
1679 return err_code; 1587 return err_code;
1680} 1588}
1681 1589
1590/* configure webcam image sensor using the serial port */
1591static int usbvision_init_webcam(struct usb_usbvision *usbvision)
1592{
1593 int rc;
1594 int i;
1595 static char init_values[38][3] = {
1596 { 0x04, 0x12, 0x08 }, { 0x05, 0xff, 0xc8 }, { 0x06, 0x18, 0x07 }, { 0x07, 0x90, 0x00 },
1597 { 0x09, 0x00, 0x00 }, { 0x0a, 0x00, 0x00 }, { 0x0b, 0x08, 0x00 }, { 0x0d, 0xcc, 0xcc },
1598 { 0x0e, 0x13, 0x14 }, { 0x10, 0x9b, 0x83 }, { 0x11, 0x5a, 0x3f }, { 0x12, 0xe4, 0x73 },
1599 { 0x13, 0x88, 0x84 }, { 0x14, 0x89, 0x80 }, { 0x15, 0x00, 0x20 }, { 0x16, 0x00, 0x00 },
1600 { 0x17, 0xff, 0xa0 }, { 0x18, 0x6b, 0x20 }, { 0x19, 0x22, 0x40 }, { 0x1a, 0x10, 0x07 },
1601 { 0x1b, 0x00, 0x47 }, { 0x1c, 0x03, 0xe0 }, { 0x1d, 0x00, 0x00 }, { 0x1e, 0x00, 0x00 },
1602 { 0x1f, 0x00, 0x00 }, { 0x20, 0x00, 0x00 }, { 0x21, 0x00, 0x00 }, { 0x22, 0x00, 0x00 },
1603 { 0x23, 0x00, 0x00 }, { 0x24, 0x00, 0x00 }, { 0x25, 0x00, 0x00 }, { 0x26, 0x00, 0x00 },
1604 { 0x27, 0x00, 0x00 }, { 0x28, 0x00, 0x00 }, { 0x29, 0x00, 0x00 }, { 0x08, 0x80, 0x60 },
1605 { 0x0f, 0x2d, 0x24 }, { 0x0c, 0x80, 0x80 }
1606 };
1607 char value[3];
1608
1609 /* the only difference between PAL and NTSC init_values */
1610 if (usbvision_device_data[usbvision->dev_model].video_norm == V4L2_STD_NTSC)
1611 init_values[4][1] = 0x34;
1612
1613 for (i = 0; i < sizeof(init_values) / 3; i++) {
1614 usbvision_write_reg(usbvision, USBVISION_SER_MODE, USBVISION_SER_MODE_SOFT);
1615 memcpy(value, init_values[i], 3);
1616 rc = usb_control_msg(usbvision->dev,
1617 usb_sndctrlpipe(usbvision->dev, 1),
1618 USBVISION_OP_CODE,
1619 USB_DIR_OUT | USB_TYPE_VENDOR |
1620 USB_RECIP_ENDPOINT, 0,
1621 (__u16) USBVISION_SER_DAT1, value,
1622 3, HZ);
1623 if (rc < 0)
1624 return rc;
1625 usbvision_write_reg(usbvision, USBVISION_SER_MODE, USBVISION_SER_MODE_SIO);
1626 /* write 3 bytes to the serial port using SIO mode */
1627 usbvision_write_reg(usbvision, USBVISION_SER_CONT, 3 | 0x10);
1628 usbvision_write_reg(usbvision, USBVISION_IOPIN_REG, 0);
1629 usbvision_write_reg(usbvision, USBVISION_SER_MODE, USBVISION_SER_MODE_SOFT);
1630 usbvision_write_reg(usbvision, USBVISION_IOPIN_REG, USBVISION_IO_2);
1631 usbvision_write_reg(usbvision, USBVISION_SER_MODE, USBVISION_SER_MODE_SOFT | USBVISION_CLK_OUT);
1632 usbvision_write_reg(usbvision, USBVISION_SER_MODE, USBVISION_SER_MODE_SOFT | USBVISION_DAT_IO);
1633 usbvision_write_reg(usbvision, USBVISION_SER_MODE, USBVISION_SER_MODE_SOFT | USBVISION_CLK_OUT | USBVISION_DAT_IO);
1634 }
1635
1636 return 0;
1637}
1638
1682/* 1639/*
1683 * usbvision_set_video_format() 1640 * usbvision_set_video_format()
1684 * 1641 *
@@ -1797,6 +1754,13 @@ int usbvision_set_output(struct usb_usbvision *usbvision, int width,
1797 1754
1798 frame_drop = FRAMERATE_MAX; /* We can allow the maximum here, because dropping is controlled */ 1755 frame_drop = FRAMERATE_MAX; /* We can allow the maximum here, because dropping is controlled */
1799 1756
1757 if (usbvision_device_data[usbvision->dev_model].codec == CODEC_WEBCAM) {
1758 if (usbvision_device_data[usbvision->dev_model].video_norm == V4L2_STD_PAL)
1759 frame_drop = 25;
1760 else
1761 frame_drop = 30;
1762 }
1763
1800 /* frame_drop = 7; => frame_phase = 1, 5, 9, 13, 17, 21, 25, 0, 4, 8, ... 1764 /* frame_drop = 7; => frame_phase = 1, 5, 9, 13, 17, 21, 25, 0, 4, 8, ...
1801 => frame_skip = 4; 1765 => frame_skip = 4;
1802 => frame_rate = (7 + 1) * 25 / 32 = 200 / 32 = 6.25; 1766 => frame_rate = (7 + 1) * 25 / 32 = 200 / 32 = 6.25;
@@ -2046,6 +2010,12 @@ int usbvision_set_input(struct usb_usbvision *usbvision)
2046 value[7] = 0x00; /* 0x0010 -> 16 Input video v offset */ 2010 value[7] = 0x00; /* 0x0010 -> 16 Input video v offset */
2047 } 2011 }
2048 2012
2013 /* webcam is only 480 pixels wide, both PAL and NTSC version */
2014 if (usbvision_device_data[usbvision->dev_model].codec == CODEC_WEBCAM) {
2015 value[0] = 0xe0;
2016 value[1] = 0x01; /* 0x01E0 -> 480 Input video line length */
2017 }
2018
2049 if (usbvision_device_data[usbvision->dev_model].x_offset >= 0) { 2019 if (usbvision_device_data[usbvision->dev_model].x_offset >= 0) {
2050 value[4] = usbvision_device_data[usbvision->dev_model].x_offset & 0xff; 2020 value[4] = usbvision_device_data[usbvision->dev_model].x_offset & 0xff;
2051 value[5] = (usbvision_device_data[usbvision->dev_model].x_offset & 0x0300) >> 8; 2021 value[5] = (usbvision_device_data[usbvision->dev_model].x_offset & 0x0300) >> 8;
@@ -2148,7 +2118,7 @@ static int usbvision_set_dram_settings(struct usb_usbvision *usbvision)
2148 (__u16) USBVISION_DRM_PRM1, value, 8, HZ); 2118 (__u16) USBVISION_DRM_PRM1, value, 8, HZ);
2149 2119
2150 if (rc < 0) { 2120 if (rc < 0) {
2151 dev_err(&usbvision->dev->dev, "%sERROR=%d\n", __func__, rc); 2121 dev_err(&usbvision->dev->dev, "%s: ERROR=%d\n", __func__, rc);
2152 return rc; 2122 return rc;
2153 } 2123 }
2154 2124
@@ -2180,8 +2150,15 @@ int usbvision_power_on(struct usb_usbvision *usbvision)
2180 usbvision_write_reg(usbvision, USBVISION_PWR_REG, 2150 usbvision_write_reg(usbvision, USBVISION_PWR_REG,
2181 USBVISION_SSPND_EN | USBVISION_RES2); 2151 USBVISION_SSPND_EN | USBVISION_RES2);
2182 2152
2153 if (usbvision_device_data[usbvision->dev_model].codec == CODEC_WEBCAM) {
2154 usbvision_write_reg(usbvision, USBVISION_VIN_REG1,
2155 USBVISION_16_422_SYNC | USBVISION_HVALID_PO);
2156 usbvision_write_reg(usbvision, USBVISION_VIN_REG2,
2157 USBVISION_NOHVALID | USBVISION_KEEP_BLANK);
2158 }
2183 usbvision_write_reg(usbvision, USBVISION_PWR_REG, 2159 usbvision_write_reg(usbvision, USBVISION_PWR_REG,
2184 USBVISION_SSPND_EN | USBVISION_PWR_VID); 2160 USBVISION_SSPND_EN | USBVISION_PWR_VID);
2161 mdelay(10);
2185 err_code = usbvision_write_reg(usbvision, USBVISION_PWR_REG, 2162 err_code = usbvision_write_reg(usbvision, USBVISION_PWR_REG,
2186 USBVISION_SSPND_EN | USBVISION_PWR_VID | USBVISION_RES2); 2163 USBVISION_SSPND_EN | USBVISION_PWR_VID | USBVISION_RES2);
2187 if (err_code == 1) 2164 if (err_code == 1)
@@ -2310,6 +2287,8 @@ int usbvision_set_audio(struct usb_usbvision *usbvision, int audio_channel)
2310 2287
2311int usbvision_setup(struct usb_usbvision *usbvision, int format) 2288int usbvision_setup(struct usb_usbvision *usbvision, int format)
2312{ 2289{
2290 if (usbvision_device_data[usbvision->dev_model].codec == CODEC_WEBCAM)
2291 usbvision_init_webcam(usbvision);
2313 usbvision_set_video_format(usbvision, format); 2292 usbvision_set_video_format(usbvision, format);
2314 usbvision_set_dram_settings(usbvision); 2293 usbvision_set_dram_settings(usbvision);
2315 usbvision_set_compress_params(usbvision); 2294 usbvision_set_compress_params(usbvision);
diff --git a/drivers/media/video/usbvision/usbvision-i2c.c b/drivers/media/video/usbvision/usbvision-i2c.c
index 05b1344181cd..d7f97513b289 100644
--- a/drivers/media/video/usbvision/usbvision-i2c.c
+++ b/drivers/media/video/usbvision/usbvision-i2c.c
@@ -222,7 +222,7 @@ int usbvision_i2c_register(struct usb_usbvision *usbvision)
222 i2c_set_adapdata(&usbvision->i2c_adap, &usbvision->v4l2_dev); 222 i2c_set_adapdata(&usbvision->i2c_adap, &usbvision->v4l2_dev);
223 223
224 if (usbvision_write_reg(usbvision, USBVISION_SER_MODE, USBVISION_IIC_LRNACK) < 0) { 224 if (usbvision_write_reg(usbvision, USBVISION_SER_MODE, USBVISION_IIC_LRNACK) < 0) {
225 printk(KERN_ERR "usbvision_register: can't write reg\n"); 225 printk(KERN_ERR "usbvision_i2c_register: can't write reg\n");
226 return -EBUSY; 226 return -EBUSY;
227 } 227 }
228 228
diff --git a/drivers/media/video/usbvision/usbvision-video.c b/drivers/media/video/usbvision/usbvision-video.c
index 9855fbe5927a..ea8ea8a48dfe 100644
--- a/drivers/media/video/usbvision/usbvision-video.c
+++ b/drivers/media/video/usbvision/usbvision-video.c
@@ -1471,7 +1471,8 @@ static void usbvision_configure_video(struct usb_usbvision *usbvision)
1471 1471
1472 /* This should be here to make i2c clients to be able to register */ 1472 /* This should be here to make i2c clients to be able to register */
1473 /* first switch off audio */ 1473 /* first switch off audio */
1474 usbvision_audio_off(usbvision); 1474 if (usbvision_device_data[model].audio_channels > 0)
1475 usbvision_audio_off(usbvision);
1475 if (!power_on_at_open) { 1476 if (!power_on_at_open) {
1476 /* and then power up the noisy tuner */ 1477 /* and then power up the noisy tuner */
1477 usbvision_power_on(usbvision); 1478 usbvision_power_on(usbvision);
diff --git a/drivers/media/video/usbvision/usbvision.h b/drivers/media/video/usbvision/usbvision.h
index 8074787fd1ac..43cf61fe4943 100644
--- a/drivers/media/video/usbvision/usbvision.h
+++ b/drivers/media/video/usbvision/usbvision.h
@@ -59,6 +59,11 @@
59 #define USBVISION_AUDIO_RADIO 2 59 #define USBVISION_AUDIO_RADIO 2
60 #define USBVISION_AUDIO_MUTE 3 60 #define USBVISION_AUDIO_MUTE 3
61#define USBVISION_SER_MODE 0x07 61#define USBVISION_SER_MODE 0x07
62 #define USBVISION_CLK_OUT (1 << 0)
63 #define USBVISION_DAT_IO (1 << 1)
64 #define USBVISION_SENS_OUT (1 << 2)
65 #define USBVISION_SER_MODE_SOFT (0 << 4)
66 #define USBVISION_SER_MODE_SIO (1 << 4)
62#define USBVISION_SER_ADRS 0x08 67#define USBVISION_SER_ADRS 0x08
63#define USBVISION_SER_CONT 0x09 68#define USBVISION_SER_CONT 0x09
64#define USBVISION_SER_DAT1 0x0A 69#define USBVISION_SER_DAT1 0x0A
@@ -328,6 +333,7 @@ struct usbvision_frame {
328 333
329#define CODEC_SAA7113 7113 334#define CODEC_SAA7113 7113
330#define CODEC_SAA7111 7111 335#define CODEC_SAA7111 7111
336#define CODEC_WEBCAM 3000
331#define BRIDGE_NT1003 1003 337#define BRIDGE_NT1003 1003
332#define BRIDGE_NT1004 1004 338#define BRIDGE_NT1004 1004
333#define BRIDGE_NT1005 1005 339#define BRIDGE_NT1005 1005
diff --git a/drivers/media/video/uvc/uvc_ctrl.c b/drivers/media/video/uvc/uvc_ctrl.c
index 59f8a9ad3796..a4db26fa2f53 100644
--- a/drivers/media/video/uvc/uvc_ctrl.c
+++ b/drivers/media/video/uvc/uvc_ctrl.c
@@ -42,281 +42,313 @@ static struct uvc_control_info uvc_ctrls[] = {
42 .selector = UVC_PU_BRIGHTNESS_CONTROL, 42 .selector = UVC_PU_BRIGHTNESS_CONTROL,
43 .index = 0, 43 .index = 0,
44 .size = 2, 44 .size = 2,
45 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE 45 .flags = UVC_CTRL_FLAG_SET_CUR
46 | UVC_CONTROL_RESTORE, 46 | UVC_CTRL_FLAG_GET_RANGE
47 | UVC_CTRL_FLAG_RESTORE,
47 }, 48 },
48 { 49 {
49 .entity = UVC_GUID_UVC_PROCESSING, 50 .entity = UVC_GUID_UVC_PROCESSING,
50 .selector = UVC_PU_CONTRAST_CONTROL, 51 .selector = UVC_PU_CONTRAST_CONTROL,
51 .index = 1, 52 .index = 1,
52 .size = 2, 53 .size = 2,
53 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE 54 .flags = UVC_CTRL_FLAG_SET_CUR
54 | UVC_CONTROL_RESTORE, 55 | UVC_CTRL_FLAG_GET_RANGE
56 | UVC_CTRL_FLAG_RESTORE,
55 }, 57 },
56 { 58 {
57 .entity = UVC_GUID_UVC_PROCESSING, 59 .entity = UVC_GUID_UVC_PROCESSING,
58 .selector = UVC_PU_HUE_CONTROL, 60 .selector = UVC_PU_HUE_CONTROL,
59 .index = 2, 61 .index = 2,
60 .size = 2, 62 .size = 2,
61 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE 63 .flags = UVC_CTRL_FLAG_SET_CUR
62 | UVC_CONTROL_RESTORE | UVC_CONTROL_AUTO_UPDATE, 64 | UVC_CTRL_FLAG_GET_RANGE
65 | UVC_CTRL_FLAG_RESTORE
66 | UVC_CTRL_FLAG_AUTO_UPDATE,
63 }, 67 },
64 { 68 {
65 .entity = UVC_GUID_UVC_PROCESSING, 69 .entity = UVC_GUID_UVC_PROCESSING,
66 .selector = UVC_PU_SATURATION_CONTROL, 70 .selector = UVC_PU_SATURATION_CONTROL,
67 .index = 3, 71 .index = 3,
68 .size = 2, 72 .size = 2,
69 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE 73 .flags = UVC_CTRL_FLAG_SET_CUR
70 | UVC_CONTROL_RESTORE, 74 | UVC_CTRL_FLAG_GET_RANGE
75 | UVC_CTRL_FLAG_RESTORE,
71 }, 76 },
72 { 77 {
73 .entity = UVC_GUID_UVC_PROCESSING, 78 .entity = UVC_GUID_UVC_PROCESSING,
74 .selector = UVC_PU_SHARPNESS_CONTROL, 79 .selector = UVC_PU_SHARPNESS_CONTROL,
75 .index = 4, 80 .index = 4,
76 .size = 2, 81 .size = 2,
77 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE 82 .flags = UVC_CTRL_FLAG_SET_CUR
78 | UVC_CONTROL_RESTORE, 83 | UVC_CTRL_FLAG_GET_RANGE
84 | UVC_CTRL_FLAG_RESTORE,
79 }, 85 },
80 { 86 {
81 .entity = UVC_GUID_UVC_PROCESSING, 87 .entity = UVC_GUID_UVC_PROCESSING,
82 .selector = UVC_PU_GAMMA_CONTROL, 88 .selector = UVC_PU_GAMMA_CONTROL,
83 .index = 5, 89 .index = 5,
84 .size = 2, 90 .size = 2,
85 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE 91 .flags = UVC_CTRL_FLAG_SET_CUR
86 | UVC_CONTROL_RESTORE, 92 | UVC_CTRL_FLAG_GET_RANGE
93 | UVC_CTRL_FLAG_RESTORE,
87 }, 94 },
88 { 95 {
89 .entity = UVC_GUID_UVC_PROCESSING, 96 .entity = UVC_GUID_UVC_PROCESSING,
90 .selector = UVC_PU_WHITE_BALANCE_TEMPERATURE_CONTROL, 97 .selector = UVC_PU_WHITE_BALANCE_TEMPERATURE_CONTROL,
91 .index = 6, 98 .index = 6,
92 .size = 2, 99 .size = 2,
93 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE 100 .flags = UVC_CTRL_FLAG_SET_CUR
94 | UVC_CONTROL_RESTORE | UVC_CONTROL_AUTO_UPDATE, 101 | UVC_CTRL_FLAG_GET_RANGE
102 | UVC_CTRL_FLAG_RESTORE
103 | UVC_CTRL_FLAG_AUTO_UPDATE,
95 }, 104 },
96 { 105 {
97 .entity = UVC_GUID_UVC_PROCESSING, 106 .entity = UVC_GUID_UVC_PROCESSING,
98 .selector = UVC_PU_WHITE_BALANCE_COMPONENT_CONTROL, 107 .selector = UVC_PU_WHITE_BALANCE_COMPONENT_CONTROL,
99 .index = 7, 108 .index = 7,
100 .size = 4, 109 .size = 4,
101 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE 110 .flags = UVC_CTRL_FLAG_SET_CUR
102 | UVC_CONTROL_RESTORE | UVC_CONTROL_AUTO_UPDATE, 111 | UVC_CTRL_FLAG_GET_RANGE
112 | UVC_CTRL_FLAG_RESTORE
113 | UVC_CTRL_FLAG_AUTO_UPDATE,
103 }, 114 },
104 { 115 {
105 .entity = UVC_GUID_UVC_PROCESSING, 116 .entity = UVC_GUID_UVC_PROCESSING,
106 .selector = UVC_PU_BACKLIGHT_COMPENSATION_CONTROL, 117 .selector = UVC_PU_BACKLIGHT_COMPENSATION_CONTROL,
107 .index = 8, 118 .index = 8,
108 .size = 2, 119 .size = 2,
109 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE 120 .flags = UVC_CTRL_FLAG_SET_CUR
110 | UVC_CONTROL_RESTORE, 121 | UVC_CTRL_FLAG_GET_RANGE
122 | UVC_CTRL_FLAG_RESTORE,
111 }, 123 },
112 { 124 {
113 .entity = UVC_GUID_UVC_PROCESSING, 125 .entity = UVC_GUID_UVC_PROCESSING,
114 .selector = UVC_PU_GAIN_CONTROL, 126 .selector = UVC_PU_GAIN_CONTROL,
115 .index = 9, 127 .index = 9,
116 .size = 2, 128 .size = 2,
117 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE 129 .flags = UVC_CTRL_FLAG_SET_CUR
118 | UVC_CONTROL_RESTORE, 130 | UVC_CTRL_FLAG_GET_RANGE
131 | UVC_CTRL_FLAG_RESTORE,
119 }, 132 },
120 { 133 {
121 .entity = UVC_GUID_UVC_PROCESSING, 134 .entity = UVC_GUID_UVC_PROCESSING,
122 .selector = UVC_PU_POWER_LINE_FREQUENCY_CONTROL, 135 .selector = UVC_PU_POWER_LINE_FREQUENCY_CONTROL,
123 .index = 10, 136 .index = 10,
124 .size = 1, 137 .size = 1,
125 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR 138 .flags = UVC_CTRL_FLAG_SET_CUR | UVC_CTRL_FLAG_GET_CUR
126 | UVC_CONTROL_GET_DEF | UVC_CONTROL_RESTORE, 139 | UVC_CTRL_FLAG_GET_DEF | UVC_CTRL_FLAG_RESTORE,
127 }, 140 },
128 { 141 {
129 .entity = UVC_GUID_UVC_PROCESSING, 142 .entity = UVC_GUID_UVC_PROCESSING,
130 .selector = UVC_PU_HUE_AUTO_CONTROL, 143 .selector = UVC_PU_HUE_AUTO_CONTROL,
131 .index = 11, 144 .index = 11,
132 .size = 1, 145 .size = 1,
133 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR 146 .flags = UVC_CTRL_FLAG_SET_CUR | UVC_CTRL_FLAG_GET_CUR
134 | UVC_CONTROL_GET_DEF | UVC_CONTROL_RESTORE, 147 | UVC_CTRL_FLAG_GET_DEF | UVC_CTRL_FLAG_RESTORE,
135 }, 148 },
136 { 149 {
137 .entity = UVC_GUID_UVC_PROCESSING, 150 .entity = UVC_GUID_UVC_PROCESSING,
138 .selector = UVC_PU_WHITE_BALANCE_TEMPERATURE_AUTO_CONTROL, 151 .selector = UVC_PU_WHITE_BALANCE_TEMPERATURE_AUTO_CONTROL,
139 .index = 12, 152 .index = 12,
140 .size = 1, 153 .size = 1,
141 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR 154 .flags = UVC_CTRL_FLAG_SET_CUR | UVC_CTRL_FLAG_GET_CUR
142 | UVC_CONTROL_GET_DEF | UVC_CONTROL_RESTORE, 155 | UVC_CTRL_FLAG_GET_DEF | UVC_CTRL_FLAG_RESTORE,
143 }, 156 },
144 { 157 {
145 .entity = UVC_GUID_UVC_PROCESSING, 158 .entity = UVC_GUID_UVC_PROCESSING,
146 .selector = UVC_PU_WHITE_BALANCE_COMPONENT_AUTO_CONTROL, 159 .selector = UVC_PU_WHITE_BALANCE_COMPONENT_AUTO_CONTROL,
147 .index = 13, 160 .index = 13,
148 .size = 1, 161 .size = 1,
149 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR 162 .flags = UVC_CTRL_FLAG_SET_CUR | UVC_CTRL_FLAG_GET_CUR
150 | UVC_CONTROL_GET_DEF | UVC_CONTROL_RESTORE, 163 | UVC_CTRL_FLAG_GET_DEF | UVC_CTRL_FLAG_RESTORE,
151 }, 164 },
152 { 165 {
153 .entity = UVC_GUID_UVC_PROCESSING, 166 .entity = UVC_GUID_UVC_PROCESSING,
154 .selector = UVC_PU_DIGITAL_MULTIPLIER_CONTROL, 167 .selector = UVC_PU_DIGITAL_MULTIPLIER_CONTROL,
155 .index = 14, 168 .index = 14,
156 .size = 2, 169 .size = 2,
157 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE 170 .flags = UVC_CTRL_FLAG_SET_CUR
158 | UVC_CONTROL_RESTORE, 171 | UVC_CTRL_FLAG_GET_RANGE
172 | UVC_CTRL_FLAG_RESTORE,
159 }, 173 },
160 { 174 {
161 .entity = UVC_GUID_UVC_PROCESSING, 175 .entity = UVC_GUID_UVC_PROCESSING,
162 .selector = UVC_PU_DIGITAL_MULTIPLIER_LIMIT_CONTROL, 176 .selector = UVC_PU_DIGITAL_MULTIPLIER_LIMIT_CONTROL,
163 .index = 15, 177 .index = 15,
164 .size = 2, 178 .size = 2,
165 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE 179 .flags = UVC_CTRL_FLAG_SET_CUR
166 | UVC_CONTROL_RESTORE, 180 | UVC_CTRL_FLAG_GET_RANGE
181 | UVC_CTRL_FLAG_RESTORE,
167 }, 182 },
168 { 183 {
169 .entity = UVC_GUID_UVC_PROCESSING, 184 .entity = UVC_GUID_UVC_PROCESSING,
170 .selector = UVC_PU_ANALOG_VIDEO_STANDARD_CONTROL, 185 .selector = UVC_PU_ANALOG_VIDEO_STANDARD_CONTROL,
171 .index = 16, 186 .index = 16,
172 .size = 1, 187 .size = 1,
173 .flags = UVC_CONTROL_GET_CUR, 188 .flags = UVC_CTRL_FLAG_GET_CUR,
174 }, 189 },
175 { 190 {
176 .entity = UVC_GUID_UVC_PROCESSING, 191 .entity = UVC_GUID_UVC_PROCESSING,
177 .selector = UVC_PU_ANALOG_LOCK_STATUS_CONTROL, 192 .selector = UVC_PU_ANALOG_LOCK_STATUS_CONTROL,
178 .index = 17, 193 .index = 17,
179 .size = 1, 194 .size = 1,
180 .flags = UVC_CONTROL_GET_CUR, 195 .flags = UVC_CTRL_FLAG_GET_CUR,
181 }, 196 },
182 { 197 {
183 .entity = UVC_GUID_UVC_CAMERA, 198 .entity = UVC_GUID_UVC_CAMERA,
184 .selector = UVC_CT_SCANNING_MODE_CONTROL, 199 .selector = UVC_CT_SCANNING_MODE_CONTROL,
185 .index = 0, 200 .index = 0,
186 .size = 1, 201 .size = 1,
187 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR 202 .flags = UVC_CTRL_FLAG_SET_CUR | UVC_CTRL_FLAG_GET_CUR
188 | UVC_CONTROL_RESTORE, 203 | UVC_CTRL_FLAG_RESTORE,
189 }, 204 },
190 { 205 {
191 .entity = UVC_GUID_UVC_CAMERA, 206 .entity = UVC_GUID_UVC_CAMERA,
192 .selector = UVC_CT_AE_MODE_CONTROL, 207 .selector = UVC_CT_AE_MODE_CONTROL,
193 .index = 1, 208 .index = 1,
194 .size = 1, 209 .size = 1,
195 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR 210 .flags = UVC_CTRL_FLAG_SET_CUR | UVC_CTRL_FLAG_GET_CUR
196 | UVC_CONTROL_GET_DEF | UVC_CONTROL_GET_RES 211 | UVC_CTRL_FLAG_GET_DEF | UVC_CTRL_FLAG_GET_RES
197 | UVC_CONTROL_RESTORE, 212 | UVC_CTRL_FLAG_RESTORE,
198 }, 213 },
199 { 214 {
200 .entity = UVC_GUID_UVC_CAMERA, 215 .entity = UVC_GUID_UVC_CAMERA,
201 .selector = UVC_CT_AE_PRIORITY_CONTROL, 216 .selector = UVC_CT_AE_PRIORITY_CONTROL,
202 .index = 2, 217 .index = 2,
203 .size = 1, 218 .size = 1,
204 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR 219 .flags = UVC_CTRL_FLAG_SET_CUR | UVC_CTRL_FLAG_GET_CUR
205 | UVC_CONTROL_RESTORE, 220 | UVC_CTRL_FLAG_RESTORE,
206 }, 221 },
207 { 222 {
208 .entity = UVC_GUID_UVC_CAMERA, 223 .entity = UVC_GUID_UVC_CAMERA,
209 .selector = UVC_CT_EXPOSURE_TIME_ABSOLUTE_CONTROL, 224 .selector = UVC_CT_EXPOSURE_TIME_ABSOLUTE_CONTROL,
210 .index = 3, 225 .index = 3,
211 .size = 4, 226 .size = 4,
212 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE 227 .flags = UVC_CTRL_FLAG_SET_CUR
213 | UVC_CONTROL_RESTORE, 228 | UVC_CTRL_FLAG_GET_RANGE
229 | UVC_CTRL_FLAG_RESTORE,
214 }, 230 },
215 { 231 {
216 .entity = UVC_GUID_UVC_CAMERA, 232 .entity = UVC_GUID_UVC_CAMERA,
217 .selector = UVC_CT_EXPOSURE_TIME_RELATIVE_CONTROL, 233 .selector = UVC_CT_EXPOSURE_TIME_RELATIVE_CONTROL,
218 .index = 4, 234 .index = 4,
219 .size = 1, 235 .size = 1,
220 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_RESTORE, 236 .flags = UVC_CTRL_FLAG_SET_CUR | UVC_CTRL_FLAG_RESTORE,
221 }, 237 },
222 { 238 {
223 .entity = UVC_GUID_UVC_CAMERA, 239 .entity = UVC_GUID_UVC_CAMERA,
224 .selector = UVC_CT_FOCUS_ABSOLUTE_CONTROL, 240 .selector = UVC_CT_FOCUS_ABSOLUTE_CONTROL,
225 .index = 5, 241 .index = 5,
226 .size = 2, 242 .size = 2,
227 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE 243 .flags = UVC_CTRL_FLAG_SET_CUR
228 | UVC_CONTROL_RESTORE | UVC_CONTROL_AUTO_UPDATE, 244 | UVC_CTRL_FLAG_GET_RANGE
245 | UVC_CTRL_FLAG_RESTORE
246 | UVC_CTRL_FLAG_AUTO_UPDATE,
229 }, 247 },
230 { 248 {
231 .entity = UVC_GUID_UVC_CAMERA, 249 .entity = UVC_GUID_UVC_CAMERA,
232 .selector = UVC_CT_FOCUS_RELATIVE_CONTROL, 250 .selector = UVC_CT_FOCUS_RELATIVE_CONTROL,
233 .index = 6, 251 .index = 6,
234 .size = 2, 252 .size = 2,
235 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_MIN 253 .flags = UVC_CTRL_FLAG_SET_CUR | UVC_CTRL_FLAG_GET_MIN
236 | UVC_CONTROL_GET_MAX | UVC_CONTROL_GET_RES 254 | UVC_CTRL_FLAG_GET_MAX | UVC_CTRL_FLAG_GET_RES
237 | UVC_CONTROL_GET_DEF | UVC_CONTROL_AUTO_UPDATE, 255 | UVC_CTRL_FLAG_GET_DEF
256 | UVC_CTRL_FLAG_AUTO_UPDATE,
238 }, 257 },
239 { 258 {
240 .entity = UVC_GUID_UVC_CAMERA, 259 .entity = UVC_GUID_UVC_CAMERA,
241 .selector = UVC_CT_IRIS_ABSOLUTE_CONTROL, 260 .selector = UVC_CT_IRIS_ABSOLUTE_CONTROL,
242 .index = 7, 261 .index = 7,
243 .size = 2, 262 .size = 2,
244 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE 263 .flags = UVC_CTRL_FLAG_SET_CUR
245 | UVC_CONTROL_RESTORE | UVC_CONTROL_AUTO_UPDATE, 264 | UVC_CTRL_FLAG_GET_RANGE
265 | UVC_CTRL_FLAG_RESTORE
266 | UVC_CTRL_FLAG_AUTO_UPDATE,
246 }, 267 },
247 { 268 {
248 .entity = UVC_GUID_UVC_CAMERA, 269 .entity = UVC_GUID_UVC_CAMERA,
249 .selector = UVC_CT_IRIS_RELATIVE_CONTROL, 270 .selector = UVC_CT_IRIS_RELATIVE_CONTROL,
250 .index = 8, 271 .index = 8,
251 .size = 1, 272 .size = 1,
252 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_AUTO_UPDATE, 273 .flags = UVC_CTRL_FLAG_SET_CUR
274 | UVC_CTRL_FLAG_AUTO_UPDATE,
253 }, 275 },
254 { 276 {
255 .entity = UVC_GUID_UVC_CAMERA, 277 .entity = UVC_GUID_UVC_CAMERA,
256 .selector = UVC_CT_ZOOM_ABSOLUTE_CONTROL, 278 .selector = UVC_CT_ZOOM_ABSOLUTE_CONTROL,
257 .index = 9, 279 .index = 9,
258 .size = 2, 280 .size = 2,
259 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE 281 .flags = UVC_CTRL_FLAG_SET_CUR
260 | UVC_CONTROL_RESTORE | UVC_CONTROL_AUTO_UPDATE, 282 | UVC_CTRL_FLAG_GET_RANGE
283 | UVC_CTRL_FLAG_RESTORE
284 | UVC_CTRL_FLAG_AUTO_UPDATE,
261 }, 285 },
262 { 286 {
263 .entity = UVC_GUID_UVC_CAMERA, 287 .entity = UVC_GUID_UVC_CAMERA,
264 .selector = UVC_CT_ZOOM_RELATIVE_CONTROL, 288 .selector = UVC_CT_ZOOM_RELATIVE_CONTROL,
265 .index = 10, 289 .index = 10,
266 .size = 3, 290 .size = 3,
267 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_MIN 291 .flags = UVC_CTRL_FLAG_SET_CUR | UVC_CTRL_FLAG_GET_MIN
268 | UVC_CONTROL_GET_MAX | UVC_CONTROL_GET_RES 292 | UVC_CTRL_FLAG_GET_MAX | UVC_CTRL_FLAG_GET_RES
269 | UVC_CONTROL_GET_DEF | UVC_CONTROL_AUTO_UPDATE, 293 | UVC_CTRL_FLAG_GET_DEF
294 | UVC_CTRL_FLAG_AUTO_UPDATE,
270 }, 295 },
271 { 296 {
272 .entity = UVC_GUID_UVC_CAMERA, 297 .entity = UVC_GUID_UVC_CAMERA,
273 .selector = UVC_CT_PANTILT_ABSOLUTE_CONTROL, 298 .selector = UVC_CT_PANTILT_ABSOLUTE_CONTROL,
274 .index = 11, 299 .index = 11,
275 .size = 8, 300 .size = 8,
276 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE 301 .flags = UVC_CTRL_FLAG_SET_CUR
277 | UVC_CONTROL_RESTORE | UVC_CONTROL_AUTO_UPDATE, 302 | UVC_CTRL_FLAG_GET_RANGE
303 | UVC_CTRL_FLAG_RESTORE
304 | UVC_CTRL_FLAG_AUTO_UPDATE,
278 }, 305 },
279 { 306 {
280 .entity = UVC_GUID_UVC_CAMERA, 307 .entity = UVC_GUID_UVC_CAMERA,
281 .selector = UVC_CT_PANTILT_RELATIVE_CONTROL, 308 .selector = UVC_CT_PANTILT_RELATIVE_CONTROL,
282 .index = 12, 309 .index = 12,
283 .size = 4, 310 .size = 4,
284 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_MIN 311 .flags = UVC_CTRL_FLAG_SET_CUR | UVC_CTRL_FLAG_GET_MIN
285 | UVC_CONTROL_GET_MAX | UVC_CONTROL_GET_RES 312 | UVC_CTRL_FLAG_GET_MAX | UVC_CTRL_FLAG_GET_RES
286 | UVC_CONTROL_GET_DEF | UVC_CONTROL_AUTO_UPDATE, 313 | UVC_CTRL_FLAG_GET_DEF
314 | UVC_CTRL_FLAG_AUTO_UPDATE,
287 }, 315 },
288 { 316 {
289 .entity = UVC_GUID_UVC_CAMERA, 317 .entity = UVC_GUID_UVC_CAMERA,
290 .selector = UVC_CT_ROLL_ABSOLUTE_CONTROL, 318 .selector = UVC_CT_ROLL_ABSOLUTE_CONTROL,
291 .index = 13, 319 .index = 13,
292 .size = 2, 320 .size = 2,
293 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE 321 .flags = UVC_CTRL_FLAG_SET_CUR
294 | UVC_CONTROL_RESTORE | UVC_CONTROL_AUTO_UPDATE, 322 | UVC_CTRL_FLAG_GET_RANGE
323 | UVC_CTRL_FLAG_RESTORE
324 | UVC_CTRL_FLAG_AUTO_UPDATE,
295 }, 325 },
296 { 326 {
297 .entity = UVC_GUID_UVC_CAMERA, 327 .entity = UVC_GUID_UVC_CAMERA,
298 .selector = UVC_CT_ROLL_RELATIVE_CONTROL, 328 .selector = UVC_CT_ROLL_RELATIVE_CONTROL,
299 .index = 14, 329 .index = 14,
300 .size = 2, 330 .size = 2,
301 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_MIN 331 .flags = UVC_CTRL_FLAG_SET_CUR | UVC_CTRL_FLAG_GET_MIN
302 | UVC_CONTROL_GET_MAX | UVC_CONTROL_GET_RES 332 | UVC_CTRL_FLAG_GET_MAX | UVC_CTRL_FLAG_GET_RES
303 | UVC_CONTROL_GET_DEF | UVC_CONTROL_AUTO_UPDATE, 333 | UVC_CTRL_FLAG_GET_DEF
334 | UVC_CTRL_FLAG_AUTO_UPDATE,
304 }, 335 },
305 { 336 {
306 .entity = UVC_GUID_UVC_CAMERA, 337 .entity = UVC_GUID_UVC_CAMERA,
307 .selector = UVC_CT_FOCUS_AUTO_CONTROL, 338 .selector = UVC_CT_FOCUS_AUTO_CONTROL,
308 .index = 17, 339 .index = 17,
309 .size = 1, 340 .size = 1,
310 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR 341 .flags = UVC_CTRL_FLAG_SET_CUR | UVC_CTRL_FLAG_GET_CUR
311 | UVC_CONTROL_GET_DEF | UVC_CONTROL_RESTORE, 342 | UVC_CTRL_FLAG_GET_DEF | UVC_CTRL_FLAG_RESTORE,
312 }, 343 },
313 { 344 {
314 .entity = UVC_GUID_UVC_CAMERA, 345 .entity = UVC_GUID_UVC_CAMERA,
315 .selector = UVC_CT_PRIVACY_CONTROL, 346 .selector = UVC_CT_PRIVACY_CONTROL,
316 .index = 18, 347 .index = 18,
317 .size = 1, 348 .size = 1,
318 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR 349 .flags = UVC_CTRL_FLAG_SET_CUR | UVC_CTRL_FLAG_GET_CUR
319 | UVC_CONTROL_RESTORE | UVC_CONTROL_AUTO_UPDATE, 350 | UVC_CTRL_FLAG_RESTORE
351 | UVC_CTRL_FLAG_AUTO_UPDATE,
320 }, 352 },
321}; 353};
322 354
@@ -816,7 +848,7 @@ static int uvc_ctrl_populate_cache(struct uvc_video_chain *chain,
816{ 848{
817 int ret; 849 int ret;
818 850
819 if (ctrl->info.flags & UVC_CONTROL_GET_DEF) { 851 if (ctrl->info.flags & UVC_CTRL_FLAG_GET_DEF) {
820 ret = uvc_query_ctrl(chain->dev, UVC_GET_DEF, ctrl->entity->id, 852 ret = uvc_query_ctrl(chain->dev, UVC_GET_DEF, ctrl->entity->id,
821 chain->dev->intfnum, ctrl->info.selector, 853 chain->dev->intfnum, ctrl->info.selector,
822 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_DEF), 854 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_DEF),
@@ -825,7 +857,7 @@ static int uvc_ctrl_populate_cache(struct uvc_video_chain *chain,
825 return ret; 857 return ret;
826 } 858 }
827 859
828 if (ctrl->info.flags & UVC_CONTROL_GET_MIN) { 860 if (ctrl->info.flags & UVC_CTRL_FLAG_GET_MIN) {
829 ret = uvc_query_ctrl(chain->dev, UVC_GET_MIN, ctrl->entity->id, 861 ret = uvc_query_ctrl(chain->dev, UVC_GET_MIN, ctrl->entity->id,
830 chain->dev->intfnum, ctrl->info.selector, 862 chain->dev->intfnum, ctrl->info.selector,
831 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MIN), 863 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MIN),
@@ -833,7 +865,7 @@ static int uvc_ctrl_populate_cache(struct uvc_video_chain *chain,
833 if (ret < 0) 865 if (ret < 0)
834 return ret; 866 return ret;
835 } 867 }
836 if (ctrl->info.flags & UVC_CONTROL_GET_MAX) { 868 if (ctrl->info.flags & UVC_CTRL_FLAG_GET_MAX) {
837 ret = uvc_query_ctrl(chain->dev, UVC_GET_MAX, ctrl->entity->id, 869 ret = uvc_query_ctrl(chain->dev, UVC_GET_MAX, ctrl->entity->id,
838 chain->dev->intfnum, ctrl->info.selector, 870 chain->dev->intfnum, ctrl->info.selector,
839 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MAX), 871 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MAX),
@@ -841,7 +873,7 @@ static int uvc_ctrl_populate_cache(struct uvc_video_chain *chain,
841 if (ret < 0) 873 if (ret < 0)
842 return ret; 874 return ret;
843 } 875 }
844 if (ctrl->info.flags & UVC_CONTROL_GET_RES) { 876 if (ctrl->info.flags & UVC_CTRL_FLAG_GET_RES) {
845 ret = uvc_query_ctrl(chain->dev, UVC_GET_RES, ctrl->entity->id, 877 ret = uvc_query_ctrl(chain->dev, UVC_GET_RES, ctrl->entity->id,
846 chain->dev->intfnum, ctrl->info.selector, 878 chain->dev->intfnum, ctrl->info.selector,
847 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_RES), 879 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_RES),
@@ -879,9 +911,9 @@ int uvc_query_v4l2_ctrl(struct uvc_video_chain *chain,
879 strlcpy(v4l2_ctrl->name, mapping->name, sizeof v4l2_ctrl->name); 911 strlcpy(v4l2_ctrl->name, mapping->name, sizeof v4l2_ctrl->name);
880 v4l2_ctrl->flags = 0; 912 v4l2_ctrl->flags = 0;
881 913
882 if (!(ctrl->info.flags & UVC_CONTROL_GET_CUR)) 914 if (!(ctrl->info.flags & UVC_CTRL_FLAG_GET_CUR))
883 v4l2_ctrl->flags |= V4L2_CTRL_FLAG_WRITE_ONLY; 915 v4l2_ctrl->flags |= V4L2_CTRL_FLAG_WRITE_ONLY;
884 if (!(ctrl->info.flags & UVC_CONTROL_SET_CUR)) 916 if (!(ctrl->info.flags & UVC_CTRL_FLAG_SET_CUR))
885 v4l2_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY; 917 v4l2_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
886 918
887 if (!ctrl->cached) { 919 if (!ctrl->cached) {
@@ -890,7 +922,7 @@ int uvc_query_v4l2_ctrl(struct uvc_video_chain *chain,
890 goto done; 922 goto done;
891 } 923 }
892 924
893 if (ctrl->info.flags & UVC_CONTROL_GET_DEF) { 925 if (ctrl->info.flags & UVC_CTRL_FLAG_GET_DEF) {
894 v4l2_ctrl->default_value = mapping->get(mapping, UVC_GET_DEF, 926 v4l2_ctrl->default_value = mapping->get(mapping, UVC_GET_DEF,
895 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_DEF)); 927 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_DEF));
896 } 928 }
@@ -927,15 +959,15 @@ int uvc_query_v4l2_ctrl(struct uvc_video_chain *chain,
927 break; 959 break;
928 } 960 }
929 961
930 if (ctrl->info.flags & UVC_CONTROL_GET_MIN) 962 if (ctrl->info.flags & UVC_CTRL_FLAG_GET_MIN)
931 v4l2_ctrl->minimum = mapping->get(mapping, UVC_GET_MIN, 963 v4l2_ctrl->minimum = mapping->get(mapping, UVC_GET_MIN,
932 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MIN)); 964 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MIN));
933 965
934 if (ctrl->info.flags & UVC_CONTROL_GET_MAX) 966 if (ctrl->info.flags & UVC_CTRL_FLAG_GET_MAX)
935 v4l2_ctrl->maximum = mapping->get(mapping, UVC_GET_MAX, 967 v4l2_ctrl->maximum = mapping->get(mapping, UVC_GET_MAX,
936 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MAX)); 968 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MAX));
937 969
938 if (ctrl->info.flags & UVC_CONTROL_GET_RES) 970 if (ctrl->info.flags & UVC_CTRL_FLAG_GET_RES)
939 v4l2_ctrl->step = mapping->get(mapping, UVC_GET_RES, 971 v4l2_ctrl->step = mapping->get(mapping, UVC_GET_RES,
940 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_RES)); 972 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_RES));
941 973
@@ -983,6 +1015,24 @@ int uvc_query_v4l2_menu(struct uvc_video_chain *chain,
983 } 1015 }
984 1016
985 menu_info = &mapping->menu_info[query_menu->index]; 1017 menu_info = &mapping->menu_info[query_menu->index];
1018
1019 if (ctrl->info.flags & UVC_CTRL_FLAG_GET_RES) {
1020 s32 bitmap;
1021
1022 if (!ctrl->cached) {
1023 ret = uvc_ctrl_populate_cache(chain, ctrl);
1024 if (ret < 0)
1025 goto done;
1026 }
1027
1028 bitmap = mapping->get(mapping, UVC_GET_RES,
1029 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_RES));
1030 if (!(bitmap & menu_info->value)) {
1031 ret = -EINVAL;
1032 goto done;
1033 }
1034 }
1035
986 strlcpy(query_menu->name, menu_info->name, sizeof query_menu->name); 1036 strlcpy(query_menu->name, menu_info->name, sizeof query_menu->name);
987 1037
988done: 1038done:
@@ -1039,7 +1089,7 @@ static int uvc_ctrl_commit_entity(struct uvc_device *dev,
1039 * marked as loaded in uvc_ctrl_get/uvc_ctrl_set to prevent 1089 * marked as loaded in uvc_ctrl_get/uvc_ctrl_set to prevent
1040 * uvc_ctrl_get from using the cached value. 1090 * uvc_ctrl_get from using the cached value.
1041 */ 1091 */
1042 if (ctrl->info.flags & UVC_CONTROL_AUTO_UPDATE) 1092 if (ctrl->info.flags & UVC_CTRL_FLAG_AUTO_UPDATE)
1043 ctrl->loaded = 0; 1093 ctrl->loaded = 0;
1044 1094
1045 if (!ctrl->dirty) 1095 if (!ctrl->dirty)
@@ -1094,7 +1144,7 @@ int uvc_ctrl_get(struct uvc_video_chain *chain,
1094 int ret; 1144 int ret;
1095 1145
1096 ctrl = uvc_find_control(chain, xctrl->id, &mapping); 1146 ctrl = uvc_find_control(chain, xctrl->id, &mapping);
1097 if (ctrl == NULL || (ctrl->info.flags & UVC_CONTROL_GET_CUR) == 0) 1147 if (ctrl == NULL || (ctrl->info.flags & UVC_CTRL_FLAG_GET_CUR) == 0)
1098 return -EINVAL; 1148 return -EINVAL;
1099 1149
1100 if (!ctrl->loaded) { 1150 if (!ctrl->loaded) {
@@ -1136,7 +1186,7 @@ int uvc_ctrl_set(struct uvc_video_chain *chain,
1136 int ret; 1186 int ret;
1137 1187
1138 ctrl = uvc_find_control(chain, xctrl->id, &mapping); 1188 ctrl = uvc_find_control(chain, xctrl->id, &mapping);
1139 if (ctrl == NULL || (ctrl->info.flags & UVC_CONTROL_SET_CUR) == 0) 1189 if (ctrl == NULL || (ctrl->info.flags & UVC_CTRL_FLAG_SET_CUR) == 0)
1140 return -EINVAL; 1190 return -EINVAL;
1141 1191
1142 /* Clamp out of range values. */ 1192 /* Clamp out of range values. */
@@ -1171,6 +1221,23 @@ int uvc_ctrl_set(struct uvc_video_chain *chain,
1171 if (xctrl->value < 0 || xctrl->value >= mapping->menu_count) 1221 if (xctrl->value < 0 || xctrl->value >= mapping->menu_count)
1172 return -ERANGE; 1222 return -ERANGE;
1173 value = mapping->menu_info[xctrl->value].value; 1223 value = mapping->menu_info[xctrl->value].value;
1224
1225 /* Valid menu indices are reported by the GET_RES request for
1226 * UVC controls that support it.
1227 */
1228 if (ctrl->info.flags & UVC_CTRL_FLAG_GET_RES) {
1229 if (!ctrl->cached) {
1230 ret = uvc_ctrl_populate_cache(chain, ctrl);
1231 if (ret < 0)
1232 return ret;
1233 }
1234
1235 step = mapping->get(mapping, UVC_GET_RES,
1236 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_RES));
1237 if (!(step & value))
1238 return -ERANGE;
1239 }
1240
1174 break; 1241 break;
1175 1242
1176 default: 1243 default:
@@ -1183,7 +1250,7 @@ int uvc_ctrl_set(struct uvc_video_chain *chain,
1183 * operation. 1250 * operation.
1184 */ 1251 */
1185 if (!ctrl->loaded && (ctrl->info.size * 8) != mapping->size) { 1252 if (!ctrl->loaded && (ctrl->info.size * 8) != mapping->size) {
1186 if ((ctrl->info.flags & UVC_CONTROL_GET_CUR) == 0) { 1253 if ((ctrl->info.flags & UVC_CTRL_FLAG_GET_CUR) == 0) {
1187 memset(uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT), 1254 memset(uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT),
1188 0, ctrl->info.size); 1255 0, ctrl->info.size);
1189 } else { 1256 } else {
@@ -1230,17 +1297,17 @@ static void uvc_ctrl_fixup_xu_info(struct uvc_device *dev,
1230 1297
1231 static const struct uvc_ctrl_fixup fixups[] = { 1298 static const struct uvc_ctrl_fixup fixups[] = {
1232 { { USB_DEVICE(0x046d, 0x08c2) }, 9, 1, 1299 { { USB_DEVICE(0x046d, 0x08c2) }, 9, 1,
1233 UVC_CONTROL_GET_MIN | UVC_CONTROL_GET_MAX | 1300 UVC_CTRL_FLAG_GET_MIN | UVC_CTRL_FLAG_GET_MAX |
1234 UVC_CONTROL_GET_DEF | UVC_CONTROL_SET_CUR | 1301 UVC_CTRL_FLAG_GET_DEF | UVC_CTRL_FLAG_SET_CUR |
1235 UVC_CONTROL_AUTO_UPDATE }, 1302 UVC_CTRL_FLAG_AUTO_UPDATE },
1236 { { USB_DEVICE(0x046d, 0x08cc) }, 9, 1, 1303 { { USB_DEVICE(0x046d, 0x08cc) }, 9, 1,
1237 UVC_CONTROL_GET_MIN | UVC_CONTROL_GET_MAX | 1304 UVC_CTRL_FLAG_GET_MIN | UVC_CTRL_FLAG_GET_MAX |
1238 UVC_CONTROL_GET_DEF | UVC_CONTROL_SET_CUR | 1305 UVC_CTRL_FLAG_GET_DEF | UVC_CTRL_FLAG_SET_CUR |
1239 UVC_CONTROL_AUTO_UPDATE }, 1306 UVC_CTRL_FLAG_AUTO_UPDATE },
1240 { { USB_DEVICE(0x046d, 0x0994) }, 9, 1, 1307 { { USB_DEVICE(0x046d, 0x0994) }, 9, 1,
1241 UVC_CONTROL_GET_MIN | UVC_CONTROL_GET_MAX | 1308 UVC_CTRL_FLAG_GET_MIN | UVC_CTRL_FLAG_GET_MAX |
1242 UVC_CONTROL_GET_DEF | UVC_CONTROL_SET_CUR | 1309 UVC_CTRL_FLAG_GET_DEF | UVC_CTRL_FLAG_SET_CUR |
1243 UVC_CONTROL_AUTO_UPDATE }, 1310 UVC_CTRL_FLAG_AUTO_UPDATE },
1244 }; 1311 };
1245 1312
1246 unsigned int i; 1313 unsigned int i;
@@ -1297,21 +1364,23 @@ static int uvc_ctrl_fill_xu_info(struct uvc_device *dev,
1297 goto done; 1364 goto done;
1298 } 1365 }
1299 1366
1300 info->flags = UVC_CONTROL_GET_MIN | UVC_CONTROL_GET_MAX 1367 info->flags = UVC_CTRL_FLAG_GET_MIN | UVC_CTRL_FLAG_GET_MAX
1301 | UVC_CONTROL_GET_RES | UVC_CONTROL_GET_DEF 1368 | UVC_CTRL_FLAG_GET_RES | UVC_CTRL_FLAG_GET_DEF
1302 | (data[0] & UVC_CONTROL_CAP_GET ? UVC_CONTROL_GET_CUR : 0) 1369 | (data[0] & UVC_CONTROL_CAP_GET ?
1303 | (data[0] & UVC_CONTROL_CAP_SET ? UVC_CONTROL_SET_CUR : 0) 1370 UVC_CTRL_FLAG_GET_CUR : 0)
1371 | (data[0] & UVC_CONTROL_CAP_SET ?
1372 UVC_CTRL_FLAG_SET_CUR : 0)
1304 | (data[0] & UVC_CONTROL_CAP_AUTOUPDATE ? 1373 | (data[0] & UVC_CONTROL_CAP_AUTOUPDATE ?
1305 UVC_CONTROL_AUTO_UPDATE : 0); 1374 UVC_CTRL_FLAG_AUTO_UPDATE : 0);
1306 1375
1307 uvc_ctrl_fixup_xu_info(dev, ctrl, info); 1376 uvc_ctrl_fixup_xu_info(dev, ctrl, info);
1308 1377
1309 uvc_trace(UVC_TRACE_CONTROL, "XU control %pUl/%u queried: len %u, " 1378 uvc_trace(UVC_TRACE_CONTROL, "XU control %pUl/%u queried: len %u, "
1310 "flags { get %u set %u auto %u }.\n", 1379 "flags { get %u set %u auto %u }.\n",
1311 info->entity, info->selector, info->size, 1380 info->entity, info->selector, info->size,
1312 (info->flags & UVC_CONTROL_GET_CUR) ? 1 : 0, 1381 (info->flags & UVC_CTRL_FLAG_GET_CUR) ? 1 : 0,
1313 (info->flags & UVC_CONTROL_SET_CUR) ? 1 : 0, 1382 (info->flags & UVC_CTRL_FLAG_SET_CUR) ? 1 : 0,
1314 (info->flags & UVC_CONTROL_AUTO_UPDATE) ? 1 : 0); 1383 (info->flags & UVC_CTRL_FLAG_AUTO_UPDATE) ? 1 : 0);
1315 1384
1316done: 1385done:
1317 kfree(data); 1386 kfree(data);
@@ -1344,32 +1413,33 @@ static int uvc_ctrl_init_xu_ctrl(struct uvc_device *dev,
1344} 1413}
1345 1414
1346int uvc_xu_ctrl_query(struct uvc_video_chain *chain, 1415int uvc_xu_ctrl_query(struct uvc_video_chain *chain,
1347 struct uvc_xu_control *xctrl, int set) 1416 struct uvc_xu_control_query *xqry)
1348{ 1417{
1349 struct uvc_entity *entity; 1418 struct uvc_entity *entity;
1350 struct uvc_control *ctrl = NULL; 1419 struct uvc_control *ctrl;
1351 unsigned int i, found = 0; 1420 unsigned int i, found = 0;
1352 int restore = 0; 1421 __u32 reqflags;
1353 __u8 *data; 1422 __u16 size;
1423 __u8 *data = NULL;
1354 int ret; 1424 int ret;
1355 1425
1356 /* Find the extension unit. */ 1426 /* Find the extension unit. */
1357 list_for_each_entry(entity, &chain->entities, chain) { 1427 list_for_each_entry(entity, &chain->entities, chain) {
1358 if (UVC_ENTITY_TYPE(entity) == UVC_VC_EXTENSION_UNIT && 1428 if (UVC_ENTITY_TYPE(entity) == UVC_VC_EXTENSION_UNIT &&
1359 entity->id == xctrl->unit) 1429 entity->id == xqry->unit)
1360 break; 1430 break;
1361 } 1431 }
1362 1432
1363 if (entity->id != xctrl->unit) { 1433 if (entity->id != xqry->unit) {
1364 uvc_trace(UVC_TRACE_CONTROL, "Extension unit %u not found.\n", 1434 uvc_trace(UVC_TRACE_CONTROL, "Extension unit %u not found.\n",
1365 xctrl->unit); 1435 xqry->unit);
1366 return -EINVAL; 1436 return -ENOENT;
1367 } 1437 }
1368 1438
1369 /* Find the control and perform delayed initialization if needed. */ 1439 /* Find the control and perform delayed initialization if needed. */
1370 for (i = 0; i < entity->ncontrols; ++i) { 1440 for (i = 0; i < entity->ncontrols; ++i) {
1371 ctrl = &entity->controls[i]; 1441 ctrl = &entity->controls[i];
1372 if (ctrl->index == xctrl->selector - 1) { 1442 if (ctrl->index == xqry->selector - 1) {
1373 found = 1; 1443 found = 1;
1374 break; 1444 break;
1375 } 1445 }
@@ -1377,8 +1447,8 @@ int uvc_xu_ctrl_query(struct uvc_video_chain *chain,
1377 1447
1378 if (!found) { 1448 if (!found) {
1379 uvc_trace(UVC_TRACE_CONTROL, "Control %pUl/%u not found.\n", 1449 uvc_trace(UVC_TRACE_CONTROL, "Control %pUl/%u not found.\n",
1380 entity->extension.guidExtensionCode, xctrl->selector); 1450 entity->extension.guidExtensionCode, xqry->selector);
1381 return -EINVAL; 1451 return -ENOENT;
1382 } 1452 }
1383 1453
1384 if (mutex_lock_interruptible(&chain->ctrl_mutex)) 1454 if (mutex_lock_interruptible(&chain->ctrl_mutex))
@@ -1390,43 +1460,72 @@ int uvc_xu_ctrl_query(struct uvc_video_chain *chain,
1390 goto done; 1460 goto done;
1391 } 1461 }
1392 1462
1393 /* Validate control data size. */ 1463 /* Validate the required buffer size and flags for the request */
1394 if (ctrl->info.size != xctrl->size) { 1464 reqflags = 0;
1465 size = ctrl->info.size;
1466
1467 switch (xqry->query) {
1468 case UVC_GET_CUR:
1469 reqflags = UVC_CTRL_FLAG_GET_CUR;
1470 break;
1471 case UVC_GET_MIN:
1472 reqflags = UVC_CTRL_FLAG_GET_MIN;
1473 break;
1474 case UVC_GET_MAX:
1475 reqflags = UVC_CTRL_FLAG_GET_MAX;
1476 break;
1477 case UVC_GET_DEF:
1478 reqflags = UVC_CTRL_FLAG_GET_DEF;
1479 break;
1480 case UVC_GET_RES:
1481 reqflags = UVC_CTRL_FLAG_GET_RES;
1482 break;
1483 case UVC_SET_CUR:
1484 reqflags = UVC_CTRL_FLAG_SET_CUR;
1485 break;
1486 case UVC_GET_LEN:
1487 size = 2;
1488 break;
1489 case UVC_GET_INFO:
1490 size = 1;
1491 break;
1492 default:
1395 ret = -EINVAL; 1493 ret = -EINVAL;
1396 goto done; 1494 goto done;
1397 } 1495 }
1398 1496
1399 if ((set && !(ctrl->info.flags & UVC_CONTROL_SET_CUR)) || 1497 if (size != xqry->size) {
1400 (!set && !(ctrl->info.flags & UVC_CONTROL_GET_CUR))) { 1498 ret = -ENOBUFS;
1401 ret = -EINVAL;
1402 goto done; 1499 goto done;
1403 } 1500 }
1404 1501
1405 memcpy(uvc_ctrl_data(ctrl, UVC_CTRL_DATA_BACKUP), 1502 if (reqflags && !(ctrl->info.flags & reqflags)) {
1406 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT), 1503 ret = -EBADRQC;
1407 ctrl->info.size); 1504 goto done;
1408 data = uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT); 1505 }
1409 restore = set;
1410 1506
1411 if (set && copy_from_user(data, xctrl->data, xctrl->size)) { 1507 data = kmalloc(size, GFP_KERNEL);
1508 if (data == NULL) {
1509 ret = -ENOMEM;
1510 goto done;
1511 }
1512
1513 if (xqry->query == UVC_SET_CUR &&
1514 copy_from_user(data, xqry->data, size)) {
1412 ret = -EFAULT; 1515 ret = -EFAULT;
1413 goto done; 1516 goto done;
1414 } 1517 }
1415 1518
1416 ret = uvc_query_ctrl(chain->dev, set ? UVC_SET_CUR : UVC_GET_CUR, 1519 ret = uvc_query_ctrl(chain->dev, xqry->query, xqry->unit,
1417 xctrl->unit, chain->dev->intfnum, xctrl->selector, 1520 chain->dev->intfnum, xqry->selector, data, size);
1418 data, xctrl->size);
1419 if (ret < 0) 1521 if (ret < 0)
1420 goto done; 1522 goto done;
1421 1523
1422 if (!set && copy_to_user(xctrl->data, data, xctrl->size)) 1524 if (xqry->query != UVC_SET_CUR &&
1525 copy_to_user(xqry->data, data, size))
1423 ret = -EFAULT; 1526 ret = -EFAULT;
1424done: 1527done:
1425 if (ret && restore) 1528 kfree(data);
1426 memcpy(uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT),
1427 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_BACKUP),
1428 xctrl->size);
1429
1430 mutex_unlock(&chain->ctrl_mutex); 1529 mutex_unlock(&chain->ctrl_mutex);
1431 return ret; 1530 return ret;
1432} 1531}
@@ -1458,7 +1557,7 @@ int uvc_ctrl_resume_device(struct uvc_device *dev)
1458 ctrl = &entity->controls[i]; 1557 ctrl = &entity->controls[i];
1459 1558
1460 if (!ctrl->initialized || !ctrl->modified || 1559 if (!ctrl->initialized || !ctrl->modified ||
1461 (ctrl->info.flags & UVC_CONTROL_RESTORE) == 0) 1560 (ctrl->info.flags & UVC_CTRL_FLAG_RESTORE) == 0)
1462 continue; 1561 continue;
1463 1562
1464 printk(KERN_INFO "restoring control %pUl/%u/%u\n", 1563 printk(KERN_INFO "restoring control %pUl/%u/%u\n",
diff --git a/drivers/media/video/uvc/uvc_driver.c b/drivers/media/video/uvc/uvc_driver.c
index 6459b8cba223..823f4b389745 100644
--- a/drivers/media/video/uvc/uvc_driver.c
+++ b/drivers/media/video/uvc/uvc_driver.c
@@ -84,6 +84,11 @@ static struct uvc_format_desc uvc_fmts[] = {
84 .fcc = V4L2_PIX_FMT_YUV420, 84 .fcc = V4L2_PIX_FMT_YUV420,
85 }, 85 },
86 { 86 {
87 .name = "YUV 4:2:0 (M420)",
88 .guid = UVC_GUID_FORMAT_M420,
89 .fcc = V4L2_PIX_FMT_M420,
90 },
91 {
87 .name = "YUV 4:2:2 (UYVY)", 92 .name = "YUV 4:2:2 (UYVY)",
88 .guid = UVC_GUID_FORMAT_UYVY, 93 .guid = UVC_GUID_FORMAT_UYVY,
89 .fcc = V4L2_PIX_FMT_UYVY, 94 .fcc = V4L2_PIX_FMT_UYVY,
@@ -103,6 +108,11 @@ static struct uvc_format_desc uvc_fmts[] = {
103 .guid = UVC_GUID_FORMAT_BY8, 108 .guid = UVC_GUID_FORMAT_BY8,
104 .fcc = V4L2_PIX_FMT_SBGGR8, 109 .fcc = V4L2_PIX_FMT_SBGGR8,
105 }, 110 },
111 {
112 .name = "RGB565",
113 .guid = UVC_GUID_FORMAT_RGBP,
114 .fcc = V4L2_PIX_FMT_RGB565,
115 },
106}; 116};
107 117
108/* ------------------------------------------------------------------------ 118/* ------------------------------------------------------------------------
@@ -2077,6 +2087,15 @@ static struct usb_device_id uvc_ids[] = {
2077 .bInterfaceSubClass = 1, 2087 .bInterfaceSubClass = 1,
2078 .bInterfaceProtocol = 0, 2088 .bInterfaceProtocol = 0,
2079 .driver_info = UVC_QUIRK_STREAM_NO_FID }, 2089 .driver_info = UVC_QUIRK_STREAM_NO_FID },
2090 /* Hercules Classic Silver */
2091 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2092 | USB_DEVICE_ID_MATCH_INT_INFO,
2093 .idVendor = 0x06f8,
2094 .idProduct = 0x300c,
2095 .bInterfaceClass = USB_CLASS_VIDEO,
2096 .bInterfaceSubClass = 1,
2097 .bInterfaceProtocol = 0,
2098 .driver_info = UVC_QUIRK_FIX_BANDWIDTH },
2080 /* ViMicro Vega */ 2099 /* ViMicro Vega */
2081 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE 2100 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2082 | USB_DEVICE_ID_MATCH_INT_INFO, 2101 | USB_DEVICE_ID_MATCH_INT_INFO,
@@ -2123,6 +2142,15 @@ static struct usb_device_id uvc_ids[] = {
2123 .bInterfaceSubClass = 1, 2142 .bInterfaceSubClass = 1,
2124 .bInterfaceProtocol = 0, 2143 .bInterfaceProtocol = 0,
2125 .driver_info = UVC_QUIRK_STREAM_NO_FID }, 2144 .driver_info = UVC_QUIRK_STREAM_NO_FID },
2145 /* JMicron USB2.0 XGA WebCam */
2146 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2147 | USB_DEVICE_ID_MATCH_INT_INFO,
2148 .idVendor = 0x152d,
2149 .idProduct = 0x0310,
2150 .bInterfaceClass = USB_CLASS_VIDEO,
2151 .bInterfaceSubClass = 1,
2152 .bInterfaceProtocol = 0,
2153 .driver_info = UVC_QUIRK_PROBE_MINMAX },
2126 /* Syntek (HP Spartan) */ 2154 /* Syntek (HP Spartan) */
2127 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE 2155 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2128 | USB_DEVICE_ID_MATCH_INT_INFO, 2156 | USB_DEVICE_ID_MATCH_INT_INFO,
diff --git a/drivers/media/video/uvc/uvc_queue.c b/drivers/media/video/uvc/uvc_queue.c
index f14581bd707f..109a06384a8f 100644
--- a/drivers/media/video/uvc/uvc_queue.c
+++ b/drivers/media/video/uvc/uvc_queue.c
@@ -424,7 +424,7 @@ int uvc_queue_mmap(struct uvc_video_queue *queue, struct vm_area_struct *vma)
424 break; 424 break;
425 } 425 }
426 426
427 if (i == queue->count || size != queue->buf_size) { 427 if (i == queue->count || PAGE_ALIGN(size) != queue->buf_size) {
428 ret = -EINVAL; 428 ret = -EINVAL;
429 goto done; 429 goto done;
430 } 430 }
@@ -436,6 +436,7 @@ int uvc_queue_mmap(struct uvc_video_queue *queue, struct vm_area_struct *vma)
436 vma->vm_flags |= VM_IO; 436 vma->vm_flags |= VM_IO;
437 437
438 addr = (unsigned long)queue->mem + buffer->buf.m.offset; 438 addr = (unsigned long)queue->mem + buffer->buf.m.offset;
439#ifdef CONFIG_MMU
439 while (size > 0) { 440 while (size > 0) {
440 page = vmalloc_to_page((void *)addr); 441 page = vmalloc_to_page((void *)addr);
441 if ((ret = vm_insert_page(vma, start, page)) < 0) 442 if ((ret = vm_insert_page(vma, start, page)) < 0)
@@ -445,6 +446,7 @@ int uvc_queue_mmap(struct uvc_video_queue *queue, struct vm_area_struct *vma)
445 addr += PAGE_SIZE; 446 addr += PAGE_SIZE;
446 size -= PAGE_SIZE; 447 size -= PAGE_SIZE;
447 } 448 }
449#endif
448 450
449 vma->vm_ops = &uvc_vm_ops; 451 vma->vm_ops = &uvc_vm_ops;
450 vma->vm_private_data = buffer; 452 vma->vm_private_data = buffer;
@@ -488,6 +490,36 @@ done:
488 return mask; 490 return mask;
489} 491}
490 492
493#ifndef CONFIG_MMU
494/*
495 * Get unmapped area.
496 *
497 * NO-MMU arch need this function to make mmap() work correctly.
498 */
499unsigned long uvc_queue_get_unmapped_area(struct uvc_video_queue *queue,
500 unsigned long pgoff)
501{
502 struct uvc_buffer *buffer;
503 unsigned int i;
504 unsigned long ret;
505
506 mutex_lock(&queue->mutex);
507 for (i = 0; i < queue->count; ++i) {
508 buffer = &queue->buffer[i];
509 if ((buffer->buf.m.offset >> PAGE_SHIFT) == pgoff)
510 break;
511 }
512 if (i == queue->count) {
513 ret = -EINVAL;
514 goto done;
515 }
516 ret = (unsigned long)queue->mem + buffer->buf.m.offset;
517done:
518 mutex_unlock(&queue->mutex);
519 return ret;
520}
521#endif
522
491/* 523/*
492 * Enable or disable the video buffers queue. 524 * Enable or disable the video buffers queue.
493 * 525 *
diff --git a/drivers/media/video/uvc/uvc_v4l2.c b/drivers/media/video/uvc/uvc_v4l2.c
index 9005a8d9d5f8..543a80395b7f 100644
--- a/drivers/media/video/uvc/uvc_v4l2.c
+++ b/drivers/media/video/uvc/uvc_v4l2.c
@@ -538,6 +538,20 @@ static int uvc_v4l2_release(struct file *file)
538 return 0; 538 return 0;
539} 539}
540 540
541static void uvc_v4l2_ioctl_warn(void)
542{
543 static int warned;
544
545 if (warned)
546 return;
547
548 uvc_printk(KERN_INFO, "Deprecated UVCIOC_CTRL_{ADD,MAP_OLD,GET,SET} "
549 "ioctls will be removed in 2.6.42.\n");
550 uvc_printk(KERN_INFO, "See http://www.ideasonboard.org/uvc/upgrade/ "
551 "for upgrade instructions.\n");
552 warned = 1;
553}
554
541static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) 555static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
542{ 556{
543 struct video_device *vdev = video_devdata(file); 557 struct video_device *vdev = video_devdata(file);
@@ -1018,21 +1032,40 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
1018 uvc_trace(UVC_TRACE_IOCTL, "Unsupported ioctl 0x%08x\n", cmd); 1032 uvc_trace(UVC_TRACE_IOCTL, "Unsupported ioctl 0x%08x\n", cmd);
1019 return -EINVAL; 1033 return -EINVAL;
1020 1034
1021 /* Dynamic controls. */ 1035 /* Dynamic controls. UVCIOC_CTRL_ADD, UVCIOC_CTRL_MAP_OLD,
1022 case UVCIOC_CTRL_ADD: 1036 * UVCIOC_CTRL_GET and UVCIOC_CTRL_SET are deprecated and scheduled for
1023 /* Legacy ioctl, kept for API compatibility reasons */ 1037 * removal in 2.6.42.
1038 */
1039 case __UVCIOC_CTRL_ADD:
1040 uvc_v4l2_ioctl_warn();
1024 return -EEXIST; 1041 return -EEXIST;
1025 1042
1026 case UVCIOC_CTRL_MAP_OLD: 1043 case __UVCIOC_CTRL_MAP_OLD:
1044 uvc_v4l2_ioctl_warn();
1045 case __UVCIOC_CTRL_MAP:
1027 case UVCIOC_CTRL_MAP: 1046 case UVCIOC_CTRL_MAP:
1028 return uvc_ioctl_ctrl_map(chain, arg, 1047 return uvc_ioctl_ctrl_map(chain, arg,
1029 cmd == UVCIOC_CTRL_MAP_OLD); 1048 cmd == __UVCIOC_CTRL_MAP_OLD);
1030 1049
1031 case UVCIOC_CTRL_GET: 1050 case __UVCIOC_CTRL_GET:
1032 return uvc_xu_ctrl_query(chain, arg, 0); 1051 case __UVCIOC_CTRL_SET:
1052 {
1053 struct uvc_xu_control *xctrl = arg;
1054 struct uvc_xu_control_query xqry = {
1055 .unit = xctrl->unit,
1056 .selector = xctrl->selector,
1057 .query = cmd == __UVCIOC_CTRL_GET
1058 ? UVC_GET_CUR : UVC_SET_CUR,
1059 .size = xctrl->size,
1060 .data = xctrl->data,
1061 };
1062
1063 uvc_v4l2_ioctl_warn();
1064 return uvc_xu_ctrl_query(chain, &xqry);
1065 }
1033 1066
1034 case UVCIOC_CTRL_SET: 1067 case UVCIOC_CTRL_QUERY:
1035 return uvc_xu_ctrl_query(chain, arg, 1); 1068 return uvc_xu_ctrl_query(chain, arg);
1036 1069
1037 default: 1070 default:
1038 uvc_trace(UVC_TRACE_IOCTL, "Unknown ioctl 0x%08x\n", cmd); 1071 uvc_trace(UVC_TRACE_IOCTL, "Unknown ioctl 0x%08x\n", cmd);
@@ -1081,6 +1114,20 @@ static unsigned int uvc_v4l2_poll(struct file *file, poll_table *wait)
1081 return uvc_queue_poll(&stream->queue, file, wait); 1114 return uvc_queue_poll(&stream->queue, file, wait);
1082} 1115}
1083 1116
1117#ifndef CONFIG_MMU
1118static unsigned long uvc_v4l2_get_unmapped_area(struct file *file,
1119 unsigned long addr, unsigned long len, unsigned long pgoff,
1120 unsigned long flags)
1121{
1122 struct uvc_fh *handle = file->private_data;
1123 struct uvc_streaming *stream = handle->stream;
1124
1125 uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_get_unmapped_area\n");
1126
1127 return uvc_queue_get_unmapped_area(&stream->queue, pgoff);
1128}
1129#endif
1130
1084const struct v4l2_file_operations uvc_fops = { 1131const struct v4l2_file_operations uvc_fops = {
1085 .owner = THIS_MODULE, 1132 .owner = THIS_MODULE,
1086 .open = uvc_v4l2_open, 1133 .open = uvc_v4l2_open,
@@ -1089,5 +1136,8 @@ const struct v4l2_file_operations uvc_fops = {
1089 .read = uvc_v4l2_read, 1136 .read = uvc_v4l2_read,
1090 .mmap = uvc_v4l2_mmap, 1137 .mmap = uvc_v4l2_mmap,
1091 .poll = uvc_v4l2_poll, 1138 .poll = uvc_v4l2_poll,
1139#ifndef CONFIG_MMU
1140 .get_unmapped_area = uvc_v4l2_get_unmapped_area,
1141#endif
1092}; 1142};
1093 1143
diff --git a/drivers/media/video/uvc/uvcvideo.h b/drivers/media/video/uvc/uvcvideo.h
index 45f01e7e13d2..7cf224bae2e5 100644
--- a/drivers/media/video/uvc/uvcvideo.h
+++ b/drivers/media/video/uvc/uvcvideo.h
@@ -4,6 +4,14 @@
4#include <linux/kernel.h> 4#include <linux/kernel.h>
5#include <linux/videodev2.h> 5#include <linux/videodev2.h>
6 6
7#ifndef __KERNEL__
8/*
9 * This header provides binary compatibility with applications using the private
10 * uvcvideo API. This API is deprecated and will be removed in 2.6.42.
11 * Applications should be recompiled against the public linux/uvcvideo.h header.
12 */
13#warn "The uvcvideo.h header is deprecated, use linux/uvcvideo.h instead."
14
7/* 15/*
8 * Dynamic controls 16 * Dynamic controls
9 */ 17 */
@@ -23,32 +31,18 @@
23#define UVC_CONTROL_GET_MAX (1 << 3) 31#define UVC_CONTROL_GET_MAX (1 << 3)
24#define UVC_CONTROL_GET_RES (1 << 4) 32#define UVC_CONTROL_GET_RES (1 << 4)
25#define UVC_CONTROL_GET_DEF (1 << 5) 33#define UVC_CONTROL_GET_DEF (1 << 5)
26/* Control should be saved at suspend and restored at resume. */
27#define UVC_CONTROL_RESTORE (1 << 6) 34#define UVC_CONTROL_RESTORE (1 << 6)
28/* Control can be updated by the camera. */
29#define UVC_CONTROL_AUTO_UPDATE (1 << 7) 35#define UVC_CONTROL_AUTO_UPDATE (1 << 7)
30 36
31#define UVC_CONTROL_GET_RANGE (UVC_CONTROL_GET_CUR | UVC_CONTROL_GET_MIN | \ 37#define UVC_CONTROL_GET_RANGE (UVC_CONTROL_GET_CUR | UVC_CONTROL_GET_MIN | \
32 UVC_CONTROL_GET_MAX | UVC_CONTROL_GET_RES | \ 38 UVC_CONTROL_GET_MAX | UVC_CONTROL_GET_RES | \
33 UVC_CONTROL_GET_DEF) 39 UVC_CONTROL_GET_DEF)
34 40
35struct uvc_xu_control_info {
36 __u8 entity[16];
37 __u8 index;
38 __u8 selector;
39 __u16 size;
40 __u32 flags;
41};
42
43struct uvc_menu_info { 41struct uvc_menu_info {
44 __u32 value; 42 __u32 value;
45 __u8 name[32]; 43 __u8 name[32];
46}; 44};
47 45
48struct uvc_xu_control_mapping_old {
49 __u8 reserved[64];
50};
51
52struct uvc_xu_control_mapping { 46struct uvc_xu_control_mapping {
53 __u32 id; 47 __u32 id;
54 __u8 name[32]; 48 __u8 name[32];
@@ -57,7 +51,7 @@ struct uvc_xu_control_mapping {
57 51
58 __u8 size; 52 __u8 size;
59 __u8 offset; 53 __u8 offset;
60 enum v4l2_ctrl_type v4l2_type; 54 __u32 v4l2_type;
61 __u32 data_type; 55 __u32 data_type;
62 56
63 struct uvc_menu_info __user *menu_info; 57 struct uvc_menu_info __user *menu_info;
@@ -66,6 +60,20 @@ struct uvc_xu_control_mapping {
66 __u32 reserved[4]; 60 __u32 reserved[4];
67}; 61};
68 62
63#endif
64
65struct uvc_xu_control_info {
66 __u8 entity[16];
67 __u8 index;
68 __u8 selector;
69 __u16 size;
70 __u32 flags;
71};
72
73struct uvc_xu_control_mapping_old {
74 __u8 reserved[64];
75};
76
69struct uvc_xu_control { 77struct uvc_xu_control {
70 __u8 unit; 78 __u8 unit;
71 __u8 selector; 79 __u8 selector;
@@ -73,16 +81,25 @@ struct uvc_xu_control {
73 __u8 __user *data; 81 __u8 __user *data;
74}; 82};
75 83
84#ifndef __KERNEL__
76#define UVCIOC_CTRL_ADD _IOW('U', 1, struct uvc_xu_control_info) 85#define UVCIOC_CTRL_ADD _IOW('U', 1, struct uvc_xu_control_info)
77#define UVCIOC_CTRL_MAP_OLD _IOWR('U', 2, struct uvc_xu_control_mapping_old) 86#define UVCIOC_CTRL_MAP_OLD _IOWR('U', 2, struct uvc_xu_control_mapping_old)
78#define UVCIOC_CTRL_MAP _IOWR('U', 2, struct uvc_xu_control_mapping) 87#define UVCIOC_CTRL_MAP _IOWR('U', 2, struct uvc_xu_control_mapping)
79#define UVCIOC_CTRL_GET _IOWR('U', 3, struct uvc_xu_control) 88#define UVCIOC_CTRL_GET _IOWR('U', 3, struct uvc_xu_control)
80#define UVCIOC_CTRL_SET _IOW('U', 4, struct uvc_xu_control) 89#define UVCIOC_CTRL_SET _IOW('U', 4, struct uvc_xu_control)
90#else
91#define __UVCIOC_CTRL_ADD _IOW('U', 1, struct uvc_xu_control_info)
92#define __UVCIOC_CTRL_MAP_OLD _IOWR('U', 2, struct uvc_xu_control_mapping_old)
93#define __UVCIOC_CTRL_MAP _IOWR('U', 2, struct uvc_xu_control_mapping)
94#define __UVCIOC_CTRL_GET _IOWR('U', 3, struct uvc_xu_control)
95#define __UVCIOC_CTRL_SET _IOW('U', 4, struct uvc_xu_control)
96#endif
81 97
82#ifdef __KERNEL__ 98#ifdef __KERNEL__
83 99
84#include <linux/poll.h> 100#include <linux/poll.h>
85#include <linux/usb/video.h> 101#include <linux/usb/video.h>
102#include <linux/uvcvideo.h>
86 103
87/* -------------------------------------------------------------------------- 104/* --------------------------------------------------------------------------
88 * UVC constants 105 * UVC constants
@@ -152,13 +169,19 @@ struct uvc_xu_control {
152#define UVC_GUID_FORMAT_BY8 \ 169#define UVC_GUID_FORMAT_BY8 \
153 { 'B', 'Y', '8', ' ', 0x00, 0x00, 0x10, 0x00, \ 170 { 'B', 'Y', '8', ' ', 0x00, 0x00, 0x10, 0x00, \
154 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} 171 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
172#define UVC_GUID_FORMAT_RGBP \
173 { 'R', 'G', 'B', 'P', 0x00, 0x00, 0x10, 0x00, \
174 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
175#define UVC_GUID_FORMAT_M420 \
176 { 'M', '4', '2', '0', 0x00, 0x00, 0x10, 0x00, \
177 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
155 178
156/* ------------------------------------------------------------------------ 179/* ------------------------------------------------------------------------
157 * Driver specific constants. 180 * Driver specific constants.
158 */ 181 */
159 182
160#define DRIVER_VERSION_NUMBER KERNEL_VERSION(1, 0, 0) 183#define DRIVER_VERSION_NUMBER KERNEL_VERSION(1, 1, 0)
161#define DRIVER_VERSION "v1.0.0" 184#define DRIVER_VERSION "v1.1.0"
162 185
163/* Number of isochronous URBs. */ 186/* Number of isochronous URBs. */
164#define UVC_URBS 5 187#define UVC_URBS 5
@@ -580,6 +603,10 @@ extern int uvc_queue_mmap(struct uvc_video_queue *queue,
580 struct vm_area_struct *vma); 603 struct vm_area_struct *vma);
581extern unsigned int uvc_queue_poll(struct uvc_video_queue *queue, 604extern unsigned int uvc_queue_poll(struct uvc_video_queue *queue,
582 struct file *file, poll_table *wait); 605 struct file *file, poll_table *wait);
606#ifndef CONFIG_MMU
607extern unsigned long uvc_queue_get_unmapped_area(struct uvc_video_queue *queue,
608 unsigned long pgoff);
609#endif
583extern int uvc_queue_allocated(struct uvc_video_queue *queue); 610extern int uvc_queue_allocated(struct uvc_video_queue *queue);
584static inline int uvc_queue_streaming(struct uvc_video_queue *queue) 611static inline int uvc_queue_streaming(struct uvc_video_queue *queue)
585{ 612{
@@ -638,7 +665,7 @@ extern int uvc_ctrl_set(struct uvc_video_chain *chain,
638 struct v4l2_ext_control *xctrl); 665 struct v4l2_ext_control *xctrl);
639 666
640extern int uvc_xu_ctrl_query(struct uvc_video_chain *chain, 667extern int uvc_xu_ctrl_query(struct uvc_video_chain *chain,
641 struct uvc_xu_control *ctrl, int set); 668 struct uvc_xu_control_query *xqry);
642 669
643/* Utility functions */ 670/* Utility functions */
644extern void uvc_simplify_fraction(uint32_t *numerator, uint32_t *denominator, 671extern void uvc_simplify_fraction(uint32_t *numerator, uint32_t *denominator,
@@ -655,4 +682,3 @@ void uvc_video_decode_isight(struct urb *urb, struct uvc_streaming *stream,
655#endif /* __KERNEL__ */ 682#endif /* __KERNEL__ */
656 683
657#endif 684#endif
658
diff --git a/drivers/media/video/v4l2-dev.c b/drivers/media/video/v4l2-dev.c
index 6dc7196296b3..19d5ae293780 100644
--- a/drivers/media/video/v4l2-dev.c
+++ b/drivers/media/video/v4l2-dev.c
@@ -352,6 +352,23 @@ static long v4l2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
352 return ret; 352 return ret;
353} 353}
354 354
355#ifdef CONFIG_MMU
356#define v4l2_get_unmapped_area NULL
357#else
358static unsigned long v4l2_get_unmapped_area(struct file *filp,
359 unsigned long addr, unsigned long len, unsigned long pgoff,
360 unsigned long flags)
361{
362 struct video_device *vdev = video_devdata(filp);
363
364 if (!vdev->fops->get_unmapped_area)
365 return -ENOSYS;
366 if (!video_is_registered(vdev))
367 return -ENODEV;
368 return vdev->fops->get_unmapped_area(filp, addr, len, pgoff, flags);
369}
370#endif
371
355static int v4l2_mmap(struct file *filp, struct vm_area_struct *vm) 372static int v4l2_mmap(struct file *filp, struct vm_area_struct *vm)
356{ 373{
357 struct video_device *vdev = video_devdata(filp); 374 struct video_device *vdev = video_devdata(filp);
@@ -454,6 +471,7 @@ static const struct file_operations v4l2_fops = {
454 .read = v4l2_read, 471 .read = v4l2_read,
455 .write = v4l2_write, 472 .write = v4l2_write,
456 .open = v4l2_open, 473 .open = v4l2_open,
474 .get_unmapped_area = v4l2_get_unmapped_area,
457 .mmap = v4l2_mmap, 475 .mmap = v4l2_mmap,
458 .unlocked_ioctl = v4l2_ioctl, 476 .unlocked_ioctl = v4l2_ioctl,
459#ifdef CONFIG_COMPAT 477#ifdef CONFIG_COMPAT
diff --git a/drivers/media/video/via-camera.c b/drivers/media/video/via-camera.c
index 8c780c2d937b..85d3048c1d67 100644
--- a/drivers/media/video/via-camera.c
+++ b/drivers/media/video/via-camera.c
@@ -29,6 +29,7 @@
29 29
30#include "via-camera.h" 30#include "via-camera.h"
31 31
32MODULE_ALIAS("platform:viafb-camera");
32MODULE_AUTHOR("Jonathan Corbet <corbet@lwn.net>"); 33MODULE_AUTHOR("Jonathan Corbet <corbet@lwn.net>");
33MODULE_DESCRIPTION("VIA framebuffer-based camera controller driver"); 34MODULE_DESCRIPTION("VIA framebuffer-based camera controller driver");
34MODULE_LICENSE("GPL"); 35MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/zoran/zoran_card.c b/drivers/media/video/zoran/zoran_card.c
index 9f2bac519647..79b04ac0f1ad 100644
--- a/drivers/media/video/zoran/zoran_card.c
+++ b/drivers/media/video/zoran/zoran_card.c
@@ -64,14 +64,6 @@ static int card[BUZ_MAX] = { [0 ... (BUZ_MAX-1)] = -1 };
64module_param_array(card, int, NULL, 0444); 64module_param_array(card, int, NULL, 0444);
65MODULE_PARM_DESC(card, "Card type"); 65MODULE_PARM_DESC(card, "Card type");
66 66
67static int encoder[BUZ_MAX] = { [0 ... (BUZ_MAX-1)] = -1 };
68module_param_array(encoder, int, NULL, 0444);
69MODULE_PARM_DESC(encoder, "Video encoder chip");
70
71static int decoder[BUZ_MAX] = { [0 ... (BUZ_MAX-1)] = -1 };
72module_param_array(decoder, int, NULL, 0444);
73MODULE_PARM_DESC(decoder, "Video decoder chip");
74
75/* 67/*
76 The video mem address of the video card. 68 The video mem address of the video card.
77 The driver has a little database for some videocards 69 The driver has a little database for some videocards
@@ -1230,7 +1222,7 @@ static int __devinit zoran_probe(struct pci_dev *pdev,
1230 mutex_init(&zr->other_lock); 1222 mutex_init(&zr->other_lock);
1231 if (pci_enable_device(pdev)) 1223 if (pci_enable_device(pdev))
1232 goto zr_unreg; 1224 goto zr_unreg;
1233 pci_read_config_byte(zr->pci_dev, PCI_CLASS_REVISION, &zr->revision); 1225 zr->revision = zr->pci_dev->revision;
1234 1226
1235 dprintk(1, 1227 dprintk(1,
1236 KERN_INFO 1228 KERN_INFO