aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@g5.osdl.org>2006-06-25 13:09:31 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-06-25 13:09:31 -0400
commit25581ad107be24b89d805da51a03d616f8f3d1be (patch)
tree36e2bd32667b5dd5a39e1939c1c5162f18967715 /drivers/media/video
parent72cf2709bf8e0410800f118c4298bfbf8715b303 (diff)
parent7477ddaa4d2d69bbcd49e12990af158dbb03f2f2 (diff)
Merge master.kernel.org:/pub/scm/linux/kernel/git/mchehab/v4l-dvb
* master.kernel.org:/pub/scm/linux/kernel/git/mchehab/v4l-dvb: (244 commits) V4L/DVB (4210b): git-dvb: tea575x-tuner build fix V4L/DVB (4210a): git-dvb versus matroxfb V4L/DVB (4209): Added some BTTV PCI IDs for newer boards Fixes some sync issues between V4L/DVB development and GIT V4L/DVB (4206): Cx88-blackbird: always set encoder height based on tvnorm->id V4L/DVB (4205): Merge tda9887 module into tuner. V4L/DVB (4203): Explicitly set the enum values. V4L/DVB (4202): allow selecting CX2341x port mode V4L/DVB (4200): Disable bitrate_mode when encoding mpeg-1. V4L/DVB (4199): Add cx2341x-specific control array to cx2341x.c V4L/DVB (4198): Avoid newer usages of obsoleted experimental MPEGCOMP API V4L/DVB (4197): Port new MPEG API to saa7134-empress with saa6752hs V4L/DVB (4196): Port cx88-blackbird to the new MPEG API. V4L/DVB (4193): Update cx2341x fw encoding API doc. V4L/DVB (4192): Use control helpers for saa7115, cx25840, msp3400. V4L/DVB (4191): Add CX2341X MPEG encoder module. V4L/DVB (4190): Add helper functions for control processing to v4l2-common. V4L/DVB (4189): Add videodev support for VIDIOC_S/G/TRY_EXT_CTRLS. V4L/DVB (4188): Add new MPEG control/ioctl definitions to videodev2.h V4L/DVB (4186): Add support for the DNTV Live! mini DVB-T card. ...
Diffstat (limited to 'drivers/media/video')
-rw-r--r--drivers/media/video/Kconfig79
-rw-r--r--drivers/media/video/Makefile7
-rw-r--r--drivers/media/video/arv.c3
-rw-r--r--drivers/media/video/bt866.c377
-rw-r--r--drivers/media/video/bt8xx/bttv-cards.c10
-rw-r--r--drivers/media/video/bt8xx/bttv-gpio.c14
-rw-r--r--drivers/media/video/bt8xx/bttv-input.c2
-rw-r--r--drivers/media/video/bt8xx/bttv.h1
-rw-r--r--drivers/media/video/bt8xx/bttvp.h2
-rw-r--r--drivers/media/video/bw-qcam.c3
-rw-r--r--drivers/media/video/c-qcam.c1
-rw-r--r--drivers/media/video/cpia.c22
-rw-r--r--drivers/media/video/cpia.h3
-rw-r--r--drivers/media/video/cpia2/cpia2.h1
-rw-r--r--drivers/media/video/cpia2/cpia2_v4l.c6
-rw-r--r--drivers/media/video/cpia_pp.c8
-rw-r--r--drivers/media/video/cpia_usb.c6
-rw-r--r--drivers/media/video/cx2341x.c915
-rw-r--r--drivers/media/video/cx25840/cx25840-audio.c54
-rw-r--r--drivers/media/video/cx25840/cx25840-core.c306
-rw-r--r--drivers/media/video/cx25840/cx25840-core.h8
-rw-r--r--drivers/media/video/cx25840/cx25840-vbi.c177
-rw-r--r--drivers/media/video/cx88/Kconfig3
-rw-r--r--drivers/media/video/cx88/cx88-alsa.c5
-rw-r--r--drivers/media/video/cx88/cx88-blackbird.c875
-rw-r--r--drivers/media/video/cx88/cx88-cards.c150
-rw-r--r--drivers/media/video/cx88/cx88-core.c8
-rw-r--r--drivers/media/video/cx88/cx88-dvb.c252
-rw-r--r--drivers/media/video/cx88/cx88-i2c.c8
-rw-r--r--drivers/media/video/cx88/cx88-input.c34
-rw-r--r--drivers/media/video/cx88/cx88-mpeg.c50
-rw-r--r--drivers/media/video/cx88/cx88-tvaudio.c16
-rw-r--r--drivers/media/video/cx88/cx88-vbi.c4
-rw-r--r--drivers/media/video/cx88/cx88.h25
-rw-r--r--drivers/media/video/dsbr100.c1
-rw-r--r--drivers/media/video/em28xx/em28xx-cards.c64
-rw-r--r--drivers/media/video/em28xx/em28xx-core.c12
-rw-r--r--drivers/media/video/em28xx/em28xx-i2c.c31
-rw-r--r--drivers/media/video/em28xx/em28xx-input.c8
-rw-r--r--drivers/media/video/em28xx/em28xx-video.c22
-rw-r--r--drivers/media/video/em28xx/em28xx.h8
-rw-r--r--drivers/media/video/et61x251/et61x251_core.c3
-rw-r--r--drivers/media/video/ir-kbd-i2c.c60
-rw-r--r--drivers/media/video/ks0127.c846
-rw-r--r--drivers/media/video/ks0127.h53
-rw-r--r--drivers/media/video/meye.c5
-rw-r--r--drivers/media/video/msp3400-driver.c112
-rw-r--r--drivers/media/video/msp3400-kthreads.c40
-rw-r--r--drivers/media/video/ov511.c4
-rw-r--r--drivers/media/video/ov511.h1
-rw-r--r--drivers/media/video/planb.c1
-rw-r--r--drivers/media/video/pms.c3
-rw-r--r--drivers/media/video/pwc/Kconfig13
-rw-r--r--drivers/media/video/pwc/Makefile11
-rw-r--r--drivers/media/video/pwc/pwc-ctrl.c699
-rw-r--r--drivers/media/video/pwc/pwc-dec1.c50
-rw-r--r--drivers/media/video/pwc/pwc-dec1.h43
-rw-r--r--drivers/media/video/pwc/pwc-dec23.c941
-rw-r--r--drivers/media/video/pwc/pwc-dec23.h67
-rw-r--r--drivers/media/video/pwc/pwc-if.c1341
-rw-r--r--drivers/media/video/pwc/pwc-kiara.c575
-rw-r--r--drivers/media/video/pwc/pwc-kiara.h8
-rw-r--r--drivers/media/video/pwc/pwc-misc.c67
-rw-r--r--drivers/media/video/pwc/pwc-timon.c1132
-rw-r--r--drivers/media/video/pwc/pwc-timon.h8
-rw-r--r--drivers/media/video/pwc/pwc-uncompress.c154
-rw-r--r--drivers/media/video/pwc/pwc-uncompress.h4
-rw-r--r--drivers/media/video/pwc/pwc-v4l.c1202
-rw-r--r--drivers/media/video/pwc/pwc.h174
-rw-r--r--drivers/media/video/saa5246a.c1
-rw-r--r--drivers/media/video/saa5249.c1
-rw-r--r--drivers/media/video/saa7110.c1
-rw-r--r--drivers/media/video/saa7115.c137
-rw-r--r--drivers/media/video/saa7127.c2
-rw-r--r--drivers/media/video/saa7134/saa6752hs.c315
-rw-r--r--drivers/media/video/saa7134/saa7134-alsa.c2
-rw-r--r--drivers/media/video/saa7134/saa7134-cards.c58
-rw-r--r--drivers/media/video/saa7134/saa7134-dvb.c259
-rw-r--r--drivers/media/video/saa7134/saa7134-empress.c24
-rw-r--r--drivers/media/video/saa7134/saa7134-input.c13
-rw-r--r--drivers/media/video/saa7134/saa7134.h3
-rw-r--r--drivers/media/video/se401.h1
-rw-r--r--drivers/media/video/sn9c102/sn9c102_core.c3
-rw-r--r--drivers/media/video/stradis.c1
-rw-r--r--drivers/media/video/stv680.c1
-rw-r--r--drivers/media/video/tda9875.c3
-rw-r--r--drivers/media/video/tda9887.c461
-rw-r--r--drivers/media/video/tea5767.c2
-rw-r--r--drivers/media/video/tlv320aic23b.c217
-rw-r--r--drivers/media/video/tuner-3036.c1
-rw-r--r--drivers/media/video/tuner-core.c34
-rw-r--r--drivers/media/video/tuner-simple.c2
-rw-r--r--drivers/media/video/tuner-types.c38
-rw-r--r--drivers/media/video/tveeprom.c2
-rw-r--r--drivers/media/video/tvmixer.c8
-rw-r--r--drivers/media/video/tvp5150.c45
-rw-r--r--drivers/media/video/usbvideo/Kconfig12
-rw-r--r--drivers/media/video/usbvideo/Makefile1
-rw-r--r--drivers/media/video/usbvideo/quickcam_messenger.c1120
-rw-r--r--drivers/media/video/usbvideo/quickcam_messenger.h126
-rw-r--r--drivers/media/video/usbvideo/usbvideo.h1
-rw-r--r--drivers/media/video/v4l1-compat.c1
-rw-r--r--drivers/media/video/v4l2-common.c533
-rw-r--r--drivers/media/video/video-buf-dvb.c5
-rw-r--r--drivers/media/video/videodev.c1272
-rw-r--r--drivers/media/video/vino.c2
-rw-r--r--drivers/media/video/vivi.c664
-rw-r--r--drivers/media/video/vpx3220.c1
-rw-r--r--drivers/media/video/w9966.c1
-rw-r--r--drivers/media/video/zc0301/Kconfig6
-rw-r--r--drivers/media/video/zc0301/Makefile2
-rw-r--r--drivers/media/video/zc0301/zc0301_core.c22
-rw-r--r--drivers/media/video/zc0301/zc0301_pas202bcb.c4
-rw-r--r--drivers/media/video/zc0301/zc0301_pb0330.c187
-rw-r--r--drivers/media/video/zc0301/zc0301_sensor.h26
-rw-r--r--drivers/media/video/zoran.h8
-rw-r--r--drivers/media/video/zoran_card.c88
-rw-r--r--drivers/media/video/zoran_device.c2
-rw-r--r--drivers/media/video/zoran_driver.c27
-rw-r--r--drivers/media/video/zoran_procfs.c1
120 files changed, 13206 insertions, 3739 deletions
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index 6b419701856..824a63c9262 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -224,6 +224,12 @@ config VIDEO_ZORAN_LML33R10
224 support for the Linux Media Labs LML33R10 MJPEG capture/playback 224 support for the Linux Media Labs LML33R10 MJPEG capture/playback
225 card. 225 card.
226 226
227config VIDEO_ZORAN_AVS6EYES
228 tristate "AverMedia 6 Eyes support (EXPERIMENTAL)"
229 depends on VIDEO_ZORAN && EXPERIMENTAL && VIDEO_V4L1
230 help
231 Support for the AverMedia 6 Eyes video surveillance card.
232
227config VIDEO_ZR36120 233config VIDEO_ZR36120
228 tristate "Zoran ZR36120/36125 Video For Linux" 234 tristate "Zoran ZR36120/36125 Video For Linux"
229 depends on PCI && I2C && VIDEO_V4L1 && BROKEN 235 depends on PCI && I2C && VIDEO_V4L1 && BROKEN
@@ -306,17 +312,6 @@ config VIDEO_HEXIUM_GEMINI
306 312
307source "drivers/media/video/cx88/Kconfig" 313source "drivers/media/video/cx88/Kconfig"
308 314
309config VIDEO_OVCAMCHIP
310 tristate "OmniVision Camera Chip support"
311 depends on I2C && VIDEO_V4L1
312 ---help---
313 Support for the OmniVision OV6xxx and OV7xxx series of camera chips.
314 This driver is intended to be used with the ov511 and w9968cf USB
315 camera drivers.
316
317 To compile this driver as a module, choose M here: the
318 module will be called ovcamchip.
319
320config VIDEO_M32R_AR 315config VIDEO_M32R_AR
321 tristate "AR devices" 316 tristate "AR devices"
322 depends on M32R && VIDEO_V4L1 317 depends on M32R && VIDEO_V4L1
@@ -357,6 +352,15 @@ config VIDEO_CS53L32A
357 To compile this driver as a module, choose M here: the 352 To compile this driver as a module, choose M here: the
358 module will be called cs53l32a. 353 module will be called cs53l32a.
359 354
355config VIDEO_TLV320AIC23B
356 tristate "Texas Instruments TLV320AIC23B audio codec"
357 depends on VIDEO_DEV && I2C && EXPERIMENTAL
358 ---help---
359 Support for the Texas Instruments TLV320AIC23B audio codec.
360
361 To compile this driver as a module, choose M here: the
362 module will be called tlv320aic23b.
363
360config VIDEO_WM8775 364config VIDEO_WM8775
361 tristate "Wolfson Microelectronics WM8775 audio ADC with input mixer" 365 tristate "Wolfson Microelectronics WM8775 audio ADC with input mixer"
362 depends on VIDEO_DEV && I2C && EXPERIMENTAL 366 depends on VIDEO_DEV && I2C && EXPERIMENTAL
@@ -380,10 +384,10 @@ config VIDEO_WM8739
380source "drivers/media/video/cx25840/Kconfig" 384source "drivers/media/video/cx25840/Kconfig"
381 385
382config VIDEO_SAA711X 386config VIDEO_SAA711X
383 tristate "Philips SAA7113/4/5 video decoders (OBSOLETED)" 387 tristate "Philips SAA7113/4/5 video decoders"
384 depends on VIDEO_V4L1 && I2C && EXPERIMENTAL 388 depends on VIDEO_DEV && I2C && EXPERIMENTAL
385 ---help--- 389 ---help---
386 Old support for the Philips SAA7113/4 video decoders. 390 Support for the Philips SAA7113/4/5 video decoders.
387 391
388 To compile this driver as a module, choose M here: the 392 To compile this driver as a module, choose M here: the
389 module will be called saa7115. 393 module will be called saa7115.
@@ -447,6 +451,35 @@ source "drivers/media/video/usbvideo/Kconfig"
447 451
448source "drivers/media/video/et61x251/Kconfig" 452source "drivers/media/video/et61x251/Kconfig"
449 453
454config VIDEO_OVCAMCHIP
455 tristate "OmniVision Camera Chip support"
456 depends on I2C && VIDEO_V4L1
457 ---help---
458 Support for the OmniVision OV6xxx and OV7xxx series of camera chips.
459 This driver is intended to be used with the ov511 and w9968cf USB
460 camera drivers.
461
462 To compile this driver as a module, choose M here: the
463 module will be called ovcamchip.
464
465config USB_W9968CF
466 tristate "USB W996[87]CF JPEG Dual Mode Camera support"
467 depends on USB && VIDEO_V4L1 && I2C
468 select VIDEO_OVCAMCHIP
469 ---help---
470 Say Y here if you want support for cameras based on OV681 or
471 Winbond W9967CF/W9968CF JPEG USB Dual Mode Camera Chips.
472
473 This driver has an optional plugin, which is distributed as a
474 separate module only (released under GPL). It allows to use higher
475 resolutions and framerates, but cannot be included in the official
476 Linux kernel for performance purposes.
477
478 See <file:Documentation/video4linux/w9968cf.txt> for more info.
479
480 To compile this driver as a module, choose M here: the
481 module will be called w9968cf.
482
450config USB_OV511 483config USB_OV511
451 tristate "USB OV511 Camera support" 484 tristate "USB OV511 Camera support"
452 depends on USB && VIDEO_V4L1 485 depends on USB && VIDEO_V4L1
@@ -483,24 +516,6 @@ config USB_STV680
483 To compile this driver as a module, choose M here: the 516 To compile this driver as a module, choose M here: the
484 module will be called stv680. 517 module will be called stv680.
485 518
486config USB_W9968CF
487 tristate "USB W996[87]CF JPEG Dual Mode Camera support"
488 depends on USB && VIDEO_V4L1 && I2C
489 select VIDEO_OVCAMCHIP
490 ---help---
491 Say Y here if you want support for cameras based on OV681 or
492 Winbond W9967CF/W9968CF JPEG USB Dual Mode Camera Chips.
493
494 This driver has an optional plugin, which is distributed as a
495 separate module only (released under GPL). It allows to use higher
496 resolutions and framerates, but cannot be included in the official
497 Linux kernel for performance purposes.
498
499 See <file:Documentation/video4linux/w9968cf.txt> for more info.
500
501 To compile this driver as a module, choose M here: the
502 module will be called w9968cf.
503
504source "drivers/media/video/zc0301/Kconfig" 519source "drivers/media/video/zc0301/Kconfig"
505 520
506source "drivers/media/video/pwc/Kconfig" 521source "drivers/media/video/pwc/Kconfig"
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile
index e5bf2687b76..6c401b46398 100644
--- a/drivers/media/video/Makefile
+++ b/drivers/media/video/Makefile
@@ -6,7 +6,7 @@ zoran-objs := zr36120.o zr36120_i2c.o zr36120_mem.o
6zr36067-objs := zoran_procfs.o zoran_device.o \ 6zr36067-objs := zoran_procfs.o zoran_device.o \
7 zoran_driver.o zoran_card.o 7 zoran_driver.o zoran_card.o
8tuner-objs := tuner-core.o tuner-types.o tuner-simple.o \ 8tuner-objs := tuner-core.o tuner-types.o tuner-simple.o \
9 mt20xx.o tda8290.o tea5767.o 9 mt20xx.o tda8290.o tea5767.o tda9887.o
10 10
11msp3400-objs := msp3400-driver.o msp3400-kthreads.o 11msp3400-objs := msp3400-driver.o msp3400-kthreads.o
12 12
@@ -33,6 +33,7 @@ obj-$(CONFIG_VIDEO_ZORAN_DC30) += adv7175.o vpx3220.o zr36050.o \
33 zr36016.o 33 zr36016.o
34obj-$(CONFIG_VIDEO_ZORAN_LML33) += bt819.o bt856.o zr36060.o 34obj-$(CONFIG_VIDEO_ZORAN_LML33) += bt819.o bt856.o zr36060.o
35obj-$(CONFIG_VIDEO_ZORAN_LML33R10) += saa7114.o adv7170.o zr36060.o 35obj-$(CONFIG_VIDEO_ZORAN_LML33R10) += saa7114.o adv7170.o zr36060.o
36obj-$(CONFIG_VIDEO_ZORAN_AVS6EYES) += bt866.o ks0127.o zr36060.o
36obj-$(CONFIG_VIDEO_ZORAN) += zr36067.o videocodec.o 37obj-$(CONFIG_VIDEO_ZORAN) += zr36067.o videocodec.o
37obj-$(CONFIG_VIDEO_PMS) += pms.o 38obj-$(CONFIG_VIDEO_PMS) += pms.o
38obj-$(CONFIG_VIDEO_PLANB) += planb.o 39obj-$(CONFIG_VIDEO_PLANB) += planb.o
@@ -48,6 +49,7 @@ obj-$(CONFIG_VIDEO_EM28XX) += em28xx/
48obj-$(CONFIG_VIDEO_EM28XX) += tvp5150.o 49obj-$(CONFIG_VIDEO_EM28XX) += tvp5150.o
49obj-$(CONFIG_VIDEO_MSP3400) += msp3400.o 50obj-$(CONFIG_VIDEO_MSP3400) += msp3400.o
50obj-$(CONFIG_VIDEO_CS53L32A) += cs53l32a.o 51obj-$(CONFIG_VIDEO_CS53L32A) += cs53l32a.o
52obj-$(CONFIG_VIDEO_TLV320AIC23B) += tlv320aic23b.o
51obj-$(CONFIG_VIDEO_WM8775) += wm8775.o 53obj-$(CONFIG_VIDEO_WM8775) += wm8775.o
52obj-$(CONFIG_VIDEO_WM8739) += wm8739.o 54obj-$(CONFIG_VIDEO_WM8739) += wm8739.o
53obj-$(CONFIG_VIDEO_OVCAMCHIP) += ovcamchip/ 55obj-$(CONFIG_VIDEO_OVCAMCHIP) += ovcamchip/
@@ -58,7 +60,7 @@ obj-$(CONFIG_VIDEO_HEXIUM_GEMINI) += hexium_gemini.o
58obj-$(CONFIG_VIDEO_DPC) += saa7111.o dpc7146.o 60obj-$(CONFIG_VIDEO_DPC) += saa7111.o dpc7146.o
59obj-$(CONFIG_TUNER_3036) += tuner-3036.o 61obj-$(CONFIG_TUNER_3036) += tuner-3036.o
60 62
61obj-$(CONFIG_VIDEO_TUNER) += tuner.o tda9887.o 63obj-$(CONFIG_VIDEO_TUNER) += tuner.o
62obj-$(CONFIG_VIDEO_BUF) += video-buf.o 64obj-$(CONFIG_VIDEO_BUF) += video-buf.o
63obj-$(CONFIG_VIDEO_BUF_DVB) += video-buf-dvb.o 65obj-$(CONFIG_VIDEO_BUF_DVB) += video-buf-dvb.o
64obj-$(CONFIG_VIDEO_BTCX) += btcx-risc.o 66obj-$(CONFIG_VIDEO_BTCX) += btcx-risc.o
@@ -71,6 +73,7 @@ obj-$(CONFIG_VIDEO_SAA711X) += saa7115.o
71obj-$(CONFIG_VIDEO_SAA7127) += saa7127.o 73obj-$(CONFIG_VIDEO_SAA7127) += saa7127.o
72obj-$(CONFIG_VIDEO_UPD64031A) += upd64031a.o 74obj-$(CONFIG_VIDEO_UPD64031A) += upd64031a.o
73obj-$(CONFIG_VIDEO_UPD64083) += upd64083.o 75obj-$(CONFIG_VIDEO_UPD64083) += upd64083.o
76obj-$(CONFIG_VIDEO_CX2341X) += cx2341x.o
74 77
75obj-$(CONFIG_USB_DABUSB) += dabusb.o 78obj-$(CONFIG_USB_DABUSB) += dabusb.o
76obj-$(CONFIG_USB_DSBR) += dsbr100.o 79obj-$(CONFIG_USB_DSBR) += dsbr100.o
diff --git a/drivers/media/video/arv.c b/drivers/media/video/arv.c
index dbe02517059..6e08e32346e 100644
--- a/drivers/media/video/arv.c
+++ b/drivers/media/video/arv.c
@@ -31,6 +31,7 @@
31#include <linux/mm.h> 31#include <linux/mm.h>
32#include <linux/sched.h> 32#include <linux/sched.h>
33#include <linux/videodev.h> 33#include <linux/videodev.h>
34#include <media/v4l2-common.h>
34#include <linux/mutex.h> 35#include <linux/mutex.h>
35 36
36#include <asm/uaccess.h> 37#include <asm/uaccess.h>
@@ -212,7 +213,7 @@ void init_iic(void)
212 ar_outl(0x0300, PLDI2CMOD); /* I2CMOD ACK/8b-data/7b-addr/auto */ 213 ar_outl(0x0300, PLDI2CMOD); /* I2CMOD ACK/8b-data/7b-addr/auto */
213 ar_outl(0x1, PLDI2CACK); /* I2CACK ACK */ 214 ar_outl(0x1, PLDI2CACK); /* I2CACK ACK */
214 215
215 /* I2C CLK */ 216 /* I2C CLK */
216 /* 50MH-100k */ 217 /* 50MH-100k */
217 if (freq == 75) { 218 if (freq == 75) {
218 ar_outl(369, PLDI2CFREQ); /* BCLK = 75MHz */ 219 ar_outl(369, PLDI2CFREQ); /* BCLK = 75MHz */
diff --git a/drivers/media/video/bt866.c b/drivers/media/video/bt866.c
new file mode 100644
index 00000000000..05e42bbcfc3
--- /dev/null
+++ b/drivers/media/video/bt866.c
@@ -0,0 +1,377 @@
1/*
2 bt866 - BT866 Digital Video Encoder (Rockwell Part)
3
4 Copyright (C) 1999 Mike Bernson <mike@mlb.org>
5 Copyright (C) 1998 Dave Perks <dperks@ibm.net>
6
7 Modifications for LML33/DC10plus unified driver
8 Copyright (C) 2000 Serguei Miridonov <mirsev@cicese.mx>
9
10 This code was modify/ported from the saa7111 driver written
11 by Dave Perks.
12
13 This code was adapted for the bt866 by Christer Weinigel and ported
14 to 2.6 by Martin Samuelsson.
15
16 This program is free software; you can redistribute it and/or modify
17 it under the terms of the GNU General Public License as published by
18 the Free Software Foundation; either version 2 of the License, or
19 (at your option) any later version.
20
21 This program is distributed in the hope that it will be useful,
22 but WITHOUT ANY WARRANTY; without even the implied warranty of
23 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 GNU General Public License for more details.
25
26 You should have received a copy of the GNU General Public License
27 along with this program; if not, write to the Free Software
28 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29*/
30
31#include <linux/module.h>
32#include <linux/init.h>
33#include <linux/delay.h>
34#include <linux/errno.h>
35#include <linux/fs.h>
36#include <linux/kernel.h>
37#include <linux/major.h>
38#include <linux/slab.h>
39#include <linux/mm.h>
40#include <linux/pci.h>
41#include <linux/signal.h>
42#include <asm/io.h>
43#include <asm/pgtable.h>
44#include <asm/page.h>
45#include <linux/sched.h>
46#include <linux/types.h>
47#include <linux/i2c.h>
48
49#include <linux/videodev.h>
50#include <asm/uaccess.h>
51
52#include <linux/video_encoder.h>
53
54MODULE_LICENSE("GPL");
55
56#define BT866_DEVNAME "bt866"
57#define I2C_BT866 0x88
58
59MODULE_LICENSE("GPL");
60
61#define DEBUG(x) /* Debug driver */
62
63/* ----------------------------------------------------------------------- */
64
65struct bt866 {
66 struct i2c_client *i2c;
67 int addr;
68 unsigned char reg[128];
69
70 int norm;
71 int enable;
72 int bright;
73 int contrast;
74 int hue;
75 int sat;
76};
77
78static int bt866_write(struct bt866 *dev,
79 unsigned char subaddr, unsigned char data);
80
81static int bt866_do_command(struct bt866 *encoder,
82 unsigned int cmd, void *arg)
83{
84 switch (cmd) {
85 case ENCODER_GET_CAPABILITIES:
86 {
87 struct video_encoder_capability *cap = arg;
88
89 DEBUG(printk
90 (KERN_INFO "%s: get capabilities\n",
91 encoder->i2c->name));
92
93 cap->flags
94 = VIDEO_ENCODER_PAL
95 | VIDEO_ENCODER_NTSC
96 | VIDEO_ENCODER_CCIR;
97 cap->inputs = 2;
98 cap->outputs = 1;
99 }
100 break;
101
102 case ENCODER_SET_NORM:
103 {
104 int *iarg = arg;
105
106 DEBUG(printk(KERN_INFO "%s: set norm %d\n",
107 encoder->i2c->name, *iarg));
108
109 switch (*iarg) {
110
111 case VIDEO_MODE_NTSC:
112 break;
113
114 case VIDEO_MODE_PAL:
115 break;
116
117 default:
118 return -EINVAL;
119
120 }
121 encoder->norm = *iarg;
122 }
123 break;
124
125 case ENCODER_SET_INPUT:
126 {
127 int *iarg = arg;
128 static const __u8 init[] = {
129 0xc8, 0xcc, /* CRSCALE */
130 0xca, 0x91, /* CBSCALE */
131 0xcc, 0x24, /* YC16 | OSDNUM */
132 0xda, 0x00, /* */
133 0xdc, 0x24, /* SETMODE | PAL */
134 0xde, 0x02, /* EACTIVE */
135
136 /* overlay colors */
137 0x70, 0xEB, 0x90, 0x80, 0xB0, 0x80, /* white */
138 0x72, 0xA2, 0x92, 0x8E, 0xB2, 0x2C, /* yellow */
139 0x74, 0x83, 0x94, 0x2C, 0xB4, 0x9C, /* cyan */
140 0x76, 0x70, 0x96, 0x3A, 0xB6, 0x48, /* green */
141 0x78, 0x54, 0x98, 0xC6, 0xB8, 0xB8, /* magenta */
142 0x7A, 0x41, 0x9A, 0xD4, 0xBA, 0x64, /* red */
143 0x7C, 0x23, 0x9C, 0x72, 0xBC, 0xD4, /* blue */
144 0x7E, 0x10, 0x9E, 0x80, 0xBE, 0x80, /* black */
145
146 0x60, 0xEB, 0x80, 0x80, 0xc0, 0x80, /* white */
147 0x62, 0xA2, 0x82, 0x8E, 0xc2, 0x2C, /* yellow */
148 0x64, 0x83, 0x84, 0x2C, 0xc4, 0x9C, /* cyan */
149 0x66, 0x70, 0x86, 0x3A, 0xc6, 0x48, /* green */
150 0x68, 0x54, 0x88, 0xC6, 0xc8, 0xB8, /* magenta */
151 0x6A, 0x41, 0x8A, 0xD4, 0xcA, 0x64, /* red */
152 0x6C, 0x23, 0x8C, 0x72, 0xcC, 0xD4, /* blue */
153 0x6E, 0x10, 0x8E, 0x80, 0xcE, 0x80, /* black */
154 };
155 int i;
156 u8 val;
157
158 for (i = 0; i < ARRAY_SIZE(init) / 2; i += 2)
159 bt866_write(encoder, init[i], init[i+1]);
160
161 val = encoder->reg[0xdc];
162
163 if (*iarg == 0)
164 val |= 0x40; /* CBSWAP */
165 else
166 val &= ~0x40; /* !CBSWAP */
167
168 bt866_write(encoder, 0xdc, val);
169
170 val = encoder->reg[0xcc];
171 if (*iarg == 2)
172 val |= 0x01; /* OSDBAR */
173 else
174 val &= ~0x01; /* !OSDBAR */
175 bt866_write(encoder, 0xcc, val);
176
177 DEBUG(printk(KERN_INFO "%s: set input %d\n",
178 encoder->i2c->name, *iarg));
179
180 switch (*iarg) {
181 case 0:
182 break;
183 case 1:
184 break;
185 default:
186 return -EINVAL;
187
188 }
189 }
190 break;
191
192 case ENCODER_SET_OUTPUT:
193 {
194 int *iarg = arg;
195
196 DEBUG(printk(KERN_INFO "%s: set output %d\n",
197 encoder->i2c->name, *iarg));
198
199 /* not much choice of outputs */
200 if (*iarg != 0)
201 return -EINVAL;
202 }
203 break;
204
205 case ENCODER_ENABLE_OUTPUT:
206 {
207 int *iarg = arg;
208 encoder->enable = !!*iarg;
209
210 DEBUG(printk
211 (KERN_INFO "%s: enable output %d\n",
212 encoder->i2c->name, encoder->enable));
213 }
214 break;
215
216 case 4711:
217 {
218 int *iarg = arg;
219 __u8 val;
220
221 printk("bt866: square = %d\n", *iarg);
222
223 val = encoder->reg[0xdc];
224 if (*iarg)
225 val |= 1; /* SQUARE */
226 else
227 val &= ~1; /* !SQUARE */
228 bt866_write(encoder, 0xdc, val);
229 break;
230 }
231
232 default:
233 return -EINVAL;
234 }
235
236 return 0;
237}
238
239static int bt866_write(struct bt866 *encoder,
240 unsigned char subaddr, unsigned char data)
241{
242 unsigned char buffer[2];
243 int err;
244
245 buffer[0] = subaddr;
246 buffer[1] = data;
247
248 encoder->reg[subaddr] = data;
249
250 DEBUG(printk
251 ("%s: write 0x%02X = 0x%02X\n",
252 encoder->i2c->name, subaddr, data));
253
254 for (err = 0; err < 3;) {
255 if (i2c_master_send(encoder->i2c, buffer, 2) == 2)
256 break;
257 err++;
258 printk(KERN_WARNING "%s: I/O error #%d "
259 "(write 0x%02x/0x%02x)\n",
260 encoder->i2c->name, err, encoder->addr, subaddr);
261 schedule_timeout_interruptible(HZ/10);
262 }
263 if (err == 3) {
264 printk(KERN_WARNING "%s: giving up\n",
265 encoder->i2c->name);
266 return -1;
267 }
268
269 return 0;
270}
271
272static int bt866_attach(struct i2c_adapter *adapter);
273static int bt866_detach(struct i2c_client *client);
274static int bt866_command(struct i2c_client *client,
275 unsigned int cmd, void *arg);
276
277
278/* Addresses to scan */
279static unsigned short normal_i2c[] = {I2C_BT866>>1, I2C_CLIENT_END};
280static unsigned short probe[2] = {I2C_CLIENT_END, I2C_CLIENT_END};
281static unsigned short ignore[2] = {I2C_CLIENT_END, I2C_CLIENT_END};
282
283static struct i2c_client_address_data addr_data = {
284 normal_i2c,
285 probe,
286 ignore,
287};
288
289static struct i2c_driver i2c_driver_bt866 = {
290 .driver.name = BT866_DEVNAME,
291 .id = I2C_DRIVERID_BT866,
292 .attach_adapter = bt866_attach,
293 .detach_client = bt866_detach,
294 .command = bt866_command
295};
296
297
298static struct i2c_client bt866_client_tmpl =
299{
300 .name = "(nil)",
301 .addr = 0,
302 .adapter = NULL,
303 .driver = &i2c_driver_bt866,
304 .usage_count = 0
305};
306
307static int bt866_found_proc(struct i2c_adapter *adapter,
308 int addr, int kind)
309{
310 struct bt866 *encoder;
311 struct i2c_client *client;
312
313 client = kzalloc(sizeof(*client), GFP_KERNEL);
314 if (client == NULL)
315 return -ENOMEM;
316 memcpy(client, &bt866_client_tmpl, sizeof(*client));
317
318 encoder = kzalloc(sizeof(*encoder), GFP_KERNEL);
319 if (encoder == NULL) {
320 kfree(client);
321 return -ENOMEM;
322 }
323
324 i2c_set_clientdata(client, encoder);
325 client->adapter = adapter;
326 client->addr = addr;
327 sprintf(client->name, "%s-%02x", BT866_DEVNAME, adapter->id);
328
329 encoder->i2c = client;
330 encoder->addr = addr;
331 //encoder->encoder_type = ENCODER_TYPE_UNKNOWN;
332
333 /* initialize */
334
335 i2c_attach_client(client);
336
337 return 0;
338}
339
340static int bt866_attach(struct i2c_adapter *adapter)
341{
342 if (adapter->id == I2C_HW_B_ZR36067)
343 return i2c_probe(adapter, &addr_data, bt866_found_proc);
344 return 0;
345}
346
347static int bt866_detach(struct i2c_client *client)
348{
349 struct bt866 *encoder = i2c_get_clientdata(client);
350
351 i2c_detach_client(client);
352 kfree(encoder);
353 kfree(client);
354
355 return 0;
356}
357
358static int bt866_command(struct i2c_client *client,
359 unsigned int cmd, void *arg)
360{
361 struct bt866 *encoder = i2c_get_clientdata(client);
362 return bt866_do_command(encoder, cmd, arg);
363}
364
365static int __devinit bt866_init(void)
366{
367 i2c_add_driver(&i2c_driver_bt866);
368 return 0;
369}
370
371static void __devexit bt866_exit(void)
372{
373 i2c_del_driver(&i2c_driver_bt866);
374}
375
376module_init(bt866_init);
377module_exit(bt866_exit);
diff --git a/drivers/media/video/bt8xx/bttv-cards.c b/drivers/media/video/bt8xx/bttv-cards.c
index 2b64aa835b4..3116345c93b 100644
--- a/drivers/media/video/bt8xx/bttv-cards.c
+++ b/drivers/media/video/bt8xx/bttv-cards.c
@@ -269,7 +269,7 @@ static struct CARD {
269 { 0x41a0a051, BTTV_BOARD_FLYVIDEO_98FM, "Lifeview FlyVideo 98 LR50 Rev Q" }, 269 { 0x41a0a051, BTTV_BOARD_FLYVIDEO_98FM, "Lifeview FlyVideo 98 LR50 Rev Q" },
270 { 0x18501f7f, BTTV_BOARD_FLYVIDEO_98, "Lifeview Flyvideo 98" }, 270 { 0x18501f7f, BTTV_BOARD_FLYVIDEO_98, "Lifeview Flyvideo 98" },
271 271
272 { 0x010115cb, BTTV_BOARD_GMV1, "AG GMV1" }, 272 { 0x010115cb, BTTV_BOARD_GMV1, "AG GMV1" },
273 { 0x010114c7, BTTV_BOARD_MODTEC_205, "Modular Technology MM201/MM202/MM205/MM210/MM215 PCTV" }, 273 { 0x010114c7, BTTV_BOARD_MODTEC_205, "Modular Technology MM201/MM202/MM205/MM210/MM215 PCTV" },
274 274
275 { 0x10b42636, BTTV_BOARD_HAUPPAUGE878, "STB ???" }, 275 { 0x10b42636, BTTV_BOARD_HAUPPAUGE878, "STB ???" },
@@ -309,6 +309,7 @@ static struct CARD {
309 { 0x07611461, BTTV_BOARD_AVDVBT_761, "AverMedia AverTV DVB-T 761" }, 309 { 0x07611461, BTTV_BOARD_AVDVBT_761, "AverMedia AverTV DVB-T 761" },
310 { 0xdb1018ac, BTTV_BOARD_DVICO_DVBT_LITE, "DViCO FusionHDTV DVB-T Lite" }, 310 { 0xdb1018ac, BTTV_BOARD_DVICO_DVBT_LITE, "DViCO FusionHDTV DVB-T Lite" },
311 { 0xd50018ac, BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE, "DViCO FusionHDTV 5 Lite" }, 311 { 0xd50018ac, BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE, "DViCO FusionHDTV 5 Lite" },
312 { 0x00261822, BTTV_BOARD_TWINHAN_DST, "DNTV Live! Mini "},
312 313
313 { 0, -1, NULL } 314 { 0, -1, NULL }
314}; 315};
@@ -1903,7 +1904,7 @@ struct tvcard bttv_tvcards[] = {
1903 .no_tda7432 = 1, 1904 .no_tda7432 = 1,
1904 }, 1905 },
1905 [BTTV_BOARD_OSPREY2x0] = { 1906 [BTTV_BOARD_OSPREY2x0] = {
1906 .name = "Osprey 210/220", /* 0x1(A|B)-04C0-C1 */ 1907 .name = "Osprey 210/220/230", /* 0x1(A|B)-04C0-C1 */
1907 .video_inputs = 2, 1908 .video_inputs = 2,
1908 .audio_inputs = 1, 1909 .audio_inputs = 1,
1909 .tuner = -1, 1910 .tuner = -1,
@@ -2745,7 +2746,7 @@ struct tvcard bttv_tvcards[] = {
2745 /* Michael Krufky <mkrufky@m1k.net> */ 2746 /* Michael Krufky <mkrufky@m1k.net> */
2746 .name = "DViCO FusionHDTV 5 Lite", 2747 .name = "DViCO FusionHDTV 5 Lite",
2747 .tuner = 0, 2748 .tuner = 0,
2748 .tuner_type = TUNER_LG_TDVS_H062F, 2749 .tuner_type = TUNER_LG_TDVS_H06XF, /* TDVS-H064F */
2749 .tuner_addr = ADDR_UNSET, 2750 .tuner_addr = ADDR_UNSET,
2750 .radio_addr = ADDR_UNSET, 2751 .radio_addr = ADDR_UNSET,
2751 .video_inputs = 3, 2752 .video_inputs = 3,
@@ -2762,7 +2763,7 @@ struct tvcard bttv_tvcards[] = {
2762 }, 2763 },
2763 /* ---- card 0x88---------------------------------- */ 2764 /* ---- card 0x88---------------------------------- */
2764 [BTTV_BOARD_ACORP_Y878F] = { 2765 [BTTV_BOARD_ACORP_Y878F] = {
2765 /* Mauro Carvalho Chehab <mchehab@brturbo.com.br> */ 2766 /* Mauro Carvalho Chehab <mchehab@infradead.org> */
2766 .name = "Acorp Y878F", 2767 .name = "Acorp Y878F",
2767 .video_inputs = 3, 2768 .video_inputs = 3,
2768 .audio_inputs = 1, 2769 .audio_inputs = 1,
@@ -3790,6 +3791,7 @@ static void __devinit osprey_eeprom(struct bttv *btv)
3790 break; 3791 break;
3791 case 0x0060: 3792 case 0x0060:
3792 case 0x0070: 3793 case 0x0070:
3794 case 0x00A0:
3793 btv->c.type = BTTV_BOARD_OSPREY2x0; 3795 btv->c.type = BTTV_BOARD_OSPREY2x0;
3794 /* enable output on select control lines */ 3796 /* enable output on select control lines */
3795 gpio_inout(0xffffff,0x000303); 3797 gpio_inout(0xffffff,0x000303);
diff --git a/drivers/media/video/bt8xx/bttv-gpio.c b/drivers/media/video/bt8xx/bttv-gpio.c
index c4d5e2b70c2..ba081f6f8c8 100644
--- a/drivers/media/video/bt8xx/bttv-gpio.c
+++ b/drivers/media/video/bt8xx/bttv-gpio.c
@@ -118,20 +118,6 @@ int bttv_sub_del_devices(struct bttv_core *core)
118 return 0; 118 return 0;
119} 119}
120 120
121void bttv_gpio_irq(struct bttv_core *core)
122{
123 struct bttv_sub_driver *drv;
124 struct bttv_sub_device *dev;
125 struct list_head *item;
126
127 list_for_each(item,&core->subs) {
128 dev = list_entry(item,struct bttv_sub_device,list);
129 drv = to_bttv_sub_drv(dev->dev.driver);
130 if (drv && drv->gpio_irq)
131 drv->gpio_irq(dev);
132 }
133}
134
135/* ----------------------------------------------------------------------- */ 121/* ----------------------------------------------------------------------- */
136/* external: sub-driver register/unregister */ 122/* external: sub-driver register/unregister */
137 123
diff --git a/drivers/media/video/bt8xx/bttv-input.c b/drivers/media/video/bt8xx/bttv-input.c
index 69efa0e5174..b41f81d2372 100644
--- a/drivers/media/video/bt8xx/bttv-input.c
+++ b/drivers/media/video/bt8xx/bttv-input.c
@@ -355,7 +355,7 @@ int bttv_input_init(struct bttv *btv)
355 355
356 if (ir->rc5_gpio) { 356 if (ir->rc5_gpio) {
357 u32 gpio; 357 u32 gpio;
358 /* enable remote irq */ 358 /* enable remote irq */
359 bttv_gpio_inout(&btv->c, (1 << 4), 1 << 4); 359 bttv_gpio_inout(&btv->c, (1 << 4), 1 << 4);
360 gpio = bttv_gpio_read(&btv->c); 360 gpio = bttv_gpio_read(&btv->c);
361 bttv_gpio_write(&btv->c, gpio & ~(1 << 4)); 361 bttv_gpio_write(&btv->c, gpio & ~(1 << 4));
diff --git a/drivers/media/video/bt8xx/bttv.h b/drivers/media/video/bt8xx/bttv.h
index 3a23265c153..f9c9e3c4d11 100644
--- a/drivers/media/video/bt8xx/bttv.h
+++ b/drivers/media/video/bt8xx/bttv.h
@@ -350,7 +350,6 @@ struct bttv_sub_driver {
350 char wanted[BUS_ID_SIZE]; 350 char wanted[BUS_ID_SIZE];
351 int (*probe)(struct bttv_sub_device *sub); 351 int (*probe)(struct bttv_sub_device *sub);
352 void (*remove)(struct bttv_sub_device *sub); 352 void (*remove)(struct bttv_sub_device *sub);
353 void (*gpio_irq)(struct bttv_sub_device *sub);
354}; 353};
355#define to_bttv_sub_drv(x) container_of((x), struct bttv_sub_driver, drv) 354#define to_bttv_sub_drv(x) container_of((x), struct bttv_sub_driver, drv)
356 355
diff --git a/drivers/media/video/bt8xx/bttvp.h b/drivers/media/video/bt8xx/bttvp.h
index ee989d2e15d..d2956010f76 100644
--- a/drivers/media/video/bt8xx/bttvp.h
+++ b/drivers/media/video/bt8xx/bttvp.h
@@ -33,6 +33,7 @@
33#include <linux/i2c.h> 33#include <linux/i2c.h>
34#include <linux/i2c-algo-bit.h> 34#include <linux/i2c-algo-bit.h>
35#include <linux/videodev.h> 35#include <linux/videodev.h>
36#include <media/v4l2-common.h>
36#include <linux/pci.h> 37#include <linux/pci.h>
37#include <linux/input.h> 38#include <linux/input.h>
38#include <linux/mutex.h> 39#include <linux/mutex.h>
@@ -214,7 +215,6 @@ extern struct videobuf_queue_ops bttv_vbi_qops;
214extern struct bus_type bttv_sub_bus_type; 215extern struct bus_type bttv_sub_bus_type;
215int bttv_sub_add_device(struct bttv_core *core, char *name); 216int bttv_sub_add_device(struct bttv_core *core, char *name);
216int bttv_sub_del_devices(struct bttv_core *core); 217int bttv_sub_del_devices(struct bttv_core *core);
217void bttv_gpio_irq(struct bttv_core *core);
218 218
219 219
220/* ---------------------------------------------------------- */ 220/* ---------------------------------------------------------- */
diff --git a/drivers/media/video/bw-qcam.c b/drivers/media/video/bw-qcam.c
index cf61c590f4a..7d0b6e59c6e 100644
--- a/drivers/media/video/bw-qcam.c
+++ b/drivers/media/video/bw-qcam.c
@@ -73,6 +73,7 @@ OTHER DEALINGS IN THE SOFTWARE.
73#include <linux/parport.h> 73#include <linux/parport.h>
74#include <linux/sched.h> 74#include <linux/sched.h>
75#include <linux/videodev.h> 75#include <linux/videodev.h>
76#include <media/v4l2-common.h>
76#include <linux/mutex.h> 77#include <linux/mutex.h>
77#include <asm/uaccess.h> 78#include <asm/uaccess.h>
78 79
@@ -759,7 +760,7 @@ static int qcam_do_ioctl(struct inode *inode, struct file *file,
759 { 760 {
760 struct video_picture *p = arg; 761 struct video_picture *p = arg;
761 if(p->palette!=VIDEO_PALETTE_GREY) 762 if(p->palette!=VIDEO_PALETTE_GREY)
762 return -EINVAL; 763 return -EINVAL;
763 if(p->depth!=4 && p->depth!=6) 764 if(p->depth!=4 && p->depth!=6)
764 return -EINVAL; 765 return -EINVAL;
765 766
diff --git a/drivers/media/video/c-qcam.c b/drivers/media/video/c-qcam.c
index 22a7386bbea..a3989bd2f81 100644
--- a/drivers/media/video/c-qcam.c
+++ b/drivers/media/video/c-qcam.c
@@ -34,6 +34,7 @@
34#include <linux/parport.h> 34#include <linux/parport.h>
35#include <linux/sched.h> 35#include <linux/sched.h>
36#include <linux/videodev.h> 36#include <linux/videodev.h>
37#include <media/v4l2-common.h>
37#include <linux/mutex.h> 38#include <linux/mutex.h>
38 39
39#include <asm/uaccess.h> 40#include <asm/uaccess.h>
diff --git a/drivers/media/video/cpia.c b/drivers/media/video/cpia.c
index 85d84e89d8f..95c5aceecc5 100644
--- a/drivers/media/video/cpia.c
+++ b/drivers/media/video/cpia.c
@@ -47,13 +47,6 @@
47 47
48#include "cpia.h" 48#include "cpia.h"
49 49
50#ifdef CONFIG_VIDEO_CPIA_PP
51extern int cpia_pp_init(void);
52#endif
53#ifdef CONFIG_VIDEO_CPIA_USB
54extern int cpia_usb_init(void);
55#endif
56
57static int video_nr = -1; 50static int video_nr = -1;
58 51
59#ifdef MODULE 52#ifdef MODULE
@@ -67,10 +60,10 @@ MODULE_SUPPORTED_DEVICE("video");
67static unsigned short colorspace_conv; 60static unsigned short colorspace_conv;
68module_param(colorspace_conv, ushort, 0444); 61module_param(colorspace_conv, ushort, 0444);
69MODULE_PARM_DESC(colorspace_conv, 62MODULE_PARM_DESC(colorspace_conv,
70 " Colorspace conversion:" 63 " Colorspace conversion:"
71 "\n 0 = disable, 1 = enable" 64 "\n 0 = disable, 1 = enable"
72 "\n Default value is 0" 65 "\n Default value is 0"
73 ); 66 );
74 67
75#define ABOUT "V4L-Driver for Vision CPiA based cameras" 68#define ABOUT "V4L-Driver for Vision CPiA based cameras"
76 69
@@ -4047,13 +4040,6 @@ static int __init cpia_init(void)
4047 proc_cpia_create(); 4040 proc_cpia_create();
4048#endif 4041#endif
4049 4042
4050#ifdef CONFIG_VIDEO_CPIA_PP
4051 cpia_pp_init();
4052#endif
4053#ifdef CONFIG_VIDEO_CPIA_USB
4054 cpia_usb_init();
4055#endif
4056
4057 return 0; 4043 return 0;
4058} 4044}
4059 4045
diff --git a/drivers/media/video/cpia.h b/drivers/media/video/cpia.h
index dde27a6a4a0..6eaa692021c 100644
--- a/drivers/media/video/cpia.h
+++ b/drivers/media/video/cpia.h
@@ -45,6 +45,7 @@
45 45
46#include <asm/uaccess.h> 46#include <asm/uaccess.h>
47#include <linux/videodev.h> 47#include <linux/videodev.h>
48#include <media/v4l2-common.h>
48#include <linux/list.h> 49#include <linux/list.h>
49#include <linux/smp_lock.h> 50#include <linux/smp_lock.h>
50#include <linux/mutex.h> 51#include <linux/mutex.h>
@@ -247,7 +248,7 @@ enum v4l_camstates {
247struct cam_data { 248struct cam_data {
248 struct list_head cam_data_list; 249 struct list_head cam_data_list;
249 250
250 struct mutex busy_lock; /* guard against SMP multithreading */ 251 struct mutex busy_lock; /* guard against SMP multithreading */
251 struct cpia_camera_ops *ops; /* lowlevel driver operations */ 252 struct cpia_camera_ops *ops; /* lowlevel driver operations */
252 void *lowlevel_data; /* private data for lowlevel driver */ 253 void *lowlevel_data; /* private data for lowlevel driver */
253 u8 *raw_image; /* buffer for raw image data */ 254 u8 *raw_image; /* buffer for raw image data */
diff --git a/drivers/media/video/cpia2/cpia2.h b/drivers/media/video/cpia2/cpia2.h
index 1764991b0ac..c5ecb2be5f9 100644
--- a/drivers/media/video/cpia2/cpia2.h
+++ b/drivers/media/video/cpia2/cpia2.h
@@ -33,6 +33,7 @@
33 33
34#include <linux/version.h> 34#include <linux/version.h>
35#include <linux/videodev.h> 35#include <linux/videodev.h>
36#include <media/v4l2-common.h>
36#include <linux/usb.h> 37#include <linux/usb.h>
37#include <linux/poll.h> 38#include <linux/poll.h>
38 39
diff --git a/drivers/media/video/cpia2/cpia2_v4l.c b/drivers/media/video/cpia2/cpia2_v4l.c
index 481e178ef56..d129db57fcd 100644
--- a/drivers/media/video/cpia2/cpia2_v4l.c
+++ b/drivers/media/video/cpia2/cpia2_v4l.c
@@ -343,7 +343,9 @@ static int cpia2_close(struct inode *inode, struct file *file)
343 cpia2_free_buffers(cam); 343 cpia2_free_buffers(cam);
344 if (!cam->present) { 344 if (!cam->present) {
345 video_unregister_device(dev); 345 video_unregister_device(dev);
346 mutex_unlock(&cam->busy_lock);
346 kfree(cam); 347 kfree(cam);
348 return 0;
347 } 349 }
348 } 350 }
349 351
@@ -1167,9 +1169,9 @@ static int ioctl_g_ctrl(void *arg,struct camera_data *cam)
1167 } else { 1169 } else {
1168 if(cam->params.flicker_control.cam_register & 1170 if(cam->params.flicker_control.cam_register &
1169 CPIA2_VP_FLICKER_MODES_50HZ) { 1171 CPIA2_VP_FLICKER_MODES_50HZ) {
1170 mode = FLICKER_50; 1172 mode = FLICKER_50;
1171 } else { 1173 } else {
1172 mode = FLICKER_60; 1174 mode = FLICKER_60;
1173 } 1175 }
1174 } 1176 }
1175 for(i=0; i<NUM_FLICKER_CONTROLS; i++) { 1177 for(i=0; i<NUM_FLICKER_CONTROLS; i++) {
diff --git a/drivers/media/video/cpia_pp.c b/drivers/media/video/cpia_pp.c
index 0b00e6027df..4c89bd395d3 100644
--- a/drivers/media/video/cpia_pp.c
+++ b/drivers/media/video/cpia_pp.c
@@ -803,7 +803,7 @@ static struct parport_driver cpia_pp_driver = {
803 .detach = cpia_pp_detach, 803 .detach = cpia_pp_detach,
804}; 804};
805 805
806int cpia_pp_init(void) 806static int cpia_pp_init(void)
807{ 807{
808 printk(KERN_INFO "%s v%d.%d.%d\n",ABOUT, 808 printk(KERN_INFO "%s v%d.%d.%d\n",ABOUT,
809 CPIA_PP_MAJ_VER,CPIA_PP_MIN_VER,CPIA_PP_PATCH_VER); 809 CPIA_PP_MAJ_VER,CPIA_PP_MIN_VER,CPIA_PP_PATCH_VER);
@@ -860,6 +860,8 @@ void cleanup_module(void)
860 860
861static int __init cpia_pp_setup(char *str) 861static int __init cpia_pp_setup(char *str)
862{ 862{
863 int err;
864
863 if (!strncmp(str, "parport", 7)) { 865 if (!strncmp(str, "parport", 7)) {
864 int n = simple_strtoul(str + 7, NULL, 10); 866 int n = simple_strtoul(str + 7, NULL, 10);
865 if (parport_ptr < PARPORT_MAX) { 867 if (parport_ptr < PARPORT_MAX) {
@@ -873,6 +875,10 @@ static int __init cpia_pp_setup(char *str)
873 parport_nr[parport_ptr++] = PPCPIA_PARPORT_NONE; 875 parport_nr[parport_ptr++] = PPCPIA_PARPORT_NONE;
874 } 876 }
875 877
878 err=cpia_pp_init();
879 if (err)
880 return err;
881
876 return 1; 882 return 1;
877} 883}
878 884
diff --git a/drivers/media/video/cpia_usb.c b/drivers/media/video/cpia_usb.c
index 9c49a4b0011..2ee34a3b928 100644
--- a/drivers/media/video/cpia_usb.c
+++ b/drivers/media/video/cpia_usb.c
@@ -474,12 +474,6 @@ static int cpia_usb_close(void *privdata)
474 return 0; 474 return 0;
475} 475}
476 476
477int cpia_usb_init(void)
478{
479 /* return -ENODEV; */
480 return 0;
481}
482
483/* Probing and initializing */ 477/* Probing and initializing */
484 478
485static int cpia_probe(struct usb_interface *intf, 479static int cpia_probe(struct usb_interface *intf,
diff --git a/drivers/media/video/cx2341x.c b/drivers/media/video/cx2341x.c
new file mode 100644
index 00000000000..554813e6f65
--- /dev/null
+++ b/drivers/media/video/cx2341x.c
@@ -0,0 +1,915 @@
1/*
2 * cx2341x - generic code for cx23415/6 based devices
3 *
4 * Copyright (C) 2006 Hans Verkuil <hverkuil@xs4all.nl>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21
22#include <linux/module.h>
23#include <linux/moduleparam.h>
24#include <linux/errno.h>
25#include <linux/kernel.h>
26#include <linux/init.h>
27#include <linux/types.h>
28#include <linux/videodev2.h>
29#include <linux/i2c.h>
30
31#include <media/tuner.h>
32#include <media/cx2341x.h>
33#include <media/v4l2-common.h>
34
35MODULE_DESCRIPTION("cx23415/6 driver");
36MODULE_AUTHOR("Hans Verkuil");
37MODULE_LICENSE("GPL");
38
39static int debug = 0;
40module_param(debug, int, 0644);
41MODULE_PARM_DESC(debug, "Debug level (0-1)");
42
43const u32 cx2341x_mpeg_ctrls[] = {
44 V4L2_CID_MPEG_CLASS,
45 V4L2_CID_MPEG_STREAM_TYPE,
46 V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ,
47 V4L2_CID_MPEG_AUDIO_ENCODING,
48 V4L2_CID_MPEG_AUDIO_L2_BITRATE,
49 V4L2_CID_MPEG_AUDIO_MODE,
50 V4L2_CID_MPEG_AUDIO_MODE_EXTENSION,
51 V4L2_CID_MPEG_AUDIO_EMPHASIS,
52 V4L2_CID_MPEG_AUDIO_CRC,
53 V4L2_CID_MPEG_VIDEO_ENCODING,
54 V4L2_CID_MPEG_VIDEO_ASPECT,
55 V4L2_CID_MPEG_VIDEO_B_FRAMES,
56 V4L2_CID_MPEG_VIDEO_GOP_SIZE,
57 V4L2_CID_MPEG_VIDEO_GOP_CLOSURE,
58 V4L2_CID_MPEG_VIDEO_PULLDOWN,
59 V4L2_CID_MPEG_VIDEO_BITRATE_MODE,
60 V4L2_CID_MPEG_VIDEO_BITRATE,
61 V4L2_CID_MPEG_VIDEO_BITRATE_PEAK,
62 V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION,
63 V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE,
64 V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER,
65 V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE,
66 V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE,
67 V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE,
68 V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER,
69 V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE,
70 V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM,
71 V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP,
72 V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM,
73 V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP,
74 0
75};
76
77
78/* Map the control ID to the correct field in the cx2341x_mpeg_params
79 struct. Return -EINVAL if the ID is unknown, else return 0. */
80static int cx2341x_get_ctrl(struct cx2341x_mpeg_params *params,
81 struct v4l2_ext_control *ctrl)
82{
83 switch (ctrl->id) {
84 case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ:
85 ctrl->value = params->audio_sampling_freq;
86 break;
87 case V4L2_CID_MPEG_AUDIO_ENCODING:
88 ctrl->value = params->audio_encoding;
89 break;
90 case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
91 ctrl->value = params->audio_l2_bitrate;
92 break;
93 case V4L2_CID_MPEG_AUDIO_MODE:
94 ctrl->value = params->audio_mode;
95 break;
96 case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION:
97 ctrl->value = params->audio_mode_extension;
98 break;
99 case V4L2_CID_MPEG_AUDIO_EMPHASIS:
100 ctrl->value = params->audio_emphasis;
101 break;
102 case V4L2_CID_MPEG_AUDIO_CRC:
103 ctrl->value = params->audio_crc;
104 break;
105 case V4L2_CID_MPEG_VIDEO_ENCODING:
106 ctrl->value = params->video_encoding;
107 break;
108 case V4L2_CID_MPEG_VIDEO_ASPECT:
109 ctrl->value = params->video_aspect;
110 break;
111 case V4L2_CID_MPEG_VIDEO_B_FRAMES:
112 ctrl->value = params->video_b_frames;
113 break;
114 case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
115 ctrl->value = params->video_gop_size;
116 break;
117 case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE:
118 ctrl->value = params->video_gop_closure;
119 break;
120 case V4L2_CID_MPEG_VIDEO_PULLDOWN:
121 ctrl->value = params->video_pulldown;
122 break;
123 case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
124 ctrl->value = params->video_bitrate_mode;
125 break;
126 case V4L2_CID_MPEG_VIDEO_BITRATE:
127 ctrl->value = params->video_bitrate;
128 break;
129 case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
130 ctrl->value = params->video_bitrate_peak;
131 break;
132 case V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION:
133 ctrl->value = params->video_temporal_decimation;
134 break;
135 case V4L2_CID_MPEG_STREAM_TYPE:
136 ctrl->value = params->stream_type;
137 break;
138 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE:
139 ctrl->value = params->video_spatial_filter_mode;
140 break;
141 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER:
142 ctrl->value = params->video_spatial_filter;
143 break;
144 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE:
145 ctrl->value = params->video_luma_spatial_filter_type;
146 break;
147 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE:
148 ctrl->value = params->video_chroma_spatial_filter_type;
149 break;
150 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE:
151 ctrl->value = params->video_temporal_filter_mode;
152 break;
153 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER:
154 ctrl->value = params->video_temporal_filter;
155 break;
156 case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE:
157 ctrl->value = params->video_median_filter_type;
158 break;
159 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP:
160 ctrl->value = params->video_luma_median_filter_top;
161 break;
162 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM:
163 ctrl->value = params->video_luma_median_filter_bottom;
164 break;
165 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP:
166 ctrl->value = params->video_chroma_median_filter_top;
167 break;
168 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM:
169 ctrl->value = params->video_chroma_median_filter_bottom;
170 break;
171 default:
172 return -EINVAL;
173 }
174 return 0;
175}
176
177/* Map the control ID to the correct field in the cx2341x_mpeg_params
178 struct. Return -EINVAL if the ID is unknown, else return 0. */
179static int cx2341x_set_ctrl(struct cx2341x_mpeg_params *params,
180 struct v4l2_ext_control *ctrl)
181{
182 switch (ctrl->id) {
183 case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ:
184 params->audio_sampling_freq = ctrl->value;
185 break;
186 case V4L2_CID_MPEG_AUDIO_ENCODING:
187 params->audio_encoding = ctrl->value;
188 break;
189 case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
190 params->audio_l2_bitrate = ctrl->value;
191 break;
192 case V4L2_CID_MPEG_AUDIO_MODE:
193 params->audio_mode = ctrl->value;
194 break;
195 case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION:
196 params->audio_mode_extension = ctrl->value;
197 break;
198 case V4L2_CID_MPEG_AUDIO_EMPHASIS:
199 params->audio_emphasis = ctrl->value;
200 break;
201 case V4L2_CID_MPEG_AUDIO_CRC:
202 params->audio_crc = ctrl->value;
203 break;
204 case V4L2_CID_MPEG_VIDEO_ASPECT:
205 params->video_aspect = ctrl->value;
206 break;
207 case V4L2_CID_MPEG_VIDEO_B_FRAMES: {
208 int b = ctrl->value + 1;
209 int gop = params->video_gop_size;
210 params->video_b_frames = ctrl->value;
211 params->video_gop_size = b * ((gop + b - 1) / b);
212 /* Max GOP size = 34 */
213 while (params->video_gop_size > 34)
214 params->video_gop_size -= b;
215 break;
216 }
217 case V4L2_CID_MPEG_VIDEO_GOP_SIZE: {
218 int b = params->video_b_frames + 1;
219 int gop = ctrl->value;
220 params->video_gop_size = b * ((gop + b - 1) / b);
221 /* Max GOP size = 34 */
222 while (params->video_gop_size > 34)
223 params->video_gop_size -= b;
224 ctrl->value = params->video_gop_size;
225 break;
226 }
227 case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE:
228 params->video_gop_closure = ctrl->value;
229 break;
230 case V4L2_CID_MPEG_VIDEO_PULLDOWN:
231 params->video_pulldown = ctrl->value;
232 break;
233 case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
234 /* MPEG-1 only allows CBR */
235 if (params->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1 &&
236 ctrl->value != V4L2_MPEG_VIDEO_BITRATE_MODE_CBR)
237 return -EINVAL;
238 params->video_bitrate_mode = ctrl->value;
239 break;
240 case V4L2_CID_MPEG_VIDEO_BITRATE:
241 params->video_bitrate = ctrl->value;
242 break;
243 case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
244 params->video_bitrate_peak = ctrl->value;
245 break;
246 case V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION:
247 params->video_temporal_decimation = ctrl->value;
248 break;
249 case V4L2_CID_MPEG_STREAM_TYPE:
250 params->stream_type = ctrl->value;
251 params->video_encoding =
252 (params->stream_type == V4L2_MPEG_STREAM_TYPE_MPEG1_SS ||
253 params->stream_type == V4L2_MPEG_STREAM_TYPE_MPEG1_VCD) ?
254 V4L2_MPEG_VIDEO_ENCODING_MPEG_1 : V4L2_MPEG_VIDEO_ENCODING_MPEG_2;
255 if (params->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1) {
256 /* MPEG-1 implies CBR */
257 params->video_bitrate_mode = V4L2_MPEG_VIDEO_BITRATE_MODE_CBR;
258 }
259 break;
260 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE:
261 params->video_spatial_filter_mode = ctrl->value;
262 break;
263 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER:
264 params->video_spatial_filter = ctrl->value;
265 break;
266 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE:
267 params->video_luma_spatial_filter_type = ctrl->value;
268 break;
269 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE:
270 params->video_chroma_spatial_filter_type = ctrl->value;
271 break;
272 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE:
273 params->video_temporal_filter_mode = ctrl->value;
274 break;
275 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER:
276 params->video_temporal_filter = ctrl->value;
277 break;
278 case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE:
279 params->video_median_filter_type = ctrl->value;
280 break;
281 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP:
282 params->video_luma_median_filter_top = ctrl->value;
283 break;
284 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM:
285 params->video_luma_median_filter_bottom = ctrl->value;
286 break;
287 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP:
288 params->video_chroma_median_filter_top = ctrl->value;
289 break;
290 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM:
291 params->video_chroma_median_filter_bottom = ctrl->value;
292 break;
293 default:
294 return -EINVAL;
295 }
296 return 0;
297}
298
299static int cx2341x_ctrl_query_fill(struct v4l2_queryctrl *qctrl, s32 min, s32 max, s32 step, s32 def)
300{
301 const char *name;
302
303 qctrl->flags = 0;
304 switch (qctrl->id) {
305 /* MPEG controls */
306 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE:
307 name = "Spatial Filter Mode";
308 break;
309 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER:
310 name = "Spatial Filter";
311 break;
312 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE:
313 name = "Spatial Luma Filter Type";
314 break;
315 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE:
316 name = "Spatial Chroma Filter Type";
317 break;
318 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE:
319 name = "Temporal Filter Mode";
320 break;
321 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER:
322 name = "Temporal Filter";
323 break;
324 case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE:
325 name = "Median Filter Type";
326 break;
327 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP:
328 name = "Median Luma Filter Maximum";
329 break;
330 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM:
331 name = "Median Luma Filter Minimum";
332 break;
333 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP:
334 name = "Median Chroma Filter Maximum";
335 break;
336 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM:
337 name = "Median Chroma Filter Minimum";
338 break;
339
340 default:
341 return v4l2_ctrl_query_fill(qctrl, min, max, step, def);
342 }
343 switch (qctrl->id) {
344 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE:
345 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE:
346 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE:
347 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE:
348 case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE:
349 qctrl->type = V4L2_CTRL_TYPE_MENU;
350 min = 0;
351 step = 1;
352 break;
353 default:
354 qctrl->type = V4L2_CTRL_TYPE_INTEGER;
355 break;
356 }
357 switch (qctrl->id) {
358 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE:
359 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE:
360 case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE:
361 qctrl->flags |= V4L2_CTRL_FLAG_UPDATE;
362 break;
363 }
364 qctrl->minimum = min;
365 qctrl->maximum = max;
366 qctrl->step = step;
367 qctrl->default_value = def;
368 qctrl->reserved[0] = qctrl->reserved[1] = 0;
369 snprintf(qctrl->name, sizeof(qctrl->name), name);
370 return 0;
371}
372
373int cx2341x_ctrl_query(struct cx2341x_mpeg_params *params, struct v4l2_queryctrl *qctrl)
374{
375 int err;
376
377 switch (qctrl->id) {
378 case V4L2_CID_MPEG_AUDIO_ENCODING:
379 return v4l2_ctrl_query_fill(qctrl,
380 V4L2_MPEG_AUDIO_ENCODING_LAYER_2,
381 V4L2_MPEG_AUDIO_ENCODING_LAYER_2, 1,
382 V4L2_MPEG_AUDIO_ENCODING_LAYER_2);
383
384 case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
385 return v4l2_ctrl_query_fill(qctrl,
386 V4L2_MPEG_AUDIO_L2_BITRATE_192K,
387 V4L2_MPEG_AUDIO_L2_BITRATE_384K, 1,
388 V4L2_MPEG_AUDIO_L2_BITRATE_224K);
389
390 case V4L2_CID_MPEG_AUDIO_L1_BITRATE:
391 case V4L2_CID_MPEG_AUDIO_L3_BITRATE:
392 return -EINVAL;
393
394 case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION:
395 err = v4l2_ctrl_query_fill_std(qctrl);
396 if (err == 0 && params->audio_mode != V4L2_MPEG_AUDIO_MODE_JOINT_STEREO)
397 qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
398 return err;
399
400 case V4L2_CID_MPEG_VIDEO_ENCODING:
401 /* this setting is read-only for the cx2341x since the
402 V4L2_CID_MPEG_STREAM_TYPE really determines the
403 MPEG-1/2 setting */
404 err = v4l2_ctrl_query_fill_std(qctrl);
405 if (err == 0)
406 qctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
407 return err;
408
409 case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
410 err = v4l2_ctrl_query_fill_std(qctrl);
411 if (err == 0 && params->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1)
412 qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
413 return err;
414
415 case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
416 err = v4l2_ctrl_query_fill_std(qctrl);
417 if (err == 0 && params->video_bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR)
418 qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
419 return err;
420
421 /* CX23415/6 specific */
422 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE:
423 return cx2341x_ctrl_query_fill(qctrl,
424 V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_MANUAL,
425 V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO, 1,
426 V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_MANUAL);
427
428 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER:
429 cx2341x_ctrl_query_fill(qctrl, 0, 15, 1, 0);
430 qctrl->flags |= V4L2_CTRL_FLAG_SLIDER;
431 if (params->video_spatial_filter_mode == V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO)
432 qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
433 return 0;
434
435 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE:
436 cx2341x_ctrl_query_fill(qctrl,
437 V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_OFF,
438 V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_2D_SYM_NON_SEPARABLE, 1,
439 V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_OFF);
440 if (params->video_spatial_filter_mode == V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO)
441 qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
442 return 0;
443
444 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE:
445 cx2341x_ctrl_query_fill(qctrl,
446 V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_OFF,
447 V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_1D_HOR, 1,
448 V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_OFF);
449 if (params->video_spatial_filter_mode == V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO)
450 qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
451 return 0;
452
453 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE:
454 return cx2341x_ctrl_query_fill(qctrl,
455 V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_MANUAL,
456 V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_AUTO, 1,
457 V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_MANUAL);
458
459 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER:
460 cx2341x_ctrl_query_fill(qctrl, 0, 31, 1, 0);
461 qctrl->flags |= V4L2_CTRL_FLAG_SLIDER;
462 if (params->video_temporal_filter_mode == V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_AUTO)
463 qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
464 return 0;
465
466 case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE:
467 return cx2341x_ctrl_query_fill(qctrl,
468 V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF,
469 V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_DIAG, 1,
470 V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF);
471
472 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP:
473 cx2341x_ctrl_query_fill(qctrl, 0, 255, 1, 255);
474 qctrl->flags |= V4L2_CTRL_FLAG_SLIDER;
475 if (params->video_median_filter_type == V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF)
476 qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
477 return 0;
478
479 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM:
480 cx2341x_ctrl_query_fill(qctrl, 0, 255, 1, 0);
481 qctrl->flags |= V4L2_CTRL_FLAG_SLIDER;
482 if (params->video_median_filter_type == V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF)
483 qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
484 return 0;
485
486 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP:
487 cx2341x_ctrl_query_fill(qctrl, 0, 255, 1, 255);
488 qctrl->flags |= V4L2_CTRL_FLAG_SLIDER;
489 if (params->video_median_filter_type == V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF)
490 qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
491 return 0;
492
493 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM:
494 cx2341x_ctrl_query_fill(qctrl, 0, 255, 1, 0);
495 qctrl->flags |= V4L2_CTRL_FLAG_SLIDER;
496 if (params->video_median_filter_type == V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF)
497 qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
498 return 0;
499
500 default:
501 return v4l2_ctrl_query_fill_std(qctrl);
502
503 }
504}
505
506const char **cx2341x_ctrl_get_menu(u32 id)
507{
508 static const char *mpeg_stream_type[] = {
509 "MPEG-2 Program Stream",
510 "",
511 "MPEG-1 System Stream",
512 "MPEG-2 DVD-compatible Stream",
513 "MPEG-1 VCD-compatible Stream",
514 "MPEG-2 SVCD-compatible Stream",
515 NULL
516 };
517
518 static const char *cx2341x_video_spatial_filter_mode_menu[] = {
519 "Manual",
520 "Auto",
521 NULL
522 };
523
524 static const char *cx2341x_video_luma_spatial_filter_type_menu[] = {
525 "Off",
526 "1D Horizontal",
527 "1D Vertical",
528 "2D H/V Separable",
529 "2D Symmetric non-separable",
530 NULL
531 };
532
533 static const char *cx2341x_video_chroma_spatial_filter_type_menu[] = {
534 "Off",
535 "1D Horizontal",
536 NULL
537 };
538
539 static const char *cx2341x_video_temporal_filter_mode_menu[] = {
540 "Manual",
541 "Auto",
542 NULL
543 };
544
545 static const char *cx2341x_video_median_filter_type_menu[] = {
546 "Off",
547 "Horizontal",
548 "Vertical",
549 "Horizontal/Vertical",
550 "Diagonal",
551 NULL
552 };
553
554 switch (id) {
555 case V4L2_CID_MPEG_STREAM_TYPE:
556 return mpeg_stream_type;
557 case V4L2_CID_MPEG_AUDIO_L1_BITRATE:
558 case V4L2_CID_MPEG_AUDIO_L3_BITRATE:
559 return NULL;
560 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE:
561 return cx2341x_video_spatial_filter_mode_menu;
562 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE:
563 return cx2341x_video_luma_spatial_filter_type_menu;
564 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE:
565 return cx2341x_video_chroma_spatial_filter_type_menu;
566 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE:
567 return cx2341x_video_temporal_filter_mode_menu;
568 case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE:
569 return cx2341x_video_median_filter_type_menu;
570 default:
571 return v4l2_ctrl_get_menu(id);
572 }
573}
574
575static void cx2341x_calc_audio_properties(struct cx2341x_mpeg_params *params)
576{
577 params->audio_properties = (params->audio_sampling_freq << 0) |
578 ((3 - params->audio_encoding) << 2) |
579 ((1 + params->audio_l2_bitrate) << 4) |
580 (params->audio_mode << 8) |
581 (params->audio_mode_extension << 10) |
582 (((params->audio_emphasis == V4L2_MPEG_AUDIO_EMPHASIS_CCITT_J17) ?
583 3 :
584 params->audio_emphasis) << 12) |
585 (params->audio_crc << 14);
586}
587
588int cx2341x_ext_ctrls(struct cx2341x_mpeg_params *params,
589 struct v4l2_ext_controls *ctrls, int cmd)
590{
591 int err = 0;
592 int i;
593
594 if (cmd == VIDIOC_G_EXT_CTRLS) {
595 for (i = 0; i < ctrls->count; i++) {
596 struct v4l2_ext_control *ctrl = ctrls->controls + i;
597
598 err = cx2341x_get_ctrl(params, ctrl);
599 if (err) {
600 ctrls->error_idx = i;
601 break;
602 }
603 }
604 return err;
605 }
606 for (i = 0; i < ctrls->count; i++) {
607 struct v4l2_ext_control *ctrl = ctrls->controls + i;
608 struct v4l2_queryctrl qctrl;
609 const char **menu_items = NULL;
610
611 qctrl.id = ctrl->id;
612 err = cx2341x_ctrl_query(params, &qctrl);
613 if (err)
614 break;
615 if (qctrl.type == V4L2_CTRL_TYPE_MENU)
616 menu_items = cx2341x_ctrl_get_menu(qctrl.id);
617 err = v4l2_ctrl_check(ctrl, &qctrl, menu_items);
618 if (err)
619 break;
620 err = cx2341x_set_ctrl(params, ctrl);
621 if (err)
622 break;
623 }
624 if (err == 0 && params->video_bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR &&
625 params->video_bitrate_peak < params->video_bitrate) {
626 err = -ERANGE;
627 ctrls->error_idx = ctrls->count;
628 }
629 if (err) {
630 ctrls->error_idx = i;
631 }
632 else {
633 cx2341x_calc_audio_properties(params);
634 }
635 return err;
636}
637
638void cx2341x_fill_defaults(struct cx2341x_mpeg_params *p)
639{
640 static struct cx2341x_mpeg_params default_params = {
641 /* misc */
642 .port = CX2341X_PORT_MEMORY,
643 .width = 720,
644 .height = 480,
645 .is_50hz = 0,
646
647 /* stream */
648 .stream_type = V4L2_MPEG_STREAM_TYPE_MPEG2_PS,
649
650 /* audio */
651 .audio_sampling_freq = V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000,
652 .audio_encoding = V4L2_MPEG_AUDIO_ENCODING_LAYER_2,
653 .audio_l2_bitrate = V4L2_MPEG_AUDIO_L2_BITRATE_224K,
654 .audio_mode = V4L2_MPEG_AUDIO_MODE_STEREO,
655 .audio_mode_extension = V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_4,
656 .audio_emphasis = V4L2_MPEG_AUDIO_EMPHASIS_NONE,
657 .audio_crc = V4L2_MPEG_AUDIO_CRC_NONE,
658
659 /* video */
660 .video_encoding = V4L2_MPEG_VIDEO_ENCODING_MPEG_2,
661 .video_aspect = V4L2_MPEG_VIDEO_ASPECT_4x3,
662 .video_b_frames = 2,
663 .video_gop_size = 12,
664 .video_gop_closure = 1,
665 .video_pulldown = 0,
666 .video_bitrate_mode = V4L2_MPEG_VIDEO_BITRATE_MODE_VBR,
667 .video_bitrate = 6000000,
668 .video_bitrate_peak = 8000000,
669 .video_temporal_decimation = 0,
670
671 /* encoding filters */
672 .video_spatial_filter_mode = V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_MANUAL,
673 .video_spatial_filter = 0,
674 .video_luma_spatial_filter_type = V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_1D_HOR,
675 .video_chroma_spatial_filter_type = V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_1D_HOR,
676 .video_temporal_filter_mode = V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_MANUAL,
677 .video_temporal_filter = 0,
678 .video_median_filter_type = V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF,
679 .video_luma_median_filter_top = 255,
680 .video_luma_median_filter_bottom = 0,
681 .video_chroma_median_filter_top = 255,
682 .video_chroma_median_filter_bottom = 0,
683 };
684
685 *p = default_params;
686 cx2341x_calc_audio_properties(p);
687}
688
689static int cx2341x_api(void *priv, cx2341x_mbox_func func, int cmd, int args, ...)
690{
691 u32 data[CX2341X_MBOX_MAX_DATA];
692 va_list vargs;
693 int i;
694
695 va_start(vargs, args);
696
697 for (i = 0; i < args; i++) {
698 data[i] = va_arg(vargs, int);
699 }
700 va_end(vargs);
701 return func(priv, cmd, args, 0, data);
702}
703
704int cx2341x_update(void *priv, cx2341x_mbox_func func,
705 const struct cx2341x_mpeg_params *old, const struct cx2341x_mpeg_params *new)
706{
707 static int mpeg_stream_type[] = {
708 0, /* MPEG-2 PS */
709 1, /* MPEG-2 TS */
710 2, /* MPEG-1 SS */
711 14, /* DVD */
712 11, /* VCD */
713 12, /* SVCD */
714 };
715
716 int err = 0;
717
718 cx2341x_api(priv, func, CX2341X_ENC_SET_OUTPUT_PORT, 2, new->port, 0);
719
720 if (old == NULL || old->is_50hz != new->is_50hz) {
721 err = cx2341x_api(priv, func, CX2341X_ENC_SET_FRAME_RATE, 1, new->is_50hz);
722 if (err) return err;
723 }
724
725 if (old == NULL || old->width != new->width || old->height != new->height ||
726 old->video_encoding != new->video_encoding) {
727 u16 w = new->width;
728 u16 h = new->height;
729
730 if (new->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1) {
731 w /= 2;
732 h /= 2;
733 }
734 err = cx2341x_api(priv, func, CX2341X_ENC_SET_FRAME_SIZE, 2, h, w);
735 if (err) return err;
736 }
737
738 if (old == NULL || old->stream_type != new->stream_type) {
739 err = cx2341x_api(priv, func, CX2341X_ENC_SET_STREAM_TYPE, 1, mpeg_stream_type[new->stream_type]);
740 if (err) return err;
741 }
742 if (old == NULL || old->video_aspect != new->video_aspect) {
743 err = cx2341x_api(priv, func, CX2341X_ENC_SET_ASPECT_RATIO, 1, 1 + new->video_aspect);
744 if (err) return err;
745 }
746 if (old == NULL || old->video_b_frames != new->video_b_frames ||
747 old->video_gop_size != new->video_gop_size) {
748 err = cx2341x_api(priv, func, CX2341X_ENC_SET_GOP_PROPERTIES, 2,
749 new->video_gop_size, new->video_b_frames + 1);
750 if (err) return err;
751 }
752 if (old == NULL || old->video_gop_closure != new->video_gop_closure) {
753 err = cx2341x_api(priv, func, CX2341X_ENC_SET_GOP_CLOSURE, 1, new->video_gop_closure);
754 if (err) return err;
755 }
756 if (old == NULL || old->video_pulldown != new->video_pulldown) {
757 err = cx2341x_api(priv, func, CX2341X_ENC_SET_3_2_PULLDOWN, 1, new->video_pulldown);
758 if (err) return err;
759 }
760 if (old == NULL || old->audio_properties != new->audio_properties) {
761 err = cx2341x_api(priv, func, CX2341X_ENC_SET_AUDIO_PROPERTIES, 1, new->audio_properties);
762 if (err) return err;
763 }
764 if (old == NULL || old->video_bitrate_mode != new->video_bitrate_mode ||
765 old->video_bitrate != new->video_bitrate ||
766 old->video_bitrate_peak != new->video_bitrate_peak) {
767 err = cx2341x_api(priv, func, CX2341X_ENC_SET_BIT_RATE, 5,
768 new->video_bitrate_mode, new->video_bitrate,
769 new->video_bitrate_peak / 400, 0, 0);
770 if (err) return err;
771 }
772 if (old == NULL || old->video_spatial_filter_mode != new->video_spatial_filter_mode ||
773 old->video_temporal_filter_mode != new->video_temporal_filter_mode ||
774 old->video_median_filter_type != new->video_median_filter_type) {
775 err = cx2341x_api(priv, func, CX2341X_ENC_SET_DNR_FILTER_MODE, 2,
776 new->video_spatial_filter_mode | (new->video_temporal_filter_mode << 1),
777 new->video_median_filter_type);
778 if (err) return err;
779 }
780 if (old == NULL ||
781 old->video_luma_median_filter_bottom != new->video_luma_median_filter_bottom ||
782 old->video_luma_median_filter_top != new->video_luma_median_filter_top ||
783 old->video_chroma_median_filter_bottom != new->video_chroma_median_filter_bottom ||
784 old->video_chroma_median_filter_top != new->video_chroma_median_filter_top) {
785 err = cx2341x_api(priv, func, CX2341X_ENC_SET_CORING_LEVELS, 4,
786 new->video_luma_median_filter_bottom,
787 new->video_luma_median_filter_top,
788 new->video_chroma_median_filter_bottom,
789 new->video_chroma_median_filter_top);
790 if (err) return err;
791 }
792 if (old == NULL ||
793 old->video_luma_spatial_filter_type != new->video_luma_spatial_filter_type ||
794 old->video_chroma_spatial_filter_type != new->video_chroma_spatial_filter_type) {
795 err = cx2341x_api(priv, func, CX2341X_ENC_SET_SPATIAL_FILTER_TYPE, 2,
796 new->video_luma_spatial_filter_type, new->video_chroma_spatial_filter_type);
797 if (err) return err;
798 }
799 if (old == NULL ||
800 old->video_spatial_filter != new->video_spatial_filter ||
801 old->video_temporal_filter != new->video_temporal_filter) {
802 err = cx2341x_api(priv, func, CX2341X_ENC_SET_DNR_FILTER_PROPS, 2,
803 new->video_spatial_filter, new->video_temporal_filter);
804 if (err) return err;
805 }
806 if (old == NULL || old->video_temporal_decimation != new->video_temporal_decimation) {
807 err = cx2341x_api(priv, func, CX2341X_ENC_SET_FRAME_DROP_RATE, 1,
808 new->video_temporal_decimation);
809 if (err) return err;
810 }
811 return 0;
812}
813
814static const char *cx2341x_menu_item(struct cx2341x_mpeg_params *p, u32 id)
815{
816 const char **menu = cx2341x_ctrl_get_menu(id);
817 struct v4l2_ext_control ctrl;
818
819 if (menu == NULL)
820 goto invalid;
821 ctrl.id = id;
822 if (cx2341x_get_ctrl(p, &ctrl))
823 goto invalid;
824 while (ctrl.value-- && *menu) menu++;
825 if (*menu == NULL)
826 goto invalid;
827 return *menu;
828
829invalid:
830 return "<invalid>";
831}
832
833void cx2341x_log_status(struct cx2341x_mpeg_params *p, int card_id)
834{
835 int is_mpeg1 = p->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1;
836
837 /* Stream */
838 printk(KERN_INFO "cx2341x-%d: Stream: %s\n",
839 card_id,
840 cx2341x_menu_item(p, V4L2_CID_MPEG_STREAM_TYPE));
841
842 /* Video */
843 printk(KERN_INFO "cx2341x-%d: Video: %dx%d, %d fps\n",
844 card_id,
845 p->width / (is_mpeg1 ? 2 : 1), p->height / (is_mpeg1 ? 2 : 1),
846 p->is_50hz ? 25 : 30);
847 printk(KERN_INFO "cx2341x-%d: Video: %s, %s, %s, %d",
848 card_id,
849 cx2341x_menu_item(p, V4L2_CID_MPEG_VIDEO_ENCODING),
850 cx2341x_menu_item(p, V4L2_CID_MPEG_VIDEO_ASPECT),
851 cx2341x_menu_item(p, V4L2_CID_MPEG_VIDEO_BITRATE_MODE),
852 p->video_bitrate);
853 if (p->video_bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR) {
854 printk(", Peak %d", p->video_bitrate_peak);
855 }
856 printk("\n");
857 printk(KERN_INFO "cx2341x-%d: Video: GOP Size %d, %d B-Frames, %sGOP Closure, %s3:2 Pulldown\n",
858 card_id,
859 p->video_gop_size, p->video_b_frames,
860 p->video_gop_closure ? "" : "No ",
861 p->video_pulldown ? "" : "No ");
862 if (p->video_temporal_decimation) {
863 printk(KERN_INFO "cx2341x-%d: Video: Temporal Decimation %d\n",
864 card_id, p->video_temporal_decimation);
865 }
866
867 /* Audio */
868 printk(KERN_INFO "cx2341x-%d: Audio: %s, %s, %s, %s",
869 card_id,
870 cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ),
871 cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_ENCODING),
872 cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_L2_BITRATE),
873 cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_MODE));
874 if (p->audio_mode == V4L2_MPEG_AUDIO_MODE_JOINT_STEREO) {
875 printk(", %s",
876 cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_MODE_EXTENSION));
877 }
878 printk(", %s, %s\n",
879 cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_EMPHASIS),
880 cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_CRC));
881
882 /* Encoding filters */
883 printk(KERN_INFO "cx2341x-%d: Spatial Filter: %s, Luma %s, Chroma %s, %d\n",
884 card_id,
885 cx2341x_menu_item(p, V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE),
886 cx2341x_menu_item(p, V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE),
887 cx2341x_menu_item(p, V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE),
888 p->video_spatial_filter);
889 printk(KERN_INFO "cx2341x-%d: Temporal Filter: %s, %d\n",
890 card_id,
891 cx2341x_menu_item(p, V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE),
892 p->video_temporal_filter);
893 printk(KERN_INFO "cx2341x-%d: Median Filter: %s, Luma [%d, %d], Chroma [%d, %d]\n",
894 card_id,
895 cx2341x_menu_item(p, V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE),
896 p->video_luma_median_filter_bottom,
897 p->video_luma_median_filter_top,
898 p->video_chroma_median_filter_bottom,
899 p->video_chroma_median_filter_top);
900}
901
902EXPORT_SYMBOL(cx2341x_fill_defaults);
903EXPORT_SYMBOL(cx2341x_ctrl_query);
904EXPORT_SYMBOL(cx2341x_ctrl_get_menu);
905EXPORT_SYMBOL(cx2341x_ext_ctrls);
906EXPORT_SYMBOL(cx2341x_update);
907EXPORT_SYMBOL(cx2341x_log_status);
908EXPORT_SYMBOL(cx2341x_mpeg_ctrls);
909
910/*
911 * Local variables:
912 * c-basic-offset: 8
913 * End:
914 */
915
diff --git a/drivers/media/video/cx25840/cx25840-audio.c b/drivers/media/video/cx25840/cx25840-audio.c
index 9a4b813152e..f897c1ebd5f 100644
--- a/drivers/media/video/cx25840/cx25840-audio.c
+++ b/drivers/media/video/cx25840/cx25840-audio.c
@@ -30,9 +30,6 @@ static int set_audclk_freq(struct i2c_client *client, u32 freq)
30 if (freq != 32000 && freq != 44100 && freq != 48000) 30 if (freq != 32000 && freq != 44100 && freq != 48000)
31 return -EINVAL; 31 return -EINVAL;
32 32
33 /* assert soft reset */
34 cx25840_and_or(client, 0x810, ~0x1, 0x01);
35
36 /* common for all inputs and rates */ 33 /* common for all inputs and rates */
37 /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x10 */ 34 /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x10 */
38 cx25840_write(client, 0x127, 0x50); 35 cx25840_write(client, 0x127, 0x50);
@@ -46,6 +43,9 @@ static int set_audclk_freq(struct i2c_client *client, u32 freq)
46 /* AUX_PLL_FRAC */ 43 /* AUX_PLL_FRAC */
47 cx25840_write4(client, 0x110, 0xee39bb01); 44 cx25840_write4(client, 0x110, 0xee39bb01);
48 45
46 if (state->is_cx25836)
47 break;
48
49 /* src3/4/6_ctl = 0x0801f77f */ 49 /* src3/4/6_ctl = 0x0801f77f */
50 cx25840_write4(client, 0x900, 0x7ff70108); 50 cx25840_write4(client, 0x900, 0x7ff70108);
51 cx25840_write4(client, 0x904, 0x7ff70108); 51 cx25840_write4(client, 0x904, 0x7ff70108);
@@ -59,6 +59,9 @@ static int set_audclk_freq(struct i2c_client *client, u32 freq)
59 /* AUX_PLL_FRAC */ 59 /* AUX_PLL_FRAC */
60 cx25840_write4(client, 0x110, 0xd66bec00); 60 cx25840_write4(client, 0x110, 0xd66bec00);
61 61
62 if (state->is_cx25836)
63 break;
64
62 /* src3/4/6_ctl = 0x08016d59 */ 65 /* src3/4/6_ctl = 0x08016d59 */
63 cx25840_write4(client, 0x900, 0x596d0108); 66 cx25840_write4(client, 0x900, 0x596d0108);
64 cx25840_write4(client, 0x904, 0x596d0108); 67 cx25840_write4(client, 0x904, 0x596d0108);
@@ -72,6 +75,9 @@ static int set_audclk_freq(struct i2c_client *client, u32 freq)
72 /* AUX_PLL_FRAC */ 75 /* AUX_PLL_FRAC */
73 cx25840_write4(client, 0x110, 0xe5d69800); 76 cx25840_write4(client, 0x110, 0xe5d69800);
74 77
78 if (state->is_cx25836)
79 break;
80
75 /* src3/4/6_ctl = 0x08014faa */ 81 /* src3/4/6_ctl = 0x08014faa */
76 cx25840_write4(client, 0x900, 0xaa4f0108); 82 cx25840_write4(client, 0x900, 0xaa4f0108);
77 cx25840_write4(client, 0x904, 0xaa4f0108); 83 cx25840_write4(client, 0x904, 0xaa4f0108);
@@ -87,6 +93,9 @@ static int set_audclk_freq(struct i2c_client *client, u32 freq)
87 /* AUX_PLL_FRAC */ 93 /* AUX_PLL_FRAC */
88 cx25840_write4(client, 0x110, 0x69082a01); 94 cx25840_write4(client, 0x110, 0x69082a01);
89 95
96 if (state->is_cx25836)
97 break;
98
90 /* src1_ctl = 0x08010000 */ 99 /* src1_ctl = 0x08010000 */
91 cx25840_write4(client, 0x8f8, 0x00000108); 100 cx25840_write4(client, 0x8f8, 0x00000108);
92 101
@@ -106,6 +115,9 @@ static int set_audclk_freq(struct i2c_client *client, u32 freq)
106 /* AUX_PLL_FRAC */ 115 /* AUX_PLL_FRAC */
107 cx25840_write4(client, 0x110, 0xd66bec00); 116 cx25840_write4(client, 0x110, 0xd66bec00);
108 117
118 if (state->is_cx25836)
119 break;
120
109 /* src1_ctl = 0x08010000 */ 121 /* src1_ctl = 0x08010000 */
110 cx25840_write4(client, 0x8f8, 0xcd600108); 122 cx25840_write4(client, 0x8f8, 0xcd600108);
111 123
@@ -122,6 +134,9 @@ static int set_audclk_freq(struct i2c_client *client, u32 freq)
122 /* AUX_PLL_FRAC */ 134 /* AUX_PLL_FRAC */
123 cx25840_write4(client, 0x110, 0xe5d69800); 135 cx25840_write4(client, 0x110, 0xe5d69800);
124 136
137 if (state->is_cx25836)
138 break;
139
125 /* src1_ctl = 0x08010000 */ 140 /* src1_ctl = 0x08010000 */
126 cx25840_write4(client, 0x8f8, 0x00800108); 141 cx25840_write4(client, 0x8f8, 0x00800108);
127 142
@@ -133,9 +148,6 @@ static int set_audclk_freq(struct i2c_client *client, u32 freq)
133 } 148 }
134 } 149 }
135 150
136 /* deassert soft reset */
137 cx25840_and_or(client, 0x810, ~0x1, 0x00);
138
139 state->audclk_freq = freq; 151 state->audclk_freq = freq;
140 152
141 return 0; 153 return 0;
@@ -148,6 +160,10 @@ void cx25840_audio_set_path(struct i2c_client *client)
148 /* stop microcontroller */ 160 /* stop microcontroller */
149 cx25840_and_or(client, 0x803, ~0x10, 0); 161 cx25840_and_or(client, 0x803, ~0x10, 0);
150 162
163 /* assert soft reset */
164 if (!state->is_cx25836)
165 cx25840_and_or(client, 0x810, ~0x1, 0x01);
166
151 /* Mute everything to prevent the PFFT! */ 167 /* Mute everything to prevent the PFFT! */
152 cx25840_write(client, 0x8d3, 0x1f); 168 cx25840_write(client, 0x8d3, 0x1f);
153 169
@@ -161,13 +177,19 @@ void cx25840_audio_set_path(struct i2c_client *client)
161 } else { 177 } else {
162 /* Set Path1 to Analog Demod Main Channel */ 178 /* Set Path1 to Analog Demod Main Channel */
163 cx25840_write4(client, 0x8d0, 0x7038061f); 179 cx25840_write4(client, 0x8d0, 0x7038061f);
180 }
164 181
182 set_audclk_freq(client, state->audclk_freq);
183
184 /* deassert soft reset */
185 if (!state->is_cx25836)
186 cx25840_and_or(client, 0x810, ~0x1, 0x00);
187
188 if (state->aud_input != CX25840_AUDIO_SERIAL) {
165 /* When the microcontroller detects the 189 /* When the microcontroller detects the
166 * audio format, it will unmute the lines */ 190 * audio format, it will unmute the lines */
167 cx25840_and_or(client, 0x803, ~0x10, 0x10); 191 cx25840_and_or(client, 0x803, ~0x10, 0x10);
168 } 192 }
169
170 set_audclk_freq(client, state->audclk_freq);
171} 193}
172 194
173static int get_volume(struct i2c_client *client) 195static int get_volume(struct i2c_client *client)
@@ -291,11 +313,25 @@ static void set_mute(struct i2c_client *client, int mute)
291 313
292int cx25840_audio(struct i2c_client *client, unsigned int cmd, void *arg) 314int cx25840_audio(struct i2c_client *client, unsigned int cmd, void *arg)
293{ 315{
316 struct cx25840_state *state = i2c_get_clientdata(client);
294 struct v4l2_control *ctrl = arg; 317 struct v4l2_control *ctrl = arg;
318 int retval;
295 319
296 switch (cmd) { 320 switch (cmd) {
297 case VIDIOC_INT_AUDIO_CLOCK_FREQ: 321 case VIDIOC_INT_AUDIO_CLOCK_FREQ:
298 return set_audclk_freq(client, *(u32 *)arg); 322 if (state->aud_input != CX25840_AUDIO_SERIAL) {
323 cx25840_and_or(client, 0x803, ~0x10, 0);
324 cx25840_write(client, 0x8d3, 0x1f);
325 }
326 if (!state->is_cx25836)
327 cx25840_and_or(client, 0x810, ~0x1, 1);
328 retval = set_audclk_freq(client, *(u32 *)arg);
329 if (!state->is_cx25836)
330 cx25840_and_or(client, 0x810, ~0x1, 0);
331 if (state->aud_input != CX25840_AUDIO_SERIAL) {
332 cx25840_and_or(client, 0x803, ~0x10, 0x10);
333 }
334 return retval;
299 335
300 case VIDIOC_G_CTRL: 336 case VIDIOC_G_CTRL:
301 switch (ctrl->id) { 337 switch (ctrl->id) {
diff --git a/drivers/media/video/cx25840/cx25840-core.c b/drivers/media/video/cx25840/cx25840-core.c
index a961bb2ab0f..5c2036b40ea 100644
--- a/drivers/media/video/cx25840/cx25840-core.c
+++ b/drivers/media/video/cx25840/cx25840-core.c
@@ -10,6 +10,9 @@
10 * 10 *
11 * VBI support by Hans Verkuil <hverkuil@xs4all.nl>. 11 * VBI support by Hans Verkuil <hverkuil@xs4all.nl>.
12 * 12 *
13 * NTSC sliced VBI support by Christopher Neufeld <television@cneufeld.ca>
14 * with additional fixes by Hans Verkuil <hverkuil@xs4all.nl>.
15 *
13 * This program is free software; you can redistribute it and/or 16 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License 17 * modify it under the terms of the GNU General Public License
15 * as published by the Free Software Foundation; either version 2 18 * as published by the Free Software Foundation; either version 2
@@ -43,7 +46,7 @@ MODULE_LICENSE("GPL");
43static unsigned short normal_i2c[] = { 0x88 >> 1, I2C_CLIENT_END }; 46static unsigned short normal_i2c[] = { 0x88 >> 1, I2C_CLIENT_END };
44 47
45 48
46static int cx25840_debug; 49int cx25840_debug;
47 50
48module_param_named(debug,cx25840_debug, int, 0644); 51module_param_named(debug,cx25840_debug, int, 0644);
49 52
@@ -105,7 +108,7 @@ u32 cx25840_read4(struct i2c_client * client, u16 addr)
105 (buffer[2] << 8) | buffer[3]; 108 (buffer[2] << 8) | buffer[3];
106} 109}
107 110
108int cx25840_and_or(struct i2c_client *client, u16 addr, u8 and_mask, 111int cx25840_and_or(struct i2c_client *client, u16 addr, unsigned and_mask,
109 u8 or_value) 112 u8 or_value)
110{ 113{
111 return cx25840_write(client, addr, 114 return cx25840_write(client, addr,
@@ -117,7 +120,8 @@ int cx25840_and_or(struct i2c_client *client, u16 addr, u8 and_mask,
117 120
118static int set_input(struct i2c_client *client, enum cx25840_video_input vid_input, 121static int set_input(struct i2c_client *client, enum cx25840_video_input vid_input,
119 enum cx25840_audio_input aud_input); 122 enum cx25840_audio_input aud_input);
120static void log_status(struct i2c_client *client); 123static void log_audio_status(struct i2c_client *client);
124static void log_video_status(struct i2c_client *client);
121 125
122/* ----------------------------------------------------------------------- */ 126/* ----------------------------------------------------------------------- */
123 127
@@ -147,6 +151,33 @@ static void init_dll2(struct i2c_client *client)
147 cx25840_write(client, 0x15d, 0xe1); 151 cx25840_write(client, 0x15d, 0xe1);
148} 152}
149 153
154static void cx25836_initialize(struct i2c_client *client)
155{
156 /* reset configuration is described on page 3-77 of the CX25836 datasheet */
157 /* 2. */
158 cx25840_and_or(client, 0x000, ~0x01, 0x01);
159 cx25840_and_or(client, 0x000, ~0x01, 0x00);
160 /* 3a. */
161 cx25840_and_or(client, 0x15a, ~0x70, 0x00);
162 /* 3b. */
163 cx25840_and_or(client, 0x15b, ~0x1e, 0x06);
164 /* 3c. */
165 cx25840_and_or(client, 0x159, ~0x02, 0x02);
166 /* 3d. */
167 /* There should be a 10-us delay here, but since the
168 i2c bus already has a 10-us delay we don't need to do
169 anything */
170 /* 3e. */
171 cx25840_and_or(client, 0x159, ~0x02, 0x00);
172 /* 3f. */
173 cx25840_and_or(client, 0x159, ~0xc0, 0xc0);
174 /* 3g. */
175 cx25840_and_or(client, 0x159, ~0x01, 0x00);
176 cx25840_and_or(client, 0x159, ~0x01, 0x01);
177 /* 3h. */
178 cx25840_and_or(client, 0x15b, ~0x1e, 0x10);
179}
180
150static void cx25840_initialize(struct i2c_client *client, int loadfw) 181static void cx25840_initialize(struct i2c_client *client, int loadfw)
151{ 182{
152 struct cx25840_state *state = i2c_get_clientdata(client); 183 struct cx25840_state *state = i2c_get_clientdata(client);
@@ -220,17 +251,7 @@ static void input_change(struct i2c_client *client)
220 cx25840_and_or(client, 0x401, ~0x60, 0); 251 cx25840_and_or(client, 0x401, ~0x60, 0);
221 cx25840_and_or(client, 0x401, ~0x60, 0x60); 252 cx25840_and_or(client, 0x401, ~0x60, 0x60);
222 253
223 /* Note: perhaps V4L2_STD_PAL_M should be handled as V4L2_STD_NTSC 254 if (std & V4L2_STD_525_60) {
224 instead of V4L2_STD_PAL. Someone needs to test this. */
225 if (std & V4L2_STD_PAL) {
226 /* Follow tuner change procedure for PAL */
227 cx25840_write(client, 0x808, 0xff);
228 cx25840_write(client, 0x80b, 0x10);
229 } else if (std & V4L2_STD_SECAM) {
230 /* Select autodetect for SECAM */
231 cx25840_write(client, 0x808, 0xff);
232 cx25840_write(client, 0x80b, 0x10);
233 } else if (std & V4L2_STD_NTSC) {
234 /* Certain Hauppauge PVR150 models have a hardware bug 255 /* Certain Hauppauge PVR150 models have a hardware bug
235 that causes audio to drop out. For these models the 256 that causes audio to drop out. For these models the
236 audio standard must be set explicitly. 257 audio standard must be set explicitly.
@@ -249,6 +270,14 @@ static void input_change(struct i2c_client *client)
249 cx25840_write(client, 0x808, hw_fix ? 0x1f : 0xf6); 270 cx25840_write(client, 0x808, hw_fix ? 0x1f : 0xf6);
250 } 271 }
251 cx25840_write(client, 0x80b, 0x00); 272 cx25840_write(client, 0x80b, 0x00);
273 } else if (std & V4L2_STD_PAL) {
274 /* Follow tuner change procedure for PAL */
275 cx25840_write(client, 0x808, 0xff);
276 cx25840_write(client, 0x80b, 0x10);
277 } else if (std & V4L2_STD_SECAM) {
278 /* Select autodetect for SECAM */
279 cx25840_write(client, 0x808, 0xff);
280 cx25840_write(client, 0x80b, 0x10);
252 } 281 }
253 282
254 if (cx25840_read(client, 0x803) & 0x10) { 283 if (cx25840_read(client, 0x803) & 0x10) {
@@ -319,8 +348,10 @@ static int set_input(struct i2c_client *client, enum cx25840_video_input vid_inp
319 348
320 state->vid_input = vid_input; 349 state->vid_input = vid_input;
321 state->aud_input = aud_input; 350 state->aud_input = aud_input;
322 cx25840_audio_set_path(client); 351 if (!state->is_cx25836) {
323 input_change(client); 352 cx25840_audio_set_path(client);
353 input_change(client);
354 }
324 return 0; 355 return 0;
325} 356}
326 357
@@ -354,6 +385,8 @@ static int set_v4lstd(struct i2c_client *client, v4l2_std_id std)
354 } 385 }
355 } 386 }
356 387
388 v4l_dbg(1, cx25840_debug, client, "changing video std to fmt %i\n",fmt);
389
357 /* Follow step 9 of section 3.16 in the cx25840 datasheet. 390 /* Follow step 9 of section 3.16 in the cx25840 datasheet.
358 Without this PAL may display a vertical ghosting effect. 391 Without this PAL may display a vertical ghosting effect.
359 This happens for example with the Yuan MPC622. */ 392 This happens for example with the Yuan MPC622. */
@@ -370,6 +403,7 @@ static int set_v4lstd(struct i2c_client *client, v4l2_std_id std)
370 403
371v4l2_std_id cx25840_get_v4lstd(struct i2c_client * client) 404v4l2_std_id cx25840_get_v4lstd(struct i2c_client * client)
372{ 405{
406 struct cx25840_state *state = i2c_get_clientdata(client);
373 /* check VID_FMT_SEL first */ 407 /* check VID_FMT_SEL first */
374 u8 fmt = cx25840_read(client, 0x400) & 0xf; 408 u8 fmt = cx25840_read(client, 0x400) & 0xf;
375 409
@@ -383,7 +417,7 @@ v4l2_std_id cx25840_get_v4lstd(struct i2c_client * client)
383 { 417 {
384 /* if the audio std is A2-M, then this is the South Korean 418 /* if the audio std is A2-M, then this is the South Korean
385 NTSC standard */ 419 NTSC standard */
386 if (cx25840_read(client, 0x805) == 2) 420 if (!state->is_cx25836 && cx25840_read(client, 0x805) == 2)
387 return V4L2_STD_NTSC_M_KR; 421 return V4L2_STD_NTSC_M_KR;
388 return V4L2_STD_NTSC_M; 422 return V4L2_STD_NTSC_M;
389 } 423 }
@@ -456,6 +490,8 @@ static int set_v4lctrl(struct i2c_client *client, struct v4l2_control *ctrl)
456 case V4L2_CID_AUDIO_TREBLE: 490 case V4L2_CID_AUDIO_TREBLE:
457 case V4L2_CID_AUDIO_BALANCE: 491 case V4L2_CID_AUDIO_BALANCE:
458 case V4L2_CID_AUDIO_MUTE: 492 case V4L2_CID_AUDIO_MUTE:
493 if (state->is_cx25836)
494 return -EINVAL;
459 return cx25840_audio(client, VIDIOC_S_CTRL, ctrl); 495 return cx25840_audio(client, VIDIOC_S_CTRL, ctrl);
460 496
461 default: 497 default:
@@ -490,6 +526,8 @@ static int get_v4lctrl(struct i2c_client *client, struct v4l2_control *ctrl)
490 case V4L2_CID_AUDIO_TREBLE: 526 case V4L2_CID_AUDIO_TREBLE:
491 case V4L2_CID_AUDIO_BALANCE: 527 case V4L2_CID_AUDIO_BALANCE:
492 case V4L2_CID_AUDIO_MUTE: 528 case V4L2_CID_AUDIO_MUTE:
529 if (state->is_cx25836)
530 return -EINVAL;
493 return cx25840_audio(client, VIDIOC_G_CTRL, ctrl); 531 return cx25840_audio(client, VIDIOC_G_CTRL, ctrl);
494 default: 532 default:
495 return -EINVAL; 533 return -EINVAL;
@@ -579,91 +617,6 @@ static int set_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt)
579 617
580/* ----------------------------------------------------------------------- */ 618/* ----------------------------------------------------------------------- */
581 619
582static struct v4l2_queryctrl cx25840_qctrl[] = {
583 {
584 .id = V4L2_CID_BRIGHTNESS,
585 .type = V4L2_CTRL_TYPE_INTEGER,
586 .name = "Brightness",
587 .minimum = 0,
588 .maximum = 255,
589 .step = 1,
590 .default_value = 128,
591 .flags = 0,
592 }, {
593 .id = V4L2_CID_CONTRAST,
594 .type = V4L2_CTRL_TYPE_INTEGER,
595 .name = "Contrast",
596 .minimum = 0,
597 .maximum = 127,
598 .step = 1,
599 .default_value = 64,
600 .flags = 0,
601 }, {
602 .id = V4L2_CID_SATURATION,
603 .type = V4L2_CTRL_TYPE_INTEGER,
604 .name = "Saturation",
605 .minimum = 0,
606 .maximum = 127,
607 .step = 1,
608 .default_value = 64,
609 .flags = 0,
610 }, {
611 .id = V4L2_CID_HUE,
612 .type = V4L2_CTRL_TYPE_INTEGER,
613 .name = "Hue",
614 .minimum = -128,
615 .maximum = 127,
616 .step = 1,
617 .default_value = 0,
618 .flags = 0,
619 }, {
620 .id = V4L2_CID_AUDIO_VOLUME,
621 .type = V4L2_CTRL_TYPE_INTEGER,
622 .name = "Volume",
623 .minimum = 0,
624 .maximum = 65535,
625 .step = 65535/100,
626 .default_value = 58880,
627 .flags = 0,
628 }, {
629 .id = V4L2_CID_AUDIO_BALANCE,
630 .type = V4L2_CTRL_TYPE_INTEGER,
631 .name = "Balance",
632 .minimum = 0,
633 .maximum = 65535,
634 .step = 65535/100,
635 .default_value = 32768,
636 .flags = 0,
637 }, {
638 .id = V4L2_CID_AUDIO_MUTE,
639 .type = V4L2_CTRL_TYPE_BOOLEAN,
640 .name = "Mute",
641 .minimum = 0,
642 .maximum = 1,
643 .step = 1,
644 .default_value = 1,
645 .flags = 0,
646 }, {
647 .id = V4L2_CID_AUDIO_BASS,
648 .type = V4L2_CTRL_TYPE_INTEGER,
649 .name = "Bass",
650 .minimum = 0,
651 .maximum = 65535,
652 .step = 65535/100,
653 .default_value = 32768,
654 }, {
655 .id = V4L2_CID_AUDIO_TREBLE,
656 .type = V4L2_CTRL_TYPE_INTEGER,
657 .name = "Treble",
658 .minimum = 0,
659 .maximum = 65535,
660 .step = 65535/100,
661 .default_value = 32768,
662 },
663};
664
665/* ----------------------------------------------------------------------- */
666
667static int cx25840_command(struct i2c_client *client, unsigned int cmd, 620static int cx25840_command(struct i2c_client *client, unsigned int cmd,
668 void *arg) 621 void *arg)
669{ 622{
@@ -706,8 +659,8 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd,
706 659
707 case VIDIOC_STREAMON: 660 case VIDIOC_STREAMON:
708 v4l_dbg(1, cx25840_debug, client, "enable output\n"); 661 v4l_dbg(1, cx25840_debug, client, "enable output\n");
709 cx25840_write(client, 0x115, 0x8c); 662 cx25840_write(client, 0x115, state->is_cx25836 ? 0x0c : 0x8c);
710 cx25840_write(client, 0x116, 0x07); 663 cx25840_write(client, 0x116, state->is_cx25836 ? 0x04 : 0x07);
711 break; 664 break;
712 665
713 case VIDIOC_STREAMOFF: 666 case VIDIOC_STREAMOFF:
@@ -717,7 +670,9 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd,
717 break; 670 break;
718 671
719 case VIDIOC_LOG_STATUS: 672 case VIDIOC_LOG_STATUS:
720 log_status(client); 673 log_video_status(client);
674 if (!state->is_cx25836)
675 log_audio_status(client);
721 break; 676 break;
722 677
723 case VIDIOC_G_CTRL: 678 case VIDIOC_G_CTRL:
@@ -729,13 +684,29 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd,
729 case VIDIOC_QUERYCTRL: 684 case VIDIOC_QUERYCTRL:
730 { 685 {
731 struct v4l2_queryctrl *qc = arg; 686 struct v4l2_queryctrl *qc = arg;
732 int i;
733 687
734 for (i = 0; i < ARRAY_SIZE(cx25840_qctrl); i++) 688 switch (qc->id) {
735 if (qc->id && qc->id == cx25840_qctrl[i].id) { 689 case V4L2_CID_BRIGHTNESS:
736 memcpy(qc, &cx25840_qctrl[i], sizeof(*qc)); 690 case V4L2_CID_CONTRAST:
737 return 0; 691 case V4L2_CID_SATURATION:
738 } 692 case V4L2_CID_HUE:
693 return v4l2_ctrl_query_fill_std(qc);
694 default:
695 break;
696 }
697 if (state->is_cx25836)
698 return -EINVAL;
699
700 switch (qc->id) {
701 case V4L2_CID_AUDIO_VOLUME:
702 case V4L2_CID_AUDIO_MUTE:
703 case V4L2_CID_AUDIO_BALANCE:
704 case V4L2_CID_AUDIO_BASS:
705 case V4L2_CID_AUDIO_TREBLE:
706 return v4l2_ctrl_query_fill_std(qc);
707 default:
708 return -EINVAL;
709 }
739 return -EINVAL; 710 return -EINVAL;
740 } 711 }
741 712
@@ -760,31 +731,41 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd,
760 return set_input(client, route->input, state->aud_input); 731 return set_input(client, route->input, state->aud_input);
761 732
762 case VIDIOC_INT_G_AUDIO_ROUTING: 733 case VIDIOC_INT_G_AUDIO_ROUTING:
734 if (state->is_cx25836)
735 return -EINVAL;
763 route->input = state->aud_input; 736 route->input = state->aud_input;
764 route->output = 0; 737 route->output = 0;
765 break; 738 break;
766 739
767 case VIDIOC_INT_S_AUDIO_ROUTING: 740 case VIDIOC_INT_S_AUDIO_ROUTING:
741 if (state->is_cx25836)
742 return -EINVAL;
768 return set_input(client, state->vid_input, route->input); 743 return set_input(client, state->vid_input, route->input);
769 744
770 case VIDIOC_S_FREQUENCY: 745 case VIDIOC_S_FREQUENCY:
771 input_change(client); 746 if (!state->is_cx25836) {
747 input_change(client);
748 }
772 break; 749 break;
773 750
774 case VIDIOC_G_TUNER: 751 case VIDIOC_G_TUNER:
775 { 752 {
776 u8 mode = cx25840_read(client, 0x804); 753 u8 vpres = cx25840_read(client, 0x40e) & 0x20;
777 u8 vpres = cx25840_read(client, 0x80a) & 0x10; 754 u8 mode;
778 int val = 0; 755 int val = 0;
779 756
780 if (state->radio) 757 if (state->radio)
781 break; 758 break;
782 759
760 vt->signal = vpres ? 0xffff : 0x0;
761 if (state->is_cx25836)
762 break;
763
783 vt->capability |= 764 vt->capability |=
784 V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LANG1 | 765 V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LANG1 |
785 V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP; 766 V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP;
786 767
787 vt->signal = vpres ? 0xffff : 0x0; 768 mode = cx25840_read(client, 0x804);
788 769
789 /* get rxsubchans and audmode */ 770 /* get rxsubchans and audmode */
790 if ((mode & 0xf) == 1) 771 if ((mode & 0xf) == 1)
@@ -804,7 +785,7 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd,
804 } 785 }
805 786
806 case VIDIOC_S_TUNER: 787 case VIDIOC_S_TUNER:
807 if (state->radio) 788 if (state->radio || state->is_cx25836)
808 break; 789 break;
809 790
810 switch (vt->audmode) { 791 switch (vt->audmode) {
@@ -846,12 +827,14 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd,
846 return set_v4lfmt(client, (struct v4l2_format *)arg); 827 return set_v4lfmt(client, (struct v4l2_format *)arg);
847 828
848 case VIDIOC_INT_RESET: 829 case VIDIOC_INT_RESET:
849 cx25840_initialize(client, 0); 830 if (state->is_cx25836)
831 cx25836_initialize(client);
832 else
833 cx25840_initialize(client, 0);
850 break; 834 break;
851 835
852 case VIDIOC_INT_G_CHIP_IDENT: 836 case VIDIOC_INT_G_CHIP_IDENT:
853 *(enum v4l2_chip_ident *)arg = 837 *(enum v4l2_chip_ident *)arg = state->id;
854 V4L2_IDENT_CX25840 + ((cx25840_read(client, 0x100) >> 4) & 0xf);
855 break; 838 break;
856 839
857 default: 840 default:
@@ -870,6 +853,7 @@ static int cx25840_detect_client(struct i2c_adapter *adapter, int address,
870{ 853{
871 struct i2c_client *client; 854 struct i2c_client *client;
872 struct cx25840_state *state; 855 struct cx25840_state *state;
856 enum v4l2_chip_ident id;
873 u16 device_id; 857 u16 device_id;
874 858
875 /* Check if the adapter supports the needed features 859 /* Check if the adapter supports the needed features
@@ -878,10 +862,11 @@ static int cx25840_detect_client(struct i2c_adapter *adapter, int address,
878 if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) 862 if (!i2c_check_functionality(adapter, I2C_FUNC_I2C))
879 return 0; 863 return 0;
880 864
881 client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL); 865 state = kzalloc(sizeof(struct cx25840_state), GFP_KERNEL);
882 if (client == 0) 866 if (state == 0)
883 return -ENOMEM; 867 return -ENOMEM;
884 868
869 client = &state->c;
885 client->addr = address; 870 client->addr = address;
886 client->adapter = adapter; 871 client->adapter = adapter;
887 client->driver = &i2c_driver_cx25840; 872 client->driver = &i2c_driver_cx25840;
@@ -893,10 +878,18 @@ static int cx25840_detect_client(struct i2c_adapter *adapter, int address,
893 device_id |= cx25840_read(client, 0x100); 878 device_id |= cx25840_read(client, 0x100);
894 879
895 /* The high byte of the device ID should be 880 /* The high byte of the device ID should be
896 * 0x84 if chip is present */ 881 * 0x83 for the cx2583x and 0x84 for the cx2584x */
897 if ((device_id & 0xff00) != 0x8400) { 882 if ((device_id & 0xff00) == 0x8300) {
883 id = V4L2_IDENT_CX25836 + ((device_id >> 4) & 0xf) - 6;
884 state->is_cx25836 = 1;
885 }
886 else if ((device_id & 0xff00) == 0x8400) {
887 id = V4L2_IDENT_CX25840 + ((device_id >> 4) & 0xf);
888 state->is_cx25836 = 0;
889 }
890 else {
898 v4l_dbg(1, cx25840_debug, client, "cx25840 not found\n"); 891 v4l_dbg(1, cx25840_debug, client, "cx25840 not found\n");
899 kfree(client); 892 kfree(state);
900 return 0; 893 return 0;
901 } 894 }
902 895
@@ -905,21 +898,19 @@ static int cx25840_detect_client(struct i2c_adapter *adapter, int address,
905 (device_id & 0x0f) < 3 ? (device_id & 0x0f) + 1 : 3, 898 (device_id & 0x0f) < 3 ? (device_id & 0x0f) + 1 : 3,
906 address << 1, adapter->name); 899 address << 1, adapter->name);
907 900
908 state = kmalloc(sizeof(struct cx25840_state), GFP_KERNEL);
909 if (state == NULL) {
910 kfree(client);
911 return -ENOMEM;
912 }
913
914 i2c_set_clientdata(client, state); 901 i2c_set_clientdata(client, state);
915 memset(state, 0, sizeof(struct cx25840_state));
916 state->vid_input = CX25840_COMPOSITE7; 902 state->vid_input = CX25840_COMPOSITE7;
917 state->aud_input = CX25840_AUDIO8; 903 state->aud_input = CX25840_AUDIO8;
918 state->audclk_freq = 48000; 904 state->audclk_freq = 48000;
919 state->pvr150_workaround = 0; 905 state->pvr150_workaround = 0;
920 state->audmode = V4L2_TUNER_MODE_LANG1; 906 state->audmode = V4L2_TUNER_MODE_LANG1;
907 state->vbi_line_offset = 8;
908 state->id = id;
921 909
922 cx25840_initialize(client, 1); 910 if (state->is_cx25836)
911 cx25836_initialize(client);
912 else
913 cx25840_initialize(client, 1);
923 914
924 i2c_attach_client(client); 915 i2c_attach_client(client);
925 916
@@ -944,7 +935,6 @@ static int cx25840_detach_client(struct i2c_client *client)
944 } 935 }
945 936
946 kfree(state); 937 kfree(state);
947 kfree(client);
948 938
949 return 0; 939 return 0;
950} 940}
@@ -977,7 +967,7 @@ module_exit(m__exit);
977 967
978/* ----------------------------------------------------------------------- */ 968/* ----------------------------------------------------------------------- */
979 969
980static void log_status(struct i2c_client *client) 970static void log_video_status(struct i2c_client *client)
981{ 971{
982 static const char *const fmt_strs[] = { 972 static const char *const fmt_strs[] = {
983 "0x0", 973 "0x0",
@@ -989,9 +979,36 @@ static void log_status(struct i2c_client *client)
989 }; 979 };
990 980
991 struct cx25840_state *state = i2c_get_clientdata(client); 981 struct cx25840_state *state = i2c_get_clientdata(client);
992 u8 microctrl_vidfmt = cx25840_read(client, 0x80a);
993 u8 vidfmt_sel = cx25840_read(client, 0x400) & 0xf; 982 u8 vidfmt_sel = cx25840_read(client, 0x400) & 0xf;
994 u8 gen_stat1 = cx25840_read(client, 0x40d); 983 u8 gen_stat1 = cx25840_read(client, 0x40d);
984 u8 gen_stat2 = cx25840_read(client, 0x40e);
985 int vid_input = state->vid_input;
986
987 v4l_info(client, "Video signal: %spresent\n",
988 (gen_stat2 & 0x20) ? "" : "not ");
989 v4l_info(client, "Detected format: %s\n",
990 fmt_strs[gen_stat1 & 0xf]);
991
992 v4l_info(client, "Specified standard: %s\n",
993 vidfmt_sel ? fmt_strs[vidfmt_sel] : "automatic detection");
994
995 if (vid_input >= CX25840_COMPOSITE1 &&
996 vid_input <= CX25840_COMPOSITE8) {
997 v4l_info(client, "Specified video input: Composite %d\n",
998 vid_input - CX25840_COMPOSITE1 + 1);
999 } else {
1000 v4l_info(client, "Specified video input: S-Video (Luma In%d, Chroma In%d)\n",
1001 (vid_input & 0xf0) >> 4, (vid_input & 0xf00) >> 8);
1002 }
1003
1004 v4l_info(client, "Specified audioclock freq: %d Hz\n", state->audclk_freq);
1005}
1006
1007/* ----------------------------------------------------------------------- */
1008
1009static void log_audio_status(struct i2c_client *client)
1010{
1011 struct cx25840_state *state = i2c_get_clientdata(client);
995 u8 download_ctl = cx25840_read(client, 0x803); 1012 u8 download_ctl = cx25840_read(client, 0x803);
996 u8 mod_det_stat0 = cx25840_read(client, 0x804); 1013 u8 mod_det_stat0 = cx25840_read(client, 0x804);
997 u8 mod_det_stat1 = cx25840_read(client, 0x805); 1014 u8 mod_det_stat1 = cx25840_read(client, 0x805);
@@ -999,15 +1016,9 @@ static void log_status(struct i2c_client *client)
999 u8 pref_mode = cx25840_read(client, 0x809); 1016 u8 pref_mode = cx25840_read(client, 0x809);
1000 u8 afc0 = cx25840_read(client, 0x80b); 1017 u8 afc0 = cx25840_read(client, 0x80b);
1001 u8 mute_ctl = cx25840_read(client, 0x8d3); 1018 u8 mute_ctl = cx25840_read(client, 0x8d3);
1002 int vid_input = state->vid_input;
1003 int aud_input = state->aud_input; 1019 int aud_input = state->aud_input;
1004 char *p; 1020 char *p;
1005 1021
1006 v4l_info(client, "Video signal: %spresent\n",
1007 (microctrl_vidfmt & 0x10) ? "" : "not ");
1008 v4l_info(client, "Detected format: %s\n",
1009 fmt_strs[gen_stat1 & 0xf]);
1010
1011 switch (mod_det_stat0) { 1022 switch (mod_det_stat0) {
1012 case 0x00: p = "mono"; break; 1023 case 0x00: p = "mono"; break;
1013 case 0x01: p = "stereo"; break; 1024 case 0x01: p = "stereo"; break;
@@ -1107,25 +1118,12 @@ static void log_status(struct i2c_client *client)
1107 v4l_info(client, "Configured audio system: %s\n", p); 1118 v4l_info(client, "Configured audio system: %s\n", p);
1108 } 1119 }
1109 1120
1110 v4l_info(client, "Specified standard: %s\n",
1111 vidfmt_sel ? fmt_strs[vidfmt_sel] : "automatic detection");
1112
1113 if (vid_input >= CX25840_COMPOSITE1 &&
1114 vid_input <= CX25840_COMPOSITE8) {
1115 v4l_info(client, "Specified video input: Composite %d\n",
1116 vid_input - CX25840_COMPOSITE1 + 1);
1117 } else {
1118 v4l_info(client, "Specified video input: S-Video (Luma In%d, Chroma In%d)\n",
1119 (vid_input & 0xf0) >> 4, (vid_input & 0xf00) >> 8);
1120 }
1121 if (aud_input) { 1121 if (aud_input) {
1122 v4l_info(client, "Specified audio input: Tuner (In%d)\n", aud_input); 1122 v4l_info(client, "Specified audio input: Tuner (In%d)\n", aud_input);
1123 } else { 1123 } else {
1124 v4l_info(client, "Specified audio input: External\n"); 1124 v4l_info(client, "Specified audio input: External\n");
1125 } 1125 }
1126 1126
1127 v4l_info(client, "Specified audioclock freq: %d Hz\n", state->audclk_freq);
1128
1129 switch (pref_mode & 0xf) { 1127 switch (pref_mode & 0xf) {
1130 case 0: p = "mono/language A"; break; 1128 case 0: p = "mono/language A"; break;
1131 case 1: p = "language B"; break; 1129 case 1: p = "language B"; break;
diff --git a/drivers/media/video/cx25840/cx25840-core.h b/drivers/media/video/cx25840/cx25840-core.h
index 1736929fc20..28049064dd7 100644
--- a/drivers/media/video/cx25840/cx25840-core.h
+++ b/drivers/media/video/cx25840/cx25840-core.h
@@ -24,6 +24,8 @@
24#include <linux/videodev2.h> 24#include <linux/videodev2.h>
25#include <linux/i2c.h> 25#include <linux/i2c.h>
26 26
27extern int cx25840_debug;
28
27/* ENABLE_PVR150_WORKAROUND activates a workaround for a hardware bug that is 29/* ENABLE_PVR150_WORKAROUND activates a workaround for a hardware bug that is
28 present in Hauppauge PVR-150 (and possibly PVR-500) cards that have 30 present in Hauppauge PVR-150 (and possibly PVR-500) cards that have
29 certain NTSC tuners (tveeprom tuner model numbers 85, 99 and 112). The 31 certain NTSC tuners (tveeprom tuner model numbers 85, 99 and 112). The
@@ -33,12 +35,16 @@
33#define CX25840_CID_ENABLE_PVR150_WORKAROUND (V4L2_CID_PRIVATE_BASE+0) 35#define CX25840_CID_ENABLE_PVR150_WORKAROUND (V4L2_CID_PRIVATE_BASE+0)
34 36
35struct cx25840_state { 37struct cx25840_state {
38 struct i2c_client c;
36 int pvr150_workaround; 39 int pvr150_workaround;
37 int radio; 40 int radio;
38 enum cx25840_video_input vid_input; 41 enum cx25840_video_input vid_input;
39 enum cx25840_audio_input aud_input; 42 enum cx25840_audio_input aud_input;
40 u32 audclk_freq; 43 u32 audclk_freq;
41 int audmode; 44 int audmode;
45 int vbi_line_offset;
46 enum v4l2_chip_ident id;
47 int is_cx25836;
42}; 48};
43 49
44/* ----------------------------------------------------------------------- */ 50/* ----------------------------------------------------------------------- */
@@ -47,7 +53,7 @@ int cx25840_write(struct i2c_client *client, u16 addr, u8 value);
47int cx25840_write4(struct i2c_client *client, u16 addr, u32 value); 53int cx25840_write4(struct i2c_client *client, u16 addr, u32 value);
48u8 cx25840_read(struct i2c_client *client, u16 addr); 54u8 cx25840_read(struct i2c_client *client, u16 addr);
49u32 cx25840_read4(struct i2c_client *client, u16 addr); 55u32 cx25840_read4(struct i2c_client *client, u16 addr);
50int cx25840_and_or(struct i2c_client *client, u16 addr, u8 mask, u8 value); 56int cx25840_and_or(struct i2c_client *client, u16 addr, unsigned mask, u8 value);
51v4l2_std_id cx25840_get_v4lstd(struct i2c_client *client); 57v4l2_std_id cx25840_get_v4lstd(struct i2c_client *client);
52 58
53/* ----------------------------------------------------------------------- */ 59/* ----------------------------------------------------------------------- */
diff --git a/drivers/media/video/cx25840/cx25840-vbi.c b/drivers/media/video/cx25840/cx25840-vbi.c
index 57feca288d2..6cc8bf215e8 100644
--- a/drivers/media/video/cx25840/cx25840-vbi.c
+++ b/drivers/media/video/cx25840/cx25840-vbi.c
@@ -84,67 +84,140 @@ static int decode_vps(u8 * dst, u8 * p)
84 84
85void cx25840_vbi_setup(struct i2c_client *client) 85void cx25840_vbi_setup(struct i2c_client *client)
86{ 86{
87 struct cx25840_state *state = i2c_get_clientdata(client);
87 v4l2_std_id std = cx25840_get_v4lstd(client); 88 v4l2_std_id std = cx25840_get_v4lstd(client);
89 int hblank,hactive,burst,vblank,vactive,sc,vblank656,src_decimation;
90 int luma_lpf,uv_lpf, comb;
91 u32 pll_int,pll_frac,pll_post;
88 92
93 /* datasheet startup, step 8d */
89 if (std & ~V4L2_STD_NTSC) { 94 if (std & ~V4L2_STD_NTSC) {
90 /* datasheet startup, step 8d */
91 cx25840_write(client, 0x49f, 0x11); 95 cx25840_write(client, 0x49f, 0x11);
96 } else {
97 cx25840_write(client, 0x49f, 0x14);
98 }
92 99
93 cx25840_write(client, 0x470, 0x84); 100 if (std & V4L2_STD_625_50) {
94 cx25840_write(client, 0x471, 0x00); 101 hblank=0x084;
95 cx25840_write(client, 0x472, 0x2d); 102 hactive=0x2d0;
96 cx25840_write(client, 0x473, 0x5d); 103 burst=0x5d;
97 104 vblank=0x024;
98 cx25840_write(client, 0x474, 0x24); 105 vactive=0x244;
99 cx25840_write(client, 0x475, 0x40); 106 vblank656=0x28;
100 cx25840_write(client, 0x476, 0x24); 107 src_decimation=0x21f;
101 cx25840_write(client, 0x477, 0x28);
102
103 cx25840_write(client, 0x478, 0x1f);
104 cx25840_write(client, 0x479, 0x02);
105 108
109 luma_lpf=2;
106 if (std & V4L2_STD_SECAM) { 110 if (std & V4L2_STD_SECAM) {
107 cx25840_write(client, 0x47a, 0x80); 111 uv_lpf=0;
108 cx25840_write(client, 0x47b, 0x00); 112 comb=0;
109 cx25840_write(client, 0x47c, 0x5f); 113 sc=0x0a425f;
110 cx25840_write(client, 0x47d, 0x42);
111 } else { 114 } else {
112 cx25840_write(client, 0x47a, 0x90); 115 uv_lpf=1;
113 cx25840_write(client, 0x47b, 0x20); 116 comb=0x20;
114 cx25840_write(client, 0x47c, 0x63); 117 sc=0x0a8263;
115 cx25840_write(client, 0x47d, 0x82);
116 } 118 }
117
118 cx25840_write(client, 0x47e, 0x0a);
119 cx25840_write(client, 0x47f, 0x01);
120 } else { 119 } else {
121 /* datasheet startup, step 8d */ 120 hactive=720;
122 cx25840_write(client, 0x49f, 0x14); 121 hblank=122;
122 vactive=487;
123 luma_lpf=1;
124 uv_lpf=1;
125
126 src_decimation=0x21f;
127 if (std == V4L2_STD_PAL_M) {
128 vblank=20;
129 vblank656=24;
130 burst=0x61;
131 comb=0x20;
132
133 sc=555452;
134 } else {
135 vblank=26;
136 vblank656=26;
137 burst=0x5b;
138 comb=0x66;
139 sc=556063;
140 }
141 }
142
143 /* DEBUG: Displays configured PLL frequency */
144 pll_int=cx25840_read(client, 0x108);
145 pll_frac=cx25840_read4(client, 0x10c)&0x1ffffff;
146 pll_post=cx25840_read(client, 0x109);
147 v4l_dbg(1, cx25840_debug, client,
148 "PLL regs = int: %u, frac: %u, post: %u\n",
149 pll_int,pll_frac,pll_post);
150
151 if (pll_post) {
152 int fin, fsc;
153 int pll= (28636363L*((((u64)pll_int)<<25L)+pll_frac)) >>25L;
154
155 pll/=pll_post;
156 v4l_dbg(1, cx25840_debug, client, "PLL = %d.%06d MHz\n",
157 pll/1000000, pll%1000000);
158 v4l_dbg(1, cx25840_debug, client, "PLL/8 = %d.%06d MHz\n",
159 pll/8000000, (pll/8)%1000000);
160
161 fin=((u64)src_decimation*pll)>>12;
162 v4l_dbg(1, cx25840_debug, client, "ADC Sampling freq = "
163 "%d.%06d MHz\n",
164 fin/1000000,fin%1000000);
165
166 fsc= (((u64)sc)*pll) >> 24L;
167 v4l_dbg(1, cx25840_debug, client, "Chroma sub-carrier freq = "
168 "%d.%06d MHz\n",
169 fsc/1000000,fsc%1000000);
170
171 v4l_dbg(1, cx25840_debug, client, "hblank %i, hactive %i, "
172 "vblank %i , vactive %i, vblank656 %i, src_dec %i,"
173 "burst 0x%02x, luma_lpf %i, uv_lpf %i, comb 0x%02x,"
174 " sc 0x%06x\n",
175 hblank, hactive, vblank, vactive, vblank656,
176 src_decimation, burst, luma_lpf, uv_lpf, comb, sc);
177 }
178
179 /* Sets horizontal blanking delay and active lines */
180 cx25840_write(client, 0x470, hblank);
181 cx25840_write(client, 0x471, 0xff&(((hblank>>8)&0x3)|(hactive <<4)));
182 cx25840_write(client, 0x472, hactive>>4);
183
184 /* Sets burst gate delay */
185 cx25840_write(client, 0x473, burst);
123 186
124 cx25840_write(client, 0x470, 0x7a); 187 /* Sets vertical blanking delay and active duration */
125 cx25840_write(client, 0x471, 0x00); 188 cx25840_write(client, 0x474, vblank);
126 cx25840_write(client, 0x472, 0x2d); 189 cx25840_write(client, 0x475, 0xff&(((vblank>>8)&0x3)|(vactive <<4)));
127 cx25840_write(client, 0x473, 0x5b); 190 cx25840_write(client, 0x476, vactive>>4);
191 cx25840_write(client, 0x477, vblank656);
128 192
129 cx25840_write(client, 0x474, 0x1a); 193 /* Sets src decimation rate */
130 cx25840_write(client, 0x475, 0x70); 194 cx25840_write(client, 0x478, 0xff&src_decimation);
131 cx25840_write(client, 0x476, 0x1e); 195 cx25840_write(client, 0x479, 0xff&(src_decimation>>8));
132 cx25840_write(client, 0x477, 0x1e);
133 196
134 cx25840_write(client, 0x478, 0x1f); 197 /* Sets Luma and UV Low pass filters */
135 cx25840_write(client, 0x479, 0x02); 198 cx25840_write(client, 0x47a, luma_lpf<<6|((uv_lpf<<4)&0x30));
136 cx25840_write(client, 0x47a, 0x50);
137 cx25840_write(client, 0x47b, 0x66);
138 199
139 cx25840_write(client, 0x47c, 0x1f); 200 /* Enables comb filters */
140 cx25840_write(client, 0x47d, 0x7c); 201 cx25840_write(client, 0x47b, comb);
141 cx25840_write(client, 0x47e, 0x08); 202
203 /* Sets SC Step*/
204 cx25840_write(client, 0x47c, sc);
205 cx25840_write(client, 0x47d, 0xff&sc>>8);
206 cx25840_write(client, 0x47e, 0xff&sc>>16);
207
208 /* Sets VBI parameters */
209 if (std & V4L2_STD_625_50) {
210 cx25840_write(client, 0x47f, 0x01);
211 state->vbi_line_offset = 5;
212 } else {
142 cx25840_write(client, 0x47f, 0x00); 213 cx25840_write(client, 0x47f, 0x00);
214 state->vbi_line_offset = 8;
143 } 215 }
144} 216}
145 217
146int cx25840_vbi(struct i2c_client *client, unsigned int cmd, void *arg) 218int cx25840_vbi(struct i2c_client *client, unsigned int cmd, void *arg)
147{ 219{
220 struct cx25840_state *state = i2c_get_clientdata(client);
148 struct v4l2_format *fmt; 221 struct v4l2_format *fmt;
149 struct v4l2_sliced_vbi_format *svbi; 222 struct v4l2_sliced_vbi_format *svbi;
150 223
@@ -182,7 +255,7 @@ int cx25840_vbi(struct i2c_client *client, unsigned int cmd, void *arg)
182 255
183 case VIDIOC_S_FMT: 256 case VIDIOC_S_FMT:
184 { 257 {
185 int is_pal = !(cx25840_get_v4lstd(client) & V4L2_STD_NTSC); 258 int is_pal = !(cx25840_get_v4lstd(client) & V4L2_STD_525_60);
186 int vbi_offset = is_pal ? 1 : 0; 259 int vbi_offset = is_pal ? 1 : 0;
187 int i, x; 260 int i, x;
188 u8 lcr[24]; 261 u8 lcr[24];
@@ -211,7 +284,7 @@ int cx25840_vbi(struct i2c_client *client, unsigned int cmd, void *arg)
211 cx25840_vbi_setup(client); 284 cx25840_vbi_setup(client);
212 285
213 /* Sliced VBI */ 286 /* Sliced VBI */
214 cx25840_write(client, 0x404, 0x36); /* Ancillery data */ 287 cx25840_write(client, 0x404, 0x32); /* Ancillary data */
215 cx25840_write(client, 0x406, 0x13); 288 cx25840_write(client, 0x406, 0x13);
216 cx25840_write(client, 0x47f, vbi_offset); 289 cx25840_write(client, 0x47f, vbi_offset);
217 290
@@ -248,8 +321,18 @@ int cx25840_vbi(struct i2c_client *client, unsigned int cmd, void *arg)
248 } 321 }
249 } 322 }
250 323
251 for (x = 1, i = 0x424; i <= 0x434; i++, x++) { 324 if (is_pal) {
252 cx25840_write(client, i, lcr[6 + x]); 325 for (x = 1, i = 0x424; i <= 0x434; i++, x++) {
326 cx25840_write(client, i, lcr[6 + x]);
327 }
328 }
329 else {
330 for (x = 1, i = 0x424; i <= 0x430; i++, x++) {
331 cx25840_write(client, i, lcr[9 + x]);
332 }
333 for (i = 0x431; i <= 0x434; i++) {
334 cx25840_write(client, i, 0);
335 }
253 } 336 }
254 337
255 cx25840_write(client, 0x43c, 0x16); 338 cx25840_write(client, 0x43c, 0x16);
@@ -257,7 +340,7 @@ int cx25840_vbi(struct i2c_client *client, unsigned int cmd, void *arg)
257 if (is_pal) { 340 if (is_pal) {
258 cx25840_write(client, 0x474, 0x2a); 341 cx25840_write(client, 0x474, 0x2a);
259 } else { 342 } else {
260 cx25840_write(client, 0x474, 0x1a + 6); 343 cx25840_write(client, 0x474, 0x22);
261 } 344 }
262 break; 345 break;
263 } 346 }
@@ -278,7 +361,7 @@ int cx25840_vbi(struct i2c_client *client, unsigned int cmd, void *arg)
278 id1 = p[-1]; 361 id1 = p[-1];
279 id2 = p[0] & 0xf; 362 id2 = p[0] & 0xf;
280 l = p[2] & 0x3f; 363 l = p[2] & 0x3f;
281 l += 5; 364 l += state->vbi_line_offset;
282 p += 4; 365 p += 4;
283 366
284 switch (id2) { 367 switch (id2) {
diff --git a/drivers/media/video/cx88/Kconfig b/drivers/media/video/cx88/Kconfig
index 630273992a4..91e1c481a16 100644
--- a/drivers/media/video/cx88/Kconfig
+++ b/drivers/media/video/cx88/Kconfig
@@ -11,6 +11,7 @@ config VIDEO_CX88
11 select VIDEO_BUF 11 select VIDEO_BUF
12 select VIDEO_TUNER 12 select VIDEO_TUNER
13 select VIDEO_TVEEPROM 13 select VIDEO_TVEEPROM
14 select VIDEO_CX2341X
14 select VIDEO_IR 15 select VIDEO_IR
15 ---help--- 16 ---help---
16 This is a video4linux driver for Conexant 2388x based 17 This is a video4linux driver for Conexant 2388x based
@@ -61,6 +62,7 @@ config VIDEO_CX88_DVB_ALL_FRONTENDS
61 select DVB_LGDT330X 62 select DVB_LGDT330X
62 select DVB_NXT200X 63 select DVB_NXT200X
63 select DVB_CX24123 64 select DVB_CX24123
65 select DVB_ISL6421
64 ---help--- 66 ---help---
65 This builds cx88-dvb with all currently supported frontend 67 This builds cx88-dvb with all currently supported frontend
66 demodulators. If you wish to tweak your configuration, and 68 demodulators. If you wish to tweak your configuration, and
@@ -139,6 +141,7 @@ config VIDEO_CX88_DVB_CX24123
139 default y 141 default y
140 depends on VIDEO_CX88_DVB && !VIDEO_CX88_DVB_ALL_FRONTENDS 142 depends on VIDEO_CX88_DVB && !VIDEO_CX88_DVB_ALL_FRONTENDS
141 select DVB_CX24123 143 select DVB_CX24123
144 select DVB_ISL6421
142 ---help--- 145 ---help---
143 This adds DVB-S support for cards based on the 146 This adds DVB-S support for cards based on the
144 Connexant 2388x chip and the CX24123 demodulator. 147 Connexant 2388x chip and the CX24123 demodulator.
diff --git a/drivers/media/video/cx88/cx88-alsa.c b/drivers/media/video/cx88/cx88-alsa.c
index 320b3d9384b..2194cbeca33 100644
--- a/drivers/media/video/cx88/cx88-alsa.c
+++ b/drivers/media/video/cx88/cx88-alsa.c
@@ -4,7 +4,7 @@
4 * PCI function #1 of the cx2388x. 4 * PCI function #1 of the cx2388x.
5 * 5 *
6 * (c) 2005,2006 Ricardo Cerqueira <v4l@cerqueira.org> 6 * (c) 2005,2006 Ricardo Cerqueira <v4l@cerqueira.org>
7 * (c) 2005 Mauro Carvalho Chehab <mchehab@brturbo.com.br> 7 * (c) 2005 Mauro Carvalho Chehab <mchehab@infradead.org>
8 * Based on a dummy cx88 module by Gerd Knorr <kraxel@bytesex.org> 8 * Based on a dummy cx88 module by Gerd Knorr <kraxel@bytesex.org>
9 * Based on dummy.c by Jaroslav Kysela <perex@suse.cz> 9 * Based on dummy.c by Jaroslav Kysela <perex@suse.cz>
10 * 10 *
@@ -111,7 +111,7 @@ MODULE_PARM_DESC(index, "Index value for cx88x capture interface(s).");
111 111
112MODULE_DESCRIPTION("ALSA driver module for cx2388x based TV cards"); 112MODULE_DESCRIPTION("ALSA driver module for cx2388x based TV cards");
113MODULE_AUTHOR("Ricardo Cerqueira"); 113MODULE_AUTHOR("Ricardo Cerqueira");
114MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@brturbo.com.br>"); 114MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>");
115MODULE_LICENSE("GPL"); 115MODULE_LICENSE("GPL");
116MODULE_SUPPORTED_DEVICE("{{Conexant,23881}," 116MODULE_SUPPORTED_DEVICE("{{Conexant,23881},"
117 "{{Conexant,23882}," 117 "{{Conexant,23882},"
@@ -696,7 +696,6 @@ static int __devinit snd_cx88_create(struct snd_card *card,
696 chip->irq = -1; 696 chip->irq = -1;
697 spin_lock_init(&chip->reg_lock); 697 spin_lock_init(&chip->reg_lock);
698 698
699 cx88_reset(core);
700 chip->core = core; 699 chip->core = core;
701 700
702 /* get irq */ 701 /* get irq */
diff --git a/drivers/media/video/cx88/cx88-blackbird.c b/drivers/media/video/cx88/cx88-blackbird.c
index e100d8ef369..67fd3302e8f 100644
--- a/drivers/media/video/cx88/cx88-blackbird.c
+++ b/drivers/media/video/cx88/cx88-blackbird.c
@@ -30,9 +30,10 @@
30#include <linux/delay.h> 30#include <linux/delay.h>
31#include <linux/device.h> 31#include <linux/device.h>
32#include <linux/firmware.h> 32#include <linux/firmware.h>
33#include <media/v4l2-common.h>
34#include <media/cx2341x.h>
33 35
34#include "cx88.h" 36#include "cx88.h"
35#include <media/v4l2-common.h>
36 37
37MODULE_DESCRIPTION("driver for cx2388x/cx23416 based mpeg encoder cards"); 38MODULE_DESCRIPTION("driver for cx2388x/cx23416 based mpeg encoder cards");
38MODULE_AUTHOR("Jelle Foks <jelle@foks.8m.com>, Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]"); 39MODULE_AUTHOR("Jelle Foks <jelle@foks.8m.com>, Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
@@ -53,7 +54,6 @@ static LIST_HEAD(cx8802_devlist);
53 54
54/* ------------------------------------------------------------------ */ 55/* ------------------------------------------------------------------ */
55 56
56#define BLACKBIRD_FIRM_ENC_FILENAME "blackbird-fw-enc.bin"
57#define BLACKBIRD_FIRM_IMAGE_SIZE 256*1024 57#define BLACKBIRD_FIRM_IMAGE_SIZE 256*1024
58 58
59/* defines below are from ivtv-driver.h */ 59/* defines below are from ivtv-driver.h */
@@ -63,8 +63,6 @@ static LIST_HEAD(cx8802_devlist);
63/* Firmware API commands */ 63/* Firmware API commands */
64#define IVTV_API_STD_TIMEOUT 500 64#define IVTV_API_STD_TIMEOUT 500
65 65
66#define BLACKBIRD_API_PING 0x80
67#define BLACKBIRD_API_BEGIN_CAPTURE 0x81
68enum blackbird_capture_type { 66enum blackbird_capture_type {
69 BLACKBIRD_MPEG_CAPTURE, 67 BLACKBIRD_MPEG_CAPTURE,
70 BLACKBIRD_RAW_CAPTURE, 68 BLACKBIRD_RAW_CAPTURE,
@@ -78,205 +76,29 @@ enum blackbird_capture_bits {
78 BLACKBIRD_RAW_BITS_PASSTHRU_CAPTURE = 0x08, 76 BLACKBIRD_RAW_BITS_PASSTHRU_CAPTURE = 0x08,
79 BLACKBIRD_RAW_BITS_TO_HOST_CAPTURE = 0x10 77 BLACKBIRD_RAW_BITS_TO_HOST_CAPTURE = 0x10
80}; 78};
81#define BLACKBIRD_API_END_CAPTURE 0x82
82enum blackbird_capture_end { 79enum blackbird_capture_end {
83 BLACKBIRD_END_AT_GOP, /* stop at the end of gop, generate irq */ 80 BLACKBIRD_END_AT_GOP, /* stop at the end of gop, generate irq */
84 BLACKBIRD_END_NOW, /* stop immediately, no irq */ 81 BLACKBIRD_END_NOW, /* stop immediately, no irq */
85}; 82};
86#define BLACKBIRD_API_SET_AUDIO_ID 0x89
87#define BLACKBIRD_API_SET_VIDEO_ID 0x8B
88#define BLACKBIRD_API_SET_PCR_ID 0x8D
89#define BLACKBIRD_API_SET_FRAMERATE 0x8F
90enum blackbird_framerate { 83enum blackbird_framerate {
91 BLACKBIRD_FRAMERATE_NTSC_30, /* NTSC: 30fps */ 84 BLACKBIRD_FRAMERATE_NTSC_30, /* NTSC: 30fps */
92 BLACKBIRD_FRAMERATE_PAL_25 /* PAL: 25fps */ 85 BLACKBIRD_FRAMERATE_PAL_25 /* PAL: 25fps */
93}; 86};
94#define BLACKBIRD_API_SET_RESOLUTION 0x91
95#define BLACKBIRD_API_SET_VIDEO_BITRATE 0x95
96enum blackbird_video_bitrate_type {
97 BLACKBIRD_VIDEO_VBR,
98 BLACKBIRD_VIDEO_CBR
99};
100#define BLACKBIRD_PEAK_RATE_DIVISOR 400
101enum blackbird_mux_rate {
102 BLACKBIRD_MUX_RATE_DEFAULT,
103 /* dvd mux rate: multiply by 400 to get the actual rate */
104 BLACKBIRD_MUX_RATE_DVD = 25200
105};
106#define BLACKBIRD_API_SET_GOP_STRUCTURE 0x97
107#define BLACKBIRD_API_SET_ASPECT_RATIO 0x99
108enum blackbird_aspect_ratio {
109 BLACKBIRD_ASPECT_RATIO_FORBIDDEN,
110 BLACKBIRD_ASPECT_RATIO_1_1_SQUARE,
111 BLACKBIRD_ASPECT_RATIO_4_3,
112 BLACKBIRD_ASPECT_RATIO_16_9,
113 BLACKBIRD_ASPECT_RATIO_221_100,
114 BLACKBIRD_ASPECT_RATIO_RESERVED
115};
116#define BLACKBIRD_API_SET_DNR_MODE 0x9B
117enum blackbird_dnr_bits {
118 BLACKBIRD_DNR_BITS_MANUAL,
119 BLACKBIRD_DNR_BITS_AUTO_SPATIAL,
120 BLACKBIRD_DNR_BITS_AUTO_TEMPORAL,
121 BLACKBIRD_DNR_BITS_AUTO
122};
123enum blackbird_median_filter {
124 BLACKBIRD_MEDIAN_FILTER_DISABLED,
125 BLACKBIRD_MEDIAN_FILTER_HORIZONTAL,
126 BLACKBIRD_MEDIAN_FILTER_VERTICAL,
127 BLACKBIRD_MEDIAN_FILTER_HV,
128 BLACKBIRD_MEDIAN_FILTER_DIAGONAL
129};
130#define BLACKBIRD_API_SET_MANUAL_DNR 0x9D
131#define BLACKBIRD_API_SET_DNR_MEDIAN 0x9F
132#define BLACKBIRD_API_SET_SPATIAL_FILTER 0xA1
133enum blackbird_spatial_filter_luma {
134 BLACKBIRD_SPATIAL_FILTER_LUMA_DISABLED,
135 BLACKBIRD_SPATIAL_FILTER_LUMA_1D_HORIZ,
136 BLACKBIRD_SPATIAL_FILTER_LUMA_1D_VERT,
137 BLACKBIRD_SPATIAL_FILTER_LUMA_2D_HV, /* separable, default */
138 BLACKBIRD_SPATIAL_FILTER_LUMA_2D_SYMM /* symmetric non-separable */
139};
140enum blackbird_spatial_filter_chroma {
141 BLACKBIRD_SPATIAL_FILTER_CHROMA_DISABLED,
142 BLACKBIRD_SPATIAL_FILTER_CHROMA_1D_HORIZ /* default */
143};
144#define BLACKBIRD_API_SET_3_2_PULLDOWN 0xB1
145enum blackbird_pulldown {
146 BLACKBIRD_3_2_PULLDOWN_DISABLED,
147 BLACKBIRD_3_2_PULLDOWN_ENABLED
148};
149#define BLACKBIRD_API_SET_VBI_LINE_NO 0xB7
150enum blackbird_vbi_line_bits {
151 BLACKBIRD_VBI_LINE_BITS_TOP_FIELD,
152 BLACKBIRD_VBI_LINE_BITS_BOT_FIELD = (1 << 31),
153 BLACKBIRD_VBI_LINE_BITS_ALL_LINES = 0xFFFFFFFF
154};
155enum blackbird_vbi_line {
156 BLACKBIRD_VBI_LINE_DISABLED,
157 BLACKBIRD_VBI_LINE_ENABLED
158};
159enum blackbird_vbi_slicing {
160 BLACKBIRD_VBI_SLICING_NONE,
161 BLACKBIRD_VBI_SLICING_CLOSED_CAPTION
162};
163#define BLACKBIRD_API_SET_STREAM_TYPE 0xB9
164enum blackbird_stream_type {
165 BLACKBIRD_STREAM_PROGRAM,
166 BLACKBIRD_STREAM_TRANSPORT,
167 BLACKBIRD_STREAM_MPEG1,
168 BLACKBIRD_STREAM_PES_AV,
169 BLACKBIRD_STREAM_UNKNOWN4,
170 BLACKBIRD_STREAM_PES_VIDEO,
171 BLACKBIRD_STREAM_UNKNOWN6,
172 BLACKBIRD_STREAM_PES_AUDIO,
173 BLACKBIRD_STREAM_UNKNOWN8,
174 BLACKBIRD_STREAM_UNKNOWN9, /* audio/pcm ? */
175 BLACKBIRD_STREAM_DVD,
176 BLACKBIRD_STREAM_VCD,
177 BLACKBIRD_STREAM_UNKNOWN12 /* svcd/xvcd ? */
178};
179#define BLACKBIRD_API_SET_OUTPUT_PORT 0xBB
180enum blackbird_stream_port { 87enum blackbird_stream_port {
181 BLACKBIRD_OUTPUT_PORT_MEMORY, 88 BLACKBIRD_OUTPUT_PORT_MEMORY,
182 BLACKBIRD_OUTPUT_PORT_STREAMING, 89 BLACKBIRD_OUTPUT_PORT_STREAMING,
183 BLACKBIRD_OUTPUT_PORT_SERIAL 90 BLACKBIRD_OUTPUT_PORT_SERIAL
184}; 91};
185#define BLACKBIRD_API_SET_AUDIO_PARAMS 0xBD
186enum blackbird_audio_bits_sample_rate {
187 BLACKBIRD_AUDIO_BITS_44100HZ,
188 BLACKBIRD_AUDIO_BITS_48000HZ,
189 BLACKBIRD_AUDIO_BITS_32000HZ,
190 BLACKBIRD_AUDIO_BITS_RESERVED_HZ,
191};
192enum blackbird_audio_bits_encoding {
193 BLACKBIRD_AUDIO_BITS_LAYER_1 = 0x1 << 2,
194 BLACKBIRD_AUDIO_BITS_LAYER_2 = 0x2 << 2,
195};
196enum blackbird_audio_bits_bitrate_layer_1 {
197 BLACKBIRD_AUDIO_BITS_LAYER_1_FREE_FORMAT,
198 BLACKBIRD_AUDIO_BITS_LAYER_1_32 = 0x01 << 4,
199 BLACKBIRD_AUDIO_BITS_LAYER_1_64 = 0x02 << 4,
200 BLACKBIRD_AUDIO_BITS_LAYER_1_96 = 0x03 << 4,
201 BLACKBIRD_AUDIO_BITS_LAYER_1_128 = 0x04 << 4,
202 BLACKBIRD_AUDIO_BITS_LAYER_1_160 = 0x05 << 4,
203 BLACKBIRD_AUDIO_BITS_LAYER_1_192 = 0x06 << 4,
204 BLACKBIRD_AUDIO_BITS_LAYER_1_224 = 0x07 << 4,
205 BLACKBIRD_AUDIO_BITS_LAYER_1_256 = 0x08 << 4,
206 BLACKBIRD_AUDIO_BITS_LAYER_1_288 = 0x09 << 4,
207 BLACKBIRD_AUDIO_BITS_LAYER_1_320 = 0x0A << 4,
208 BLACKBIRD_AUDIO_BITS_LAYER_1_352 = 0x0B << 4,
209 BLACKBIRD_AUDIO_BITS_LAYER_1_384 = 0x0C << 4,
210 BLACKBIRD_AUDIO_BITS_LAYER_1_416 = 0x0D << 4,
211 BLACKBIRD_AUDIO_BITS_LAYER_1_448 = 0x0E << 4,
212};
213enum blackbird_audio_bits_bitrate_layer_2 {
214 BLACKBIRD_AUDIO_BITS_LAYER_2_FREE_FORMAT,
215 BLACKBIRD_AUDIO_BITS_LAYER_2_32 = 0x01 << 4,
216 BLACKBIRD_AUDIO_BITS_LAYER_2_48 = 0x02 << 4,
217 BLACKBIRD_AUDIO_BITS_LAYER_2_56 = 0x03 << 4,
218 BLACKBIRD_AUDIO_BITS_LAYER_2_64 = 0x04 << 4,
219 BLACKBIRD_AUDIO_BITS_LAYER_2_80 = 0x05 << 4,
220 BLACKBIRD_AUDIO_BITS_LAYER_2_96 = 0x06 << 4,
221 BLACKBIRD_AUDIO_BITS_LAYER_2_112 = 0x07 << 4,
222 BLACKBIRD_AUDIO_BITS_LAYER_2_128 = 0x08 << 4,
223 BLACKBIRD_AUDIO_BITS_LAYER_2_160 = 0x09 << 4,
224 BLACKBIRD_AUDIO_BITS_LAYER_2_192 = 0x0A << 4,
225 BLACKBIRD_AUDIO_BITS_LAYER_2_224 = 0x0B << 4,
226 BLACKBIRD_AUDIO_BITS_LAYER_2_256 = 0x0C << 4,
227 BLACKBIRD_AUDIO_BITS_LAYER_2_320 = 0x0D << 4,
228 BLACKBIRD_AUDIO_BITS_LAYER_2_384 = 0x0E << 4,
229};
230enum blackbird_audio_bits_mode {
231 BLACKBIRD_AUDIO_BITS_STEREO,
232 BLACKBIRD_AUDIO_BITS_JOINT_STEREO = 0x1 << 8,
233 BLACKBIRD_AUDIO_BITS_DUAL = 0x2 << 8,
234 BLACKBIRD_AUDIO_BITS_MONO = 0x3 << 8,
235};
236enum blackbird_audio_bits_mode_extension {
237 BLACKBIRD_AUDIO_BITS_BOUND_4,
238 BLACKBIRD_AUDIO_BITS_BOUND_8 = 0x1 << 10,
239 BLACKBIRD_AUDIO_BITS_BOUND_12 = 0x2 << 10,
240 BLACKBIRD_AUDIO_BITS_BOUND_16 = 0x3 << 10,
241};
242enum blackbird_audio_bits_emphasis {
243 BLACKBIRD_AUDIO_BITS_EMPHASIS_NONE,
244 BLACKBIRD_AUDIO_BITS_EMPHASIS_50_15 = 0x1 << 12,
245 BLACKBIRD_AUDIO_BITS_EMPHASIS_RESERVED = 0x2 << 12,
246 BLACKBIRD_AUDIO_BITS_EMPHASIS_CCITT_J17 = 0x3 << 12,
247};
248enum blackbird_audio_bits_crc {
249 BLACKBIRD_AUDIO_BITS_CRC_OFF,
250 BLACKBIRD_AUDIO_BITS_CRC_ON = 0x1 << 14,
251};
252enum blackbird_audio_bits_copyright {
253 BLACKBIRD_AUDIO_BITS_COPYRIGHT_OFF,
254 BLACKBIRD_AUDIO_BITS_COPYRIGHT_ON = 0x1 << 15,
255};
256enum blackbird_audio_bits_original {
257 BLACKBIRD_AUDIO_BITS_COPY,
258 BLACKBIRD_AUDIO_BITS_ORIGINAL = 0x1 << 16,
259};
260#define BLACKBIRD_API_HALT 0xC3
261#define BLACKBIRD_API_GET_VERSION 0xC4
262#define BLACKBIRD_API_SET_GOP_CLOSURE 0xC5
263enum blackbird_gop_closure {
264 BLACKBIRD_GOP_CLOSURE_OFF,
265 BLACKBIRD_GOP_CLOSURE_ON,
266};
267#define BLACKBIRD_API_DATA_XFER_STATUS 0xC6
268enum blackbird_data_xfer_status { 92enum blackbird_data_xfer_status {
269 BLACKBIRD_MORE_BUFFERS_FOLLOW, 93 BLACKBIRD_MORE_BUFFERS_FOLLOW,
270 BLACKBIRD_LAST_BUFFER, 94 BLACKBIRD_LAST_BUFFER,
271}; 95};
272#define BLACKBIRD_API_PROGRAM_INDEX_INFO 0xC7
273enum blackbird_picture_mask { 96enum blackbird_picture_mask {
274 BLACKBIRD_PICTURE_MASK_NONE, 97 BLACKBIRD_PICTURE_MASK_NONE,
275 BLACKBIRD_PICTURE_MASK_I_FRAMES, 98 BLACKBIRD_PICTURE_MASK_I_FRAMES,
276 BLACKBIRD_PICTURE_MASK_I_P_FRAMES = 0x3, 99 BLACKBIRD_PICTURE_MASK_I_P_FRAMES = 0x3,
277 BLACKBIRD_PICTURE_MASK_ALL_FRAMES = 0x7, 100 BLACKBIRD_PICTURE_MASK_ALL_FRAMES = 0x7,
278}; 101};
279#define BLACKBIRD_API_SET_VBI_PARAMS 0xC8
280enum blackbird_vbi_mode_bits { 102enum blackbird_vbi_mode_bits {
281 BLACKBIRD_VBI_BITS_SLICED, 103 BLACKBIRD_VBI_BITS_SLICED,
282 BLACKBIRD_VBI_BITS_RAW, 104 BLACKBIRD_VBI_BITS_RAW,
@@ -288,33 +110,23 @@ enum blackbird_vbi_insertion_bits {
288 BLACKBIRD_VBI_BITS_SEPARATE_STREAM_USR_DATA = 0x4 << 1, 110 BLACKBIRD_VBI_BITS_SEPARATE_STREAM_USR_DATA = 0x4 << 1,
289 BLACKBIRD_VBI_BITS_SEPARATE_STREAM_PRV_DATA = 0x5 << 1, 111 BLACKBIRD_VBI_BITS_SEPARATE_STREAM_PRV_DATA = 0x5 << 1,
290}; 112};
291#define BLACKBIRD_API_SET_DMA_BLOCK_SIZE 0xC9
292enum blackbird_dma_unit { 113enum blackbird_dma_unit {
293 BLACKBIRD_DMA_BYTES, 114 BLACKBIRD_DMA_BYTES,
294 BLACKBIRD_DMA_FRAMES, 115 BLACKBIRD_DMA_FRAMES,
295}; 116};
296#define BLACKBIRD_API_DMA_TRANSFER_INFO 0xCA
297#define BLACKBIRD_API_DMA_TRANSFER_STAT 0xCB
298enum blackbird_dma_transfer_status_bits { 117enum blackbird_dma_transfer_status_bits {
299 BLACKBIRD_DMA_TRANSFER_BITS_DONE = 0x01, 118 BLACKBIRD_DMA_TRANSFER_BITS_DONE = 0x01,
300 BLACKBIRD_DMA_TRANSFER_BITS_ERROR = 0x04, 119 BLACKBIRD_DMA_TRANSFER_BITS_ERROR = 0x04,
301 BLACKBIRD_DMA_TRANSFER_BITS_LL_ERROR = 0x10, 120 BLACKBIRD_DMA_TRANSFER_BITS_LL_ERROR = 0x10,
302}; 121};
303#define BLACKBIRD_API_SET_DMA2HOST_ADDR 0xCC
304#define BLACKBIRD_API_INIT_VIDEO_INPUT 0xCD
305#define BLACKBIRD_API_SET_FRAMESKIP 0xD0
306#define BLACKBIRD_API_PAUSE 0xD2
307enum blackbird_pause { 122enum blackbird_pause {
308 BLACKBIRD_PAUSE_ENCODING, 123 BLACKBIRD_PAUSE_ENCODING,
309 BLACKBIRD_RESUME_ENCODING, 124 BLACKBIRD_RESUME_ENCODING,
310}; 125};
311#define BLACKBIRD_API_REFRESH_INPUT 0xD3
312#define BLACKBIRD_API_SET_COPYRIGHT 0xD4
313enum blackbird_copyright { 126enum blackbird_copyright {
314 BLACKBIRD_COPYRIGHT_OFF, 127 BLACKBIRD_COPYRIGHT_OFF,
315 BLACKBIRD_COPYRIGHT_ON, 128 BLACKBIRD_COPYRIGHT_ON,
316}; 129};
317#define BLACKBIRD_API_SET_NOTIFICATION 0xD5
318enum blackbird_notification_type { 130enum blackbird_notification_type {
319 BLACKBIRD_NOTIFICATION_REFRESH, 131 BLACKBIRD_NOTIFICATION_REFRESH,
320}; 132};
@@ -325,7 +137,6 @@ enum blackbird_notification_status {
325enum blackbird_notification_mailbox { 137enum blackbird_notification_mailbox {
326 BLACKBIRD_NOTIFICATION_NO_MAILBOX = -1, 138 BLACKBIRD_NOTIFICATION_NO_MAILBOX = -1,
327}; 139};
328#define BLACKBIRD_API_SET_CAPTURE_LINES 0xD6
329enum blackbird_field1_lines { 140enum blackbird_field1_lines {
330 BLACKBIRD_FIELD1_SAA7114 = 0x00EF, /* 239 */ 141 BLACKBIRD_FIELD1_SAA7114 = 0x00EF, /* 239 */
331 BLACKBIRD_FIELD1_SAA7115 = 0x00F0, /* 240 */ 142 BLACKBIRD_FIELD1_SAA7115 = 0x00F0, /* 240 */
@@ -336,12 +147,10 @@ enum blackbird_field2_lines {
336 BLACKBIRD_FIELD2_SAA7115 = 0x00F0, /* 240 */ 147 BLACKBIRD_FIELD2_SAA7115 = 0x00F0, /* 240 */
337 BLACKBIRD_FIELD2_MICRONAS = 0x0106, /* 262 */ 148 BLACKBIRD_FIELD2_MICRONAS = 0x0106, /* 262 */
338}; 149};
339#define BLACKBIRD_API_SET_CUSTOM_DATA 0xD7
340enum blackbird_custom_data_type { 150enum blackbird_custom_data_type {
341 BLACKBIRD_CUSTOM_EXTENSION_USR_DATA, 151 BLACKBIRD_CUSTOM_EXTENSION_USR_DATA,
342 BLACKBIRD_CUSTOM_PRIVATE_PACKET, 152 BLACKBIRD_CUSTOM_PRIVATE_PACKET,
343}; 153};
344#define BLACKBIRD_API_MUTE_VIDEO 0xD9
345enum blackbird_mute { 154enum blackbird_mute {
346 BLACKBIRD_UNMUTE, 155 BLACKBIRD_UNMUTE,
347 BLACKBIRD_MUTE, 156 BLACKBIRD_MUTE,
@@ -356,7 +165,6 @@ enum blackbird_mute_video_shift {
356 BLACKBIRD_MUTE_VIDEO_U_SHIFT = 16, 165 BLACKBIRD_MUTE_VIDEO_U_SHIFT = 16,
357 BLACKBIRD_MUTE_VIDEO_Y_SHIFT = 24, 166 BLACKBIRD_MUTE_VIDEO_Y_SHIFT = 24,
358}; 167};
359#define BLACKBIRD_API_MUTE_AUDIO 0xDA
360 168
361/* Registers */ 169/* Registers */
362#define IVTV_REG_ENC_SDRAM_REFRESH (0x07F8 /*| IVTV_REG_OFFSET*/) 170#define IVTV_REG_ENC_SDRAM_REFRESH (0x07F8 /*| IVTV_REG_OFFSET*/)
@@ -498,15 +306,12 @@ static int register_read(struct cx88_core *core, u32 address, u32 *value)
498 306
499/* ------------------------------------------------------------------ */ 307/* ------------------------------------------------------------------ */
500 308
501/* We don't need to call the API often, so using just one mailbox will probably suffice */ 309static int blackbird_mbox_func(void *priv, int command, int in, int out, u32 data[CX2341X_MBOX_MAX_DATA])
502static int blackbird_api_cmd(struct cx8802_dev *dev, u32 command,
503 u32 inputcnt, u32 outputcnt, ...)
504{ 310{
311 struct cx8802_dev *dev = priv;
505 unsigned long timeout; 312 unsigned long timeout;
506 u32 value, flag, retval; 313 u32 value, flag, retval;
507 int i; 314 int i;
508 va_list args;
509 va_start(args, outputcnt);
510 315
511 dprintk(1,"%s: 0x%X\n", __FUNCTION__, command); 316 dprintk(1,"%s: 0x%X\n", __FUNCTION__, command);
512 317
@@ -530,12 +335,11 @@ static int blackbird_api_cmd(struct cx8802_dev *dev, u32 command,
530 /* write command + args + fill remaining with zeros */ 335 /* write command + args + fill remaining with zeros */
531 memory_write(dev->core, dev->mailbox + 1, command); /* command code */ 336 memory_write(dev->core, dev->mailbox + 1, command); /* command code */
532 memory_write(dev->core, dev->mailbox + 3, IVTV_API_STD_TIMEOUT); /* timeout */ 337 memory_write(dev->core, dev->mailbox + 3, IVTV_API_STD_TIMEOUT); /* timeout */
533 for (i = 0; i < inputcnt ; i++) { 338 for (i = 0; i < in; i++) {
534 value = va_arg(args, int); 339 memory_write(dev->core, dev->mailbox + 4 + i, data[i]);
535 memory_write(dev->core, dev->mailbox + 4 + i, value); 340 dprintk(1, "API Input %d = %d\n", i, data[i]);
536 dprintk(1, "API Input %d = %d\n", i, value);
537 } 341 }
538 for (; i < 16 ; i++) 342 for (; i < CX2341X_MBOX_MAX_DATA; i++)
539 memory_write(dev->core, dev->mailbox + 4 + i, 0); 343 memory_write(dev->core, dev->mailbox + 4 + i, 0);
540 344
541 flag |= 3; /* tell 'em we're done writing */ 345 flag |= 3; /* tell 'em we're done writing */
@@ -555,12 +359,10 @@ static int blackbird_api_cmd(struct cx8802_dev *dev, u32 command,
555 } 359 }
556 360
557 /* read output values */ 361 /* read output values */
558 for (i = 0; i < outputcnt ; i++) { 362 for (i = 0; i < out; i++) {
559 int *vptr = va_arg(args, int *); 363 memory_read(dev->core, dev->mailbox + 4 + i, data + i);
560 memory_read(dev->core, dev->mailbox + 4 + i, vptr); 364 dprintk(1, "API Output %d = %d\n", i, data[i]);
561 dprintk(1, "API Output %d = %d\n", i, *vptr);
562 } 365 }
563 va_end(args);
564 366
565 memory_read(dev->core, dev->mailbox + 2, &retval); 367 memory_read(dev->core, dev->mailbox + 2, &retval);
566 dprintk(1, "API result = %d\n",retval); 368 dprintk(1, "API result = %d\n",retval);
@@ -569,7 +371,29 @@ static int blackbird_api_cmd(struct cx8802_dev *dev, u32 command,
569 memory_write(dev->core, dev->mailbox, flag); 371 memory_write(dev->core, dev->mailbox, flag);
570 return retval; 372 return retval;
571} 373}
374/* ------------------------------------------------------------------ */
572 375
376/* We don't need to call the API often, so using just one mailbox will probably suffice */
377static int blackbird_api_cmd(struct cx8802_dev *dev, u32 command,
378 u32 inputcnt, u32 outputcnt, ...)
379{
380 u32 data[CX2341X_MBOX_MAX_DATA];
381 va_list vargs;
382 int i, err;
383
384 va_start(vargs, outputcnt);
385
386 for (i = 0; i < inputcnt; i++) {
387 data[i] = va_arg(vargs, int);
388 }
389 err = blackbird_mbox_func(dev, command, inputcnt, outputcnt, data);
390 for (i = 0; i < outputcnt; i++) {
391 int *vptr = va_arg(vargs, int *);
392 *vptr = data[i];
393 }
394 va_end(vargs);
395 return err;
396}
573 397
574static int blackbird_find_mailbox(struct cx8802_dev *dev) 398static int blackbird_find_mailbox(struct cx8802_dev *dev)
575{ 399{
@@ -614,13 +438,13 @@ static int blackbird_load_firmware(struct cx8802_dev *dev)
614 if (retval < 0) 438 if (retval < 0)
615 dprintk(0, "Error with register_write\n"); 439 dprintk(0, "Error with register_write\n");
616 440
617 retval = request_firmware(&firmware, BLACKBIRD_FIRM_ENC_FILENAME, 441 retval = request_firmware(&firmware, CX2341X_FIRM_ENC_FILENAME,
618 &dev->pci->dev); 442 &dev->pci->dev);
619 443
620 444
621 if (retval != 0) { 445 if (retval != 0) {
622 dprintk(0, "ERROR: Hotplug firmware request failed (%s).\n", 446 dprintk(0, "ERROR: Hotplug firmware request failed (%s).\n",
623 BLACKBIRD_FIRM_ENC_FILENAME); 447 CX2341X_FIRM_ENC_FILENAME);
624 dprintk(0, "Please fix your hotplug setup, the board will " 448 dprintk(0, "Please fix your hotplug setup, the board will "
625 "not work without firmware loaded!\n"); 449 "not work without firmware loaded!\n");
626 return -1; 450 return -1;
@@ -686,12 +510,19 @@ DB* DVD | MPEG2 | 720x576PAL | CBR | 600 :Good | 6000 Kbps | 25fps | M
686*DB: "DirectBurn" 510*DB: "DirectBurn"
687*/ 511*/
688 512
689static struct blackbird_dnr default_dnr_params = { 513static void blackbird_codec_settings(struct cx8802_dev *dev)
690 .mode = BLACKBIRD_DNR_BITS_MANUAL, 514{
691 .type = BLACKBIRD_MEDIAN_FILTER_DISABLED, 515 /* assign frame size */
692 .spatial = 0, 516 blackbird_api_cmd(dev, CX2341X_ENC_SET_FRAME_SIZE, 2, 0,
693 .temporal = 0 517 dev->height, dev->width);
694}; 518
519 dev->params.width = dev->width;
520 dev->params.height = dev->height;
521 dev->params.is_50hz = (dev->core->tvnorm->id & V4L2_STD_625_50) != 0;
522
523 cx2341x_update(dev, blackbird_mbox_func, NULL, &dev->params);
524}
525
695static struct v4l2_mpeg_compression default_mpeg_params = { 526static struct v4l2_mpeg_compression default_mpeg_params = {
696 .st_type = V4L2_MPEG_PS_2, 527 .st_type = V4L2_MPEG_PS_2,
697 .st_bitrate = { 528 .st_bitrate = {
@@ -712,7 +543,7 @@ static struct v4l2_mpeg_compression default_mpeg_params = {
712 .target = 224, 543 .target = 224,
713 .max = 224 544 .max = 224
714 }, 545 },
715 .au_sample_rate = 44100, 546 .au_sample_rate = 48000,
716 .au_pesid = 0, 547 .au_pesid = 0,
717 .vi_type = V4L2_MPEG_VI_2, 548 .vi_type = V4L2_MPEG_VI_2,
718 .vi_aspect_ratio = V4L2_MPEG_ASPECT_4_3, 549 .vi_aspect_ratio = V4L2_MPEG_ASPECT_4_3,
@@ -723,524 +554,13 @@ static struct v4l2_mpeg_compression default_mpeg_params = {
723 .max = 6000 554 .max = 6000
724 }, 555 },
725 .vi_frame_rate = 25, 556 .vi_frame_rate = 25,
726 .vi_frames_per_gop = 15, 557 .vi_frames_per_gop = 12,
727 .vi_bframes_count = 2, 558 .vi_bframes_count = 2,
728 .vi_pesid = 0, 559 .vi_pesid = 0,
729 .closed_gops = 0, 560 .closed_gops = 1,
730 .pulldown = 0 561 .pulldown = 0
731}; 562};
732 563
733static enum blackbird_stream_type mpeg_stream_types[] = {
734 [V4L2_MPEG_SS_1] = BLACKBIRD_STREAM_MPEG1,
735 [V4L2_MPEG_PS_2] = BLACKBIRD_STREAM_PROGRAM,
736 [V4L2_MPEG_TS_2] = BLACKBIRD_STREAM_TRANSPORT,
737 [V4L2_MPEG_PS_DVD] = BLACKBIRD_STREAM_DVD,
738};
739static enum blackbird_aspect_ratio mpeg_stream_ratios[] = {
740 [V4L2_MPEG_ASPECT_SQUARE] = BLACKBIRD_ASPECT_RATIO_1_1_SQUARE,
741 [V4L2_MPEG_ASPECT_4_3] = BLACKBIRD_ASPECT_RATIO_4_3,
742 [V4L2_MPEG_ASPECT_16_9] = BLACKBIRD_ASPECT_RATIO_16_9,
743 [V4L2_MPEG_ASPECT_1_221] = BLACKBIRD_ASPECT_RATIO_221_100,
744};
745static enum blackbird_video_bitrate_type mpeg_video_bitrates[] = {
746 [V4L2_BITRATE_NONE] = BLACKBIRD_VIDEO_CBR,
747 [V4L2_BITRATE_CBR] = BLACKBIRD_VIDEO_CBR,
748 [V4L2_BITRATE_VBR] = BLACKBIRD_VIDEO_VBR,
749};
750/* find the best layer I/II bitrate to fit a given numeric value */
751struct bitrate_bits {
752 u32 bits; /* layer bits for the best fit */
753 u32 rate; /* actual numeric value for the layer best fit */
754};
755struct bitrate_approximation {
756 u32 target; /* numeric value of the rate we want */
757 struct bitrate_bits layer[2];
758};
759static struct bitrate_approximation mpeg_audio_bitrates[] = {
760 /* target layer[0].bits layer[0].rate layer[1].bits layer[1].rate */
761 { 0, { { 0, 0, }, { 0, 0, }, }, },
762 { 32, { { BLACKBIRD_AUDIO_BITS_LAYER_1_32 , 32, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_32 , 32, }, }, },
763 { 48, { { BLACKBIRD_AUDIO_BITS_LAYER_1_64 , 64, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_48 , 48, }, }, },
764 { 56, { { BLACKBIRD_AUDIO_BITS_LAYER_1_64 , 64, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_56 , 56, }, }, },
765 { 64, { { BLACKBIRD_AUDIO_BITS_LAYER_1_64 , 64, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_64 , 64, }, }, },
766 { 80, { { BLACKBIRD_AUDIO_BITS_LAYER_1_96 , 96, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_80 , 80, }, }, },
767 { 96, { { BLACKBIRD_AUDIO_BITS_LAYER_1_96 , 96, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_96 , 96, }, }, },
768 { 112, { { BLACKBIRD_AUDIO_BITS_LAYER_1_128, 128, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_112, 112, }, }, },
769 { 128, { { BLACKBIRD_AUDIO_BITS_LAYER_1_128, 128, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_128, 128, }, }, },
770 { 160, { { BLACKBIRD_AUDIO_BITS_LAYER_1_160, 160, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_160, 160, }, }, },
771 { 192, { { BLACKBIRD_AUDIO_BITS_LAYER_1_192, 192, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_192, 192, }, }, },
772 { 224, { { BLACKBIRD_AUDIO_BITS_LAYER_1_224, 224, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_224, 224, }, }, },
773 { 256, { { BLACKBIRD_AUDIO_BITS_LAYER_1_256, 256, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_256, 256, }, }, },
774 { 288, { { BLACKBIRD_AUDIO_BITS_LAYER_1_288, 288, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_320, 320, }, }, },
775 { 320, { { BLACKBIRD_AUDIO_BITS_LAYER_1_320, 320, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_320, 320, }, }, },
776 { 352, { { BLACKBIRD_AUDIO_BITS_LAYER_1_352, 352, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_384, 384, }, }, },
777 { 384, { { BLACKBIRD_AUDIO_BITS_LAYER_1_384, 384, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_384, 384, }, }, },
778 { 416, { { BLACKBIRD_AUDIO_BITS_LAYER_1_416, 416, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_384, 384, }, }, },
779 { 448, { { BLACKBIRD_AUDIO_BITS_LAYER_1_448, 448, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_384, 384, }, }, },
780};
781static const int BITRATES_SIZE = ARRAY_SIZE(mpeg_audio_bitrates);
782
783static void blackbird_set_default_params(struct cx8802_dev *dev)
784{
785 struct v4l2_mpeg_compression *params = &dev->params;
786 u32 au_params;
787
788 /* assign stream type */
789 if( params->st_type >= ARRAY_SIZE(mpeg_stream_types) )
790 params->st_type = V4L2_MPEG_PS_2;
791 if( params->st_type == V4L2_MPEG_SS_1 )
792 params->vi_type = V4L2_MPEG_VI_1;
793 else
794 params->vi_type = V4L2_MPEG_VI_2;
795 blackbird_api_cmd(dev, BLACKBIRD_API_SET_STREAM_TYPE, 1, 0, mpeg_stream_types[params->st_type]);
796
797 /* assign framerate */
798 if( params->vi_frame_rate <= 25 )
799 {
800 params->vi_frame_rate = 25;
801 blackbird_api_cmd(dev, BLACKBIRD_API_SET_FRAMERATE, 1, 0, BLACKBIRD_FRAMERATE_PAL_25);
802 }
803 else
804 {
805 params->vi_frame_rate = 30;
806 blackbird_api_cmd(dev, BLACKBIRD_API_SET_FRAMERATE, 1, 0, BLACKBIRD_FRAMERATE_NTSC_30);
807 }
808
809 /* assign aspect ratio */
810 if( params->vi_aspect_ratio >= ARRAY_SIZE(mpeg_stream_ratios) )
811 params->vi_aspect_ratio = V4L2_MPEG_ASPECT_4_3;
812 blackbird_api_cmd(dev, BLACKBIRD_API_SET_ASPECT_RATIO, 1, 0, mpeg_stream_ratios[params->vi_aspect_ratio]);
813
814 /* assign gop properties */
815 blackbird_api_cmd(dev, BLACKBIRD_API_SET_GOP_STRUCTURE, 2, 0, params->vi_frames_per_gop, params->vi_bframes_count+1);
816
817 /* assign gop closure */
818 blackbird_api_cmd(dev, BLACKBIRD_API_SET_GOP_CLOSURE, 1, 0, params->closed_gops);
819
820 /* assign 3 2 pulldown */
821 blackbird_api_cmd(dev, BLACKBIRD_API_SET_3_2_PULLDOWN, 1, 0, params->pulldown);
822
823 /* make sure the params are within bounds */
824 if( params->st_bitrate.mode >= ARRAY_SIZE(mpeg_video_bitrates) )
825 params->vi_bitrate.mode = V4L2_BITRATE_NONE;
826 if( params->vi_bitrate.mode >= ARRAY_SIZE(mpeg_video_bitrates) )
827 params->vi_bitrate.mode = V4L2_BITRATE_NONE;
828 if( params->au_bitrate.mode >= ARRAY_SIZE(mpeg_video_bitrates) )
829 params->au_bitrate.mode = V4L2_BITRATE_NONE;
830
831 /* assign audio properties */
832 /* note: it's not necessary to set the samplerate, the mpeg encoder seems to autodetect/adjust */
833 au_params = BLACKBIRD_AUDIO_BITS_STEREO |
834 /* BLACKBIRD_AUDIO_BITS_BOUND_4 | */
835 BLACKBIRD_AUDIO_BITS_EMPHASIS_NONE |
836 BLACKBIRD_AUDIO_BITS_CRC_OFF |
837 BLACKBIRD_AUDIO_BITS_COPYRIGHT_OFF |
838 BLACKBIRD_AUDIO_BITS_COPY |
839 0;
840 if( params->au_sample_rate <= 32000 )
841 {
842 params->au_sample_rate = 32000;
843 au_params |= BLACKBIRD_AUDIO_BITS_32000HZ;
844 }
845 else if( params->au_sample_rate <= 44100 )
846 {
847 params->au_sample_rate = 44100;
848 au_params |= BLACKBIRD_AUDIO_BITS_44100HZ;
849 }
850 else
851 {
852 params->au_sample_rate = 48000;
853 au_params |= BLACKBIRD_AUDIO_BITS_48000HZ;
854 }
855 if( params->au_type == V4L2_MPEG_AU_2_I )
856 {
857 au_params |= BLACKBIRD_AUDIO_BITS_LAYER_1;
858 }
859 else
860 {
861 /* TODO: try to handle the other formats more gracefully */
862 params->au_type = V4L2_MPEG_AU_2_II;
863 au_params |= BLACKBIRD_AUDIO_BITS_LAYER_2;
864 }
865 if( params->au_bitrate.mode )
866 {
867 int layer;
868
869 if( params->au_bitrate.mode == V4L2_BITRATE_CBR )
870 params->au_bitrate.max = params->vi_bitrate.target;
871 else
872 params->au_bitrate.target = params->vi_bitrate.max;
873
874 layer = params->au_type;
875 if( params->au_bitrate.target == 0 )
876 {
877 /* TODO: use the minimum possible bitrate instead of 0 ? */
878 au_params |= 0;
879 }
880 else if( params->au_bitrate.target >=
881 mpeg_audio_bitrates[BITRATES_SIZE-1].layer[layer].rate )
882 {
883 /* clamp the bitrate to the max supported by the standard */
884 params->au_bitrate.target = mpeg_audio_bitrates[BITRATES_SIZE-1].layer[layer].rate;
885 params->au_bitrate.max = params->au_bitrate.target;
886 au_params |= mpeg_audio_bitrates[BITRATES_SIZE-1].layer[layer].bits;
887 }
888 else
889 {
890 /* round up to the nearest supported bitrate */
891 int i;
892 for(i = 1; i < BITRATES_SIZE; i++)
893 {
894 if( params->au_bitrate.target > mpeg_audio_bitrates[i-1].layer[layer].rate &&
895 params->au_bitrate.target <= mpeg_audio_bitrates[i].layer[layer].rate )
896 {
897 params->au_bitrate.target = mpeg_audio_bitrates[i].layer[layer].rate;
898 params->au_bitrate.max = params->au_bitrate.target;
899 au_params |= mpeg_audio_bitrates[i].layer[layer].bits;
900 break;
901 }
902 }
903 }
904 }
905 else
906 {
907 /* TODO: ??? */
908 params->au_bitrate.target = params->au_bitrate.max = 0;
909 au_params |= 0;
910 }
911 blackbird_api_cmd(dev, BLACKBIRD_API_SET_AUDIO_PARAMS, 1, 0, au_params );
912
913 /* assign bitrates */
914 if( params->vi_bitrate.mode )
915 {
916 /* bitrate is set, let's figure out the cbr/vbr mess */
917 if( params->vi_bitrate.max < params->vi_bitrate.target )
918 {
919 if( params->vi_bitrate.mode == V4L2_BITRATE_CBR )
920 params->vi_bitrate.max = params->vi_bitrate.target;
921 else
922 params->vi_bitrate.target = params->vi_bitrate.max;
923 }
924 }
925 else
926 {
927 if( params->st_bitrate.max < params->st_bitrate.target )
928 {
929 if( params->st_bitrate.mode == V4L2_BITRATE_VBR )
930 params->st_bitrate.target = params->st_bitrate.max;
931 else
932 params->st_bitrate.max = params->st_bitrate.target;
933 }
934 /* calculate vi_bitrate = st_bitrate - au_bitrate */
935 params->vi_bitrate.max = params->st_bitrate.max - params->au_bitrate.max;
936 params->vi_bitrate.target = params->st_bitrate.target - params->au_bitrate.target;
937 }
938 blackbird_api_cmd(dev, BLACKBIRD_API_SET_VIDEO_BITRATE, 4, 0,
939 mpeg_video_bitrates[params->vi_bitrate.mode],
940 params->vi_bitrate.target * 1000, /* kbps -> bps */
941 params->vi_bitrate.max * 1000 / BLACKBIRD_PEAK_RATE_DIVISOR, /* peak/400 */
942 BLACKBIRD_MUX_RATE_DEFAULT /*, 0x70*/); /* encoding buffer, ckennedy */
943
944 /* TODO: implement the stream ID stuff:
945 ts_pid_pmt, ts_pid_audio, ts_pid_video, ts_pid_pcr,
946 ps_size, au_pesid, vi_pesid
947 */
948}
949#define CHECK_PARAM( name ) ( dev->params.name != params->name )
950#define IF_PARAM( name ) if( CHECK_PARAM( name ) )
951#define UPDATE_PARAM( name ) dev->params.name = params->name
952void blackbird_set_params(struct cx8802_dev *dev, struct v4l2_mpeg_compression *params)
953{
954 u32 au_params;
955
956 /* assign stream type */
957 if( params->st_type >= ARRAY_SIZE(mpeg_stream_types) )
958 params->st_type = V4L2_MPEG_PS_2;
959 if( params->st_type == V4L2_MPEG_SS_1 )
960 params->vi_type = V4L2_MPEG_VI_1;
961 else
962 params->vi_type = V4L2_MPEG_VI_2;
963 if( CHECK_PARAM( st_type ) || CHECK_PARAM( vi_type ) )
964 {
965 UPDATE_PARAM( st_type );
966 UPDATE_PARAM( vi_type );
967 blackbird_api_cmd(dev, BLACKBIRD_API_SET_STREAM_TYPE, 1, 0, mpeg_stream_types[params->st_type]);
968 }
969
970 /* assign framerate */
971 if( params->vi_frame_rate <= 25 )
972 params->vi_frame_rate = 25;
973 else
974 params->vi_frame_rate = 30;
975 IF_PARAM( vi_frame_rate )
976 {
977 UPDATE_PARAM( vi_frame_rate );
978 if( params->vi_frame_rate == 25 )
979 blackbird_api_cmd(dev, BLACKBIRD_API_SET_FRAMERATE, 1, 0, BLACKBIRD_FRAMERATE_PAL_25);
980 else
981 blackbird_api_cmd(dev, BLACKBIRD_API_SET_FRAMERATE, 1, 0, BLACKBIRD_FRAMERATE_NTSC_30);
982 }
983
984 /* assign aspect ratio */
985 if( params->vi_aspect_ratio >= ARRAY_SIZE(mpeg_stream_ratios) )
986 params->vi_aspect_ratio = V4L2_MPEG_ASPECT_4_3;
987 IF_PARAM( vi_aspect_ratio )
988 {
989 UPDATE_PARAM( vi_aspect_ratio );
990 blackbird_api_cmd(dev, BLACKBIRD_API_SET_ASPECT_RATIO, 1, 0, mpeg_stream_ratios[params->vi_aspect_ratio]);
991 }
992
993 /* assign gop properties */
994 if( CHECK_PARAM( vi_frames_per_gop ) || CHECK_PARAM( vi_bframes_count ) )
995 {
996 UPDATE_PARAM( vi_frames_per_gop );
997 UPDATE_PARAM( vi_bframes_count );
998 blackbird_api_cmd(dev, BLACKBIRD_API_SET_GOP_STRUCTURE, 2, 0, params->vi_frames_per_gop, params->vi_bframes_count+1);
999 }
1000
1001 /* assign gop closure */
1002 IF_PARAM( closed_gops )
1003 {
1004 UPDATE_PARAM( closed_gops );
1005 blackbird_api_cmd(dev, BLACKBIRD_API_SET_GOP_CLOSURE, 1, 0, params->closed_gops);
1006 }
1007
1008 /* assign 3 2 pulldown */
1009 IF_PARAM( pulldown )
1010 {
1011 UPDATE_PARAM( pulldown );
1012 blackbird_api_cmd(dev, BLACKBIRD_API_SET_3_2_PULLDOWN, 1, 0, params->pulldown);
1013 }
1014
1015 /* make sure the params are within bounds */
1016 if( params->st_bitrate.mode >= ARRAY_SIZE(mpeg_video_bitrates) )
1017 params->vi_bitrate.mode = V4L2_BITRATE_NONE;
1018 if( params->vi_bitrate.mode >= ARRAY_SIZE(mpeg_video_bitrates) )
1019 params->vi_bitrate.mode = V4L2_BITRATE_NONE;
1020 if( params->au_bitrate.mode >= ARRAY_SIZE(mpeg_video_bitrates) )
1021 params->au_bitrate.mode = V4L2_BITRATE_NONE;
1022
1023 /* assign audio properties */
1024 /* note: it's not necessary to set the samplerate, the mpeg encoder seems to autodetect/adjust */
1025 au_params = BLACKBIRD_AUDIO_BITS_STEREO |
1026 /* BLACKBIRD_AUDIO_BITS_BOUND_4 | */
1027 BLACKBIRD_AUDIO_BITS_EMPHASIS_NONE |
1028 BLACKBIRD_AUDIO_BITS_CRC_OFF |
1029 BLACKBIRD_AUDIO_BITS_COPYRIGHT_OFF |
1030 BLACKBIRD_AUDIO_BITS_COPY |
1031 0;
1032 if( params->au_sample_rate < 32000 )
1033 {
1034 params->au_sample_rate = 32000;
1035 au_params |= BLACKBIRD_AUDIO_BITS_32000HZ;
1036 }
1037 else if( params->au_sample_rate < 44100 )
1038 {
1039 params->au_sample_rate = 44100;
1040 au_params |= BLACKBIRD_AUDIO_BITS_44100HZ;
1041 }
1042 else
1043 {
1044 params->au_sample_rate = 48000;
1045 au_params |= BLACKBIRD_AUDIO_BITS_48000HZ;
1046 }
1047 if( params->au_type == V4L2_MPEG_AU_2_I )
1048 {
1049 au_params |= BLACKBIRD_AUDIO_BITS_LAYER_1;
1050 }
1051 else
1052 {
1053 /* TODO: try to handle the other formats more gracefully */
1054 params->au_type = V4L2_MPEG_AU_2_II;
1055 au_params |= BLACKBIRD_AUDIO_BITS_LAYER_2;
1056 }
1057 if( params->au_bitrate.mode )
1058 {
1059 int layer;
1060
1061 if( params->au_bitrate.mode == V4L2_BITRATE_CBR )
1062 params->au_bitrate.max = params->vi_bitrate.target;
1063 else
1064 params->au_bitrate.target = params->vi_bitrate.max;
1065
1066 layer = params->au_type;
1067 if( params->au_bitrate.target == 0 )
1068 {
1069 /* TODO: use the minimum possible bitrate instead of 0 ? */
1070 au_params |= 0;
1071 }
1072 else if( params->au_bitrate.target >=
1073 mpeg_audio_bitrates[BITRATES_SIZE-1].layer[layer].rate )
1074 {
1075 /* clamp the bitrate to the max supported by the standard */
1076 params->au_bitrate.target = mpeg_audio_bitrates[BITRATES_SIZE-1].layer[layer].rate;
1077 params->au_bitrate.max = params->au_bitrate.target;
1078 au_params |= mpeg_audio_bitrates[BITRATES_SIZE-1].layer[layer].bits;
1079 }
1080 else
1081 {
1082 /* round up to the nearest supported bitrate */
1083 int i;
1084 for(i = 1; i < BITRATES_SIZE; i++)
1085 {
1086 if( params->au_bitrate.target > mpeg_audio_bitrates[i-1].layer[layer].rate &&
1087 params->au_bitrate.target <= mpeg_audio_bitrates[i].layer[layer].rate )
1088 {
1089 params->au_bitrate.target = mpeg_audio_bitrates[i].layer[layer].rate;
1090 params->au_bitrate.max = params->au_bitrate.target;
1091 au_params |= mpeg_audio_bitrates[i].layer[layer].bits;
1092 break;
1093 }
1094 }
1095 }
1096 }
1097 else
1098 {
1099 /* TODO: ??? */
1100 params->au_bitrate.target = params->au_bitrate.max = 0;
1101 au_params |= 0;
1102 }
1103 if( CHECK_PARAM( au_type ) || CHECK_PARAM( au_sample_rate )
1104 || CHECK_PARAM( au_bitrate.mode ) || CHECK_PARAM( au_bitrate.max )
1105 || CHECK_PARAM( au_bitrate.target )
1106 )
1107 {
1108 UPDATE_PARAM( au_type );
1109 UPDATE_PARAM( au_sample_rate );
1110 UPDATE_PARAM( au_bitrate );
1111 blackbird_api_cmd(dev, BLACKBIRD_API_SET_AUDIO_PARAMS, 1, 0, au_params );
1112 }
1113
1114 /* assign bitrates */
1115 if( params->vi_bitrate.mode )
1116 {
1117 /* bitrate is set, let's figure out the cbr/vbr mess */
1118 if( params->vi_bitrate.max < params->vi_bitrate.target )
1119 {
1120 if( params->vi_bitrate.mode == V4L2_BITRATE_CBR )
1121 params->vi_bitrate.max = params->vi_bitrate.target;
1122 else
1123 params->vi_bitrate.target = params->vi_bitrate.max;
1124 }
1125 }
1126 else
1127 {
1128 if( params->st_bitrate.max < params->st_bitrate.target )
1129 {
1130 if( params->st_bitrate.mode == V4L2_BITRATE_VBR )
1131 params->st_bitrate.target = params->st_bitrate.max;
1132 else
1133 params->st_bitrate.max = params->st_bitrate.target;
1134 }
1135 /* calculate vi_bitrate = st_bitrate - au_bitrate */
1136 params->vi_bitrate.max = params->st_bitrate.max - params->au_bitrate.max;
1137 params->vi_bitrate.target = params->st_bitrate.target - params->au_bitrate.target;
1138 }
1139 UPDATE_PARAM( st_bitrate );
1140 if( CHECK_PARAM( vi_bitrate.mode ) || CHECK_PARAM( vi_bitrate.max )
1141 || CHECK_PARAM( vi_bitrate.target )
1142 )
1143 {
1144 UPDATE_PARAM( vi_bitrate );
1145 blackbird_api_cmd(dev, BLACKBIRD_API_SET_VIDEO_BITRATE, 4, 0,
1146 mpeg_video_bitrates[params->vi_bitrate.mode],
1147 params->vi_bitrate.target * 1000, /* kbps -> bps */
1148 params->vi_bitrate.max * 1000 / BLACKBIRD_PEAK_RATE_DIVISOR, /* peak/400 */
1149 BLACKBIRD_MUX_RATE_DEFAULT /*, 0x70*/); /* encoding buffer, ckennedy */
1150 }
1151
1152 /* TODO: implement the stream ID stuff:
1153 ts_pid_pmt, ts_pid_audio, ts_pid_video, ts_pid_pcr,
1154 ps_size, au_pesid, vi_pesid
1155 */
1156 UPDATE_PARAM( ts_pid_pmt );
1157 UPDATE_PARAM( ts_pid_audio );
1158 UPDATE_PARAM( ts_pid_video );
1159 UPDATE_PARAM( ts_pid_pcr );
1160 UPDATE_PARAM( ps_size );
1161 UPDATE_PARAM( au_pesid );
1162 UPDATE_PARAM( vi_pesid );
1163}
1164
1165static void blackbird_set_default_dnr_params(struct cx8802_dev *dev)
1166{
1167 /* assign dnr filter mode */
1168 if( dev->dnr_params.mode > BLACKBIRD_DNR_BITS_AUTO )
1169 dev->dnr_params.mode = BLACKBIRD_DNR_BITS_MANUAL;
1170 if( dev->dnr_params.type > BLACKBIRD_MEDIAN_FILTER_DIAGONAL )
1171 dev->dnr_params.type = BLACKBIRD_MEDIAN_FILTER_DISABLED;
1172 blackbird_api_cmd(dev, BLACKBIRD_API_SET_DNR_MODE, 2, 0,
1173 dev->dnr_params.mode,
1174 dev->dnr_params.type
1175 );
1176
1177 /* assign dnr filter props*/
1178 if( dev->dnr_params.spatial > 15 )
1179 dev->dnr_params.spatial = 15;
1180 if( dev->dnr_params.temporal > 31 )
1181 dev->dnr_params.temporal = 31;
1182 blackbird_api_cmd(dev, BLACKBIRD_API_SET_MANUAL_DNR, 2, 0,
1183 dev->dnr_params.spatial,
1184 dev->dnr_params.temporal
1185 );
1186}
1187#define CHECK_DNR_PARAM( name ) ( dev->dnr_params.name != dnr_params->name )
1188#define UPDATE_DNR_PARAM( name ) dev->dnr_params.name = dnr_params->name
1189void blackbird_set_dnr_params(struct cx8802_dev *dev, struct blackbird_dnr* dnr_params)
1190{
1191 /* assign dnr filter mode */
1192 /* clamp values */
1193 if( dnr_params->mode > BLACKBIRD_DNR_BITS_AUTO )
1194 dnr_params->mode = BLACKBIRD_DNR_BITS_MANUAL;
1195 if( dnr_params->type > BLACKBIRD_MEDIAN_FILTER_DIAGONAL )
1196 dnr_params->type = BLACKBIRD_MEDIAN_FILTER_DISABLED;
1197 /* check if the params actually changed */
1198 if( CHECK_DNR_PARAM( mode ) || CHECK_DNR_PARAM( type ) )
1199 {
1200 UPDATE_DNR_PARAM( mode );
1201 UPDATE_DNR_PARAM( type );
1202 blackbird_api_cmd(dev, BLACKBIRD_API_SET_DNR_MODE, 2, 0, dnr_params->mode, dnr_params->type);
1203 }
1204
1205 /* assign dnr filter props*/
1206 if( dnr_params->spatial > 15 )
1207 dnr_params->spatial = 15;
1208 if( dnr_params->temporal > 31 )
1209 dnr_params->temporal = 31;
1210 if( CHECK_DNR_PARAM( spatial ) || CHECK_DNR_PARAM( temporal ) )
1211 {
1212 UPDATE_DNR_PARAM( spatial );
1213 UPDATE_DNR_PARAM( temporal );
1214 blackbird_api_cmd(dev, BLACKBIRD_API_SET_MANUAL_DNR, 2, 0, dnr_params->spatial, dnr_params->temporal);
1215 }
1216}
1217
1218static void blackbird_codec_settings(struct cx8802_dev *dev)
1219{
1220
1221 /* assign output port */
1222 blackbird_api_cmd(dev, BLACKBIRD_API_SET_OUTPUT_PORT, 1, 0, BLACKBIRD_OUTPUT_PORT_STREAMING); /* Host */
1223
1224 /* assign frame size */
1225 blackbird_api_cmd(dev, BLACKBIRD_API_SET_RESOLUTION, 2, 0,
1226 dev->height, dev->width);
1227
1228 /* assign coring levels (luma_h, luma_l, chroma_h, chroma_l) */
1229 blackbird_api_cmd(dev, BLACKBIRD_API_SET_DNR_MEDIAN, 4, 0, 0, 255, 0, 255);
1230
1231 /* assign spatial filter type: luma_t: horiz_only, chroma_t: horiz_only */
1232 blackbird_api_cmd(dev, BLACKBIRD_API_SET_SPATIAL_FILTER, 2, 0,
1233 BLACKBIRD_SPATIAL_FILTER_LUMA_1D_HORIZ,
1234 BLACKBIRD_SPATIAL_FILTER_CHROMA_1D_HORIZ
1235 );
1236
1237 /* assign frame drop rate */
1238 /* blackbird_api_cmd(dev, IVTV_API_ASSIGN_FRAME_DROP_RATE, 1, 0, 0); */
1239
1240 blackbird_set_default_params(dev);
1241 blackbird_set_default_dnr_params(dev);
1242}
1243
1244static int blackbird_initialize_codec(struct cx8802_dev *dev) 564static int blackbird_initialize_codec(struct cx8802_dev *dev)
1245{ 565{
1246 struct cx88_core *core = dev->core; 566 struct cx88_core *core = dev->core;
@@ -1248,7 +568,7 @@ static int blackbird_initialize_codec(struct cx8802_dev *dev)
1248 int retval; 568 int retval;
1249 569
1250 dprintk(1,"Initialize codec\n"); 570 dprintk(1,"Initialize codec\n");
1251 retval = blackbird_api_cmd(dev, BLACKBIRD_API_PING, 0, 0); /* ping */ 571 retval = blackbird_api_cmd(dev, CX2341X_ENC_PING_FW, 0, 0); /* ping */
1252 if (retval < 0) { 572 if (retval < 0) {
1253 /* ping was not successful, reset and upload firmware */ 573 /* ping was not successful, reset and upload firmware */
1254 cx_write(MO_SRST_IO, 0); /* SYS_RSTO=0 */ 574 cx_write(MO_SRST_IO, 0); /* SYS_RSTO=0 */
@@ -1263,13 +583,13 @@ static int blackbird_initialize_codec(struct cx8802_dev *dev)
1263 if (dev->mailbox < 0) 583 if (dev->mailbox < 0)
1264 return -1; 584 return -1;
1265 585
1266 retval = blackbird_api_cmd(dev, BLACKBIRD_API_PING, 0, 0); /* ping */ 586 retval = blackbird_api_cmd(dev, CX2341X_ENC_PING_FW, 0, 0); /* ping */
1267 if (retval < 0) { 587 if (retval < 0) {
1268 dprintk(0, "ERROR: Firmware ping failed!\n"); 588 dprintk(0, "ERROR: Firmware ping failed!\n");
1269 return -1; 589 return -1;
1270 } 590 }
1271 591
1272 retval = blackbird_api_cmd(dev, BLACKBIRD_API_GET_VERSION, 0, 1, &version); 592 retval = blackbird_api_cmd(dev, CX2341X_ENC_GET_VERSION, 0, 1, &version);
1273 if (retval < 0) { 593 if (retval < 0) {
1274 dprintk(0, "ERROR: Firmware get encoder version failed!\n"); 594 dprintk(0, "ERROR: Firmware get encoder version failed!\n");
1275 return -1; 595 return -1;
@@ -1289,35 +609,35 @@ static int blackbird_initialize_codec(struct cx8802_dev *dev)
1289 /* blackbird_api_cmd(dev, IVTV_API_ASSIGN_NUM_VSYNC_LINES, 4, 0, 0xef, 0xef); 609 /* blackbird_api_cmd(dev, IVTV_API_ASSIGN_NUM_VSYNC_LINES, 4, 0, 0xef, 0xef);
1290 blackbird_api_cmd(dev, IVTV_API_ASSIGN_NUM_VSYNC_LINES, 4, 0, 0xf0, 0xf0); 610 blackbird_api_cmd(dev, IVTV_API_ASSIGN_NUM_VSYNC_LINES, 4, 0, 0xf0, 0xf0);
1291 blackbird_api_cmd(dev, IVTV_API_ASSIGN_NUM_VSYNC_LINES, 4, 0, 0x180, 0x180); */ 611 blackbird_api_cmd(dev, IVTV_API_ASSIGN_NUM_VSYNC_LINES, 4, 0, 0x180, 0x180); */
1292 blackbird_api_cmd(dev, BLACKBIRD_API_SET_CAPTURE_LINES, 2, 0, 612 blackbird_api_cmd(dev, CX2341X_ENC_SET_NUM_VSYNC_LINES, 2, 0,
1293 BLACKBIRD_FIELD1_SAA7115, 613 BLACKBIRD_FIELD1_SAA7115,
1294 BLACKBIRD_FIELD1_SAA7115 614 BLACKBIRD_FIELD2_SAA7115
1295 ); 615 );
1296 616
1297 /* blackbird_api_cmd(dev, IVTV_API_ASSIGN_PLACEHOLDER, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); */ 617 /* blackbird_api_cmd(dev, IVTV_API_ASSIGN_PLACEHOLDER, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); */
1298 blackbird_api_cmd(dev, BLACKBIRD_API_SET_CUSTOM_DATA, 12, 0, 618 blackbird_api_cmd(dev, CX2341X_ENC_SET_PLACEHOLDER, 12, 0,
1299 BLACKBIRD_CUSTOM_EXTENSION_USR_DATA, 619 BLACKBIRD_CUSTOM_EXTENSION_USR_DATA,
1300 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); 620 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
1301 621
1302 /* initialize the video input */ 622 /* initialize the video input */
1303 blackbird_api_cmd(dev, BLACKBIRD_API_INIT_VIDEO_INPUT, 0, 0); 623 blackbird_api_cmd(dev, CX2341X_ENC_INITIALIZE_INPUT, 0, 0);
1304 624
1305 msleep(1); 625 msleep(1);
1306 626
1307 blackbird_api_cmd(dev, BLACKBIRD_API_MUTE_VIDEO, 1, 0, BLACKBIRD_UNMUTE); 627 blackbird_api_cmd(dev, CX2341X_ENC_MUTE_VIDEO, 1, 0, BLACKBIRD_UNMUTE);
1308 msleep(1); 628 msleep(1);
1309 blackbird_api_cmd(dev, BLACKBIRD_API_MUTE_AUDIO, 1, 0, BLACKBIRD_UNMUTE); 629 blackbird_api_cmd(dev, CX2341X_ENC_MUTE_AUDIO, 1, 0, BLACKBIRD_UNMUTE);
1310 msleep(1); 630 msleep(1);
1311 631
1312 /* start capturing to the host interface */ 632 /* start capturing to the host interface */
1313 /* blackbird_api_cmd(dev, BLACKBIRD_API_BEGIN_CAPTURE, 2, 0, 0, 0x13); */ 633 /* blackbird_api_cmd(dev, CX2341X_ENC_START_CAPTURE, 2, 0, 0, 0x13); */
1314 blackbird_api_cmd(dev, BLACKBIRD_API_BEGIN_CAPTURE, 2, 0, 634 blackbird_api_cmd(dev, CX2341X_ENC_START_CAPTURE, 2, 0,
1315 BLACKBIRD_MPEG_CAPTURE, 635 BLACKBIRD_MPEG_CAPTURE,
1316 BLACKBIRD_RAW_BITS_NONE 636 BLACKBIRD_RAW_BITS_NONE
1317 ); 637 );
1318 msleep(10); 638 msleep(10);
1319 639
1320 blackbird_api_cmd(dev, BLACKBIRD_API_REFRESH_INPUT, 0,0); 640 blackbird_api_cmd(dev, CX2341X_ENC_REFRESH_INPUT, 0,0);
1321 return 0; 641 return 0;
1322} 642}
1323 643
@@ -1485,14 +805,52 @@ static int mpeg_do_ioctl(struct inode *inode, struct file *file,
1485 { 805 {
1486 struct v4l2_mpeg_compression *f = arg; 806 struct v4l2_mpeg_compression *f = arg;
1487 807
1488 memcpy(f,&dev->params,sizeof(*f)); 808 printk(KERN_WARNING "VIDIOC_G_MPEGCOMP is obsolete. "
809 "Replace with VIDIOC_G_EXT_CTRLS!");
810 memcpy(f,&default_mpeg_params,sizeof(*f));
1489 return 0; 811 return 0;
1490 } 812 }
1491 case VIDIOC_S_MPEGCOMP: 813 case VIDIOC_S_MPEGCOMP:
814 printk(KERN_WARNING "VIDIOC_S_MPEGCOMP is obsolete. "
815 "Replace with VIDIOC_S_EXT_CTRLS!");
816 return 0;
817 case VIDIOC_G_EXT_CTRLS:
1492 { 818 {
1493 struct v4l2_mpeg_compression *f = arg; 819 struct v4l2_ext_controls *f = arg;
1494 820
1495 blackbird_set_params(dev, f); 821 if (f->ctrl_class != V4L2_CTRL_CLASS_MPEG)
822 return -EINVAL;
823 return cx2341x_ext_ctrls(&dev->params, f, cmd);
824 }
825 case VIDIOC_S_EXT_CTRLS:
826 case VIDIOC_TRY_EXT_CTRLS:
827 {
828 struct v4l2_ext_controls *f = arg;
829 struct cx2341x_mpeg_params p;
830 int err;
831
832 if (f->ctrl_class != V4L2_CTRL_CLASS_MPEG)
833 return -EINVAL;
834 p = dev->params;
835 err = cx2341x_ext_ctrls(&p, f, cmd);
836 if (err == 0 && cmd == VIDIOC_S_EXT_CTRLS) {
837 err = cx2341x_update(dev, blackbird_mbox_func, &dev->params, &p);
838 dev->params = p;
839 }
840 return err;
841 }
842 case VIDIOC_S_FREQUENCY:
843 {
844 blackbird_api_cmd(fh->dev, CX2341X_ENC_STOP_CAPTURE, 3, 0,
845 BLACKBIRD_END_NOW,
846 BLACKBIRD_MPEG_CAPTURE,
847 BLACKBIRD_RAW_BITS_NONE);
848
849 cx88_do_ioctl( inode, file, 0, dev->core, cmd, arg, cx88_ioctl_hook );
850
851 blackbird_initialize_codec(dev);
852 cx88_set_scale(dev->core, dev->width, dev->height,
853 fh->mpegq.field);
1496 return 0; 854 return 0;
1497 } 855 }
1498 856
@@ -1562,13 +920,14 @@ static int mpeg_release(struct inode *inode, struct file *file)
1562{ 920{
1563 struct cx8802_fh *fh = file->private_data; 921 struct cx8802_fh *fh = file->private_data;
1564 922
1565 /* blackbird_api_cmd(fh->dev, BLACKBIRD_API_END_CAPTURE, 3, 0, BLACKBIRD_END_NOW, 0, 0x13); */ 923 /* blackbird_api_cmd(fh->dev, CX2341X_ENC_STOP_CAPTURE, 3, 0, BLACKBIRD_END_NOW, 0, 0x13); */
1566 blackbird_api_cmd(fh->dev, BLACKBIRD_API_END_CAPTURE, 3, 0, 924 blackbird_api_cmd(fh->dev, CX2341X_ENC_STOP_CAPTURE, 3, 0,
1567 BLACKBIRD_END_NOW, 925 BLACKBIRD_END_NOW,
1568 BLACKBIRD_MPEG_CAPTURE, 926 BLACKBIRD_MPEG_CAPTURE,
1569 BLACKBIRD_RAW_BITS_NONE 927 BLACKBIRD_RAW_BITS_NONE
1570 ); 928 );
1571 929
930 cx8802_cancel_buffers(fh->dev);
1572 /* stop mpeg capture */ 931 /* stop mpeg capture */
1573 if (fh->mpegq.streaming) 932 if (fh->mpegq.streaming)
1574 videobuf_streamoff(&fh->mpegq); 933 videobuf_streamoff(&fh->mpegq);
@@ -1683,19 +1042,13 @@ static int __devinit blackbird_probe(struct pci_dev *pci_dev,
1683 dev->core = core; 1042 dev->core = core;
1684 dev->width = 720; 1043 dev->width = 720;
1685 dev->height = 576; 1044 dev->height = 576;
1686 memcpy(&dev->params,&default_mpeg_params,sizeof(default_mpeg_params)); 1045 cx2341x_fill_defaults(&dev->params);
1687 memcpy(&dev->dnr_params,&default_dnr_params,sizeof(default_dnr_params)); 1046 dev->params.port = CX2341X_PORT_STREAMING;
1688
1689 if (core->board == CX88_BOARD_HAUPPAUGE_ROSLYN) {
1690
1691 if (core->tuner_formats & V4L2_STD_525_60) {
1692 dev->height = 480;
1693 dev->params.vi_frame_rate = 30;
1694 } else {
1695 dev->height = 576;
1696 dev->params.vi_frame_rate = 25;
1697 }
1698 1047
1048 if (core->tvnorm->id & V4L2_STD_525_60) {
1049 dev->height = 480;
1050 } else {
1051 dev->height = 576;
1699 } 1052 }
1700 1053
1701 err = cx8802_init_common(dev); 1054 err = cx8802_init_common(dev);
@@ -1781,8 +1134,6 @@ module_exit(blackbird_fini);
1781 1134
1782EXPORT_SYMBOL(cx88_ioctl_hook); 1135EXPORT_SYMBOL(cx88_ioctl_hook);
1783EXPORT_SYMBOL(cx88_ioctl_translator); 1136EXPORT_SYMBOL(cx88_ioctl_translator);
1784EXPORT_SYMBOL(blackbird_set_params);
1785EXPORT_SYMBOL(blackbird_set_dnr_params);
1786 1137
1787/* ----------------------------------------------------------- */ 1138/* ----------------------------------------------------------- */
1788/* 1139/*
diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c
index f80154b87d2..67cdd827086 100644
--- a/drivers/media/video/cx88/cx88-cards.c
+++ b/drivers/media/video/cx88/cx88-cards.c
@@ -114,7 +114,7 @@ struct cx88_board cx88_boards[] = {
114 .radio = { 114 .radio = {
115 .type = CX88_RADIO, 115 .type = CX88_RADIO,
116 .gpio0 = 0xff10, 116 .gpio0 = 0xff10,
117 }, 117 },
118 }, 118 },
119 [CX88_BOARD_ATI_WONDER_PRO] = { 119 [CX88_BOARD_ATI_WONDER_PRO] = {
120 .name = "ATI TV Wonder Pro", 120 .name = "ATI TV Wonder Pro",
@@ -267,7 +267,7 @@ struct cx88_board cx88_boards[] = {
267 .gpio1 = 0x00007004, 267 .gpio1 = 0x00007004,
268 .gpio2 = 0x0035d700, 268 .gpio2 = 0x0035d700,
269 .gpio3 = 0x02000000, 269 .gpio3 = 0x02000000,
270 }, 270 },
271 }, 271 },
272 [CX88_BOARD_LEADTEK_PVR2000] = { 272 [CX88_BOARD_LEADTEK_PVR2000] = {
273 // gpio values for PAL version from regspy by DScaler 273 // gpio values for PAL version from regspy by DScaler
@@ -413,7 +413,7 @@ struct cx88_board cx88_boards[] = {
413 .type = CX88_VMUX_COMPOSITE1, 413 .type = CX88_VMUX_COMPOSITE1,
414 .vmux = 1, 414 .vmux = 1,
415 .gpio0 = 0x000027df, 415 .gpio0 = 0x000027df,
416 },{ 416 },{
417 .type = CX88_VMUX_SVIDEO, 417 .type = CX88_VMUX_SVIDEO,
418 .vmux = 2, 418 .vmux = 2,
419 .gpio0 = 0x000027df, 419 .gpio0 = 0x000027df,
@@ -536,7 +536,7 @@ struct cx88_board cx88_boards[] = {
536 .type = CX88_VMUX_COMPOSITE1, 536 .type = CX88_VMUX_COMPOSITE1,
537 .vmux = 1, 537 .vmux = 1,
538 .gpio0 = 0x000027df, 538 .gpio0 = 0x000027df,
539 },{ 539 },{
540 .type = CX88_VMUX_SVIDEO, 540 .type = CX88_VMUX_SVIDEO,
541 .vmux = 2, 541 .vmux = 2,
542 .gpio0 = 0x000027df, 542 .gpio0 = 0x000027df,
@@ -759,7 +759,7 @@ struct cx88_board cx88_boards[] = {
759 }, 759 },
760 [CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD] = { 760 [CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD] = {
761 .name = "DViCO FusionHDTV 5 Gold", 761 .name = "DViCO FusionHDTV 5 Gold",
762 .tuner_type = TUNER_LG_TDVS_H062F, 762 .tuner_type = TUNER_LG_TDVS_H06XF, /* TDVS-H062F */
763 .radio_type = UNSET, 763 .radio_type = UNSET,
764 .tuner_addr = ADDR_UNSET, 764 .tuner_addr = ADDR_UNSET,
765 .radio_addr = ADDR_UNSET, 765 .radio_addr = ADDR_UNSET,
@@ -1050,11 +1050,7 @@ struct cx88_board cx88_boards[] = {
1050 .dvb = 1, 1050 .dvb = 1,
1051 }, 1051 },
1052 [CX88_BOARD_KWORLD_HARDWARE_MPEG_TV_XPERT] = { 1052 [CX88_BOARD_KWORLD_HARDWARE_MPEG_TV_XPERT] = {
1053 /* FIXME: Standard video using the cx88 broadcast decoder is 1053 /* FIXME: Audio not working for s-video / composite inputs. */
1054 * working, but blackbird isn't working yet, audio is only
1055 * working correctly for television mode. S-Video and Composite
1056 * are working for video-only, so I have them disabled for now.
1057 */
1058 .name = "KWorld HardwareMpegTV XPert", 1054 .name = "KWorld HardwareMpegTV XPert",
1059 .tuner_type = TUNER_PHILIPS_TDA8290, 1055 .tuner_type = TUNER_PHILIPS_TDA8290,
1060 .radio_type = UNSET, 1056 .radio_type = UNSET,
@@ -1065,12 +1061,21 @@ struct cx88_board cx88_boards[] = {
1065 .vmux = 0, 1061 .vmux = 0,
1066 .gpio0 = 0x3de2, 1062 .gpio0 = 0x3de2,
1067 .gpio2 = 0x00ff, 1063 .gpio2 = 0x00ff,
1064 },{
1065 .type = CX88_VMUX_COMPOSITE1,
1066 .vmux = 1,
1067 .gpio0 = 0x3de6,
1068 },{
1069 .type = CX88_VMUX_SVIDEO,
1070 .vmux = 2,
1071 .gpio0 = 0x3de6,
1068 }}, 1072 }},
1069 .radio = { 1073 .radio = {
1070 .type = CX88_RADIO, 1074 .type = CX88_RADIO,
1071 .gpio0 = 0x3de6, 1075 .gpio0 = 0x3de6,
1072 .gpio2 = 0x00ff, 1076 .gpio2 = 0x00ff,
1073 }, 1077 },
1078 .blackbird = 1,
1074 }, 1079 },
1075 [CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID] = { 1080 [CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID] = {
1076 .name = "DViCO FusionHDTV DVB-T Hybrid", 1081 .name = "DViCO FusionHDTV DVB-T Hybrid",
@@ -1093,7 +1098,102 @@ struct cx88_board cx88_boards[] = {
1093 }}, 1098 }},
1094 .dvb = 1, 1099 .dvb = 1,
1095 }, 1100 },
1096 1101 [CX88_BOARD_PCHDTV_HD5500] = {
1102 .name = "pcHDTV HD5500 HDTV",
1103 .tuner_type = TUNER_LG_TDVS_H06XF, /* TDVS-H064F */
1104 .radio_type = UNSET,
1105 .tuner_addr = ADDR_UNSET,
1106 .radio_addr = ADDR_UNSET,
1107 .tda9887_conf = TDA9887_PRESENT,
1108 .input = {{
1109 .type = CX88_VMUX_TELEVISION,
1110 .vmux = 0,
1111 .gpio0 = 0x87fd,
1112 },{
1113 .type = CX88_VMUX_COMPOSITE1,
1114 .vmux = 1,
1115 .gpio0 = 0x87f9,
1116 },{
1117 .type = CX88_VMUX_SVIDEO,
1118 .vmux = 2,
1119 .gpio0 = 0x87f9,
1120 }},
1121 .dvb = 1,
1122 },
1123 [CX88_BOARD_KWORLD_MCE200_DELUXE] = {
1124 /* FIXME: tested TV input only, disabled composite,
1125 svideo and radio until they can be tested also. */
1126 .name = "Kworld MCE 200 Deluxe",
1127 .tuner_type = TUNER_TENA_9533_DI,
1128 .radio_type = UNSET,
1129 .tda9887_conf = TDA9887_PRESENT,
1130 .tuner_addr = ADDR_UNSET,
1131 .radio_addr = ADDR_UNSET,
1132 .input = {{
1133 .type = CX88_VMUX_TELEVISION,
1134 .vmux = 0,
1135 .gpio0 = 0x0000BDE6
1136 }},
1137 .blackbird = 1,
1138 },
1139 [CX88_BOARD_PIXELVIEW_PLAYTV_P7000] = {
1140 /* FIXME: SVideo, Composite and FM inputs are untested */
1141 .name = "PixelView PlayTV P7000",
1142 .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
1143 .radio_type = UNSET,
1144 .tuner_addr = ADDR_UNSET,
1145 .radio_addr = ADDR_UNSET,
1146 .tda9887_conf = TDA9887_PRESENT | TDA9887_PORT1_ACTIVE |
1147 TDA9887_PORT2_ACTIVE,
1148 .input = {{
1149 .type = CX88_VMUX_TELEVISION,
1150 .vmux = 0,
1151 .gpio0 = 0x5da6,
1152 }},
1153 .blackbird = 1,
1154 },
1155 [CX88_BOARD_NPGTECH_REALTV_TOP10FM] = {
1156 .name = "NPG Tech Real TV FM Top 10",
1157 .tuner_type = TUNER_TNF_5335MF, /* Actually a TNF9535 */
1158 .radio_type = UNSET,
1159 .tuner_addr = ADDR_UNSET,
1160 .radio_addr = ADDR_UNSET,
1161 .input = {{
1162 .type = CX88_VMUX_TELEVISION,
1163 .vmux = 0,
1164 .gpio0 = 0x0788,
1165 },{
1166 .type = CX88_VMUX_COMPOSITE1,
1167 .vmux = 1,
1168 .gpio0 = 0x078b,
1169 },{
1170 .type = CX88_VMUX_SVIDEO,
1171 .vmux = 2,
1172 .gpio0 = 0x078b,
1173 }},
1174 .radio = {
1175 .type = CX88_RADIO,
1176 .gpio0 = 0x074a,
1177 },
1178 },
1179 [CX88_BOARD_WINFAST_DTV2000H] = {
1180 /* video inputs and radio still in testing */
1181 .name = "WinFast DTV2000 H",
1182 .tuner_type = TUNER_PHILIPS_FMD1216ME_MK3,
1183 .radio_type = UNSET,
1184 .tuner_addr = ADDR_UNSET,
1185 .radio_addr = ADDR_UNSET,
1186 .tda9887_conf = TDA9887_PRESENT,
1187 .input = {{
1188 .type = CX88_VMUX_TELEVISION,
1189 .vmux = 0,
1190 .gpio0 = 0x00017304,
1191 .gpio1 = 0x00008203,
1192 .gpio2 = 0x00017304,
1193 .gpio3 = 0x02000000,
1194 }},
1195 .dvb = 1,
1196 },
1097}; 1197};
1098const unsigned int cx88_bcount = ARRAY_SIZE(cx88_boards); 1198const unsigned int cx88_bcount = ARRAY_SIZE(cx88_boards);
1099 1199
@@ -1311,6 +1411,34 @@ struct cx88_subid cx88_subids[] = {
1311 .subvendor = 0x18ac, 1411 .subvendor = 0x18ac,
1312 .subdevice = 0xdb44, 1412 .subdevice = 0xdb44,
1313 .card = CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID, 1413 .card = CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID,
1414 },{
1415 .subvendor = 0x7063,
1416 .subdevice = 0x5500,
1417 .card = CX88_BOARD_PCHDTV_HD5500,
1418 },{
1419 .subvendor = 0x17de,
1420 .subdevice = 0x0841,
1421 .card = CX88_BOARD_KWORLD_MCE200_DELUXE,
1422 },{
1423 .subvendor = 0x1822,
1424 .subdevice = 0x0019,
1425 .card = CX88_BOARD_DNTV_LIVE_DVB_T_PRO,
1426 },{
1427 .subvendor = 0x1554,
1428 .subdevice = 0x4813,
1429 .card = CX88_BOARD_PIXELVIEW_PLAYTV_P7000,
1430 },{
1431 .subvendor = 0x14f1,
1432 .subdevice = 0x0842,
1433 .card = CX88_BOARD_NPGTECH_REALTV_TOP10FM,
1434 },{
1435 .subvendor = 0x107d,
1436 .subdevice = 0x665e,
1437 .card = CX88_BOARD_WINFAST_DTV2000H,
1438 },{
1439 .subvendor = 0x18ac,
1440 .subdevice = 0xd800, /* FusionHDTV 3 Gold (original revision) */
1441 .card = CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_Q,
1314 }, 1442 },
1315}; 1443};
1316const unsigned int cx88_idcount = ARRAY_SIZE(cx88_subids); 1444const unsigned int cx88_idcount = ARRAY_SIZE(cx88_subids);
diff --git a/drivers/media/video/cx88/cx88-core.c b/drivers/media/video/cx88/cx88-core.c
index e1092d5d462..c56292d8d93 100644
--- a/drivers/media/video/cx88/cx88-core.c
+++ b/drivers/media/video/cx88/cx88-core.c
@@ -677,7 +677,7 @@ static unsigned int inline norm_htotal(struct cx88_tvnorm *norm)
677 677
678static unsigned int inline norm_vbipack(struct cx88_tvnorm *norm) 678static unsigned int inline norm_vbipack(struct cx88_tvnorm *norm)
679{ 679{
680 return (norm->id & V4L2_STD_625_50) ? 511 : 288; 680 return (norm->id & V4L2_STD_625_50) ? 511 : 400;
681} 681}
682 682
683int cx88_set_scale(struct cx88_core *core, unsigned int width, unsigned int height, 683int cx88_set_scale(struct cx88_core *core, unsigned int width, unsigned int height,
@@ -932,9 +932,9 @@ int cx88_set_tvnorm(struct cx88_core *core, struct cx88_tvnorm *norm)
932 htotal, cx_read(MO_HTOTAL), (u32)tmp64); 932 htotal, cx_read(MO_HTOTAL), (u32)tmp64);
933 cx_write(MO_HTOTAL, htotal); 933 cx_write(MO_HTOTAL, htotal);
934 934
935 // vbi stuff 935 // vbi stuff, set vbi offset to 10 (for 20 Clk*2 pixels), this makes
936 cx_write(MO_VBI_PACKET, ((1 << 11) | /* (norm_vdelay(norm) << 11) | */ 936 // the effective vbi offset ~244 samples, the same as the Bt8x8
937 norm_vbipack(norm))); 937 cx_write(MO_VBI_PACKET, (10<<11) | norm_vbipack(norm));
938 938
939 // this is needed as well to set all tvnorm parameter 939 // this is needed as well to set all tvnorm parameter
940 cx88_set_scale(core, 320, 240, V4L2_FIELD_INTERLACED); 940 cx88_set_scale(core, 320, 240, V4L2_FIELD_INTERLACED);
diff --git a/drivers/media/video/cx88/cx88-dvb.c b/drivers/media/video/cx88/cx88-dvb.c
index 3619a449aef..dce1feddd55 100644
--- a/drivers/media/video/cx88/cx88-dvb.c
+++ b/drivers/media/video/cx88/cx88-dvb.c
@@ -51,6 +51,7 @@
51#endif 51#endif
52#ifdef HAVE_LGDT330X 52#ifdef HAVE_LGDT330X
53# include "lgdt330x.h" 53# include "lgdt330x.h"
54# include "lg_h06xf.h"
54#endif 55#endif
55#ifdef HAVE_NXT200X 56#ifdef HAVE_NXT200X
56# include "nxt200x.h" 57# include "nxt200x.h"
@@ -58,6 +59,7 @@
58#ifdef HAVE_CX24123 59#ifdef HAVE_CX24123
59# include "cx24123.h" 60# include "cx24123.h"
60#endif 61#endif
62#include "isl6421.h"
61 63
62MODULE_DESCRIPTION("driver for cx2388x based DVB cards"); 64MODULE_DESCRIPTION("driver for cx2388x based DVB cards");
63MODULE_AUTHOR("Chris Pascoe <c.pascoe@itee.uq.edu.au>"); 65MODULE_AUTHOR("Chris Pascoe <c.pascoe@itee.uq.edu.au>");
@@ -113,21 +115,6 @@ static struct videobuf_queue_ops dvb_qops = {
113 115
114/* ------------------------------------------------------------------ */ 116/* ------------------------------------------------------------------ */
115 117
116#if defined(HAVE_MT352) || defined(HAVE_ZL10353)
117static int zarlink_pll_set(struct dvb_frontend *fe,
118 struct dvb_frontend_parameters *params,
119 u8 *pllbuf)
120{
121 struct cx8802_dev *dev = fe->dvb->priv;
122
123 pllbuf[0] = dev->core->pll_addr << 1;
124 dvb_pll_configure(dev->core->pll_desc, pllbuf + 1,
125 params->frequency,
126 params->u.ofdm.bandwidth);
127 return 0;
128}
129#endif
130
131#ifdef HAVE_MT352 118#ifdef HAVE_MT352
132static int dvico_fusionhdtv_demod_init(struct dvb_frontend* fe) 119static int dvico_fusionhdtv_demod_init(struct dvb_frontend* fe)
133{ 120{
@@ -196,19 +183,16 @@ static int dntv_live_dvbt_demod_init(struct dvb_frontend* fe)
196static struct mt352_config dvico_fusionhdtv = { 183static struct mt352_config dvico_fusionhdtv = {
197 .demod_address = 0x0F, 184 .demod_address = 0x0F,
198 .demod_init = dvico_fusionhdtv_demod_init, 185 .demod_init = dvico_fusionhdtv_demod_init,
199 .pll_set = zarlink_pll_set,
200}; 186};
201 187
202static struct mt352_config dntv_live_dvbt_config = { 188static struct mt352_config dntv_live_dvbt_config = {
203 .demod_address = 0x0f, 189 .demod_address = 0x0f,
204 .demod_init = dntv_live_dvbt_demod_init, 190 .demod_init = dntv_live_dvbt_demod_init,
205 .pll_set = zarlink_pll_set,
206}; 191};
207 192
208static struct mt352_config dvico_fusionhdtv_dual = { 193static struct mt352_config dvico_fusionhdtv_dual = {
209 .demod_address = 0x0F, 194 .demod_address = 0x0F,
210 .demod_init = dvico_dual_demod_init, 195 .demod_init = dvico_dual_demod_init,
211 .pll_set = zarlink_pll_set,
212}; 196};
213 197
214#ifdef HAVE_VP3054_I2C 198#ifdef HAVE_VP3054_I2C
@@ -246,6 +230,8 @@ static int philips_fmd1216_pll_init(struct dvb_frontend *fe)
246 .buf = fmd1216_init, .len = sizeof(fmd1216_init) }; 230 .buf = fmd1216_init, .len = sizeof(fmd1216_init) };
247 int err; 231 int err;
248 232
233 if (fe->ops.i2c_gate_ctrl)
234 fe->ops.i2c_gate_ctrl(fe, 1);
249 if ((err = i2c_transfer(&dev->core->i2c_adap, &msg, 1)) != 1) { 235 if ((err = i2c_transfer(&dev->core->i2c_adap, &msg, 1)) != 1) {
250 if (err < 0) 236 if (err < 0)
251 return err; 237 return err;
@@ -256,14 +242,14 @@ static int philips_fmd1216_pll_init(struct dvb_frontend *fe)
256 return 0; 242 return 0;
257} 243}
258 244
259static int dntv_live_dvbt_pro_pll_set(struct dvb_frontend* fe, 245static int dntv_live_dvbt_pro_tuner_set_params(struct dvb_frontend* fe,
260 struct dvb_frontend_parameters* params, 246 struct dvb_frontend_parameters* params)
261 u8* pllbuf)
262{ 247{
263 struct cx8802_dev *dev= fe->dvb->priv; 248 struct cx8802_dev *dev= fe->dvb->priv;
249 u8 buf[4];
264 struct i2c_msg msg = 250 struct i2c_msg msg =
265 { .addr = dev->core->pll_addr, .flags = 0, 251 { .addr = dev->core->pll_addr, .flags = 0,
266 .buf = pllbuf+1, .len = 4 }; 252 .buf = buf, .len = 4 };
267 int err; 253 int err;
268 254
269 /* Switch PLL to DVB mode */ 255 /* Switch PLL to DVB mode */
@@ -272,14 +258,16 @@ static int dntv_live_dvbt_pro_pll_set(struct dvb_frontend* fe,
272 return err; 258 return err;
273 259
274 /* Tune PLL */ 260 /* Tune PLL */
275 pllbuf[0] = dev->core->pll_addr << 1; 261 dvb_pll_configure(dev->core->pll_desc, buf,
276 dvb_pll_configure(dev->core->pll_desc, pllbuf+1,
277 params->frequency, 262 params->frequency,
278 params->u.ofdm.bandwidth); 263 params->u.ofdm.bandwidth);
264 if (fe->ops.i2c_gate_ctrl)
265 fe->ops.i2c_gate_ctrl(fe, 1);
279 if ((err = i2c_transfer(&dev->core->i2c_adap, &msg, 1)) != 1) { 266 if ((err = i2c_transfer(&dev->core->i2c_adap, &msg, 1)) != 1) {
267
280 printk(KERN_WARNING "cx88-dvb: %s error " 268 printk(KERN_WARNING "cx88-dvb: %s error "
281 "(addr %02x <- %02x, err = %i)\n", 269 "(addr %02x <- %02x, err = %i)\n",
282 __FUNCTION__, pllbuf[0], pllbuf[1], err); 270 __FUNCTION__, dev->core->pll_addr, buf[0], err);
283 if (err < 0) 271 if (err < 0)
284 return err; 272 return err;
285 else 273 else
@@ -293,27 +281,27 @@ static struct mt352_config dntv_live_dvbt_pro_config = {
293 .demod_address = 0x0f, 281 .demod_address = 0x0f,
294 .no_tuner = 1, 282 .no_tuner = 1,
295 .demod_init = dntv_live_dvbt_pro_demod_init, 283 .demod_init = dntv_live_dvbt_pro_demod_init,
296 .pll_set = dntv_live_dvbt_pro_pll_set,
297}; 284};
298#endif 285#endif
299#endif 286#endif
300 287
301#ifdef HAVE_ZL10353 288#ifdef HAVE_ZL10353
302static int dvico_hybrid_tune_pll(struct dvb_frontend *fe, 289static int dvico_hybrid_tuner_set_params(struct dvb_frontend *fe,
303 struct dvb_frontend_parameters *params, 290 struct dvb_frontend_parameters *params)
304 u8 *pllbuf)
305{ 291{
292 u8 pllbuf[4];
306 struct cx8802_dev *dev= fe->dvb->priv; 293 struct cx8802_dev *dev= fe->dvb->priv;
307 struct i2c_msg msg = 294 struct i2c_msg msg =
308 { .addr = dev->core->pll_addr, .flags = 0, 295 { .addr = dev->core->pll_addr, .flags = 0,
309 .buf = pllbuf + 1, .len = 4 }; 296 .buf = pllbuf, .len = 4 };
310 int err; 297 int err;
311 298
312 pllbuf[0] = dev->core->pll_addr << 1; 299 dvb_pll_configure(dev->core->pll_desc, pllbuf,
313 dvb_pll_configure(dev->core->pll_desc, pllbuf + 1,
314 params->frequency, 300 params->frequency,
315 params->u.ofdm.bandwidth); 301 params->u.ofdm.bandwidth);
316 302
303 if (fe->ops.i2c_gate_ctrl)
304 fe->ops.i2c_gate_ctrl(fe, 1);
317 if ((err = i2c_transfer(&dev->core->i2c_adap, &msg, 1)) != 1) { 305 if ((err = i2c_transfer(&dev->core->i2c_adap, &msg, 1)) != 1) {
318 printk(KERN_WARNING "cx88-dvb: %s error " 306 printk(KERN_WARNING "cx88-dvb: %s error "
319 "(addr %02x <- %02x, err = %i)\n", 307 "(addr %02x <- %02x, err = %i)\n",
@@ -329,12 +317,11 @@ static int dvico_hybrid_tune_pll(struct dvb_frontend *fe,
329 317
330static struct zl10353_config dvico_fusionhdtv_hybrid = { 318static struct zl10353_config dvico_fusionhdtv_hybrid = {
331 .demod_address = 0x0F, 319 .demod_address = 0x0F,
332 .pll_set = dvico_hybrid_tune_pll, 320 .no_tuner = 1,
333}; 321};
334 322
335static struct zl10353_config dvico_fusionhdtv_plus_v1_1 = { 323static struct zl10353_config dvico_fusionhdtv_plus_v1_1 = {
336 .demod_address = 0x0F, 324 .demod_address = 0x0F,
337 .pll_set = zarlink_pll_set,
338}; 325};
339#endif 326#endif
340 327
@@ -342,21 +329,15 @@ static struct zl10353_config dvico_fusionhdtv_plus_v1_1 = {
342static struct cx22702_config connexant_refboard_config = { 329static struct cx22702_config connexant_refboard_config = {
343 .demod_address = 0x43, 330 .demod_address = 0x43,
344 .output_mode = CX22702_SERIAL_OUTPUT, 331 .output_mode = CX22702_SERIAL_OUTPUT,
345 .pll_address = 0x60,
346 .pll_desc = &dvb_pll_thomson_dtt7579,
347}; 332};
348 333
349static struct cx22702_config hauppauge_novat_config = { 334static struct cx22702_config hauppauge_novat_config = {
350 .demod_address = 0x43, 335 .demod_address = 0x43,
351 .output_mode = CX22702_SERIAL_OUTPUT, 336 .output_mode = CX22702_SERIAL_OUTPUT,
352 .pll_address = 0x61,
353 .pll_desc = &dvb_pll_thomson_dtt759x,
354}; 337};
355static struct cx22702_config hauppauge_hvr1100_config = { 338static struct cx22702_config hauppauge_hvr1100_config = {
356 .demod_address = 0x63, 339 .demod_address = 0x63,
357 .output_mode = CX22702_SERIAL_OUTPUT, 340 .output_mode = CX22702_SERIAL_OUTPUT,
358 .pll_address = 0x61,
359 .pll_desc = &dvb_pll_fmd1216me,
360}; 341};
361#endif 342#endif
362 343
@@ -371,15 +352,13 @@ static int or51132_set_ts_param(struct dvb_frontend* fe,
371 352
372static struct or51132_config pchdtv_hd3000 = { 353static struct or51132_config pchdtv_hd3000 = {
373 .demod_address = 0x15, 354 .demod_address = 0x15,
374 .pll_address = 0x61,
375 .pll_desc = &dvb_pll_thomson_dtt761x,
376 .set_ts_params = or51132_set_ts_param, 355 .set_ts_params = or51132_set_ts_param,
377}; 356};
378#endif 357#endif
379 358
380#ifdef HAVE_LGDT330X 359#ifdef HAVE_LGDT330X
381static int lgdt330x_pll_set(struct dvb_frontend* fe, 360static int lgdt3302_tuner_set_params(struct dvb_frontend* fe,
382 struct dvb_frontend_parameters* params) 361 struct dvb_frontend_parameters* params)
383{ 362{
384 /* FIXME make this routine use the tuner-simple code. 363 /* FIXME make this routine use the tuner-simple code.
385 * It could probably be shared with a number of ATSC 364 * It could probably be shared with a number of ATSC
@@ -392,12 +371,12 @@ static int lgdt330x_pll_set(struct dvb_frontend* fe,
392 { .addr = dev->core->pll_addr, .flags = 0, .buf = buf, .len = 4 }; 371 { .addr = dev->core->pll_addr, .flags = 0, .buf = buf, .len = 4 };
393 int err; 372 int err;
394 373
395 /* Put the analog decoder in standby to keep it quiet */
396 cx88_call_i2c_clients (dev->core, TUNER_SET_STANDBY, NULL);
397
398 dvb_pll_configure(core->pll_desc, buf, params->frequency, 0); 374 dvb_pll_configure(core->pll_desc, buf, params->frequency, 0);
399 dprintk(1, "%s: tuner at 0x%02x bytes: 0x%02x 0x%02x 0x%02x 0x%02x\n", 375 dprintk(1, "%s: tuner at 0x%02x bytes: 0x%02x 0x%02x 0x%02x 0x%02x\n",
400 __FUNCTION__, msg.addr, buf[0],buf[1],buf[2],buf[3]); 376 __FUNCTION__, msg.addr, buf[0],buf[1],buf[2],buf[3]);
377
378 if (fe->ops.i2c_gate_ctrl)
379 fe->ops.i2c_gate_ctrl(fe, 1);
401 if ((err = i2c_transfer(&core->i2c_adap, &msg, 1)) != 1) { 380 if ((err = i2c_transfer(&core->i2c_adap, &msg, 1)) != 1) {
402 printk(KERN_WARNING "cx88-dvb: %s error " 381 printk(KERN_WARNING "cx88-dvb: %s error "
403 "(addr %02x <- %02x, err = %i)\n", 382 "(addr %02x <- %02x, err = %i)\n",
@@ -407,16 +386,21 @@ static int lgdt330x_pll_set(struct dvb_frontend* fe,
407 else 386 else
408 return -EREMOTEIO; 387 return -EREMOTEIO;
409 } 388 }
410 if (core->tuner_type == TUNER_LG_TDVS_H062F) {
411 /* Set the Auxiliary Byte. */
412 buf[2] &= ~0x20;
413 buf[2] |= 0x18;
414 buf[3] = 0x50;
415 i2c_transfer(&core->i2c_adap, &msg, 1);
416 }
417 return 0; 389 return 0;
418} 390}
419 391
392static int lgdt3303_tuner_set_params(struct dvb_frontend* fe,
393 struct dvb_frontend_parameters* params)
394{
395 struct cx8802_dev *dev= fe->dvb->priv;
396 struct cx88_core *core = dev->core;
397
398 /* Put the analog decoder in standby to keep it quiet */
399 cx88_call_i2c_clients (dev->core, TUNER_SET_STANDBY, NULL);
400
401 return lg_h06xf_pll_set(fe, &core->i2c_adap, params);
402}
403
420static int lgdt330x_pll_rf_set(struct dvb_frontend* fe, int index) 404static int lgdt330x_pll_rf_set(struct dvb_frontend* fe, int index)
421{ 405{
422 struct cx8802_dev *dev= fe->dvb->priv; 406 struct cx8802_dev *dev= fe->dvb->priv;
@@ -444,7 +428,6 @@ static struct lgdt330x_config fusionhdtv_3_gold = {
444 .demod_address = 0x0e, 428 .demod_address = 0x0e,
445 .demod_chip = LGDT3302, 429 .demod_chip = LGDT3302,
446 .serial_mpeg = 0x04, /* TPSERIAL for 3302 in TOP_CONTROL */ 430 .serial_mpeg = 0x04, /* TPSERIAL for 3302 in TOP_CONTROL */
447 .pll_set = lgdt330x_pll_set,
448 .set_ts_params = lgdt330x_set_ts_param, 431 .set_ts_params = lgdt330x_set_ts_param,
449}; 432};
450 433
@@ -452,7 +435,13 @@ static struct lgdt330x_config fusionhdtv_5_gold = {
452 .demod_address = 0x0e, 435 .demod_address = 0x0e,
453 .demod_chip = LGDT3303, 436 .demod_chip = LGDT3303,
454 .serial_mpeg = 0x40, /* TPSERIAL for 3303 in TOP_CONTROL */ 437 .serial_mpeg = 0x40, /* TPSERIAL for 3303 in TOP_CONTROL */
455 .pll_set = lgdt330x_pll_set, 438 .set_ts_params = lgdt330x_set_ts_param,
439};
440
441static struct lgdt330x_config pchdtv_hd5500 = {
442 .demod_address = 0x59,
443 .demod_chip = LGDT3303,
444 .serial_mpeg = 0x40, /* TPSERIAL for 3303 in TOP_CONTROL */
456 .set_ts_params = lgdt330x_set_ts_param, 445 .set_ts_params = lgdt330x_set_ts_param,
457}; 446};
458#endif 447#endif
@@ -477,8 +466,6 @@ static int nxt200x_set_pll_input(u8* buf, int input)
477 466
478static struct nxt200x_config ati_hdtvwonder = { 467static struct nxt200x_config ati_hdtvwonder = {
479 .demod_address = 0x0a, 468 .demod_address = 0x0a,
480 .pll_address = 0x61,
481 .pll_desc = &dvb_pll_tuv1236d,
482 .set_pll_input = nxt200x_set_pll_input, 469 .set_pll_input = nxt200x_set_pll_input,
483 .set_ts_params = nxt200x_set_ts_param, 470 .set_ts_params = nxt200x_set_ts_param,
484}; 471};
@@ -493,28 +480,30 @@ static int cx24123_set_ts_param(struct dvb_frontend* fe,
493 return 0; 480 return 0;
494} 481}
495 482
496static void cx24123_enable_lnb_voltage(struct dvb_frontend* fe, int on) 483static int kworld_dvbs_100_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage)
497{ 484{
498 struct cx8802_dev *dev= fe->dvb->priv; 485 struct cx8802_dev *dev= fe->dvb->priv;
499 struct cx88_core *core = dev->core; 486 struct cx88_core *core = dev->core;
500 487
501 if (on) 488 if (voltage == SEC_VOLTAGE_OFF) {
502 cx_write(MO_GP0_IO, 0x000006f9);
503 else
504 cx_write(MO_GP0_IO, 0x000006fB); 489 cx_write(MO_GP0_IO, 0x000006fB);
490 } else {
491 cx_write(MO_GP0_IO, 0x000006f9);
492 }
493
494 if (core->prev_set_voltage)
495 return core->prev_set_voltage(fe, voltage);
496 return 0;
505} 497}
506 498
507static struct cx24123_config hauppauge_novas_config = { 499static struct cx24123_config hauppauge_novas_config = {
508 .demod_address = 0x55, 500 .demod_address = 0x55,
509 .use_isl6421 = 1,
510 .set_ts_params = cx24123_set_ts_param, 501 .set_ts_params = cx24123_set_ts_param,
511}; 502};
512 503
513static struct cx24123_config kworld_dvbs_100_config = { 504static struct cx24123_config kworld_dvbs_100_config = {
514 .demod_address = 0x15, 505 .demod_address = 0x15,
515 .use_isl6421 = 0,
516 .set_ts_params = cx24123_set_ts_param, 506 .set_ts_params = cx24123_set_ts_param,
517 .enable_lnb_voltage = cx24123_enable_lnb_voltage,
518}; 507};
519#endif 508#endif
520 509
@@ -530,6 +519,11 @@ static int dvb_register(struct cx8802_dev *dev)
530 case CX88_BOARD_HAUPPAUGE_DVB_T1: 519 case CX88_BOARD_HAUPPAUGE_DVB_T1:
531 dev->dvb.frontend = cx22702_attach(&hauppauge_novat_config, 520 dev->dvb.frontend = cx22702_attach(&hauppauge_novat_config,
532 &dev->core->i2c_adap); 521 &dev->core->i2c_adap);
522 if (dev->dvb.frontend != NULL) {
523 dvb_pll_attach(dev->dvb.frontend, 0x61,
524 &dev->core->i2c_adap,
525 &dvb_pll_thomson_dtt759x);
526 }
533 break; 527 break;
534 case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1: 528 case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1:
535 case CX88_BOARD_CONEXANT_DVB_T1: 529 case CX88_BOARD_CONEXANT_DVB_T1:
@@ -537,44 +531,92 @@ static int dvb_register(struct cx8802_dev *dev)
537 case CX88_BOARD_WINFAST_DTV1000: 531 case CX88_BOARD_WINFAST_DTV1000:
538 dev->dvb.frontend = cx22702_attach(&connexant_refboard_config, 532 dev->dvb.frontend = cx22702_attach(&connexant_refboard_config,
539 &dev->core->i2c_adap); 533 &dev->core->i2c_adap);
534 if (dev->dvb.frontend != NULL) {
535 dvb_pll_attach(dev->dvb.frontend, 0x60,
536 &dev->core->i2c_adap,
537 &dvb_pll_thomson_dtt7579);
538 }
540 break; 539 break;
540 case CX88_BOARD_WINFAST_DTV2000H:
541 case CX88_BOARD_HAUPPAUGE_HVR1100: 541 case CX88_BOARD_HAUPPAUGE_HVR1100:
542 case CX88_BOARD_HAUPPAUGE_HVR1100LP: 542 case CX88_BOARD_HAUPPAUGE_HVR1100LP:
543 dev->dvb.frontend = cx22702_attach(&hauppauge_hvr1100_config, 543 dev->dvb.frontend = cx22702_attach(&hauppauge_hvr1100_config,
544 &dev->core->i2c_adap); 544 &dev->core->i2c_adap);
545 if (dev->dvb.frontend != NULL) {
546 dvb_pll_attach(dev->dvb.frontend, 0x61,
547 &dev->core->i2c_adap,
548 &dvb_pll_fmd1216me);
549 }
545 break; 550 break;
546#endif 551#endif
547#if defined(HAVE_MT352) || defined(HAVE_ZL10353) 552#if defined(HAVE_MT352) || defined(HAVE_ZL10353)
548 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS: 553 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS:
549 dev->core->pll_addr = 0x60;
550 dev->core->pll_desc = &dvb_pll_thomson_dtt7579;
551#ifdef HAVE_MT352 554#ifdef HAVE_MT352
552 dev->dvb.frontend = mt352_attach(&dvico_fusionhdtv, 555 dev->dvb.frontend = mt352_attach(&dvico_fusionhdtv,
553 &dev->core->i2c_adap); 556 &dev->core->i2c_adap);
554 if (dev->dvb.frontend != NULL) 557 if (dev->dvb.frontend != NULL) {
558 dvb_pll_attach(dev->dvb.frontend, 0x60,
559 &dev->core->i2c_adap,
560 &dvb_pll_thomson_dtt7579);
555 break; 561 break;
562 }
556#endif 563#endif
557#ifdef HAVE_ZL10353 564#ifdef HAVE_ZL10353
558 /* ZL10353 replaces MT352 on later cards */ 565 /* ZL10353 replaces MT352 on later cards */
559 dev->dvb.frontend = zl10353_attach(&dvico_fusionhdtv_plus_v1_1, 566 dev->dvb.frontend = zl10353_attach(&dvico_fusionhdtv_plus_v1_1,
560 &dev->core->i2c_adap); 567 &dev->core->i2c_adap);
568 if (dev->dvb.frontend != NULL) {
569 dvb_pll_attach(dev->dvb.frontend, 0x60,
570 &dev->core->i2c_adap,
571 &dvb_pll_thomson_dtt7579);
572 }
573#endif
574 break;
575 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL:
576#ifdef HAVE_MT352
577 /* The tin box says DEE1601, but it seems to be DTT7579
578 * compatible, with a slightly different MT352 AGC gain. */
579 dev->dvb.frontend = mt352_attach(&dvico_fusionhdtv_dual,
580 &dev->core->i2c_adap);
581 if (dev->dvb.frontend != NULL) {
582 dvb_pll_attach(dev->dvb.frontend, 0x61,
583 &dev->core->i2c_adap,
584 &dvb_pll_thomson_dtt7579);
585 break;
586 }
587#endif
588#ifdef HAVE_ZL10353
589 /* ZL10353 replaces MT352 on later cards */
590 dev->dvb.frontend = zl10353_attach(&dvico_fusionhdtv_plus_v1_1,
591 &dev->core->i2c_adap);
592 if (dev->dvb.frontend != NULL) {
593 dvb_pll_attach(dev->dvb.frontend, 0x61,
594 &dev->core->i2c_adap,
595 &dvb_pll_thomson_dtt7579);
596 }
561#endif 597#endif
562 break; 598 break;
563#endif /* HAVE_MT352 || HAVE_ZL10353 */ 599#endif /* HAVE_MT352 || HAVE_ZL10353 */
564#ifdef HAVE_MT352 600#ifdef HAVE_MT352
565 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1: 601 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1:
566 dev->core->pll_addr = 0x61;
567 dev->core->pll_desc = &dvb_pll_lg_z201;
568 dev->dvb.frontend = mt352_attach(&dvico_fusionhdtv, 602 dev->dvb.frontend = mt352_attach(&dvico_fusionhdtv,
569 &dev->core->i2c_adap); 603 &dev->core->i2c_adap);
604 if (dev->dvb.frontend != NULL) {
605 dvb_pll_attach(dev->dvb.frontend, 0x61,
606 &dev->core->i2c_adap,
607 &dvb_pll_lg_z201);
608 }
570 break; 609 break;
571 case CX88_BOARD_KWORLD_DVB_T: 610 case CX88_BOARD_KWORLD_DVB_T:
572 case CX88_BOARD_DNTV_LIVE_DVB_T: 611 case CX88_BOARD_DNTV_LIVE_DVB_T:
573 case CX88_BOARD_ADSTECH_DVB_T_PCI: 612 case CX88_BOARD_ADSTECH_DVB_T_PCI:
574 dev->core->pll_addr = 0x61;
575 dev->core->pll_desc = &dvb_pll_unknown_1;
576 dev->dvb.frontend = mt352_attach(&dntv_live_dvbt_config, 613 dev->dvb.frontend = mt352_attach(&dntv_live_dvbt_config,
577 &dev->core->i2c_adap); 614 &dev->core->i2c_adap);
615 if (dev->dvb.frontend != NULL) {
616 dvb_pll_attach(dev->dvb.frontend, 0x61,
617 &dev->core->i2c_adap,
618 &dvb_pll_unknown_1);
619 }
578 break; 620 break;
579 case CX88_BOARD_DNTV_LIVE_DVB_T_PRO: 621 case CX88_BOARD_DNTV_LIVE_DVB_T_PRO:
580#ifdef HAVE_VP3054_I2C 622#ifdef HAVE_VP3054_I2C
@@ -582,18 +624,13 @@ static int dvb_register(struct cx8802_dev *dev)
582 dev->core->pll_desc = &dvb_pll_fmd1216me; 624 dev->core->pll_desc = &dvb_pll_fmd1216me;
583 dev->dvb.frontend = mt352_attach(&dntv_live_dvbt_pro_config, 625 dev->dvb.frontend = mt352_attach(&dntv_live_dvbt_pro_config,
584 &((struct vp3054_i2c_state *)dev->card_priv)->adap); 626 &((struct vp3054_i2c_state *)dev->card_priv)->adap);
627 if (dev->dvb.frontend != NULL) {
628 dev->dvb.frontend->ops.tuner_ops.set_params = dntv_live_dvbt_pro_tuner_set_params;
629 }
585#else 630#else
586 printk("%s: built without vp3054 support\n", dev->core->name); 631 printk("%s: built without vp3054 support\n", dev->core->name);
587#endif 632#endif
588 break; 633 break;
589 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL:
590 /* The tin box says DEE1601, but it seems to be DTT7579
591 * compatible, with a slightly different MT352 AGC gain. */
592 dev->core->pll_addr = 0x61;
593 dev->core->pll_desc = &dvb_pll_thomson_dtt7579;
594 dev->dvb.frontend = mt352_attach(&dvico_fusionhdtv_dual,
595 &dev->core->i2c_adap);
596 break;
597#endif 634#endif
598#ifdef HAVE_ZL10353 635#ifdef HAVE_ZL10353
599 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID: 636 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID:
@@ -601,12 +638,20 @@ static int dvb_register(struct cx8802_dev *dev)
601 dev->core->pll_desc = &dvb_pll_thomson_fe6600; 638 dev->core->pll_desc = &dvb_pll_thomson_fe6600;
602 dev->dvb.frontend = zl10353_attach(&dvico_fusionhdtv_hybrid, 639 dev->dvb.frontend = zl10353_attach(&dvico_fusionhdtv_hybrid,
603 &dev->core->i2c_adap); 640 &dev->core->i2c_adap);
641 if (dev->dvb.frontend != NULL) {
642 dev->dvb.frontend->ops.tuner_ops.set_params = dvico_hybrid_tuner_set_params;
643 }
604 break; 644 break;
605#endif 645#endif
606#ifdef HAVE_OR51132 646#ifdef HAVE_OR51132
607 case CX88_BOARD_PCHDTV_HD3000: 647 case CX88_BOARD_PCHDTV_HD3000:
608 dev->dvb.frontend = or51132_attach(&pchdtv_hd3000, 648 dev->dvb.frontend = or51132_attach(&pchdtv_hd3000,
609 &dev->core->i2c_adap); 649 &dev->core->i2c_adap);
650 if (dev->dvb.frontend != NULL) {
651 dvb_pll_attach(dev->dvb.frontend, 0x61,
652 &dev->core->i2c_adap,
653 &dvb_pll_thomson_dtt761x);
654 }
610 break; 655 break;
611#endif 656#endif
612#ifdef HAVE_LGDT330X 657#ifdef HAVE_LGDT330X
@@ -627,6 +672,9 @@ static int dvb_register(struct cx8802_dev *dev)
627 dev->core->pll_desc = &dvb_pll_microtune_4042; 672 dev->core->pll_desc = &dvb_pll_microtune_4042;
628 dev->dvb.frontend = lgdt330x_attach(&fusionhdtv_3_gold, 673 dev->dvb.frontend = lgdt330x_attach(&fusionhdtv_3_gold,
629 &dev->core->i2c_adap); 674 &dev->core->i2c_adap);
675 if (dev->dvb.frontend != NULL) {
676 dev->dvb.frontend->ops.tuner_ops.set_params = lgdt3302_tuner_set_params;
677 }
630 } 678 }
631 break; 679 break;
632 case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T: 680 case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T:
@@ -643,6 +691,9 @@ static int dvb_register(struct cx8802_dev *dev)
643 dev->core->pll_desc = &dvb_pll_thomson_dtt761x; 691 dev->core->pll_desc = &dvb_pll_thomson_dtt761x;
644 dev->dvb.frontend = lgdt330x_attach(&fusionhdtv_3_gold, 692 dev->dvb.frontend = lgdt330x_attach(&fusionhdtv_3_gold,
645 &dev->core->i2c_adap); 693 &dev->core->i2c_adap);
694 if (dev->dvb.frontend != NULL) {
695 dev->dvb.frontend->ops.tuner_ops.set_params = lgdt3302_tuner_set_params;
696 }
646 } 697 }
647 break; 698 break;
648 case CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD: 699 case CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD:
@@ -655,10 +706,28 @@ static int dvb_register(struct cx8802_dev *dev)
655 mdelay(100); 706 mdelay(100);
656 cx_set(MO_GP0_IO, 1); 707 cx_set(MO_GP0_IO, 1);
657 mdelay(200); 708 mdelay(200);
658 dev->core->pll_addr = 0x61;
659 dev->core->pll_desc = &dvb_pll_tdvs_tua6034;
660 dev->dvb.frontend = lgdt330x_attach(&fusionhdtv_5_gold, 709 dev->dvb.frontend = lgdt330x_attach(&fusionhdtv_5_gold,
661 &dev->core->i2c_adap); 710 &dev->core->i2c_adap);
711 if (dev->dvb.frontend != NULL) {
712 dev->dvb.frontend->ops.tuner_ops.set_params = lgdt3303_tuner_set_params;
713 }
714 }
715 break;
716 case CX88_BOARD_PCHDTV_HD5500:
717 dev->ts_gen_cntrl = 0x08;
718 {
719 /* Do a hardware reset of chip before using it. */
720 struct cx88_core *core = dev->core;
721
722 cx_clear(MO_GP0_IO, 1);
723 mdelay(100);
724 cx_set(MO_GP0_IO, 1);
725 mdelay(200);
726 dev->dvb.frontend = lgdt330x_attach(&pchdtv_hd5500,
727 &dev->core->i2c_adap);
728 if (dev->dvb.frontend != NULL) {
729 dev->dvb.frontend->ops.tuner_ops.set_params = lgdt3303_tuner_set_params;
730 }
662 } 731 }
663 break; 732 break;
664#endif 733#endif
@@ -666,6 +735,11 @@ static int dvb_register(struct cx8802_dev *dev)
666 case CX88_BOARD_ATI_HDTVWONDER: 735 case CX88_BOARD_ATI_HDTVWONDER:
667 dev->dvb.frontend = nxt200x_attach(&ati_hdtvwonder, 736 dev->dvb.frontend = nxt200x_attach(&ati_hdtvwonder,
668 &dev->core->i2c_adap); 737 &dev->core->i2c_adap);
738 if (dev->dvb.frontend != NULL) {
739 dvb_pll_attach(dev->dvb.frontend, 0x61,
740 &dev->core->i2c_adap,
741 &dvb_pll_tuv1236d);
742 }
669 break; 743 break;
670#endif 744#endif
671#ifdef HAVE_CX24123 745#ifdef HAVE_CX24123
@@ -673,10 +747,18 @@ static int dvb_register(struct cx8802_dev *dev)
673 case CX88_BOARD_HAUPPAUGE_NOVASE2_S1: 747 case CX88_BOARD_HAUPPAUGE_NOVASE2_S1:
674 dev->dvb.frontend = cx24123_attach(&hauppauge_novas_config, 748 dev->dvb.frontend = cx24123_attach(&hauppauge_novas_config,
675 &dev->core->i2c_adap); 749 &dev->core->i2c_adap);
750 if (dev->dvb.frontend) {
751 isl6421_attach(dev->dvb.frontend, &dev->core->i2c_adap,
752 0x08, 0x00, 0x00);
753 }
676 break; 754 break;
677 case CX88_BOARD_KWORLD_DVBS_100: 755 case CX88_BOARD_KWORLD_DVBS_100:
678 dev->dvb.frontend = cx24123_attach(&kworld_dvbs_100_config, 756 dev->dvb.frontend = cx24123_attach(&kworld_dvbs_100_config,
679 &dev->core->i2c_adap); 757 &dev->core->i2c_adap);
758 if (dev->dvb.frontend) {
759 dev->core->prev_set_voltage = dev->dvb.frontend->ops.set_voltage;
760 dev->dvb.frontend->ops.set_voltage = kworld_dvbs_100_set_voltage;
761 }
680 break; 762 break;
681#endif 763#endif
682 default: 764 default:
@@ -690,15 +772,15 @@ static int dvb_register(struct cx8802_dev *dev)
690 } 772 }
691 773
692 if (dev->core->pll_desc) { 774 if (dev->core->pll_desc) {
693 dev->dvb.frontend->ops->info.frequency_min = dev->core->pll_desc->min; 775 dev->dvb.frontend->ops.info.frequency_min = dev->core->pll_desc->min;
694 dev->dvb.frontend->ops->info.frequency_max = dev->core->pll_desc->max; 776 dev->dvb.frontend->ops.info.frequency_max = dev->core->pll_desc->max;
695 } 777 }
696 778
697 /* Put the analog decoder in standby to keep it quiet */ 779 /* Put the analog decoder in standby to keep it quiet */
698 cx88_call_i2c_clients (dev->core, TUNER_SET_STANDBY, NULL); 780 cx88_call_i2c_clients (dev->core, TUNER_SET_STANDBY, NULL);
699 781
700 /* register everything */ 782 /* register everything */
701 return videobuf_dvb_register(&dev->dvb, THIS_MODULE, dev); 783 return videobuf_dvb_register(&dev->dvb, THIS_MODULE, dev, &dev->pci->dev);
702} 784}
703 785
704/* ----------------------------------------------------------- */ 786/* ----------------------------------------------------------- */
diff --git a/drivers/media/video/cx88/cx88-i2c.c b/drivers/media/video/cx88/cx88-i2c.c
index f720901e963..7efa6def0bd 100644
--- a/drivers/media/video/cx88/cx88-i2c.c
+++ b/drivers/media/video/cx88/cx88-i2c.c
@@ -138,13 +138,13 @@ void cx88_call_i2c_clients(struct cx88_core *core, unsigned int cmd, void *arg)
138 return; 138 return;
139 139
140 if (core->dvbdev) { 140 if (core->dvbdev) {
141 if (core->dvbdev->dvb.frontend->ops->i2c_gate_ctrl) 141 if (core->dvbdev->dvb.frontend->ops.i2c_gate_ctrl)
142 core->dvbdev->dvb.frontend->ops->i2c_gate_ctrl(core->dvbdev->dvb.frontend, 1); 142 core->dvbdev->dvb.frontend->ops.i2c_gate_ctrl(core->dvbdev->dvb.frontend, 1);
143 143
144 i2c_clients_command(&core->i2c_adap, cmd, arg); 144 i2c_clients_command(&core->i2c_adap, cmd, arg);
145 145
146 if (core->dvbdev->dvb.frontend->ops->i2c_gate_ctrl) 146 if (core->dvbdev->dvb.frontend->ops.i2c_gate_ctrl)
147 core->dvbdev->dvb.frontend->ops->i2c_gate_ctrl(core->dvbdev->dvb.frontend, 0); 147 core->dvbdev->dvb.frontend->ops.i2c_gate_ctrl(core->dvbdev->dvb.frontend, 0);
148 } else 148 } else
149 i2c_clients_command(&core->i2c_adap, cmd, arg); 149 i2c_clients_command(&core->i2c_adap, cmd, arg);
150} 150}
diff --git a/drivers/media/video/cx88/cx88-input.c b/drivers/media/video/cx88/cx88-input.c
index 78a63b7dd38..72b630a91f4 100644
--- a/drivers/media/video/cx88/cx88-input.c
+++ b/drivers/media/video/cx88/cx88-input.c
@@ -70,14 +70,33 @@ MODULE_PARM_DESC(ir_debug, "enable debug messages [IR]");
70static void cx88_ir_handle_key(struct cx88_IR *ir) 70static void cx88_ir_handle_key(struct cx88_IR *ir)
71{ 71{
72 struct cx88_core *core = ir->core; 72 struct cx88_core *core = ir->core;
73 u32 gpio, data; 73 u32 gpio, data, auxgpio;
74 74
75 /* read gpio value */ 75 /* read gpio value */
76 gpio = cx_read(ir->gpio_addr); 76 gpio = cx_read(ir->gpio_addr);
77 if (core->board == CX88_BOARD_NPGTECH_REALTV_TOP10FM) {
78 /* This board apparently uses a combination of 2 GPIO
79 to represent the keys. Additionally, the second GPIO
80 can be used for parity.
81
82 Example:
83
84 for key "5"
85 gpio = 0x758, auxgpio = 0xe5 or 0xf5
86 for key "Power"
87 gpio = 0x758, auxgpio = 0xed or 0xfd
88 */
89
90 auxgpio = cx_read(MO_GP1_IO);
91 /* Take out the parity part */
92 gpio+=(gpio & 0x7fd) + (auxgpio & 0xef);
93 } else
94 auxgpio = gpio;
95
77 if (ir->polling) { 96 if (ir->polling) {
78 if (ir->last_gpio == gpio) 97 if (ir->last_gpio == auxgpio)
79 return; 98 return;
80 ir->last_gpio = gpio; 99 ir->last_gpio = auxgpio;
81 } 100 }
82 101
83 /* extract data */ 102 /* extract data */
@@ -172,12 +191,13 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
172 ir_type = IR_TYPE_RC5; 191 ir_type = IR_TYPE_RC5;
173 ir->sampling = 1; 192 ir->sampling = 1;
174 break; 193 break;
194 case CX88_BOARD_WINFAST_DTV2000H:
175 case CX88_BOARD_WINFAST2000XP_EXPERT: 195 case CX88_BOARD_WINFAST2000XP_EXPERT:
176 ir_codes = ir_codes_winfast; 196 ir_codes = ir_codes_winfast;
177 ir->gpio_addr = MO_GP0_IO; 197 ir->gpio_addr = MO_GP0_IO;
178 ir->mask_keycode = 0x8f8; 198 ir->mask_keycode = 0x8f8;
179 ir->mask_keyup = 0x100; 199 ir->mask_keyup = 0x100;
180 ir->polling = 1; /* ms */ 200 ir->polling = 50; /* ms */
181 break; 201 break;
182 case CX88_BOARD_IODATA_GVBCTV7E: 202 case CX88_BOARD_IODATA_GVBCTV7E:
183 ir_codes = ir_codes_iodata_bctv7e; 203 ir_codes = ir_codes_iodata_bctv7e;
@@ -228,6 +248,12 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
228 ir_type = IR_TYPE_PD; 248 ir_type = IR_TYPE_PD;
229 ir->sampling = 0xff00; /* address */ 249 ir->sampling = 0xff00; /* address */
230 break; 250 break;
251 case CX88_BOARD_NPGTECH_REALTV_TOP10FM:
252 ir_codes = ir_codes_npgtech;
253 ir->gpio_addr = MO_GP0_IO;
254 ir->mask_keycode = 0xfa;
255 ir->polling = 50; /* ms */
256 break;
231 } 257 }
232 258
233 if (NULL == ir_codes) { 259 if (NULL == ir_codes) {
diff --git a/drivers/media/video/cx88/cx88-mpeg.c b/drivers/media/video/cx88/cx88-mpeg.c
index 7d16888b4a8..a9d7795a8e1 100644
--- a/drivers/media/video/cx88/cx88-mpeg.c
+++ b/drivers/media/video/cx88/cx88-mpeg.c
@@ -54,7 +54,7 @@ static int cx8802_start_dma(struct cx8802_dev *dev,
54{ 54{
55 struct cx88_core *core = dev->core; 55 struct cx88_core *core = dev->core;
56 56
57 dprintk(0, "cx8802_start_dma w: %d, h: %d, f: %d\n", dev->width, dev->height, buf->vb.field); 57 dprintk(1, "cx8802_start_dma w: %d, h: %d, f: %d\n", dev->width, dev->height, buf->vb.field);
58 58
59 /* setup fifo + format */ 59 /* setup fifo + format */
60 cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH28], 60 cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH28],
@@ -76,6 +76,7 @@ static int cx8802_start_dma(struct cx8802_dev *dev,
76 case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_Q: 76 case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_Q:
77 case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T: 77 case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T:
78 case CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD: 78 case CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD:
79 case CX88_BOARD_PCHDTV_HD5500:
79 cx_write(TS_SOP_STAT, 1<<13); 80 cx_write(TS_SOP_STAT, 1<<13);
80 break; 81 break;
81 case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1: 82 case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1:
@@ -109,7 +110,7 @@ static int cx8802_start_dma(struct cx8802_dev *dev,
109 q->count = 1; 110 q->count = 1;
110 111
111 /* enable irqs */ 112 /* enable irqs */
112 dprintk( 0, "setting the interrupt mask\n" ); 113 dprintk( 1, "setting the interrupt mask\n" );
113 cx_set(MO_PCI_INTMSK, core->pci_irqmask | 0x04); 114 cx_set(MO_PCI_INTMSK, core->pci_irqmask | 0x04);
114 cx_set(MO_TS_INTMSK, 0x1f0011); 115 cx_set(MO_TS_INTMSK, 0x1f0011);
115 116
@@ -122,7 +123,7 @@ static int cx8802_start_dma(struct cx8802_dev *dev,
122static int cx8802_stop_dma(struct cx8802_dev *dev) 123static int cx8802_stop_dma(struct cx8802_dev *dev)
123{ 124{
124 struct cx88_core *core = dev->core; 125 struct cx88_core *core = dev->core;
125 dprintk( 0, "cx8802_stop_dma\n" ); 126 dprintk( 1, "cx8802_stop_dma\n" );
126 127
127 /* stop dma */ 128 /* stop dma */
128 cx_clear(MO_TS_DMACNTRL, 0x11); 129 cx_clear(MO_TS_DMACNTRL, 0x11);
@@ -142,10 +143,43 @@ static int cx8802_restart_queue(struct cx8802_dev *dev,
142 struct cx88_buffer *buf; 143 struct cx88_buffer *buf;
143 struct list_head *item; 144 struct list_head *item;
144 145
145 dprintk( 0, "cx8802_restart_queue\n" ); 146 dprintk( 1, "cx8802_restart_queue\n" );
146 if (list_empty(&q->active)) 147 if (list_empty(&q->active))
147 { 148 {
148 dprintk( 0, "cx8802_restart_queue: queue is empty\n" ); 149 struct cx88_buffer *prev;
150 prev = NULL;
151
152 dprintk(1, "cx8802_restart_queue: queue is empty\n" );
153
154 for (;;) {
155 if (list_empty(&q->queued))
156 return 0;
157 buf = list_entry(q->queued.next, struct cx88_buffer, vb.queue);
158 if (NULL == prev) {
159 list_del(&buf->vb.queue);
160 list_add_tail(&buf->vb.queue,&q->active);
161 cx8802_start_dma(dev, q, buf);
162 buf->vb.state = STATE_ACTIVE;
163 buf->count = q->count++;
164 mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT);
165 dprintk(1,"[%p/%d] restart_queue - first active\n",
166 buf,buf->vb.i);
167
168 } else if (prev->vb.width == buf->vb.width &&
169 prev->vb.height == buf->vb.height &&
170 prev->fmt == buf->fmt) {
171 list_del(&buf->vb.queue);
172 list_add_tail(&buf->vb.queue,&q->active);
173 buf->vb.state = STATE_ACTIVE;
174 buf->count = q->count++;
175 prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
176 dprintk(1,"[%p/%d] restart_queue - move to active\n",
177 buf,buf->vb.i);
178 } else {
179 return 0;
180 }
181 prev = buf;
182 }
149 return 0; 183 return 0;
150 } 184 }
151 185
@@ -204,13 +238,13 @@ void cx8802_buf_queue(struct cx8802_dev *dev, struct cx88_buffer *buf)
204 buf->risc.jmp[1] = cpu_to_le32(cx88q->stopper.dma); 238 buf->risc.jmp[1] = cpu_to_le32(cx88q->stopper.dma);
205 239
206 if (list_empty(&cx88q->active)) { 240 if (list_empty(&cx88q->active)) {
207 dprintk( 0, "queue is empty - first active\n" ); 241 dprintk( 1, "queue is empty - first active\n" );
208 list_add_tail(&buf->vb.queue,&cx88q->active); 242 list_add_tail(&buf->vb.queue,&cx88q->active);
209 cx8802_start_dma(dev, cx88q, buf); 243 cx8802_start_dma(dev, cx88q, buf);
210 buf->vb.state = STATE_ACTIVE; 244 buf->vb.state = STATE_ACTIVE;
211 buf->count = cx88q->count++; 245 buf->count = cx88q->count++;
212 mod_timer(&cx88q->timeout, jiffies+BUFFER_TIMEOUT); 246 mod_timer(&cx88q->timeout, jiffies+BUFFER_TIMEOUT);
213 dprintk(0,"[%p/%d] %s - first active\n", 247 dprintk(1,"[%p/%d] %s - first active\n",
214 buf, buf->vb.i, __FUNCTION__); 248 buf, buf->vb.i, __FUNCTION__);
215 249
216 } else { 250 } else {
@@ -244,7 +278,7 @@ static void do_cancel_buffers(struct cx8802_dev *dev, char *reason, int restart)
244 } 278 }
245 if (restart) 279 if (restart)
246 { 280 {
247 dprintk(0, "restarting queue\n" ); 281 dprintk(1, "restarting queue\n" );
248 cx8802_restart_queue(dev,q); 282 cx8802_restart_queue(dev,q);
249 } 283 }
250 spin_unlock_irqrestore(&dev->slock,flags); 284 spin_unlock_irqrestore(&dev->slock,flags);
diff --git a/drivers/media/video/cx88/cx88-tvaudio.c b/drivers/media/video/cx88/cx88-tvaudio.c
index 641a0c5a649..1e4278b588d 100644
--- a/drivers/media/video/cx88/cx88-tvaudio.c
+++ b/drivers/media/video/cx88/cx88-tvaudio.c
@@ -52,6 +52,7 @@
52#include <linux/init.h> 52#include <linux/init.h>
53#include <linux/smp_lock.h> 53#include <linux/smp_lock.h>
54#include <linux/delay.h> 54#include <linux/delay.h>
55#include <linux/config.h>
55#include <linux/kthread.h> 56#include <linux/kthread.h>
56 57
57#include "cx88.h" 58#include "cx88.h"
@@ -137,21 +138,28 @@ static void set_audio_finish(struct cx88_core *core, u32 ctl)
137{ 138{
138 u32 volume; 139 u32 volume;
139 140
140#ifndef USING_CX88_ALSA 141#ifndef CONFIG_VIDEO_CX88_ALSA
141 /* restart dma; This avoids buzz in NICAM and is good in others */ 142 /* restart dma; This avoids buzz in NICAM and is good in others */
142 cx88_stop_audio_dma(core); 143 cx88_stop_audio_dma(core);
143#endif 144#endif
144 cx_write(AUD_RATE_THRES_DMD, 0x000000C0); 145 cx_write(AUD_RATE_THRES_DMD, 0x000000C0);
145#ifndef USING_CX88_ALSA 146#ifndef CONFIG_VIDEO_CX88_ALSA
146 cx88_start_audio_dma(core); 147 cx88_start_audio_dma(core);
147#endif 148#endif
148 149
149 if (cx88_boards[core->board].blackbird) { 150 if (cx88_boards[core->board].blackbird) {
150 /* sets sound input from external adc */ 151 /* sets sound input from external adc */
151 if (core->board == CX88_BOARD_HAUPPAUGE_ROSLYN) 152 switch (core->board) {
153 case CX88_BOARD_HAUPPAUGE_ROSLYN:
154 case CX88_BOARD_KWORLD_MCE200_DELUXE:
155 case CX88_BOARD_KWORLD_HARDWARE_MPEG_TV_XPERT:
156 case CX88_BOARD_PIXELVIEW_PLAYTV_P7000:
157 case CX88_BOARD_ASUS_PVR_416:
152 cx_clear(AUD_CTL, EN_I2SIN_ENABLE); 158 cx_clear(AUD_CTL, EN_I2SIN_ENABLE);
153 else 159 break;
160 default:
154 cx_set(AUD_CTL, EN_I2SIN_ENABLE); 161 cx_set(AUD_CTL, EN_I2SIN_ENABLE);
162 }
155 163
156 cx_write(AUD_I2SINPUTCNTL, 4); 164 cx_write(AUD_I2SINPUTCNTL, 4);
157 cx_write(AUD_BAUDRATE, 1); 165 cx_write(AUD_BAUDRATE, 1);
diff --git a/drivers/media/video/cx88/cx88-vbi.c b/drivers/media/video/cx88/cx88-vbi.c
index 846faadc9f1..aa2a6977009 100644
--- a/drivers/media/video/cx88/cx88-vbi.c
+++ b/drivers/media/video/cx88/cx88-vbi.c
@@ -34,8 +34,8 @@ void cx8800_vbi_fmt(struct cx8800_dev *dev, struct v4l2_format *f)
34 if (dev->core->tvnorm->id & V4L2_STD_525_60) { 34 if (dev->core->tvnorm->id & V4L2_STD_525_60) {
35 /* ntsc */ 35 /* ntsc */
36 f->fmt.vbi.sampling_rate = 28636363; 36 f->fmt.vbi.sampling_rate = 28636363;
37 f->fmt.vbi.start[0] = 10 -1; 37 f->fmt.vbi.start[0] = 10;
38 f->fmt.vbi.start[1] = 273 -1; 38 f->fmt.vbi.start[1] = 273;
39 39
40 } else if (dev->core->tvnorm->id & V4L2_STD_625_50) { 40 } else if (dev->core->tvnorm->id & V4L2_STD_625_50) {
41 /* pal */ 41 /* pal */
diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h
index 326a25f147f..dc7bc35f18f 100644
--- a/drivers/media/video/cx88/cx88.h
+++ b/drivers/media/video/cx88/cx88.h
@@ -25,9 +25,11 @@
25#include <linux/videodev2.h> 25#include <linux/videodev2.h>
26#include <linux/kdev_t.h> 26#include <linux/kdev_t.h>
27 27
28#include <media/v4l2-common.h>
28#include <media/tuner.h> 29#include <media/tuner.h>
29#include <media/tveeprom.h> 30#include <media/tveeprom.h>
30#include <media/video-buf.h> 31#include <media/video-buf.h>
32#include <media/cx2341x.h>
31#include <media/video-buf-dvb.h> 33#include <media/video-buf-dvb.h>
32 34
33#include "btcx-risc.h" 35#include "btcx-risc.h"
@@ -35,7 +37,7 @@
35 37
36#include <linux/version.h> 38#include <linux/version.h>
37#include <linux/mutex.h> 39#include <linux/mutex.h>
38#define CX88_VERSION_CODE KERNEL_VERSION(0,0,5) 40#define CX88_VERSION_CODE KERNEL_VERSION(0,0,6)
39 41
40#ifndef TRUE 42#ifndef TRUE
41# define TRUE (1==1) 43# define TRUE (1==1)
@@ -189,6 +191,11 @@ extern struct sram_channel cx88_sram_channels[];
189#define CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL 44 191#define CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL 44
190#define CX88_BOARD_KWORLD_HARDWARE_MPEG_TV_XPERT 45 192#define CX88_BOARD_KWORLD_HARDWARE_MPEG_TV_XPERT 45
191#define CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID 46 193#define CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID 46
194#define CX88_BOARD_PCHDTV_HD5500 47
195#define CX88_BOARD_KWORLD_MCE200_DELUXE 48
196#define CX88_BOARD_PIXELVIEW_PLAYTV_P7000 49
197#define CX88_BOARD_NPGTECH_REALTV_TOP10FM 50
198#define CX88_BOARD_WINFAST_DTV2000H 51
192 199
193enum cx88_itype { 200enum cx88_itype {
194 CX88_VMUX_COMPOSITE1 = 1, 201 CX88_VMUX_COMPOSITE1 = 1,
@@ -296,6 +303,7 @@ struct cx88_core {
296 /* config info -- dvb */ 303 /* config info -- dvb */
297 struct dvb_pll_desc *pll_desc; 304 struct dvb_pll_desc *pll_desc;
298 unsigned int pll_addr; 305 unsigned int pll_addr;
306 int (*prev_set_voltage)(struct dvb_frontend* fe, fe_sec_voltage_t voltage);
299 307
300 /* state info */ 308 /* state info */
301 struct task_struct *kthread; 309 struct task_struct *kthread;
@@ -391,14 +399,6 @@ struct cx8802_suspend_state {
391 int disabled; 399 int disabled;
392}; 400};
393 401
394/* TODO: move this to struct v4l2_mpeg_compression ? */
395struct blackbird_dnr {
396 u32 mode;
397 u32 type;
398 u32 spatial;
399 u32 temporal;
400};
401
402struct cx8802_dev { 402struct cx8802_dev {
403 struct cx88_core *core; 403 struct cx88_core *core;
404 spinlock_t slock; 404 spinlock_t slock;
@@ -432,8 +432,7 @@ struct cx8802_dev {
432 unsigned char ts_gen_cntrl; 432 unsigned char ts_gen_cntrl;
433 433
434 /* mpeg params */ 434 /* mpeg params */
435 struct v4l2_mpeg_compression params; 435 struct cx2341x_mpeg_params params;
436 struct blackbird_dnr dnr_params;
437}; 436};
438 437
439/* ----------------------------------------------------------- */ 438/* ----------------------------------------------------------- */
@@ -598,10 +597,6 @@ extern int cx88_do_ioctl(struct inode *inode, struct file *file, int radio,
598extern int (*cx88_ioctl_hook)(struct inode *inode, struct file *file, 597extern int (*cx88_ioctl_hook)(struct inode *inode, struct file *file,
599 unsigned int cmd, void *arg); 598 unsigned int cmd, void *arg);
600extern unsigned int (*cx88_ioctl_translator)(unsigned int cmd); 599extern unsigned int (*cx88_ioctl_translator)(unsigned int cmd);
601void blackbird_set_params(struct cx8802_dev *dev,
602 struct v4l2_mpeg_compression *params);
603void blackbird_set_dnr_params(struct cx8802_dev *dev,
604 struct blackbird_dnr* dnr_params);
605 600
606/* 601/*
607 * Local variables: 602 * Local variables:
diff --git a/drivers/media/video/dsbr100.c b/drivers/media/video/dsbr100.c
index 3b4e9985c3d..f7e33f9ee8e 100644
--- a/drivers/media/video/dsbr100.c
+++ b/drivers/media/video/dsbr100.c
@@ -72,6 +72,7 @@
72#include <linux/slab.h> 72#include <linux/slab.h>
73#include <linux/input.h> 73#include <linux/input.h>
74#include <linux/videodev.h> 74#include <linux/videodev.h>
75#include <media/v4l2-common.h>
75#include <linux/usb.h> 76#include <linux/usb.h>
76#include <linux/smp_lock.h> 77#include <linux/smp_lock.h>
77 78
diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c
index 3ba3439db58..ed882ebc7b9 100644
--- a/drivers/media/video/em28xx/em28xx-cards.c
+++ b/drivers/media/video/em28xx/em28xx-cards.c
@@ -3,7 +3,7 @@
3 3
4 Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it> 4 Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it>
5 Markus Rechberger <mrechberger@gmail.com> 5 Markus Rechberger <mrechberger@gmail.com>
6 Mauro Carvalho Chehab <mchehab@brturbo.com.br> 6 Mauro Carvalho Chehab <mchehab@infradead.org>
7 Sascha Sommer <saschasommer@freenet.de> 7 Sascha Sommer <saschasommer@freenet.de>
8 8
9 This program is free software; you can redistribute it and/or modify 9 This program is free software; you can redistribute it and/or modify
@@ -29,6 +29,8 @@
29#include <linux/usb.h> 29#include <linux/usb.h>
30#include <media/tuner.h> 30#include <media/tuner.h>
31#include <media/msp3400.h> 31#include <media/msp3400.h>
32#include <media/saa7115.h>
33#include <media/tvp5150.h>
32#include <media/tveeprom.h> 34#include <media/tveeprom.h>
33#include <media/audiochip.h> 35#include <media/audiochip.h>
34#include <media/v4l2-common.h> 36#include <media/v4l2-common.h>
@@ -46,11 +48,11 @@ struct em28xx_board em28xx_boards[] = {
46 .decoder = EM28XX_SAA7113, 48 .decoder = EM28XX_SAA7113,
47 .input = {{ 49 .input = {{
48 .type = EM28XX_VMUX_COMPOSITE1, 50 .type = EM28XX_VMUX_COMPOSITE1,
49 .vmux = 0, 51 .vmux = SAA7115_COMPOSITE0,
50 .amux = 1, 52 .amux = 1,
51 },{ 53 },{
52 .type = EM28XX_VMUX_SVIDEO, 54 .type = EM28XX_VMUX_SVIDEO,
53 .vmux = 9, 55 .vmux = SAA7115_SVIDEO3,
54 .amux = 1, 56 .amux = 1,
55 }}, 57 }},
56 }, 58 },
@@ -64,11 +66,11 @@ struct em28xx_board em28xx_boards[] = {
64 .decoder = EM28XX_SAA7113, 66 .decoder = EM28XX_SAA7113,
65 .input = {{ 67 .input = {{
66 .type = EM28XX_VMUX_COMPOSITE1, 68 .type = EM28XX_VMUX_COMPOSITE1,
67 .vmux = 0, 69 .vmux = SAA7115_COMPOSITE0,
68 .amux = 1, 70 .amux = 1,
69 },{ 71 },{
70 .type = EM28XX_VMUX_SVIDEO, 72 .type = EM28XX_VMUX_SVIDEO,
71 .vmux = 9, 73 .vmux = SAA7115_SVIDEO3,
72 .amux = 1, 74 .amux = 1,
73 }}, 75 }},
74 }, 76 },
@@ -82,11 +84,11 @@ struct em28xx_board em28xx_boards[] = {
82 .decoder = EM28XX_SAA7113, 84 .decoder = EM28XX_SAA7113,
83 .input = {{ 85 .input = {{
84 .type = EM28XX_VMUX_COMPOSITE1, 86 .type = EM28XX_VMUX_COMPOSITE1,
85 .vmux = 0, 87 .vmux = SAA7115_COMPOSITE0,
86 .amux = 1, 88 .amux = 1,
87 },{ 89 },{
88 .type = EM28XX_VMUX_SVIDEO, 90 .type = EM28XX_VMUX_SVIDEO,
89 .vmux = 9, 91 .vmux = SAA7115_SVIDEO3,
90 .amux = 1, 92 .amux = 1,
91 }}, 93 }},
92 }, 94 },
@@ -100,15 +102,15 @@ struct em28xx_board em28xx_boards[] = {
100 .decoder = EM28XX_SAA7113, 102 .decoder = EM28XX_SAA7113,
101 .input = {{ 103 .input = {{
102 .type = EM28XX_VMUX_TELEVISION, 104 .type = EM28XX_VMUX_TELEVISION,
103 .vmux = 2, 105 .vmux = SAA7115_COMPOSITE2,
104 .amux = 1, 106 .amux = 1,
105 },{ 107 },{
106 .type = EM28XX_VMUX_COMPOSITE1, 108 .type = EM28XX_VMUX_COMPOSITE1,
107 .vmux = 0, 109 .vmux = SAA7115_COMPOSITE0,
108 .amux = 1, 110 .amux = 1,
109 },{ 111 },{
110 .type = EM28XX_VMUX_SVIDEO, 112 .type = EM28XX_VMUX_SVIDEO,
111 .vmux = 9, 113 .vmux = SAA7115_SVIDEO3,
112 .amux = 1, 114 .amux = 1,
113 }}, 115 }},
114 }, 116 },
@@ -122,15 +124,15 @@ struct em28xx_board em28xx_boards[] = {
122 .decoder = EM28XX_SAA7113, 124 .decoder = EM28XX_SAA7113,
123 .input = {{ 125 .input = {{
124 .type = EM28XX_VMUX_TELEVISION, 126 .type = EM28XX_VMUX_TELEVISION,
125 .vmux = 2, 127 .vmux = SAA7115_COMPOSITE2,
126 .amux = 0, 128 .amux = 0,
127 },{ 129 },{
128 .type = EM28XX_VMUX_COMPOSITE1, 130 .type = EM28XX_VMUX_COMPOSITE1,
129 .vmux = 0, 131 .vmux = SAA7115_COMPOSITE0,
130 .amux = 1, 132 .amux = 1,
131 },{ 133 },{
132 .type = EM28XX_VMUX_SVIDEO, 134 .type = EM28XX_VMUX_SVIDEO,
133 .vmux = 9, 135 .vmux = SAA7115_SVIDEO3,
134 .amux = 1, 136 .amux = 1,
135 }}, 137 }},
136 }, 138 },
@@ -146,11 +148,11 @@ struct em28xx_board em28xx_boards[] = {
146 /*FIXME: S-Video not tested */ 148 /*FIXME: S-Video not tested */
147 .input = {{ 149 .input = {{
148 .type = EM28XX_VMUX_TELEVISION, 150 .type = EM28XX_VMUX_TELEVISION,
149 .vmux = 0, 151 .vmux = TVP5150_COMPOSITE0,
150 .amux = MSP_INPUT_DEFAULT, 152 .amux = MSP_INPUT_DEFAULT,
151 },{ 153 },{
152 .type = EM28XX_VMUX_SVIDEO, 154 .type = EM28XX_VMUX_SVIDEO,
153 .vmux = 2, 155 .vmux = TVP5150_SVIDEO,
154 .amux = MSP_INPUT(MSP_IN_SCART1, MSP_IN_TUNER1, 156 .amux = MSP_INPUT(MSP_IN_SCART1, MSP_IN_TUNER1,
155 MSP_DSP_IN_SCART, MSP_DSP_IN_SCART), 157 MSP_DSP_IN_SCART, MSP_DSP_IN_SCART),
156 }}, 158 }},
@@ -165,15 +167,15 @@ struct em28xx_board em28xx_boards[] = {
165 .decoder = EM28XX_SAA7114, 167 .decoder = EM28XX_SAA7114,
166 .input = {{ 168 .input = {{
167 .type = EM28XX_VMUX_TELEVISION, 169 .type = EM28XX_VMUX_TELEVISION,
168 .vmux = 4, 170 .vmux = SAA7115_COMPOSITE4,
169 .amux = 0, 171 .amux = 0,
170 },{ 172 },{
171 .type = EM28XX_VMUX_COMPOSITE1, 173 .type = EM28XX_VMUX_COMPOSITE1,
172 .vmux = 0, 174 .vmux = SAA7115_COMPOSITE0,
173 .amux = 1, 175 .amux = 1,
174 },{ 176 },{
175 .type = EM28XX_VMUX_SVIDEO, 177 .type = EM28XX_VMUX_SVIDEO,
176 .vmux = 9, 178 .vmux = SAA7115_SVIDEO3,
177 .amux = 1, 179 .amux = 1,
178 }}, 180 }},
179 }, 181 },
@@ -188,15 +190,15 @@ struct em28xx_board em28xx_boards[] = {
188 .decoder = EM28XX_SAA7113, 190 .decoder = EM28XX_SAA7113,
189 .input = {{ 191 .input = {{
190 .type = EM28XX_VMUX_TELEVISION, 192 .type = EM28XX_VMUX_TELEVISION,
191 .vmux = 2, 193 .vmux = SAA7115_COMPOSITE2,
192 .amux = 0, 194 .amux = 0,
193 },{ 195 },{
194 .type = EM28XX_VMUX_COMPOSITE1, 196 .type = EM28XX_VMUX_COMPOSITE1,
195 .vmux = 0, 197 .vmux = SAA7115_COMPOSITE0,
196 .amux = 1, 198 .amux = 1,
197 },{ 199 },{
198 .type = EM28XX_VMUX_SVIDEO, 200 .type = EM28XX_VMUX_SVIDEO,
199 .vmux = 9, 201 .vmux = SAA7115_SVIDEO3,
200 .amux = 1, 202 .amux = 1,
201 }}, 203 }},
202 }, 204 },
@@ -211,15 +213,15 @@ struct em28xx_board em28xx_boards[] = {
211 .decoder = EM28XX_SAA7113, 213 .decoder = EM28XX_SAA7113,
212 .input = {{ 214 .input = {{
213 .type = EM28XX_VMUX_TELEVISION, 215 .type = EM28XX_VMUX_TELEVISION,
214 .vmux = 2, 216 .vmux = SAA7115_COMPOSITE2,
215 .amux = 0, 217 .amux = 0,
216 },{ 218 },{
217 .type = EM28XX_VMUX_COMPOSITE1, 219 .type = EM28XX_VMUX_COMPOSITE1,
218 .vmux = 0, 220 .vmux = SAA7115_COMPOSITE0,
219 .amux = 1, 221 .amux = 1,
220 },{ 222 },{
221 .type = EM28XX_VMUX_SVIDEO, 223 .type = EM28XX_VMUX_SVIDEO,
222 .vmux = 9, 224 .vmux = SAA7115_SVIDEO3,
223 .amux = 1, 225 .amux = 1,
224 }}, 226 }},
225 }, 227 },
@@ -234,15 +236,15 @@ struct em28xx_board em28xx_boards[] = {
234 .decoder = EM28XX_SAA7113, 236 .decoder = EM28XX_SAA7113,
235 .input = {{ 237 .input = {{
236 .type = EM28XX_VMUX_TELEVISION, 238 .type = EM28XX_VMUX_TELEVISION,
237 .vmux = 2, 239 .vmux = SAA7115_COMPOSITE2,
238 .amux = 0, 240 .amux = 0,
239 },{ 241 },{
240 .type = EM28XX_VMUX_COMPOSITE1, 242 .type = EM28XX_VMUX_COMPOSITE1,
241 .vmux = 0, 243 .vmux = SAA7115_COMPOSITE0,
242 .amux = 1, 244 .amux = 1,
243 },{ 245 },{
244 .type = EM28XX_VMUX_SVIDEO, 246 .type = EM28XX_VMUX_SVIDEO,
245 .vmux = 9, 247 .vmux = SAA7115_SVIDEO3,
246 .amux = 1, 248 .amux = 1,
247 }}, 249 }},
248 }, 250 },
@@ -254,11 +256,11 @@ struct em28xx_board em28xx_boards[] = {
254 .decoder = EM28XX_SAA7113, 256 .decoder = EM28XX_SAA7113,
255 .input = {{ 257 .input = {{
256 .type = EM28XX_VMUX_COMPOSITE1, 258 .type = EM28XX_VMUX_COMPOSITE1,
257 .vmux = 0, 259 .vmux = SAA7115_COMPOSITE0,
258 .amux = 1, 260 .amux = 1,
259 },{ 261 },{
260 .type = EM28XX_VMUX_SVIDEO, 262 .type = EM28XX_VMUX_SVIDEO,
261 .vmux = 9, 263 .vmux = SAA7115_SVIDEO3,
262 .amux = 1, 264 .amux = 1,
263 }}, 265 }},
264 }, 266 },
@@ -324,8 +326,4 @@ void em28xx_card_setup(struct em28xx *dev)
324 } 326 }
325} 327}
326 328
327EXPORT_SYMBOL(em28xx_boards);
328EXPORT_SYMBOL(em28xx_bcount);
329EXPORT_SYMBOL(em28xx_id_table);
330
331MODULE_DEVICE_TABLE (usb, em28xx_id_table); 329MODULE_DEVICE_TABLE (usb, em28xx_id_table);
diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c
index e5ee8bceb21..4350cc75b02 100644
--- a/drivers/media/video/em28xx/em28xx-core.c
+++ b/drivers/media/video/em28xx/em28xx-core.c
@@ -3,7 +3,7 @@
3 3
4 Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it> 4 Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it>
5 Markus Rechberger <mrechberger@gmail.com> 5 Markus Rechberger <mrechberger@gmail.com>
6 Mauro Carvalho Chehab <mchehab@brturbo.com.br> 6 Mauro Carvalho Chehab <mchehab@infradead.org>
7 Sascha Sommer <saschasommer@freenet.de> 7 Sascha Sommer <saschasommer@freenet.de>
8 8
9 This program is free software; you can redistribute it and/or modify 9 This program is free software; you can redistribute it and/or modify
@@ -317,8 +317,8 @@ int em28xx_outfmt_set_yuv422(struct em28xx *dev)
317 return em28xx_write_regs(dev, VINCTRL_REG, "\x11", 1); 317 return em28xx_write_regs(dev, VINCTRL_REG, "\x11", 1);
318} 318}
319 319
320int em28xx_accumulator_set(struct em28xx *dev, u8 xmin, u8 xmax, u8 ymin, 320static int em28xx_accumulator_set(struct em28xx *dev, u8 xmin, u8 xmax,
321 u8 ymax) 321 u8 ymin, u8 ymax)
322{ 322{
323 em28xx_coredbg("em28xx Scale: (%d,%d)-(%d,%d)\n", xmin, ymin, xmax, ymax); 323 em28xx_coredbg("em28xx Scale: (%d,%d)-(%d,%d)\n", xmin, ymin, xmax, ymax);
324 324
@@ -328,7 +328,7 @@ int em28xx_accumulator_set(struct em28xx *dev, u8 xmin, u8 xmax, u8 ymin,
328 return em28xx_write_regs(dev, YMAX_REG, &ymax, 1); 328 return em28xx_write_regs(dev, YMAX_REG, &ymax, 1);
329} 329}
330 330
331int em28xx_capture_area_set(struct em28xx *dev, u8 hstart, u8 vstart, 331static int em28xx_capture_area_set(struct em28xx *dev, u8 hstart, u8 vstart,
332 u16 width, u16 height) 332 u16 width, u16 height)
333{ 333{
334 u8 cwidth = width; 334 u8 cwidth = width;
@@ -345,7 +345,7 @@ int em28xx_capture_area_set(struct em28xx *dev, u8 hstart, u8 vstart,
345 return em28xx_write_regs(dev, OFLOW_REG, &overflow, 1); 345 return em28xx_write_regs(dev, OFLOW_REG, &overflow, 1);
346} 346}
347 347
348int em28xx_scaler_set(struct em28xx *dev, u16 h, u16 v) 348static int em28xx_scaler_set(struct em28xx *dev, u16 h, u16 v)
349{ 349{
350 u8 mode; 350 u8 mode;
351 /* the em2800 scaler only supports scaling down to 50% */ 351 /* the em2800 scaler only supports scaling down to 50% */
@@ -534,7 +534,7 @@ static inline void em28xx_isoc_video_copy(struct em28xx *dev,
534 * em28xx_isoIrq() 534 * em28xx_isoIrq()
535 * handles the incoming isoc urbs and fills the frames from our inqueue 535 * handles the incoming isoc urbs and fills the frames from our inqueue
536 */ 536 */
537void em28xx_isocIrq(struct urb *urb, struct pt_regs *regs) 537static void em28xx_isocIrq(struct urb *urb, struct pt_regs *regs)
538{ 538{
539 struct em28xx *dev = urb->context; 539 struct em28xx *dev = urb->context;
540 int i, status; 540 int i, status;
diff --git a/drivers/media/video/em28xx/em28xx-i2c.c b/drivers/media/video/em28xx/em28xx-i2c.c
index 5b6cece37ae..d829d8f8c1f 100644
--- a/drivers/media/video/em28xx/em28xx-i2c.c
+++ b/drivers/media/video/em28xx/em28xx-i2c.c
@@ -3,7 +3,7 @@
3 3
4 Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it> 4 Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it>
5 Markus Rechberger <mrechberger@gmail.com> 5 Markus Rechberger <mrechberger@gmail.com>
6 Mauro Carvalho Chehab <mchehab@brturbo.com.br> 6 Mauro Carvalho Chehab <mchehab@infradead.org>
7 Sascha Sommer <saschasommer@freenet.de> 7 Sascha Sommer <saschasommer@freenet.de>
8 8
9 This program is free software; you can redistribute it and/or modify 9 This program is free software; you can redistribute it and/or modify
@@ -399,17 +399,6 @@ static u32 functionality(struct i2c_adapter *adap)
399 return I2C_FUNC_SMBUS_EMUL; 399 return I2C_FUNC_SMBUS_EMUL;
400} 400}
401 401
402#ifndef I2C_PEC
403static void inc_use(struct i2c_adapter *adap)
404{
405 MOD_INC_USE_COUNT;
406}
407
408static void dec_use(struct i2c_adapter *adap)
409{
410 MOD_DEC_USE_COUNT;
411}
412#endif
413 402
414static int em28xx_set_tuner(int check_eeprom, struct i2c_client *client) 403static int em28xx_set_tuner(int check_eeprom, struct i2c_client *client)
415{ 404{
@@ -436,9 +425,19 @@ static int attach_inform(struct i2c_client *client)
436 struct em28xx *dev = client->adapter->algo_data; 425 struct em28xx *dev = client->adapter->algo_data;
437 426
438 switch (client->addr << 1) { 427 switch (client->addr << 1) {
439 case 0x86: 428 case 0x43:
429 case 0x4b:
430 {
431 struct tuner_setup tun_setup;
432
433 tun_setup.mode_mask = T_ANALOG_TV | T_RADIO;
434 tun_setup.type = TUNER_TDA9887;
435 tun_setup.addr = client->addr;
436
437 em28xx_i2c_call_clients(dev, TUNER_SET_TYPE_ADDR, &tun_setup);
440 em28xx_i2c_call_clients(dev, TDA9887_SET_CONFIG, &dev->tda9887_conf); 438 em28xx_i2c_call_clients(dev, TDA9887_SET_CONFIG, &dev->tda9887_conf);
441 break; 439 break;
440 }
442 case 0x42: 441 case 0x42:
443 dprintk1(1,"attach_inform: saa7114 detected.\n"); 442 dprintk1(1,"attach_inform: saa7114 detected.\n");
444 break; 443 break;
@@ -464,6 +463,7 @@ static int attach_inform(struct i2c_client *client)
464 case 0xba: 463 case 0xba:
465 dprintk1(1,"attach_inform: tvp5150 detected.\n"); 464 dprintk1(1,"attach_inform: tvp5150 detected.\n");
466 break; 465 break;
466
467 default: 467 default:
468 dprintk1(1,"attach inform: detected I2C address %x\n", client->addr << 1); 468 dprintk1(1,"attach inform: detected I2C address %x\n", client->addr << 1);
469 dev->tuner_addr = client->addr; 469 dev->tuner_addr = client->addr;
@@ -480,12 +480,7 @@ static struct i2c_algorithm em28xx_algo = {
480}; 480};
481 481
482static struct i2c_adapter em28xx_adap_template = { 482static struct i2c_adapter em28xx_adap_template = {
483#ifdef I2C_PEC
484 .owner = THIS_MODULE, 483 .owner = THIS_MODULE,
485#else
486 .inc_use = inc_use,
487 .dec_use = dec_use,
488#endif
489 .class = I2C_CLASS_TV_ANALOG, 484 .class = I2C_CLASS_TV_ANALOG,
490 .name = "em28xx", 485 .name = "em28xx",
491 .id = I2C_HW_B_EM28XX, 486 .id = I2C_HW_B_EM28XX,
diff --git a/drivers/media/video/em28xx/em28xx-input.c b/drivers/media/video/em28xx/em28xx-input.c
index 31e89e4f18b..3ffb5684f12 100644
--- a/drivers/media/video/em28xx/em28xx-input.c
+++ b/drivers/media/video/em28xx/em28xx-input.c
@@ -3,7 +3,7 @@
3 3
4 Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it> 4 Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it>
5 Markus Rechberger <mrechberger@gmail.com> 5 Markus Rechberger <mrechberger@gmail.com>
6 Mauro Carvalho Chehab <mchehab@brturbo.com.br> 6 Mauro Carvalho Chehab <mchehab@infradead.org>
7 Sascha Sommer <saschasommer@freenet.de> 7 Sascha Sommer <saschasommer@freenet.de>
8 8
9 This program is free software; you can redistribute it and/or modify 9 This program is free software; you can redistribute it and/or modify
@@ -105,7 +105,7 @@ static int get_key_em_haup(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
105 return 1; 105 return 1;
106} 106}
107 107
108static int get_key_pinnacle_usb(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) 108static int get_key_pinnacle_usb_grey(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
109{ 109{
110 unsigned char buf[3]; 110 unsigned char buf[3];
111 111
@@ -148,8 +148,8 @@ void em28xx_set_ir(struct em28xx * dev,struct IR_i2c *ir)
148 snprintf(ir->c.name, sizeof(ir->c.name), "i2c IR (EM28XX Terratec)"); 148 snprintf(ir->c.name, sizeof(ir->c.name), "i2c IR (EM28XX Terratec)");
149 break; 149 break;
150 case (EM2820_BOARD_PINNACLE_USB_2): 150 case (EM2820_BOARD_PINNACLE_USB_2):
151 ir->ir_codes = ir_codes_em_pinnacle_usb; 151 ir->ir_codes = ir_codes_pinnacle_grey;
152 ir->get_key = get_key_pinnacle_usb; 152 ir->get_key = get_key_pinnacle_usb_grey;
153 snprintf(ir->c.name, sizeof(ir->c.name), "i2c IR (EM28XX Pinnacle PCTV)"); 153 snprintf(ir->c.name, sizeof(ir->c.name), "i2c IR (EM28XX Pinnacle PCTV)");
154 break; 154 break;
155 case (EM2820_BOARD_HAUPPAUGE_WINTV_USB_2): 155 case (EM2820_BOARD_HAUPPAUGE_WINTV_USB_2):
diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c
index cf7cdf9ef61..9286090817c 100644
--- a/drivers/media/video/em28xx/em28xx-video.c
+++ b/drivers/media/video/em28xx/em28xx-video.c
@@ -3,7 +3,7 @@
3 3
4 Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it> 4 Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it>
5 Markus Rechberger <mrechberger@gmail.com> 5 Markus Rechberger <mrechberger@gmail.com>
6 Mauro Carvalho Chehab <mchehab@brturbo.com.br> 6 Mauro Carvalho Chehab <mchehab@infradead.org>
7 Sascha Sommer <saschasommer@freenet.de> 7 Sascha Sommer <saschasommer@freenet.de>
8 8
9 Some parts based on SN9C10x PC Camera Controllers GPL driver made 9 Some parts based on SN9C10x PC Camera Controllers GPL driver made
@@ -42,7 +42,7 @@
42 42
43#define DRIVER_AUTHOR "Ludovico Cavedon <cavedon@sssup.it>, " \ 43#define DRIVER_AUTHOR "Ludovico Cavedon <cavedon@sssup.it>, " \
44 "Markus Rechberger <mrechberger@gmail.com>, " \ 44 "Markus Rechberger <mrechberger@gmail.com>, " \
45 "Mauro Carvalho Chehab <mchehab@brturbo.com.br>, " \ 45 "Mauro Carvalho Chehab <mchehab@infradead.org>, " \
46 "Sascha Sommer <saschasommer@freenet.de>" 46 "Sascha Sommer <saschasommer@freenet.de>"
47 47
48#define DRIVER_NAME "em28xx" 48#define DRIVER_NAME "em28xx"
@@ -170,8 +170,12 @@ static int em28xx_config(struct em28xx *dev)
170static void em28xx_config_i2c(struct em28xx *dev) 170static void em28xx_config_i2c(struct em28xx *dev)
171{ 171{
172 struct v4l2_frequency f; 172 struct v4l2_frequency f;
173 struct v4l2_routing route;
174
175 route.input = INPUT(dev->ctl_input)->vmux;
176 route.output = 0;
173 em28xx_i2c_call_clients(dev, VIDIOC_INT_RESET, NULL); 177 em28xx_i2c_call_clients(dev, VIDIOC_INT_RESET, NULL);
174 em28xx_i2c_call_clients(dev, VIDIOC_S_INPUT, &dev->ctl_input); 178 em28xx_i2c_call_clients(dev, VIDIOC_INT_S_VIDEO_ROUTING, &route);
175 em28xx_i2c_call_clients(dev, VIDIOC_STREAMON, NULL); 179 em28xx_i2c_call_clients(dev, VIDIOC_STREAMON, NULL);
176 180
177 /* configure tuner */ 181 /* configure tuner */
@@ -206,19 +210,19 @@ static void em28xx_empty_framequeues(struct em28xx *dev)
206 210
207static void video_mux(struct em28xx *dev, int index) 211static void video_mux(struct em28xx *dev, int index)
208{ 212{
209 int input, ainput; 213 int ainput;
214 struct v4l2_routing route;
210 215
211 input = INPUT(index)->vmux; 216 route.input = INPUT(index)->vmux;
217 route.output = 0;
212 dev->ctl_input = index; 218 dev->ctl_input = index;
213 dev->ctl_ainput = INPUT(index)->amux; 219 dev->ctl_ainput = INPUT(index)->amux;
214 220
215 em28xx_i2c_call_clients(dev, VIDIOC_S_INPUT, &input); 221 em28xx_i2c_call_clients(dev, VIDIOC_INT_S_VIDEO_ROUTING, &route);
216 222
217 em28xx_videodbg("Setting input index=%d, vmux=%d, amux=%d\n",index,input,dev->ctl_ainput); 223 em28xx_videodbg("Setting input index=%d, vmux=%d, amux=%d\n",index,route.input,dev->ctl_ainput);
218 224
219 if (dev->has_msp34xx) { 225 if (dev->has_msp34xx) {
220 struct v4l2_routing route;
221
222 if (dev->i2s_speed) 226 if (dev->i2s_speed)
223 em28xx_i2c_call_clients(dev, VIDIOC_INT_I2S_CLOCK_FREQ, &dev->i2s_speed); 227 em28xx_i2c_call_clients(dev, VIDIOC_INT_I2S_CLOCK_FREQ, &dev->i2s_speed);
224 route.input = dev->ctl_ainput; 228 route.input = dev->ctl_ainput;
diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h
index e1ddc2f27a2..d8fcc9e17ac 100644
--- a/drivers/media/video/em28xx/em28xx.h
+++ b/drivers/media/video/em28xx/em28xx.h
@@ -3,7 +3,7 @@
3 3
4 Copyright (C) 2005 Markus Rechberger <mrechberger@gmail.com> 4 Copyright (C) 2005 Markus Rechberger <mrechberger@gmail.com>
5 Ludovico Cavedon <cavedon@sssup.it> 5 Ludovico Cavedon <cavedon@sssup.it>
6 Mauro Carvalho Chehab <mchehab@brturbo.com.br> 6 Mauro Carvalho Chehab <mchehab@infradead.org>
7 7
8 Based on the em2800 driver from Sascha Sommer <saschasommer@freenet.de> 8 Based on the em2800 driver from Sascha Sommer <saschasommer@freenet.de>
9 9
@@ -319,13 +319,7 @@ int em28xx_audio_analog_set(struct em28xx *dev);
319int em28xx_colorlevels_set_default(struct em28xx *dev); 319int em28xx_colorlevels_set_default(struct em28xx *dev);
320int em28xx_capture_start(struct em28xx *dev, int start); 320int em28xx_capture_start(struct em28xx *dev, int start);
321int em28xx_outfmt_set_yuv422(struct em28xx *dev); 321int em28xx_outfmt_set_yuv422(struct em28xx *dev);
322int em28xx_accumulator_set(struct em28xx *dev, u8 xmin, u8 xmax, u8 ymin,
323 u8 ymax);
324int em28xx_capture_area_set(struct em28xx *dev, u8 hstart, u8 vstart,
325 u16 width, u16 height);
326int em28xx_scaler_set(struct em28xx *dev, u16 h, u16 v);
327int em28xx_resolution_set(struct em28xx *dev); 322int em28xx_resolution_set(struct em28xx *dev);
328void em28xx_isocIrq(struct urb *urb, struct pt_regs *regs);
329int em28xx_init_isoc(struct em28xx *dev); 323int em28xx_init_isoc(struct em28xx *dev);
330void em28xx_uninit_isoc(struct em28xx *dev); 324void em28xx_uninit_isoc(struct em28xx *dev);
331int em28xx_set_alternate(struct em28xx *dev); 325int em28xx_set_alternate(struct em28xx *dev);
diff --git a/drivers/media/video/et61x251/et61x251_core.c b/drivers/media/video/et61x251/et61x251_core.c
index dfc9dd732c9..8992b6e62b9 100644
--- a/drivers/media/video/et61x251/et61x251_core.c
+++ b/drivers/media/video/et61x251/et61x251_core.c
@@ -2341,11 +2341,9 @@ static int et61x251_ioctl_v4l2(struct inode* inode, struct file* filp,
2341 case VIDIOC_G_CTRL: 2341 case VIDIOC_G_CTRL:
2342 return et61x251_vidioc_g_ctrl(cam, arg); 2342 return et61x251_vidioc_g_ctrl(cam, arg);
2343 2343
2344 case VIDIOC_S_CTRL_OLD:
2345 case VIDIOC_S_CTRL: 2344 case VIDIOC_S_CTRL:
2346 return et61x251_vidioc_s_ctrl(cam, arg); 2345 return et61x251_vidioc_s_ctrl(cam, arg);
2347 2346
2348 case VIDIOC_CROPCAP_OLD:
2349 case VIDIOC_CROPCAP: 2347 case VIDIOC_CROPCAP:
2350 return et61x251_vidioc_cropcap(cam, arg); 2348 return et61x251_vidioc_cropcap(cam, arg);
2351 2349
@@ -2392,7 +2390,6 @@ static int et61x251_ioctl_v4l2(struct inode* inode, struct file* filp,
2392 case VIDIOC_G_PARM: 2390 case VIDIOC_G_PARM:
2393 return et61x251_vidioc_g_parm(cam, arg); 2391 return et61x251_vidioc_g_parm(cam, arg);
2394 2392
2395 case VIDIOC_S_PARM_OLD:
2396 case VIDIOC_S_PARM: 2393 case VIDIOC_S_PARM:
2397 return et61x251_vidioc_s_parm(cam, arg); 2394 return et61x251_vidioc_s_parm(cam, arg);
2398 2395
diff --git a/drivers/media/video/ir-kbd-i2c.c b/drivers/media/video/ir-kbd-i2c.c
index 7e66d83fe0c..fba30a40e9c 100644
--- a/drivers/media/video/ir-kbd-i2c.c
+++ b/drivers/media/video/ir-kbd-i2c.c
@@ -150,12 +150,11 @@ static int get_key_knc1(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
150 return 1; 150 return 1;
151} 151}
152 152
153/* The new pinnacle PCTV remote (with the colored buttons) 153/* Common (grey or coloured) pinnacle PCTV remote handling
154 * 154 *
155 * Ricardo Cerqueira <v4l@cerqueira.org>
156 */ 155 */
157 156static int get_key_pinnacle(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw,
158int get_key_pinnacle(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) 157 int parity_offset, int marker, int code_modulo)
159{ 158{
160 unsigned char b[4]; 159 unsigned char b[4];
161 unsigned int start = 0,parity = 0,code = 0; 160 unsigned int start = 0,parity = 0,code = 0;
@@ -167,9 +166,9 @@ int get_key_pinnacle(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
167 } 166 }
168 167
169 for (start = 0; start<4; start++) { 168 for (start = 0; start<4; start++) {
170 if (b[start] == 0x80) { 169 if (b[start] == marker) {
171 code=b[(start+3)%4]; 170 code=b[(start+parity_offset+1)%4];
172 parity=b[(start+2)%4]; 171 parity=b[(start+parity_offset)%4];
173 } 172 }
174 } 173 }
175 174
@@ -181,16 +180,14 @@ int get_key_pinnacle(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
181 if (ir->old == parity) 180 if (ir->old == parity)
182 return 0; 181 return 0;
183 182
184
185 ir->old = parity; 183 ir->old = parity;
186 184
187 /* Reduce code value to fit inside IR_KEYTAB_SIZE 185 /* drop special codes when a key is held down a long time for the grey controller
188 * 186 In this case, the second bit of the code is asserted */
189 * this is the only value that results in 42 unique 187 if (marker == 0xfe && (code & 0x40))
190 * codes < 128 188 return 0;
191 */
192 189
193 code %= 0x88; 190 code %= code_modulo;
194 191
195 *ir_raw = code; 192 *ir_raw = code;
196 *ir_key = code; 193 *ir_key = code;
@@ -200,7 +197,40 @@ int get_key_pinnacle(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
200 return 1; 197 return 1;
201} 198}
202 199
203EXPORT_SYMBOL_GPL(get_key_pinnacle); 200/* The grey pinnacle PCTV remote
201 *
202 * There are one issue with this remote:
203 * - I2c packet does not change when the same key is pressed quickly. The workaround
204 * is to hold down each key for about half a second, so that another code is generated
205 * in the i2c packet, and the function can distinguish key presses.
206 *
207 * Sylvain Pasche <sylvain.pasche@gmail.com>
208 */
209int get_key_pinnacle_grey(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
210{
211
212 return get_key_pinnacle(ir, ir_key, ir_raw, 1, 0xfe, 0xff);
213}
214
215EXPORT_SYMBOL_GPL(get_key_pinnacle_grey);
216
217
218/* The new pinnacle PCTV remote (with the colored buttons)
219 *
220 * Ricardo Cerqueira <v4l@cerqueira.org>
221 */
222int get_key_pinnacle_color(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
223{
224 /* code_modulo parameter (0x88) is used to reduce code value to fit inside IR_KEYTAB_SIZE
225 *
226 * this is the only value that results in 42 unique
227 * codes < 128
228 */
229
230 return get_key_pinnacle(ir, ir_key, ir_raw, 2, 0x80, 0x88);
231}
232
233EXPORT_SYMBOL_GPL(get_key_pinnacle_color);
204 234
205/* ----------------------------------------------------------------------- */ 235/* ----------------------------------------------------------------------- */
206 236
diff --git a/drivers/media/video/ks0127.c b/drivers/media/video/ks0127.c
new file mode 100644
index 00000000000..3bf7ac4f528
--- /dev/null
+++ b/drivers/media/video/ks0127.c
@@ -0,0 +1,846 @@
1/*
2 * Video Capture Driver (Video for Linux 1/2)
3 * for the Matrox Marvel G200,G400 and Rainbow Runner-G series
4 *
5 * This module is an interface to the KS0127 video decoder chip.
6 *
7 * Copyright (C) 1999 Ryan Drake <stiletto@mediaone.net>
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 *
23 *****************************************************************************
24 *
25 * Modified and extended by
26 * Mike Bernson <mike@mlb.org>
27 * Gerard v.d. Horst
28 * Leon van Stuivenberg <l.vanstuivenberg@chello.nl>
29 * Gernot Ziegler <gz@lysator.liu.se>
30 *
31 * Version History:
32 * V1.0 Ryan Drake Initial version by Ryan Drake
33 * V1.1 Gerard v.d. Horst Added some debugoutput, reset the video-standard
34 */
35
36#ifndef __KERNEL__
37#define __KERNEL__
38#endif
39
40#include <linux/init.h>
41#include <linux/module.h>
42#include <linux/delay.h>
43#include <linux/errno.h>
44#include <linux/kernel.h>
45#include <linux/slab.h>
46#include <linux/proc_fs.h>
47#include "ks0127.h"
48
49#include <linux/i2c.h>
50#include <linux/video_decoder.h>
51
52#define dprintk if (debug) printk
53
54/* i2c identification */
55#define I2C_KS0127_ADDON 0xD8
56#define I2C_KS0127_ONBOARD 0xDA
57
58#define KS_TYPE_UNKNOWN 0
59#define KS_TYPE_0122S 1
60#define KS_TYPE_0127 2
61#define KS_TYPE_0127B 3
62
63/* ks0127 control registers */
64#define KS_STAT 0x00
65#define KS_CMDA 0x01
66#define KS_CMDB 0x02
67#define KS_CMDC 0x03
68#define KS_CMDD 0x04
69#define KS_HAVB 0x05
70#define KS_HAVE 0x06
71#define KS_HS1B 0x07
72#define KS_HS1E 0x08
73#define KS_HS2B 0x09
74#define KS_HS2E 0x0a
75#define KS_AGC 0x0b
76#define KS_HXTRA 0x0c
77#define KS_CDEM 0x0d
78#define KS_PORTAB 0x0e
79#define KS_LUMA 0x0f
80#define KS_CON 0x10
81#define KS_BRT 0x11
82#define KS_CHROMA 0x12
83#define KS_CHROMB 0x13
84#define KS_DEMOD 0x14
85#define KS_SAT 0x15
86#define KS_HUE 0x16
87#define KS_VERTIA 0x17
88#define KS_VERTIB 0x18
89#define KS_VERTIC 0x19
90#define KS_HSCLL 0x1a
91#define KS_HSCLH 0x1b
92#define KS_VSCLL 0x1c
93#define KS_VSCLH 0x1d
94#define KS_OFMTA 0x1e
95#define KS_OFMTB 0x1f
96#define KS_VBICTL 0x20
97#define KS_CCDAT2 0x21
98#define KS_CCDAT1 0x22
99#define KS_VBIL30 0x23
100#define KS_VBIL74 0x24
101#define KS_VBIL118 0x25
102#define KS_VBIL1512 0x26
103#define KS_TTFRAM 0x27
104#define KS_TESTA 0x28
105#define KS_UVOFFH 0x29
106#define KS_UVOFFL 0x2a
107#define KS_UGAIN 0x2b
108#define KS_VGAIN 0x2c
109#define KS_VAVB 0x2d
110#define KS_VAVE 0x2e
111#define KS_CTRACK 0x2f
112#define KS_POLCTL 0x30
113#define KS_REFCOD 0x31
114#define KS_INVALY 0x32
115#define KS_INVALU 0x33
116#define KS_INVALV 0x34
117#define KS_UNUSEY 0x35
118#define KS_UNUSEU 0x36
119#define KS_UNUSEV 0x37
120#define KS_USRSAV 0x38
121#define KS_USREAV 0x39
122#define KS_SHS1A 0x3a
123#define KS_SHS1B 0x3b
124#define KS_SHS1C 0x3c
125#define KS_CMDE 0x3d
126#define KS_VSDEL 0x3e
127#define KS_CMDF 0x3f
128#define KS_GAMMA0 0x40
129#define KS_GAMMA1 0x41
130#define KS_GAMMA2 0x42
131#define KS_GAMMA3 0x43
132#define KS_GAMMA4 0x44
133#define KS_GAMMA5 0x45
134#define KS_GAMMA6 0x46
135#define KS_GAMMA7 0x47
136#define KS_GAMMA8 0x48
137#define KS_GAMMA9 0x49
138#define KS_GAMMA10 0x4a
139#define KS_GAMMA11 0x4b
140#define KS_GAMMA12 0x4c
141#define KS_GAMMA13 0x4d
142#define KS_GAMMA14 0x4e
143#define KS_GAMMA15 0x4f
144#define KS_GAMMA16 0x50
145#define KS_GAMMA17 0x51
146#define KS_GAMMA18 0x52
147#define KS_GAMMA19 0x53
148#define KS_GAMMA20 0x54
149#define KS_GAMMA21 0x55
150#define KS_GAMMA22 0x56
151#define KS_GAMMA23 0x57
152#define KS_GAMMA24 0x58
153#define KS_GAMMA25 0x59
154#define KS_GAMMA26 0x5a
155#define KS_GAMMA27 0x5b
156#define KS_GAMMA28 0x5c
157#define KS_GAMMA29 0x5d
158#define KS_GAMMA30 0x5e
159#define KS_GAMMA31 0x5f
160#define KS_GAMMAD0 0x60
161#define KS_GAMMAD1 0x61
162#define KS_GAMMAD2 0x62
163#define KS_GAMMAD3 0x63
164#define KS_GAMMAD4 0x64
165#define KS_GAMMAD5 0x65
166#define KS_GAMMAD6 0x66
167#define KS_GAMMAD7 0x67
168#define KS_GAMMAD8 0x68
169#define KS_GAMMAD9 0x69
170#define KS_GAMMAD10 0x6a
171#define KS_GAMMAD11 0x6b
172#define KS_GAMMAD12 0x6c
173#define KS_GAMMAD13 0x6d
174#define KS_GAMMAD14 0x6e
175#define KS_GAMMAD15 0x6f
176#define KS_GAMMAD16 0x70
177#define KS_GAMMAD17 0x71
178#define KS_GAMMAD18 0x72
179#define KS_GAMMAD19 0x73
180#define KS_GAMMAD20 0x74
181#define KS_GAMMAD21 0x75
182#define KS_GAMMAD22 0x76
183#define KS_GAMMAD23 0x77
184#define KS_GAMMAD24 0x78
185#define KS_GAMMAD25 0x79
186#define KS_GAMMAD26 0x7a
187#define KS_GAMMAD27 0x7b
188#define KS_GAMMAD28 0x7c
189#define KS_GAMMAD29 0x7d
190#define KS_GAMMAD30 0x7e
191#define KS_GAMMAD31 0x7f
192
193
194/****************************************************************************
195* mga_dev : represents one ks0127 chip.
196****************************************************************************/
197
198struct adjust {
199 int contrast;
200 int bright;
201 int hue;
202 int ugain;
203 int vgain;
204};
205
206struct ks0127 {
207 struct i2c_client *client;
208 unsigned char addr;
209 int format_width;
210 int format_height;
211 int cap_width;
212 int cap_height;
213 int norm;
214 int ks_type;
215 u8 regs[256];
216};
217
218
219static int debug; /* insmod parameter */
220
221module_param(debug, int, 0);
222MODULE_PARM_DESC(debug, "Debug output");
223MODULE_LICENSE("GPL");
224
225static u8 reg_defaults[64];
226
227
228
229static void init_reg_defaults(void)
230{
231 u8 *table = reg_defaults;
232
233 table[KS_CMDA] = 0x2c; /* VSE=0, CCIR 601, autodetect standard */
234 table[KS_CMDB] = 0x12; /* VALIGN=0, AGC control and input */
235 table[KS_CMDC] = 0x00; /* Test options */
236 /* clock & input select, write 1 to PORTA */
237 table[KS_CMDD] = 0x01;
238 table[KS_HAVB] = 0x00; /* HAV Start Control */
239 table[KS_HAVE] = 0x00; /* HAV End Control */
240 table[KS_HS1B] = 0x10; /* HS1 Start Control */
241 table[KS_HS1E] = 0x00; /* HS1 End Control */
242 table[KS_HS2B] = 0x00; /* HS2 Start Control */
243 table[KS_HS2E] = 0x00; /* HS2 End Control */
244 table[KS_AGC] = 0x53; /* Manual setting for AGC */
245 table[KS_HXTRA] = 0x00; /* Extra Bits for HAV and HS1/2 */
246 table[KS_CDEM] = 0x00; /* Chroma Demodulation Control */
247 table[KS_PORTAB] = 0x0f; /* port B is input, port A output GPPORT */
248 table[KS_LUMA] = 0x01; /* Luma control */
249 table[KS_CON] = 0x00; /* Contrast Control */
250 table[KS_BRT] = 0x00; /* Brightness Control */
251 table[KS_CHROMA] = 0x2a; /* Chroma control A */
252 table[KS_CHROMB] = 0x90; /* Chroma control B */
253 table[KS_DEMOD] = 0x00; /* Chroma Demodulation Control & Status */
254 table[KS_SAT] = 0x00; /* Color Saturation Control*/
255 table[KS_HUE] = 0x00; /* Hue Control */
256 table[KS_VERTIA] = 0x00; /* Vertical Processing Control A */
257 /* Vertical Processing Control B, luma 1 line delayed */
258 table[KS_VERTIB] = 0x12;
259 table[KS_VERTIC] = 0x0b; /* Vertical Processing Control C */
260 table[KS_HSCLL] = 0x00; /* Horizontal Scaling Ratio Low */
261 table[KS_HSCLH] = 0x00; /* Horizontal Scaling Ratio High */
262 table[KS_VSCLL] = 0x00; /* Vertical Scaling Ratio Low */
263 table[KS_VSCLH] = 0x00; /* Vertical Scaling Ratio High */
264 /* 16 bit YCbCr 4:2:2 output; I can't make the bt866 like 8 bit /Sam */
265 table[KS_OFMTA] = 0x30;
266 table[KS_OFMTB] = 0x00; /* Output Control B */
267 /* VBI Decoder Control; 4bit fmt: avoid Y overflow */
268 table[KS_VBICTL] = 0x5d;
269 table[KS_CCDAT2] = 0x00; /* Read Only register */
270 table[KS_CCDAT1] = 0x00; /* Read Only register */
271 table[KS_VBIL30] = 0xa8; /* VBI data decoding options */
272 table[KS_VBIL74] = 0xaa; /* VBI data decoding options */
273 table[KS_VBIL118] = 0x2a; /* VBI data decoding options */
274 table[KS_VBIL1512] = 0x00; /* VBI data decoding options */
275 table[KS_TTFRAM] = 0x00; /* Teletext frame alignment pattern */
276 table[KS_TESTA] = 0x00; /* test register, shouldn't be written */
277 table[KS_UVOFFH] = 0x00; /* UV Offset Adjustment High */
278 table[KS_UVOFFL] = 0x00; /* UV Offset Adjustment Low */
279 table[KS_UGAIN] = 0x00; /* U Component Gain Adjustment */
280 table[KS_VGAIN] = 0x00; /* V Component Gain Adjustment */
281 table[KS_VAVB] = 0x07; /* VAV Begin */
282 table[KS_VAVE] = 0x00; /* VAV End */
283 table[KS_CTRACK] = 0x00; /* Chroma Tracking Control */
284 table[KS_POLCTL] = 0x41; /* Timing Signal Polarity Control */
285 table[KS_REFCOD] = 0x80; /* Reference Code Insertion Control */
286 table[KS_INVALY] = 0x10; /* Invalid Y Code */
287 table[KS_INVALU] = 0x80; /* Invalid U Code */
288 table[KS_INVALV] = 0x80; /* Invalid V Code */
289 table[KS_UNUSEY] = 0x10; /* Unused Y Code */
290 table[KS_UNUSEU] = 0x80; /* Unused U Code */
291 table[KS_UNUSEV] = 0x80; /* Unused V Code */
292 table[KS_USRSAV] = 0x00; /* reserved */
293 table[KS_USREAV] = 0x00; /* reserved */
294 table[KS_SHS1A] = 0x00; /* User Defined SHS1 A */
295 /* User Defined SHS1 B, ALT656=1 on 0127B */
296 table[KS_SHS1B] = 0x80;
297 table[KS_SHS1C] = 0x00; /* User Defined SHS1 C */
298 table[KS_CMDE] = 0x00; /* Command Register E */
299 table[KS_VSDEL] = 0x00; /* VS Delay Control */
300 /* Command Register F, update -immediately- */
301 /* (there might come no vsync)*/
302 table[KS_CMDF] = 0x02;
303}
304
305
306/* We need to manually read because of a bug in the KS0127 chip.
307 *
308 * An explanation from kayork@mail.utexas.edu:
309 *
310 * During I2C reads, the KS0127 only samples for a stop condition
311 * during the place where the acknoledge bit should be. Any standard
312 * I2C implementation (correctly) throws in another clock transition
313 * at the 9th bit, and the KS0127 will not recognize the stop condition
314 * and will continue to clock out data.
315 *
316 * So we have to do the read ourself. Big deal.
317 workaround in i2c-algo-bit
318 */
319
320
321static u8 ks0127_read(struct ks0127 *ks, u8 reg)
322{
323 struct i2c_client *c = ks->client;
324 char val = 0;
325 struct i2c_msg msgs[] = {
326 {c->addr, 0, sizeof(reg), &reg},
327 {c->addr, I2C_M_RD | I2C_M_NO_RD_ACK, sizeof(val), &val}};
328 int ret;
329
330 ret = i2c_transfer(c->adapter, msgs, ARRAY_SIZE(msgs));
331 if (ret != ARRAY_SIZE(msgs))
332 dprintk("ks0127_write error\n");
333
334 return val;
335}
336
337
338static void ks0127_write(struct ks0127 *ks, u8 reg, u8 val)
339{
340 char msg[] = {reg, val};
341
342 if (i2c_master_send(ks->client, msg, sizeof(msg)) != sizeof(msg))
343 dprintk("ks0127_write error\n");
344
345 ks->regs[reg] = val;
346}
347
348
349/* generic bit-twiddling */
350static void ks0127_and_or(struct ks0127 *ks, u8 reg, u8 and_v, u8 or_v)
351{
352 u8 val = ks->regs[reg];
353 val = (val & and_v) | or_v;
354 ks0127_write(ks, reg, val);
355}
356
357
358
359/****************************************************************************
360* ks0127 private api
361****************************************************************************/
362static void ks0127_reset(struct ks0127* ks)
363{
364 int i;
365 u8 *table = reg_defaults;
366
367 ks->ks_type = KS_TYPE_UNKNOWN;
368
369 dprintk("ks0127: reset\n");
370 msleep(1);
371
372 /* initialize all registers to known values */
373 /* (except STAT, 0x21, 0x22, TEST and 0x38,0x39) */
374
375 for(i = 1; i < 33; i++)
376 ks0127_write(ks, i, table[i]);
377
378 for(i = 35; i < 40; i++)
379 ks0127_write(ks, i, table[i]);
380
381 for(i = 41; i < 56; i++)
382 ks0127_write(ks, i, table[i]);
383
384 for(i = 58; i < 64; i++)
385 ks0127_write(ks, i, table[i]);
386
387
388 if ((ks0127_read(ks, KS_STAT) & 0x80) == 0) {
389 ks->ks_type = KS_TYPE_0122S;
390 dprintk("ks0127: ks0122s Found\n");
391 return;
392 }
393
394 switch(ks0127_read(ks, KS_CMDE) & 0x0f) {
395
396 case 0:
397 ks->ks_type = KS_TYPE_0127;
398 dprintk("ks0127: ks0127 found\n");
399 break;
400
401 case 9:
402 ks->ks_type = KS_TYPE_0127B;
403 dprintk("ks0127: ks0127B Revision A found\n");
404 break;
405
406 default:
407 dprintk("ks0127: unknown revision\n");
408 break;
409 }
410}
411
412static int ks0127_command(struct i2c_client *client,
413 unsigned int cmd, void *arg)
414{
415 struct ks0127 *ks = i2c_get_clientdata(client);
416
417 int *iarg = (int*)arg;
418
419 int status;
420
421 if (!ks)
422 return -ENODEV;
423
424 switch (cmd) {
425
426 case DECODER_INIT:
427 dprintk("ks0127: command DECODER_INIT\n");
428 ks0127_reset(ks);
429 break;
430
431 case DECODER_SET_INPUT:
432 switch(*iarg) {
433 case KS_INPUT_COMPOSITE_1:
434 case KS_INPUT_COMPOSITE_2:
435 case KS_INPUT_COMPOSITE_3:
436 case KS_INPUT_COMPOSITE_4:
437 case KS_INPUT_COMPOSITE_5:
438 case KS_INPUT_COMPOSITE_6:
439 dprintk("ks0127: command DECODER_SET_INPUT %d: "
440 "Composite\n", *iarg);
441 /* autodetect 50/60 Hz */
442 ks0127_and_or(ks, KS_CMDA, 0xfc, 0x00);
443 /* VSE=0 */
444 ks0127_and_or(ks, KS_CMDA, ~0x40, 0x00);
445 /* set input line */
446 ks0127_and_or(ks, KS_CMDB, 0xb0, *iarg);
447 /* non-freerunning mode */
448 ks0127_and_or(ks, KS_CMDC, 0x70, 0x0a);
449 /* analog input */
450 ks0127_and_or(ks, KS_CMDD, 0x03, 0x00);
451 /* enable chroma demodulation */
452 ks0127_and_or(ks, KS_CTRACK, 0xcf, 0x00);
453 /* chroma trap, HYBWR=1 */
454 ks0127_and_or(ks, KS_LUMA, 0x00,
455 (reg_defaults[KS_LUMA])|0x0c);
456 /* scaler fullbw, luma comb off */
457 ks0127_and_or(ks, KS_VERTIA, 0x08, 0x81);
458 /* manual chroma comb .25 .5 .25 */
459 ks0127_and_or(ks, KS_VERTIC, 0x0f, 0x90);
460
461 /* chroma path delay */
462 ks0127_and_or(ks, KS_CHROMB, 0x0f, 0x90);
463
464 ks0127_write(ks, KS_UGAIN, reg_defaults[KS_UGAIN]);
465 ks0127_write(ks, KS_VGAIN, reg_defaults[KS_VGAIN]);
466 ks0127_write(ks, KS_UVOFFH, reg_defaults[KS_UVOFFH]);
467 ks0127_write(ks, KS_UVOFFL, reg_defaults[KS_UVOFFL]);
468 break;
469
470 case KS_INPUT_SVIDEO_1:
471 case KS_INPUT_SVIDEO_2:
472 case KS_INPUT_SVIDEO_3:
473 dprintk("ks0127: command DECODER_SET_INPUT %d: "
474 "S-Video\n", *iarg);
475 /* autodetect 50/60 Hz */
476 ks0127_and_or(ks, KS_CMDA, 0xfc, 0x00);
477 /* VSE=0 */
478 ks0127_and_or(ks, KS_CMDA, ~0x40, 0x00);
479 /* set input line */
480 ks0127_and_or(ks, KS_CMDB, 0xb0, *iarg);
481 /* non-freerunning mode */
482 ks0127_and_or(ks, KS_CMDC, 0x70, 0x0a);
483 /* analog input */
484 ks0127_and_or(ks, KS_CMDD, 0x03, 0x00);
485 /* enable chroma demodulation */
486 ks0127_and_or(ks, KS_CTRACK, 0xcf, 0x00);
487 ks0127_and_or(ks, KS_LUMA, 0x00,
488 reg_defaults[KS_LUMA]);
489 /* disable luma comb */
490 ks0127_and_or(ks, KS_VERTIA, 0x08,
491 (reg_defaults[KS_VERTIA]&0xf0)|0x01);
492 ks0127_and_or(ks, KS_VERTIC, 0x0f,
493 reg_defaults[KS_VERTIC]&0xf0);
494
495 ks0127_and_or(ks, KS_CHROMB, 0x0f,
496 reg_defaults[KS_CHROMB]&0xf0);
497
498 ks0127_write(ks, KS_UGAIN, reg_defaults[KS_UGAIN]);
499 ks0127_write(ks, KS_VGAIN, reg_defaults[KS_VGAIN]);
500 ks0127_write(ks, KS_UVOFFH, reg_defaults[KS_UVOFFH]);
501 ks0127_write(ks, KS_UVOFFL, reg_defaults[KS_UVOFFL]);
502 break;
503
504 case KS_INPUT_YUV656:
505 dprintk("ks0127: command DECODER_SET_INPUT 15: "
506 "YUV656\n");
507 if (ks->norm == VIDEO_MODE_NTSC ||
508 ks->norm == KS_STD_PAL_M)
509 /* force 60 Hz */
510 ks0127_and_or(ks, KS_CMDA, 0xfc, 0x03);
511 else
512 /* force 50 Hz */
513 ks0127_and_or(ks, KS_CMDA, 0xfc, 0x02);
514
515 ks0127_and_or(ks, KS_CMDA, 0xff, 0x40); /* VSE=1 */
516 /* set input line and VALIGN */
517 ks0127_and_or(ks, KS_CMDB, 0xb0, (*iarg | 0x40));
518 /* freerunning mode, */
519 /* TSTGEN = 1 TSTGFR=11 TSTGPH=0 TSTGPK=0 VMEM=1*/
520 ks0127_and_or(ks, KS_CMDC, 0x70, 0x87);
521 /* digital input, SYNDIR = 0 INPSL=01 CLKDIR=0 EAV=0 */
522 ks0127_and_or(ks, KS_CMDD, 0x03, 0x08);
523 /* disable chroma demodulation */
524 ks0127_and_or(ks, KS_CTRACK, 0xcf, 0x30);
525 /* HYPK =01 CTRAP = 0 HYBWR=0 PED=1 RGBH=1 UNIT=1 */
526 ks0127_and_or(ks, KS_LUMA, 0x00, 0x71);
527 ks0127_and_or(ks, KS_VERTIC, 0x0f,
528 reg_defaults[KS_VERTIC]&0xf0);
529
530 /* scaler fullbw, luma comb off */
531 ks0127_and_or(ks, KS_VERTIA, 0x08, 0x81);
532
533 ks0127_and_or(ks, KS_CHROMB, 0x0f,
534 reg_defaults[KS_CHROMB]&0xf0);
535
536 ks0127_and_or(ks, KS_CON, 0x00, 0x00);
537 ks0127_and_or(ks, KS_BRT, 0x00, 32); /* spec: 34 */
538 /* spec: 229 (e5) */
539 ks0127_and_or(ks, KS_SAT, 0x00, 0xe8);
540 ks0127_and_or(ks, KS_HUE, 0x00, 0);
541
542 ks0127_and_or(ks, KS_UGAIN, 0x00, 238);
543 ks0127_and_or(ks, KS_VGAIN, 0x00, 0x00);
544
545 /*UOFF:0x30, VOFF:0x30, TSTCGN=1 */
546 ks0127_and_or(ks, KS_UVOFFH, 0x00, 0x4f);
547 ks0127_and_or(ks, KS_UVOFFL, 0x00, 0x00);
548 break;
549
550 default:
551 dprintk("ks0127: command DECODER_SET_INPUT: "
552 "Unknown input %d\n", *iarg);
553 break;
554 }
555
556 /* hack: CDMLPF sometimes spontaneously switches on; */
557 /* force back off */
558 ks0127_write(ks, KS_DEMOD, reg_defaults[KS_DEMOD]);
559 break;
560
561 case DECODER_SET_OUTPUT:
562 switch(*iarg) {
563 case KS_OUTPUT_YUV656E:
564 dprintk("ks0127: command DECODER_SET_OUTPUT: "
565 "OUTPUT_YUV656E (Missing)\n");
566 return -EINVAL;
567 break;
568
569 case KS_OUTPUT_EXV:
570 dprintk("ks0127: command DECODER_SET_OUTPUT: "
571 "OUTPUT_EXV\n");
572 ks0127_and_or(ks, KS_OFMTA, 0xf0, 0x09);
573 break;
574 }
575 break;
576
577 case DECODER_SET_NORM: //sam This block mixes old and new norm names...
578 /* Set to automatic SECAM/Fsc mode */
579 ks0127_and_or(ks, KS_DEMOD, 0xf0, 0x00);
580
581 ks->norm = *iarg;
582 switch(*iarg)
583 {
584 /* this is untested !! */
585 /* It just detects PAL_N/NTSC_M (no special frequencies) */
586 /* And you have to set the standard a second time afterwards */
587 case VIDEO_MODE_AUTO:
588 dprintk("ks0127: command DECODER_SET_NORM: AUTO\n");
589
590 /* The chip determines the format */
591 /* based on the current field rate */
592 ks0127_and_or(ks, KS_CMDA, 0xfc, 0x00);
593 ks0127_and_or(ks, KS_CHROMA, 0x9f, 0x20);
594 /* This is wrong for PAL ! As I said, */
595 /* you need to set the standard once again !! */
596 ks->format_height = 240;
597 ks->format_width = 704;
598 break;
599
600 case VIDEO_MODE_NTSC:
601 dprintk("ks0127: command DECODER_SET_NORM: NTSC_M\n");
602 ks0127_and_or(ks, KS_CHROMA, 0x9f, 0x20);
603 ks->format_height = 240;
604 ks->format_width = 704;
605 break;
606
607 case KS_STD_NTSC_N:
608 dprintk("ks0127: command KS0127_SET_STANDARD: "
609 "NTSC_N (fixme)\n");
610 ks0127_and_or(ks, KS_CHROMA, 0x9f, 0x40);
611 ks->format_height = 240;
612 ks->format_width = 704;
613 break;
614
615 case VIDEO_MODE_PAL:
616 dprintk("ks0127: command DECODER_SET_NORM: PAL_N\n");
617 ks0127_and_or(ks, KS_CHROMA, 0x9f, 0x20);
618 ks->format_height = 290;
619 ks->format_width = 704;
620 break;
621
622 case KS_STD_PAL_M:
623 dprintk("ks0127: command KS0127_SET_STANDARD: "
624 "PAL_M (fixme)\n");
625 ks0127_and_or(ks, KS_CHROMA, 0x9f, 0x40);
626 ks->format_height = 290;
627 ks->format_width = 704;
628 break;
629
630 case VIDEO_MODE_SECAM:
631 dprintk("ks0127: command KS0127_SET_STANDARD: "
632 "SECAM\n");
633 ks->format_height = 290;
634 ks->format_width = 704;
635
636 /* set to secam autodetection */
637 ks0127_and_or(ks, KS_CHROMA, 0xdf, 0x20);
638 ks0127_and_or(ks, KS_DEMOD, 0xf0, 0x00);
639 schedule_timeout_interruptible(HZ/10+1);
640
641 /* did it autodetect? */
642 if (ks0127_read(ks, KS_DEMOD) & 0x40)
643 break;
644
645 /* force to secam mode */
646 ks0127_and_or(ks, KS_DEMOD, 0xf0, 0x0f);
647 break;
648
649 default:
650 dprintk("ks0127: command DECODER_SET_NORM: "
651 "Unknown norm %d\n", *iarg);
652 break;
653 }
654 break;
655
656 case DECODER_SET_PICTURE:
657 dprintk("ks0127: command DECODER_SET_PICTURE "
658 "not yet supported (fixme)\n");
659 return -EINVAL;
660
661 //sam todo: KS0127_SET_BRIGHTNESS: Merge into DECODER_SET_PICTURE
662 //sam todo: KS0127_SET_CONTRAST: Merge into DECODER_SET_PICTURE
663 //sam todo: KS0127_SET_HUE: Merge into DECODER_SET_PICTURE?
664 //sam todo: KS0127_SET_SATURATION: Merge into DECODER_SET_PICTURE
665 //sam todo: KS0127_SET_AGC_MODE:
666 //sam todo: KS0127_SET_AGC:
667 //sam todo: KS0127_SET_CHROMA_MODE:
668 //sam todo: KS0127_SET_PIXCLK_MODE:
669 //sam todo: KS0127_SET_GAMMA_MODE:
670 //sam todo: KS0127_SET_UGAIN:
671 //sam todo: KS0127_SET_VGAIN:
672 //sam todo: KS0127_SET_INVALY:
673 //sam todo: KS0127_SET_INVALU:
674 //sam todo: KS0127_SET_INVALV:
675 //sam todo: KS0127_SET_UNUSEY:
676 //sam todo: KS0127_SET_UNUSEU:
677 //sam todo: KS0127_SET_UNUSEV:
678 //sam todo: KS0127_SET_VSALIGN_MODE:
679
680 case DECODER_ENABLE_OUTPUT:
681 {
682
683 int *iarg = arg;
684 int enable = (*iarg != 0);
685 if (enable) {
686 dprintk("ks0127: command "
687 "DECODER_ENABLE_OUTPUT on "
688 "(%d)\n", enable);
689 /* All output pins on */
690 ks0127_and_or(ks, KS_OFMTA, 0xcf, 0x30);
691 /* Obey the OEN pin */
692 ks0127_and_or(ks, KS_CDEM, 0x7f, 0x00);
693 } else {
694 dprintk("ks0127: command "
695 "DECODER_ENABLE_OUTPUT off "
696 "(%d)\n", enable);
697 /* Video output pins off */
698 ks0127_and_or(ks, KS_OFMTA, 0xcf, 0x00);
699 /* Ignore the OEN pin */
700 ks0127_and_or(ks, KS_CDEM, 0x7f, 0x80);
701 }
702 }
703 break;
704
705 //sam todo: KS0127_SET_OUTPUT_MODE:
706 //sam todo: KS0127_SET_WIDTH:
707 //sam todo: KS0127_SET_HEIGHT:
708 //sam todo: KS0127_SET_HSCALE:
709
710 case DECODER_GET_STATUS:
711 dprintk("ks0127: command DECODER_GET_STATUS\n");
712 *iarg = 0;
713 status = ks0127_read(ks, KS_STAT);
714 if (!(status & 0x20)) /* NOVID not set */
715 *iarg = (*iarg & DECODER_STATUS_GOOD);
716 if ((status & 0x01)) /* CLOCK set */
717 *iarg = (*iarg & DECODER_STATUS_COLOR);
718 if ((status & 0x08)) /* PALDET set */
719 *iarg = (*iarg & DECODER_STATUS_PAL);
720 else
721 *iarg = (*iarg & DECODER_STATUS_NTSC);
722 break;
723
724 //Catch any unknown command
725 default:
726 dprintk("ks0127: command unknown: %04X\n", cmd);
727 return -EINVAL;
728 }
729 return 0;
730}
731
732
733
734
735static int ks0127_probe(struct i2c_adapter *adapter);
736static int ks0127_detach(struct i2c_client *client);
737static int ks0127_command(struct i2c_client *client,
738 unsigned int cmd, void *arg);
739
740
741
742/* Addresses to scan */
743static unsigned short normal_i2c[] = {I2C_KS0127_ADDON>>1,
744 I2C_KS0127_ONBOARD>>1, I2C_CLIENT_END};
745static unsigned short probe[2] = {I2C_CLIENT_END, I2C_CLIENT_END};
746static unsigned short ignore[2] = {I2C_CLIENT_END, I2C_CLIENT_END};
747static struct i2c_client_address_data addr_data = {
748 normal_i2c,
749 probe,
750 ignore,
751};
752
753static struct i2c_driver i2c_driver_ks0127 = {
754 .driver.name = "ks0127",
755 .id = I2C_DRIVERID_KS0127,
756 .attach_adapter = ks0127_probe,
757 .detach_client = ks0127_detach,
758 .command = ks0127_command
759};
760
761static struct i2c_client ks0127_client_tmpl =
762{
763 .name = "(ks0127 unset)",
764 .addr = 0,
765 .adapter = NULL,
766 .driver = &i2c_driver_ks0127,
767 .usage_count = 0
768};
769
770static int ks0127_found_proc(struct i2c_adapter *adapter, int addr, int kind)
771{
772 struct ks0127 *ks;
773 struct i2c_client *client;
774
775 client = kzalloc(sizeof(*client), GFP_KERNEL);
776 if (client == NULL)
777 return -ENOMEM;
778 memcpy(client, &ks0127_client_tmpl, sizeof(*client));
779
780 ks = kzalloc(sizeof(*ks), GFP_KERNEL);
781 if (ks == NULL) {
782 kfree(client);
783 return -ENOMEM;
784 }
785
786 i2c_set_clientdata(client, ks);
787 client->adapter = adapter;
788 client->addr = addr;
789 sprintf(client->name, "ks0127-%02x", adapter->id);
790
791 ks->client = client;
792 ks->addr = addr;
793 ks->ks_type = KS_TYPE_UNKNOWN;
794
795 /* power up */
796 ks0127_write(ks, KS_CMDA, 0x2c);
797 mdelay(10);
798
799 /* reset the device */
800 ks0127_reset(ks);
801 printk(KERN_INFO "ks0127: attach: %s video decoder\n",
802 ks->addr==(I2C_KS0127_ADDON>>1) ? "addon" : "on-board");
803
804 i2c_attach_client(client);
805 return 0;
806}
807
808
809static int ks0127_probe(struct i2c_adapter *adapter)
810{
811 if (adapter->id == I2C_HW_B_ZR36067)
812 return i2c_probe(adapter, &addr_data, ks0127_found_proc);
813 return 0;
814}
815
816static int ks0127_detach(struct i2c_client *client)
817{
818 struct ks0127 *ks = i2c_get_clientdata(client);
819
820 ks0127_write(ks, KS_OFMTA, 0x20); /*tristate*/
821 ks0127_write(ks, KS_CMDA, 0x2c | 0x80); /* power down */
822
823 i2c_detach_client(client);
824 kfree(ks);
825 kfree(client);
826
827 dprintk("ks0127: detach\n");
828 return 0;
829}
830
831
832static int __devinit ks0127_init_module(void)
833{
834 init_reg_defaults();
835 i2c_add_driver(&i2c_driver_ks0127);
836 return 0;
837}
838
839static void __devexit ks0127_cleanup_module(void)
840{
841 i2c_del_driver(&i2c_driver_ks0127);
842}
843
844
845module_init(ks0127_init_module);
846module_exit(ks0127_cleanup_module);
diff --git a/drivers/media/video/ks0127.h b/drivers/media/video/ks0127.h
new file mode 100644
index 00000000000..1ec578833ae
--- /dev/null
+++ b/drivers/media/video/ks0127.h
@@ -0,0 +1,53 @@
1/*
2 * Video Capture Driver ( Video for Linux 1/2 )
3 * for the Matrox Marvel G200,G400 and Rainbow Runner-G series
4 *
5 * This module is an interface to the KS0127 video decoder chip.
6 *
7 * Copyright (C) 1999 Ryan Drake <stiletto@mediaone.net>
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 */
23
24#ifndef KS0127_H
25#define KS0127_H
26
27#include <linux/videodev.h>
28
29/* input channels */
30#define KS_INPUT_COMPOSITE_1 0
31#define KS_INPUT_COMPOSITE_2 1
32#define KS_INPUT_COMPOSITE_3 2
33#define KS_INPUT_COMPOSITE_4 4
34#define KS_INPUT_COMPOSITE_5 5
35#define KS_INPUT_COMPOSITE_6 6
36
37#define KS_INPUT_SVIDEO_1 8
38#define KS_INPUT_SVIDEO_2 9
39#define KS_INPUT_SVIDEO_3 10
40
41#define KS_INPUT_YUV656 15
42#define KS_INPUT_COUNT 10
43
44/* output channels */
45#define KS_OUTPUT_YUV656E 0
46#define KS_OUTPUT_EXV 1
47
48/* video standards */
49#define KS_STD_NTSC_N 112 /* 50 Hz NTSC */
50#define KS_STD_PAL_M 113 /* 60 Hz PAL */
51
52#endif /* KS0127_H */
53
diff --git a/drivers/media/video/meye.c b/drivers/media/video/meye.c
index 850bee97090..f68ca7d9f53 100644
--- a/drivers/media/video/meye.c
+++ b/drivers/media/video/meye.c
@@ -32,6 +32,7 @@
32#include <linux/sched.h> 32#include <linux/sched.h>
33#include <linux/init.h> 33#include <linux/init.h>
34#include <linux/videodev.h> 34#include <linux/videodev.h>
35#include <media/v4l2-common.h>
35#include <asm/uaccess.h> 36#include <asm/uaccess.h>
36#include <asm/io.h> 37#include <asm/io.h>
37#include <linux/delay.h> 38#include <linux/delay.h>
@@ -1682,13 +1683,13 @@ static unsigned int meye_poll(struct file *file, poll_table *wait)
1682 1683
1683static void meye_vm_open(struct vm_area_struct *vma) 1684static void meye_vm_open(struct vm_area_struct *vma)
1684{ 1685{
1685 int idx = (int)vma->vm_private_data; 1686 long idx = (long)vma->vm_private_data;
1686 meye.vma_use_count[idx]++; 1687 meye.vma_use_count[idx]++;
1687} 1688}
1688 1689
1689static void meye_vm_close(struct vm_area_struct *vma) 1690static void meye_vm_close(struct vm_area_struct *vma)
1690{ 1691{
1691 int idx = (int)vma->vm_private_data; 1692 long idx = (long)vma->vm_private_data;
1692 meye.vma_use_count[idx]--; 1693 meye.vma_use_count[idx]--;
1693} 1694}
1694 1695
diff --git a/drivers/media/video/msp3400-driver.c b/drivers/media/video/msp3400-driver.c
index b806999d6e0..dbb75a7db19 100644
--- a/drivers/media/video/msp3400-driver.c
+++ b/drivers/media/video/msp3400-driver.c
@@ -385,67 +385,6 @@ static int msp_mode_v4l1_to_v4l2(int mode)
385 return V4L2_TUNER_MODE_MONO; 385 return V4L2_TUNER_MODE_MONO;
386} 386}
387 387
388static struct v4l2_queryctrl msp_qctrl_std[] = {
389 {
390 .id = V4L2_CID_AUDIO_VOLUME,
391 .name = "Volume",
392 .minimum = 0,
393 .maximum = 65535,
394 .step = 65535/100,
395 .default_value = 58880,
396 .flags = 0,
397 .type = V4L2_CTRL_TYPE_INTEGER,
398 },{
399 .id = V4L2_CID_AUDIO_MUTE,
400 .name = "Mute",
401 .minimum = 0,
402 .maximum = 1,
403 .step = 1,
404 .default_value = 1,
405 .flags = 0,
406 .type = V4L2_CTRL_TYPE_BOOLEAN,
407 },
408};
409
410static struct v4l2_queryctrl msp_qctrl_sound_processing[] = {
411 {
412 .id = V4L2_CID_AUDIO_BALANCE,
413 .name = "Balance",
414 .minimum = 0,
415 .maximum = 65535,
416 .step = 65535/100,
417 .default_value = 32768,
418 .flags = 0,
419 .type = V4L2_CTRL_TYPE_INTEGER,
420 },{
421 .id = V4L2_CID_AUDIO_BASS,
422 .name = "Bass",
423 .minimum = 0,
424 .maximum = 65535,
425 .step = 65535/100,
426 .default_value = 32768,
427 .type = V4L2_CTRL_TYPE_INTEGER,
428 },{
429 .id = V4L2_CID_AUDIO_TREBLE,
430 .name = "Treble",
431 .minimum = 0,
432 .maximum = 65535,
433 .step = 65535/100,
434 .default_value = 32768,
435 .type = V4L2_CTRL_TYPE_INTEGER,
436 },{
437 .id = V4L2_CID_AUDIO_LOUDNESS,
438 .name = "Loudness",
439 .minimum = 0,
440 .maximum = 1,
441 .step = 1,
442 .default_value = 1,
443 .flags = 0,
444 .type = V4L2_CTRL_TYPE_BOOLEAN,
445 },
446};
447
448
449static int msp_get_ctrl(struct i2c_client *client, struct v4l2_control *ctrl) 388static int msp_get_ctrl(struct i2c_client *client, struct v4l2_control *ctrl)
450{ 389{
451 struct msp_state *state = i2c_get_clientdata(client); 390 struct msp_state *state = i2c_get_clientdata(client);
@@ -674,22 +613,31 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
674 int sc1_out = rt->output & 0xf; 613 int sc1_out = rt->output & 0xf;
675 int sc2_out = (rt->output >> 4) & 0xf; 614 int sc2_out = (rt->output >> 4) & 0xf;
676 u16 val, reg; 615 u16 val, reg;
616 int i;
617 int extern_input = 1;
677 618
678 if (state->routing.input == rt->input && 619 if (state->routing.input == rt->input &&
679 state->routing.output == rt->output) 620 state->routing.output == rt->output)
680 break; 621 break;
681 state->routing = *rt; 622 state->routing = *rt;
623 /* check if the tuner input is used */
624 for (i = 0; i < 5; i++) {
625 if (((rt->input >> (4 + i * 4)) & 0xf) == 0)
626 extern_input = 0;
627 }
628 if (extern_input)
629 state->mode = MSP_MODE_EXTERN;
630 else
631 state->mode = MSP_MODE_AM_DETECT;
682 msp_set_scart(client, sc_in, 0); 632 msp_set_scart(client, sc_in, 0);
683 msp_set_scart(client, sc1_out, 1); 633 msp_set_scart(client, sc1_out, 1);
684 msp_set_scart(client, sc2_out, 2); 634 msp_set_scart(client, sc2_out, 2);
685 msp_set_audmode(client); 635 msp_set_audmode(client);
686 reg = (state->opmode == OPMODE_AUTOSELECT) ? 0x30 : 0xbb; 636 reg = (state->opmode == OPMODE_AUTOSELECT) ? 0x30 : 0xbb;
687 val = msp_read_dem(client, reg); 637 val = msp_read_dem(client, reg);
688 if (tuner != ((val >> 8) & 1)) { 638 msp_write_dem(client, reg, (val & ~0x100) | (tuner << 8));
689 msp_write_dem(client, reg, (val & ~0x100) | (tuner << 8)); 639 /* wake thread when a new input is chosen */
690 /* wake thread when a new tuner input is chosen */ 640 msp_wake_thread(client);
691 msp_wake_thread(client);
692 }
693 break; 641 break;
694 } 642 }
695 643
@@ -744,21 +692,25 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
744 case VIDIOC_QUERYCTRL: 692 case VIDIOC_QUERYCTRL:
745 { 693 {
746 struct v4l2_queryctrl *qc = arg; 694 struct v4l2_queryctrl *qc = arg;
747 int i;
748 695
749 for (i = 0; i < ARRAY_SIZE(msp_qctrl_std); i++) 696 switch (qc->id) {
750 if (qc->id && qc->id == msp_qctrl_std[i].id) { 697 case V4L2_CID_AUDIO_VOLUME:
751 memcpy(qc, &msp_qctrl_std[i], sizeof(*qc)); 698 case V4L2_CID_AUDIO_MUTE:
752 return 0; 699 return v4l2_ctrl_query_fill_std(qc);
753 } 700 default:
701 break;
702 }
754 if (!state->has_sound_processing) 703 if (!state->has_sound_processing)
755 return -EINVAL; 704 return -EINVAL;
756 for (i = 0; i < ARRAY_SIZE(msp_qctrl_sound_processing); i++) 705 switch (qc->id) {
757 if (qc->id && qc->id == msp_qctrl_sound_processing[i].id) { 706 case V4L2_CID_AUDIO_LOUDNESS:
758 memcpy(qc, &msp_qctrl_sound_processing[i], sizeof(*qc)); 707 case V4L2_CID_AUDIO_BALANCE:
759 return 0; 708 case V4L2_CID_AUDIO_BASS:
760 } 709 case V4L2_CID_AUDIO_TREBLE:
761 return -EINVAL; 710 return v4l2_ctrl_query_fill_std(qc);
711 default:
712 return -EINVAL;
713 }
762 } 714 }
763 715
764 case VIDIOC_G_CTRL: 716 case VIDIOC_G_CTRL:
@@ -794,7 +746,9 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
794 case MSP_MODE_EXTERN: p = "External input"; break; 746 case MSP_MODE_EXTERN: p = "External input"; break;
795 default: p = "unknown"; break; 747 default: p = "unknown"; break;
796 } 748 }
797 if (state->opmode == OPMODE_MANUAL) { 749 if (state->mode == MSP_MODE_EXTERN) {
750 v4l_info(client, "Mode: %s\n", p);
751 } else if (state->opmode == OPMODE_MANUAL) {
798 v4l_info(client, "Mode: %s (%s%s)\n", p, 752 v4l_info(client, "Mode: %s (%s%s)\n", p,
799 (state->rxsubchans & V4L2_TUNER_SUB_STEREO) ? "stereo" : "mono", 753 (state->rxsubchans & V4L2_TUNER_SUB_STEREO) ? "stereo" : "mono",
800 (state->rxsubchans & V4L2_TUNER_SUB_LANG2) ? ", dual" : ""); 754 (state->rxsubchans & V4L2_TUNER_SUB_LANG2) ? ", dual" : "");
diff --git a/drivers/media/video/msp3400-kthreads.c b/drivers/media/video/msp3400-kthreads.c
index 633a1021378..f2fd9195b3a 100644
--- a/drivers/media/video/msp3400-kthreads.c
+++ b/drivers/media/video/msp3400-kthreads.c
@@ -244,19 +244,21 @@ static void msp3400c_set_audmode(struct i2c_client *client)
244 the hardware does not support SAP. So the rxsubchans combination 244 the hardware does not support SAP. So the rxsubchans combination
245 of STEREO | LANG2 does not occur. */ 245 of STEREO | LANG2 does not occur. */
246 246
247 /* switch to mono if only mono is available */ 247 if (state->mode != MSP_MODE_EXTERN) {
248 if (state->rxsubchans == V4L2_TUNER_SUB_MONO) 248 /* switch to mono if only mono is available */
249 audmode = V4L2_TUNER_MODE_MONO; 249 if (state->rxsubchans == V4L2_TUNER_SUB_MONO)
250 /* if bilingual */ 250 audmode = V4L2_TUNER_MODE_MONO;
251 else if (state->rxsubchans & V4L2_TUNER_SUB_LANG2) { 251 /* if bilingual */
252 /* and mono or stereo, then fallback to lang1 */ 252 else if (state->rxsubchans & V4L2_TUNER_SUB_LANG2) {
253 if (audmode == V4L2_TUNER_MODE_MONO || 253 /* and mono or stereo, then fallback to lang1 */
254 audmode == V4L2_TUNER_MODE_STEREO) 254 if (audmode == V4L2_TUNER_MODE_MONO ||
255 audmode = V4L2_TUNER_MODE_LANG1; 255 audmode == V4L2_TUNER_MODE_STEREO)
256 audmode = V4L2_TUNER_MODE_LANG1;
257 }
258 /* if stereo, and audmode is not mono, then switch to stereo */
259 else if (audmode != V4L2_TUNER_MODE_MONO)
260 audmode = V4L2_TUNER_MODE_STEREO;
256 } 261 }
257 /* if stereo, and audmode is not mono, then switch to stereo */
258 else if (audmode != V4L2_TUNER_MODE_MONO)
259 audmode = V4L2_TUNER_MODE_STEREO;
260 262
261 /* switch demodulator */ 263 /* switch demodulator */
262 switch (state->mode) { 264 switch (state->mode) {
@@ -481,6 +483,7 @@ int msp3400c_thread(void *data)
481 /* no carrier scan, just unmute */ 483 /* no carrier scan, just unmute */
482 v4l_dbg(1, msp_debug, client, "thread: no carrier scan\n"); 484 v4l_dbg(1, msp_debug, client, "thread: no carrier scan\n");
483 state->scan_in_progress = 0; 485 state->scan_in_progress = 0;
486 state->rxsubchans = V4L2_TUNER_SUB_STEREO;
484 msp_set_audio(client); 487 msp_set_audio(client);
485 continue; 488 continue;
486 } 489 }
@@ -947,6 +950,14 @@ int msp34xxg_thread(void *data)
947 if (kthread_should_stop()) 950 if (kthread_should_stop())
948 break; 951 break;
949 952
953 if (state->mode == MSP_MODE_EXTERN) {
954 /* no carrier scan needed, just unmute */
955 v4l_dbg(1, msp_debug, client, "thread: no carrier scan\n");
956 state->scan_in_progress = 0;
957 msp_set_audio(client);
958 continue;
959 }
960
950 /* setup the chip*/ 961 /* setup the chip*/
951 msp34xxg_reset(client); 962 msp34xxg_reset(client);
952 state->std = state->radio ? 0x40 : msp_standard; 963 state->std = state->radio ? 0x40 : msp_standard;
@@ -978,6 +989,11 @@ int msp34xxg_thread(void *data)
978 v4l_dbg(1, msp_debug, client, "detected standard: %s (0x%04x)\n", 989 v4l_dbg(1, msp_debug, client, "detected standard: %s (0x%04x)\n",
979 msp_standard_std_name(state->std), state->std); 990 msp_standard_std_name(state->std), state->std);
980 991
992 if (state->std == 9) {
993 /* AM NICAM mode */
994 msp_write_dsp(client, 0x0e, 0x7c00);
995 }
996
981 /* unmute: dispatch sound to scart output, set scart volume */ 997 /* unmute: dispatch sound to scart output, set scart volume */
982 msp_set_audio(client); 998 msp_set_audio(client);
983 999
diff --git a/drivers/media/video/ov511.c b/drivers/media/video/ov511.c
index fdc8e3f1393..a988df226aa 100644
--- a/drivers/media/video/ov511.c
+++ b/drivers/media/video/ov511.c
@@ -3239,7 +3239,7 @@ ov511_move_data(struct usb_ov511 *ov, unsigned char *in, int n)
3239 RESTRICT_TO_RANGE(frame->bytes_recvd, 8, max_raw); 3239 RESTRICT_TO_RANGE(frame->bytes_recvd, 8, max_raw);
3240 3240
3241 if (frame->scanstate == STATE_LINES) { 3241 if (frame->scanstate == STATE_LINES) {
3242 int nextf; 3242 int nextf;
3243 3243
3244 frame->grabstate = FRAME_DONE; 3244 frame->grabstate = FRAME_DONE;
3245 wake_up_interruptible(&frame->wq); 3245 wake_up_interruptible(&frame->wq);
@@ -3405,7 +3405,7 @@ eof:
3405 RESTRICT_TO_RANGE(frame->bytes_recvd, 8, max_raw); 3405 RESTRICT_TO_RANGE(frame->bytes_recvd, 8, max_raw);
3406 3406
3407 if (frame->scanstate == STATE_LINES) { 3407 if (frame->scanstate == STATE_LINES) {
3408 int nextf; 3408 int nextf;
3409 3409
3410 frame->grabstate = FRAME_DONE; 3410 frame->grabstate = FRAME_DONE;
3411 wake_up_interruptible(&frame->wq); 3411 wake_up_interruptible(&frame->wq);
diff --git a/drivers/media/video/ov511.h b/drivers/media/video/ov511.h
index 12b3d51e1c3..68b082bcee1 100644
--- a/drivers/media/video/ov511.h
+++ b/drivers/media/video/ov511.h
@@ -3,6 +3,7 @@
3 3
4#include <asm/uaccess.h> 4#include <asm/uaccess.h>
5#include <linux/videodev.h> 5#include <linux/videodev.h>
6#include <media/v4l2-common.h>
6#include <linux/smp_lock.h> 7#include <linux/smp_lock.h>
7#include <linux/usb.h> 8#include <linux/usb.h>
8#include <linux/mutex.h> 9#include <linux/mutex.h>
diff --git a/drivers/media/video/planb.c b/drivers/media/video/planb.c
index d9e3cada52f..3484e36b680 100644
--- a/drivers/media/video/planb.c
+++ b/drivers/media/video/planb.c
@@ -40,6 +40,7 @@
40#include <linux/mm.h> 40#include <linux/mm.h>
41#include <linux/sched.h> 41#include <linux/sched.h>
42#include <linux/videodev.h> 42#include <linux/videodev.h>
43#include <media/v4l2-common.h>
43#include <linux/wait.h> 44#include <linux/wait.h>
44#include <asm/uaccess.h> 45#include <asm/uaccess.h>
45#include <asm/io.h> 46#include <asm/io.h>
diff --git a/drivers/media/video/pms.c b/drivers/media/video/pms.c
index 09835ca098b..5d681fa8bcb 100644
--- a/drivers/media/video/pms.c
+++ b/drivers/media/video/pms.c
@@ -30,6 +30,7 @@
30#include <asm/io.h> 30#include <asm/io.h>
31#include <linux/sched.h> 31#include <linux/sched.h>
32#include <linux/videodev.h> 32#include <linux/videodev.h>
33#include <media/v4l2-common.h>
33#include <linux/mutex.h> 34#include <linux/mutex.h>
34 35
35#include <asm/uaccess.h> 36#include <asm/uaccess.h>
@@ -804,7 +805,7 @@ static int pms_do_ioctl(struct inode *inode, struct file *file,
804 struct video_picture *p = arg; 805 struct video_picture *p = arg;
805 if(!((p->palette==VIDEO_PALETTE_RGB565 && p->depth==16) 806 if(!((p->palette==VIDEO_PALETTE_RGB565 && p->depth==16)
806 ||(p->palette==VIDEO_PALETTE_RGB555 && p->depth==15))) 807 ||(p->palette==VIDEO_PALETTE_RGB555 && p->depth==15)))
807 return -EINVAL; 808 return -EINVAL;
808 pd->picture= *p; 809 pd->picture= *p;
809 810
810 /* 811 /*
diff --git a/drivers/media/video/pwc/Kconfig b/drivers/media/video/pwc/Kconfig
index 53cbc950f95..697145e0bf1 100644
--- a/drivers/media/video/pwc/Kconfig
+++ b/drivers/media/video/pwc/Kconfig
@@ -7,6 +7,7 @@ config USB_PWC
7 * Philips PCA645, PCA646 7 * Philips PCA645, PCA646
8 * Philips PCVC675, PCVC680, PCVC690 8 * Philips PCVC675, PCVC680, PCVC690
9 * Philips PCVC720/40, PCVC730, PCVC740, PCVC750 9 * Philips PCVC720/40, PCVC730, PCVC740, PCVC750
10 * Philips SPC900NC
10 * Askey VC010 11 * Askey VC010
11 * Logitech QuickCam Pro 3000, 4000, 'Zoom', 'Notebook Pro' 12 * Logitech QuickCam Pro 3000, 4000, 'Zoom', 'Notebook Pro'
12 and 'Orbit'/'Sphere' 13 and 'Orbit'/'Sphere'
@@ -19,10 +20,18 @@ config USB_PWC
19 and never will be, but the 665 and 720/20 are supported by other 20 and never will be, but the 665 and 720/20 are supported by other
20 drivers. 21 drivers.
21 22
22 See <file:Documentation/usb/philips.txt> for more information and 23 Some newer logitech webcams are not handled by this driver but by the
23 installation instructions. 24 Usb Video Class driver (linux-uvc).
24 25
25 The built-in microphone is enabled by selecting USB Audio support. 26 The built-in microphone is enabled by selecting USB Audio support.
26 27
27 To compile this driver as a module, choose M here: the 28 To compile this driver as a module, choose M here: the
28 module will be called pwc. 29 module will be called pwc.
30
31config USB_PWC_DEBUG
32 bool "USB Philips Cameras verbose debug"
33 depends USB_PWC
34 help
35 Say Y here in order to have the pwc driver generate verbose debugging
36 messages.
37 A special module options 'trace' is used to control the verbosity.
diff --git a/drivers/media/video/pwc/Makefile b/drivers/media/video/pwc/Makefile
index 33d60126c02..9db2260d10c 100644
--- a/drivers/media/video/pwc/Makefile
+++ b/drivers/media/video/pwc/Makefile
@@ -1,3 +1,12 @@
1pwc-objs := pwc-if.o pwc-misc.o pwc-ctrl.o pwc-uncompress.o pwc-timon.o pwc-kiara.o 1pwc-objs := pwc-if.o pwc-misc.o pwc-ctrl.o pwc-v4l.o pwc-uncompress.o
2pwc-objs += pwc-dec1.o pwc-dec23.o pwc-kiara.o pwc-timon.o
2 3
3obj-$(CONFIG_USB_PWC) += pwc.o 4obj-$(CONFIG_USB_PWC) += pwc.o
5
6ifeq ($(CONFIG_USB_PWC_DEBUG),y)
7EXTRA_CFLAGS += -DCONFIG_PWC_DEBUG=1
8else
9EXTRA_CFLAGS += -DCONFIG_PWC_DEBUG=0
10endif
11
12
diff --git a/drivers/media/video/pwc/pwc-ctrl.c b/drivers/media/video/pwc/pwc-ctrl.c
index 4ba549bfa0e..0bd115588f3 100644
--- a/drivers/media/video/pwc/pwc-ctrl.c
+++ b/drivers/media/video/pwc/pwc-ctrl.c
@@ -2,7 +2,7 @@
2 Functions that send various control messages to the webcam, including 2 Functions that send various control messages to the webcam, including
3 video modes. 3 video modes.
4 (C) 1999-2003 Nemosoft Unv. 4 (C) 1999-2003 Nemosoft Unv.
5 (C) 2004 Luc Saillard (luc@saillard.org) 5 (C) 2004-2006 Luc Saillard (luc@saillard.org)
6 6
7 NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx 7 NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx
8 driver and thus may have bugs that are not present in the original version. 8 driver and thus may have bugs that are not present in the original version.
@@ -41,12 +41,14 @@
41#include <asm/uaccess.h> 41#include <asm/uaccess.h>
42#endif 42#endif
43#include <asm/errno.h> 43#include <asm/errno.h>
44#include <linux/version.h>
44 45
45#include "pwc.h" 46#include "pwc.h"
46#include "pwc-ioctl.h"
47#include "pwc-uncompress.h" 47#include "pwc-uncompress.h"
48#include "pwc-kiara.h" 48#include "pwc-kiara.h"
49#include "pwc-timon.h" 49#include "pwc-timon.h"
50#include "pwc-dec1.h"
51#include "pwc-dec23.h"
50 52
51/* Request types: video */ 53/* Request types: video */
52#define SET_LUM_CTL 0x01 54#define SET_LUM_CTL 0x01
@@ -57,6 +59,10 @@
57#define GET_STATUS_CTL 0x06 59#define GET_STATUS_CTL 0x06
58#define SET_EP_STREAM_CTL 0x07 60#define SET_EP_STREAM_CTL 0x07
59#define GET_EP_STREAM_CTL 0x08 61#define GET_EP_STREAM_CTL 0x08
62#define GET_XX_CTL 0x09
63#define SET_XX_CTL 0x0A
64#define GET_XY_CTL 0x0B
65#define SET_XY_CTL 0x0C
60#define SET_MPT_CTL 0x0D 66#define SET_MPT_CTL 0x0D
61#define GET_MPT_CTL 0x0E 67#define GET_MPT_CTL 0x0E
62 68
@@ -93,12 +99,20 @@
93#define READ_SHUTTER_FORMATTER 0x0600 99#define READ_SHUTTER_FORMATTER 0x0600
94#define READ_RED_GAIN_FORMATTER 0x0700 100#define READ_RED_GAIN_FORMATTER 0x0700
95#define READ_BLUE_GAIN_FORMATTER 0x0800 101#define READ_BLUE_GAIN_FORMATTER 0x0800
102#define GET_STATUS_B00 0x0B00
96#define SENSOR_TYPE_FORMATTER1 0x0C00 103#define SENSOR_TYPE_FORMATTER1 0x0C00
104#define GET_STATUS_3000 0x3000
97#define READ_RAW_Y_MEAN_FORMATTER 0x3100 105#define READ_RAW_Y_MEAN_FORMATTER 0x3100
98#define SET_POWER_SAVE_MODE_FORMATTER 0x3200 106#define SET_POWER_SAVE_MODE_FORMATTER 0x3200
99#define MIRROR_IMAGE_FORMATTER 0x3300 107#define MIRROR_IMAGE_FORMATTER 0x3300
100#define LED_FORMATTER 0x3400 108#define LED_FORMATTER 0x3400
109#define LOWLIGHT 0x3500
110#define GET_STATUS_3600 0x3600
101#define SENSOR_TYPE_FORMATTER2 0x3700 111#define SENSOR_TYPE_FORMATTER2 0x3700
112#define GET_STATUS_3800 0x3800
113#define GET_STATUS_4000 0x4000
114#define GET_STATUS_4100 0x4100 /* Get */
115#define CTL_STATUS_4200 0x4200 /* [GS] 1 */
102 116
103/* Formatters for the Video Endpoint controls [GS]ET_EP_STREAM_CTL */ 117/* Formatters for the Video Endpoint controls [GS]ET_EP_STREAM_CTL */
104#define VIDEO_OUTPUT_CONTROL_FORMATTER 0x0100 118#define VIDEO_OUTPUT_CONTROL_FORMATTER 0x0100
@@ -138,6 +152,7 @@ static struct Nala_table_entry Nala_table[PSZ_MAX][8] =
138#include "pwc-nala.h" 152#include "pwc-nala.h"
139}; 153};
140 154
155static void pwc_set_image_buffer_size(struct pwc_device *pdev);
141 156
142/****************************************************************************/ 157/****************************************************************************/
143 158
@@ -159,31 +174,7 @@ static struct Nala_table_entry Nala_table[PSZ_MAX][8] =
159 &buf, buflen, 500) 174 &buf, buflen, 500)
160 175
161 176
162#if PWC_DEBUG 177static int send_video_command(struct usb_device *udev, int index, void *buf, int buflen)
163void pwc_hexdump(void *p, int len)
164{
165 int i;
166 unsigned char *s;
167 char buf[100], *d;
168
169 s = (unsigned char *)p;
170 d = buf;
171 *d = '\0';
172 Debug("Doing hexdump @ %p, %d bytes.\n", p, len);
173 for (i = 0; i < len; i++) {
174 d += sprintf(d, "%02X ", *s++);
175 if ((i & 0xF) == 0xF) {
176 Debug("%s\n", buf);
177 d = buf;
178 *d = '\0';
179 }
180 }
181 if ((i & 0xF) != 0)
182 Debug("%s\n", buf);
183}
184#endif
185
186static inline int send_video_command(struct usb_device *udev, int index, void *buf, int buflen)
187{ 178{
188 return usb_control_msg(udev, 179 return usb_control_msg(udev,
189 usb_sndctrlpipe(udev, 0), 180 usb_sndctrlpipe(udev, 0),
@@ -196,7 +187,7 @@ static inline int send_video_command(struct usb_device *udev, int index, void *b
196 187
197 188
198 189
199static inline int set_video_mode_Nala(struct pwc_device *pdev, int size, int frames) 190static int set_video_mode_Nala(struct pwc_device *pdev, int size, int frames)
200{ 191{
201 unsigned char buf[3]; 192 unsigned char buf[3];
202 int ret, fps; 193 int ret, fps;
@@ -229,34 +220,14 @@ static inline int set_video_mode_Nala(struct pwc_device *pdev, int size, int fra
229 if (pEntry->alternate == 0) 220 if (pEntry->alternate == 0)
230 return -EINVAL; 221 return -EINVAL;
231 222
232 if (pEntry->compressed)
233 return -ENOENT; /* Not supported. */
234
235 memcpy(buf, pEntry->mode, 3); 223 memcpy(buf, pEntry->mode, 3);
236 ret = send_video_command(pdev->udev, pdev->vendpoint, buf, 3); 224 ret = send_video_command(pdev->udev, pdev->vendpoint, buf, 3);
237 if (ret < 0) { 225 if (ret < 0) {
238 Debug("Failed to send video command... %d\n", ret); 226 PWC_DEBUG_MODULE("Failed to send video command... %d\n", ret);
239 return ret; 227 return ret;
240 } 228 }
241 if (pEntry->compressed && pdev->vpalette != VIDEO_PALETTE_RAW) 229 if (pEntry->compressed && pdev->vpalette != VIDEO_PALETTE_RAW)
242 { 230 pwc_dec1_init(pdev->type, pdev->release, buf, pdev->decompress_data);
243 switch(pdev->type) {
244 case 645:
245 case 646:
246/* pwc_dec1_init(pdev->type, pdev->release, buf, pdev->decompress_data); */
247 break;
248
249 case 675:
250 case 680:
251 case 690:
252 case 720:
253 case 730:
254 case 740:
255 case 750:
256/* pwc_dec23_init(pdev->type, pdev->release, buf, pdev->decompress_data); */
257 break;
258 }
259 }
260 231
261 pdev->cmd_len = 3; 232 pdev->cmd_len = 3;
262 memcpy(pdev->cmd_buf, buf, 3); 233 memcpy(pdev->cmd_buf, buf, 3);
@@ -283,7 +254,7 @@ static inline int set_video_mode_Nala(struct pwc_device *pdev, int size, int fra
283} 254}
284 255
285 256
286static inline int set_video_mode_Timon(struct pwc_device *pdev, int size, int frames, int compression, int snapshot) 257static int set_video_mode_Timon(struct pwc_device *pdev, int size, int frames, int compression, int snapshot)
287{ 258{
288 unsigned char buf[13]; 259 unsigned char buf[13];
289 const struct Timon_table_entry *pChoose; 260 const struct Timon_table_entry *pChoose;
@@ -315,8 +286,8 @@ static inline int set_video_mode_Timon(struct pwc_device *pdev, int size, int fr
315 if (ret < 0) 286 if (ret < 0)
316 return ret; 287 return ret;
317 288
318/* if (pChoose->bandlength > 0 && pdev->vpalette != VIDEO_PALETTE_RAW) 289 if (pChoose->bandlength > 0 && pdev->vpalette != VIDEO_PALETTE_RAW)
319 pwc_dec23_init(pdev->type, pdev->release, buf, pdev->decompress_data); */ 290 pwc_dec23_init(pdev, pdev->type, buf);
320 291
321 pdev->cmd_len = 13; 292 pdev->cmd_len = 13;
322 memcpy(pdev->cmd_buf, buf, 13); 293 memcpy(pdev->cmd_buf, buf, 13);
@@ -336,7 +307,7 @@ static inline int set_video_mode_Timon(struct pwc_device *pdev, int size, int fr
336} 307}
337 308
338 309
339static inline int set_video_mode_Kiara(struct pwc_device *pdev, int size, int frames, int compression, int snapshot) 310static int set_video_mode_Kiara(struct pwc_device *pdev, int size, int frames, int compression, int snapshot)
340{ 311{
341 const struct Kiara_table_entry *pChoose = NULL; 312 const struct Kiara_table_entry *pChoose = NULL;
342 int fps, ret; 313 int fps, ret;
@@ -350,21 +321,14 @@ static inline int set_video_mode_Kiara(struct pwc_device *pdev, int size, int fr
350 fps = (frames / 5) - 1; 321 fps = (frames / 5) - 1;
351 322
352 /* special case: VGA @ 5 fps and snapshot is raw bayer mode */ 323 /* special case: VGA @ 5 fps and snapshot is raw bayer mode */
353 if (size == PSZ_VGA && frames == 5 && snapshot) 324 if (size == PSZ_VGA && frames == 5 && snapshot && pdev->vpalette == VIDEO_PALETTE_RAW)
354 { 325 {
355 /* Only available in case the raw palette is selected or 326 /* Only available in case the raw palette is selected or
356 we have the decompressor available. This mode is 327 we have the decompressor available. This mode is
357 only available in compressed form 328 only available in compressed form
358 */ 329 */
359 if (pdev->vpalette == VIDEO_PALETTE_RAW) 330 PWC_DEBUG_SIZE("Choosing VGA/5 BAYER mode.\n");
360 { 331 pChoose = &RawEntry;
361 Info("Choosing VGA/5 BAYER mode (%d).\n", pdev->vpalette);
362 pChoose = &RawEntry;
363 }
364 else
365 {
366 Info("VGA/5 BAYER mode _must_ have a decompressor available, or use RAW palette.\n");
367 }
368 } 332 }
369 else 333 else
370 { 334 {
@@ -372,6 +336,7 @@ static inline int set_video_mode_Kiara(struct pwc_device *pdev, int size, int fr
372 if the preferred ratio is not available. 336 if the preferred ratio is not available.
373 Skip this step when using RAW modes. 337 Skip this step when using RAW modes.
374 */ 338 */
339 snapshot = 0;
375 while (compression <= 3) { 340 while (compression <= 3) {
376 pChoose = &Kiara_table[size][fps][compression]; 341 pChoose = &Kiara_table[size][fps][compression];
377 if (pChoose->alternate != 0) 342 if (pChoose->alternate != 0)
@@ -382,7 +347,7 @@ static inline int set_video_mode_Kiara(struct pwc_device *pdev, int size, int fr
382 if (pChoose == NULL || pChoose->alternate == 0) 347 if (pChoose == NULL || pChoose->alternate == 0)
383 return -ENOENT; /* Not supported. */ 348 return -ENOENT; /* Not supported. */
384 349
385 Debug("Using alternate setting %d.\n", pChoose->alternate); 350 PWC_TRACE("Using alternate setting %d.\n", pChoose->alternate);
386 351
387 /* usb_control_msg won't take staticly allocated arrays as argument?? */ 352 /* usb_control_msg won't take staticly allocated arrays as argument?? */
388 memcpy(buf, pChoose->mode, 12); 353 memcpy(buf, pChoose->mode, 12);
@@ -394,8 +359,8 @@ static inline int set_video_mode_Kiara(struct pwc_device *pdev, int size, int fr
394 if (ret < 0) 359 if (ret < 0)
395 return ret; 360 return ret;
396 361
397/* if (pChoose->bandlength > 0 && pdev->vpalette != VIDEO_PALETTE_RAW) 362 if (pChoose->bandlength > 0 && pdev->vpalette != VIDEO_PALETTE_RAW)
398 pwc_dec23_init(pdev->type, pdev->release, buf, pdev->decompress_data); */ 363 pwc_dec23_init(pdev, pdev->type, buf);
399 364
400 pdev->cmd_len = 12; 365 pdev->cmd_len = 12;
401 memcpy(pdev->cmd_buf, buf, 12); 366 memcpy(pdev->cmd_buf, buf, 12);
@@ -410,49 +375,13 @@ static inline int set_video_mode_Kiara(struct pwc_device *pdev, int size, int fr
410 pdev->frame_size = (pdev->vbandlength * pdev->image.y) / 4; 375 pdev->frame_size = (pdev->vbandlength * pdev->image.y) / 4;
411 else 376 else
412 pdev->frame_size = (pdev->image.x * pdev->image.y * 12) / 8; 377 pdev->frame_size = (pdev->image.x * pdev->image.y * 12) / 8;
378 PWC_TRACE("frame_size=%d, vframes=%d, vsize=%d, vsnapshot=%d, vbandlength=%d\n",
379 pdev->frame_size,pdev->vframes,pdev->vsize,pdev->vsnapshot,pdev->vbandlength);
413 return 0; 380 return 0;
414} 381}
415 382
416 383
417 384
418static void pwc_set_image_buffer_size(struct pwc_device *pdev)
419{
420 int i, factor = 0, filler = 0;
421
422 /* for PALETTE_YUV420P */
423 switch(pdev->vpalette)
424 {
425 case VIDEO_PALETTE_YUV420P:
426 factor = 6;
427 filler = 128;
428 break;
429 case VIDEO_PALETTE_RAW:
430 factor = 6; /* can be uncompressed YUV420P */
431 filler = 0;
432 break;
433 }
434
435 /* Set sizes in bytes */
436 pdev->image.size = pdev->image.x * pdev->image.y * factor / 4;
437 pdev->view.size = pdev->view.x * pdev->view.y * factor / 4;
438
439 /* Align offset, or you'll get some very weird results in
440 YUV420 mode... x must be multiple of 4 (to get the Y's in
441 place), and y even (or you'll mixup U & V). This is less of a
442 problem for YUV420P.
443 */
444 pdev->offset.x = ((pdev->view.x - pdev->image.x) / 2) & 0xFFFC;
445 pdev->offset.y = ((pdev->view.y - pdev->image.y) / 2) & 0xFFFE;
446
447 /* Fill buffers with gray or black */
448 for (i = 0; i < MAX_IMAGES; i++) {
449 if (pdev->image_ptr[i] != NULL)
450 memset(pdev->image_ptr[i], filler, pdev->view.size);
451 }
452}
453
454
455
456/** 385/**
457 @pdev: device structure 386 @pdev: device structure
458 @width: viewport width 387 @width: viewport width
@@ -465,50 +394,78 @@ int pwc_set_video_mode(struct pwc_device *pdev, int width, int height, int frame
465{ 394{
466 int ret, size; 395 int ret, size;
467 396
468 Trace(TRACE_FLOW, "set_video_mode(%dx%d @ %d, palette %d).\n", width, height, frames, pdev->vpalette); 397 PWC_DEBUG_FLOW("set_video_mode(%dx%d @ %d, palette %d).\n", width, height, frames, pdev->vpalette);
469 size = pwc_decode_size(pdev, width, height); 398 size = pwc_decode_size(pdev, width, height);
470 if (size < 0) { 399 if (size < 0) {
471 Debug("Could not find suitable size.\n"); 400 PWC_DEBUG_MODULE("Could not find suitable size.\n");
472 return -ERANGE; 401 return -ERANGE;
473 } 402 }
474 Debug("decode_size = %d.\n", size); 403 PWC_TRACE("decode_size = %d.\n", size);
475 404
476 ret = -EINVAL; 405 if (DEVICE_USE_CODEC1(pdev->type)) {
477 switch(pdev->type) {
478 case 645:
479 case 646:
480 ret = set_video_mode_Nala(pdev, size, frames); 406 ret = set_video_mode_Nala(pdev, size, frames);
481 break;
482 407
483 case 675: 408 } else if (DEVICE_USE_CODEC3(pdev->type)) {
484 case 680:
485 case 690:
486 ret = set_video_mode_Timon(pdev, size, frames, compression, snapshot);
487 break;
488
489 case 720:
490 case 730:
491 case 740:
492 case 750:
493 ret = set_video_mode_Kiara(pdev, size, frames, compression, snapshot); 409 ret = set_video_mode_Kiara(pdev, size, frames, compression, snapshot);
494 break; 410
411 } else {
412 ret = set_video_mode_Timon(pdev, size, frames, compression, snapshot);
495 } 413 }
496 if (ret < 0) { 414 if (ret < 0) {
497 if (ret == -ENOENT) 415 PWC_ERROR("Failed to set video mode %s@%d fps; return code = %d\n", size2name[size], frames, ret);
498 Info("Video mode %s@%d fps is only supported with the decompressor module (pwcx).\n", size2name[size], frames);
499 else {
500 Err("Failed to set video mode %s@%d fps; return code = %d\n", size2name[size], frames, ret);
501 }
502 return ret; 416 return ret;
503 } 417 }
504 pdev->view.x = width; 418 pdev->view.x = width;
505 pdev->view.y = height; 419 pdev->view.y = height;
506 pdev->frame_total_size = pdev->frame_size + pdev->frame_header_size + pdev->frame_trailer_size; 420 pdev->frame_total_size = pdev->frame_size + pdev->frame_header_size + pdev->frame_trailer_size;
507 pwc_set_image_buffer_size(pdev); 421 pwc_set_image_buffer_size(pdev);
508 Trace(TRACE_SIZE, "Set viewport to %dx%d, image size is %dx%d.\n", width, height, pwc_image_sizes[size].x, pwc_image_sizes[size].y); 422 PWC_DEBUG_SIZE("Set viewport to %dx%d, image size is %dx%d.\n", width, height, pwc_image_sizes[size].x, pwc_image_sizes[size].y);
509 return 0; 423 return 0;
510} 424}
511 425
426#define BLACK_Y 0
427#define BLACK_U 128
428#define BLACK_V 128
429
430static void pwc_set_image_buffer_size(struct pwc_device *pdev)
431{
432 int i, factor = 0;
433
434 /* for PALETTE_YUV420P */
435 switch(pdev->vpalette)
436 {
437 case VIDEO_PALETTE_YUV420P:
438 factor = 6;
439 break;
440 case VIDEO_PALETTE_RAW:
441 factor = 6; /* can be uncompressed YUV420P */
442 break;
443 }
444
445 /* Set sizes in bytes */
446 pdev->image.size = pdev->image.x * pdev->image.y * factor / 4;
447 pdev->view.size = pdev->view.x * pdev->view.y * factor / 4;
448
449 /* Align offset, or you'll get some very weird results in
450 YUV420 mode... x must be multiple of 4 (to get the Y's in
451 place), and y even (or you'll mixup U & V). This is less of a
452 problem for YUV420P.
453 */
454 pdev->offset.x = ((pdev->view.x - pdev->image.x) / 2) & 0xFFFC;
455 pdev->offset.y = ((pdev->view.y - pdev->image.y) / 2) & 0xFFFE;
456
457 /* Fill buffers with black colors */
458 for (i = 0; i < pwc_mbufs; i++) {
459 unsigned char *p = pdev->image_data + pdev->images[i].offset;
460 memset(p, BLACK_Y, pdev->view.x * pdev->view.y);
461 p += pdev->view.x * pdev->view.y;
462 memset(p, BLACK_U, pdev->view.x * pdev->view.y/4);
463 p += pdev->view.x * pdev->view.y/4;
464 memset(p, BLACK_V, pdev->view.x * pdev->view.y/4);
465 }
466}
467
468
512 469
513/* BRIGHTNESS */ 470/* BRIGHTNESS */
514 471
@@ -520,7 +477,7 @@ int pwc_get_brightness(struct pwc_device *pdev)
520 ret = RecvControlMsg(GET_LUM_CTL, BRIGHTNESS_FORMATTER, 1); 477 ret = RecvControlMsg(GET_LUM_CTL, BRIGHTNESS_FORMATTER, 1);
521 if (ret < 0) 478 if (ret < 0)
522 return ret; 479 return ret;
523 return buf << 9; 480 return buf;
524} 481}
525 482
526int pwc_set_brightness(struct pwc_device *pdev, int value) 483int pwc_set_brightness(struct pwc_device *pdev, int value)
@@ -545,7 +502,7 @@ int pwc_get_contrast(struct pwc_device *pdev)
545 ret = RecvControlMsg(GET_LUM_CTL, CONTRAST_FORMATTER, 1); 502 ret = RecvControlMsg(GET_LUM_CTL, CONTRAST_FORMATTER, 1);
546 if (ret < 0) 503 if (ret < 0)
547 return ret; 504 return ret;
548 return buf << 10; 505 return buf;
549} 506}
550 507
551int pwc_set_contrast(struct pwc_device *pdev, int value) 508int pwc_set_contrast(struct pwc_device *pdev, int value)
@@ -570,7 +527,7 @@ int pwc_get_gamma(struct pwc_device *pdev)
570 ret = RecvControlMsg(GET_LUM_CTL, GAMMA_FORMATTER, 1); 527 ret = RecvControlMsg(GET_LUM_CTL, GAMMA_FORMATTER, 1);
571 if (ret < 0) 528 if (ret < 0)
572 return ret; 529 return ret;
573 return buf << 11; 530 return buf;
574} 531}
575 532
576int pwc_set_gamma(struct pwc_device *pdev, int value) 533int pwc_set_gamma(struct pwc_device *pdev, int value)
@@ -588,37 +545,47 @@ int pwc_set_gamma(struct pwc_device *pdev, int value)
588 545
589/* SATURATION */ 546/* SATURATION */
590 547
591int pwc_get_saturation(struct pwc_device *pdev) 548/* return a value between [-100 , 100] */
549int pwc_get_saturation(struct pwc_device *pdev, int *value)
592{ 550{
593 char buf; 551 char buf;
594 int ret; 552 int ret, saturation_register;
595 553
596 if (pdev->type < 675) 554 if (pdev->type < 675)
597 return -1; 555 return -EINVAL;
598 ret = RecvControlMsg(GET_CHROM_CTL, pdev->type < 730 ? SATURATION_MODE_FORMATTER2 : SATURATION_MODE_FORMATTER1, 1); 556 if (pdev->type < 730)
557 saturation_register = SATURATION_MODE_FORMATTER2;
558 else
559 saturation_register = SATURATION_MODE_FORMATTER1;
560 ret = RecvControlMsg(GET_CHROM_CTL, saturation_register, 1);
599 if (ret < 0) 561 if (ret < 0)
600 return ret; 562 return ret;
601 return 32768 + buf * 327; 563 *value = (signed)buf;
564 return 0;
602} 565}
603 566
567/* @param value saturation color between [-100 , 100] */
604int pwc_set_saturation(struct pwc_device *pdev, int value) 568int pwc_set_saturation(struct pwc_device *pdev, int value)
605{ 569{
606 char buf; 570 char buf;
571 int saturation_register;
607 572
608 if (pdev->type < 675) 573 if (pdev->type < 675)
609 return -EINVAL; 574 return -EINVAL;
610 if (value < 0) 575 if (value < -100)
611 value = 0; 576 value = -100;
612 if (value > 0xffff) 577 if (value > 100)
613 value = 0xffff; 578 value = 100;
614 /* saturation ranges from -100 to +100 */ 579 if (pdev->type < 730)
615 buf = (value - 32768) / 327; 580 saturation_register = SATURATION_MODE_FORMATTER2;
616 return SendControlMsg(SET_CHROM_CTL, pdev->type < 730 ? SATURATION_MODE_FORMATTER2 : SATURATION_MODE_FORMATTER1, 1); 581 else
582 saturation_register = SATURATION_MODE_FORMATTER1;
583 return SendControlMsg(SET_CHROM_CTL, saturation_register, 1);
617} 584}
618 585
619/* AGC */ 586/* AGC */
620 587
621static inline int pwc_set_agc(struct pwc_device *pdev, int mode, int value) 588int pwc_set_agc(struct pwc_device *pdev, int mode, int value)
622{ 589{
623 char buf; 590 char buf;
624 int ret; 591 int ret;
@@ -643,7 +610,7 @@ static inline int pwc_set_agc(struct pwc_device *pdev, int mode, int value)
643 return 0; 610 return 0;
644} 611}
645 612
646static inline int pwc_get_agc(struct pwc_device *pdev, int *value) 613int pwc_get_agc(struct pwc_device *pdev, int *value)
647{ 614{
648 unsigned char buf; 615 unsigned char buf;
649 int ret; 616 int ret;
@@ -673,7 +640,7 @@ static inline int pwc_get_agc(struct pwc_device *pdev, int *value)
673 return 0; 640 return 0;
674} 641}
675 642
676static inline int pwc_set_shutter_speed(struct pwc_device *pdev, int mode, int value) 643int pwc_set_shutter_speed(struct pwc_device *pdev, int mode, int value)
677{ 644{
678 char buf[2]; 645 char buf[2];
679 int speed, ret; 646 int speed, ret;
@@ -691,23 +658,16 @@ static inline int pwc_set_shutter_speed(struct pwc_device *pdev, int mode, int v
691 value = 0; 658 value = 0;
692 if (value > 0xffff) 659 if (value > 0xffff)
693 value = 0xffff; 660 value = 0xffff;
694 switch(pdev->type) { 661
695 case 675: 662 if (DEVICE_USE_CODEC2(pdev->type)) {
696 case 680:
697 case 690:
698 /* speed ranges from 0x0 to 0x290 (656) */ 663 /* speed ranges from 0x0 to 0x290 (656) */
699 speed = (value / 100); 664 speed = (value / 100);
700 buf[1] = speed >> 8; 665 buf[1] = speed >> 8;
701 buf[0] = speed & 0xff; 666 buf[0] = speed & 0xff;
702 break; 667 } else if (DEVICE_USE_CODEC3(pdev->type)) {
703 case 720:
704 case 730:
705 case 740:
706 case 750:
707 /* speed seems to range from 0x0 to 0xff */ 668 /* speed seems to range from 0x0 to 0xff */
708 buf[1] = 0; 669 buf[1] = 0;
709 buf[0] = value >> 8; 670 buf[0] = value >> 8;
710 break;
711 } 671 }
712 672
713 ret = SendControlMsg(SET_LUM_CTL, PRESET_SHUTTER_FORMATTER, 2); 673 ret = SendControlMsg(SET_LUM_CTL, PRESET_SHUTTER_FORMATTER, 2);
@@ -715,6 +675,25 @@ static inline int pwc_set_shutter_speed(struct pwc_device *pdev, int mode, int v
715 return ret; 675 return ret;
716} 676}
717 677
678/* This function is not exported to v4l1, so output values between 0 -> 256 */
679int pwc_get_shutter_speed(struct pwc_device *pdev, int *value)
680{
681 unsigned char buf[2];
682 int ret;
683
684 ret = RecvControlMsg(GET_STATUS_CTL, READ_SHUTTER_FORMATTER, 2);
685 if (ret < 0)
686 return ret;
687 *value = buf[0] + (buf[1] << 8);
688 if (DEVICE_USE_CODEC2(pdev->type)) {
689 /* speed ranges from 0x0 to 0x290 (656) */
690 *value *= 256/656;
691 } else if (DEVICE_USE_CODEC3(pdev->type)) {
692 /* speed seems to range from 0x0 to 0xff */
693 }
694 return 0;
695}
696
718 697
719/* POWER */ 698/* POWER */
720 699
@@ -736,19 +715,19 @@ int pwc_camera_power(struct pwc_device *pdev, int power)
736 715
737/* private calls */ 716/* private calls */
738 717
739static inline int pwc_restore_user(struct pwc_device *pdev) 718int pwc_restore_user(struct pwc_device *pdev)
740{ 719{
741 char buf; /* dummy */ 720 char buf; /* dummy */
742 return SendControlMsg(SET_STATUS_CTL, RESTORE_USER_DEFAULTS_FORMATTER, 0); 721 return SendControlMsg(SET_STATUS_CTL, RESTORE_USER_DEFAULTS_FORMATTER, 0);
743} 722}
744 723
745static inline int pwc_save_user(struct pwc_device *pdev) 724int pwc_save_user(struct pwc_device *pdev)
746{ 725{
747 char buf; /* dummy */ 726 char buf; /* dummy */
748 return SendControlMsg(SET_STATUS_CTL, SAVE_USER_DEFAULTS_FORMATTER, 0); 727 return SendControlMsg(SET_STATUS_CTL, SAVE_USER_DEFAULTS_FORMATTER, 0);
749} 728}
750 729
751static inline int pwc_restore_factory(struct pwc_device *pdev) 730int pwc_restore_factory(struct pwc_device *pdev)
752{ 731{
753 char buf; /* dummy */ 732 char buf; /* dummy */
754 return SendControlMsg(SET_STATUS_CTL, RESTORE_FACTORY_DEFAULTS_FORMATTER, 0); 733 return SendControlMsg(SET_STATUS_CTL, RESTORE_FACTORY_DEFAULTS_FORMATTER, 0);
@@ -766,7 +745,7 @@ static inline int pwc_restore_factory(struct pwc_device *pdev)
766 * 03: manual 745 * 03: manual
767 * 04: auto 746 * 04: auto
768 */ 747 */
769static inline int pwc_set_awb(struct pwc_device *pdev, int mode) 748int pwc_set_awb(struct pwc_device *pdev, int mode)
770{ 749{
771 char buf; 750 char buf;
772 int ret; 751 int ret;
@@ -786,7 +765,7 @@ static inline int pwc_set_awb(struct pwc_device *pdev, int mode)
786 return 0; 765 return 0;
787} 766}
788 767
789static inline int pwc_get_awb(struct pwc_device *pdev) 768int pwc_get_awb(struct pwc_device *pdev)
790{ 769{
791 unsigned char buf; 770 unsigned char buf;
792 int ret; 771 int ret;
@@ -798,7 +777,7 @@ static inline int pwc_get_awb(struct pwc_device *pdev)
798 return buf; 777 return buf;
799} 778}
800 779
801static inline int pwc_set_red_gain(struct pwc_device *pdev, int value) 780int pwc_set_red_gain(struct pwc_device *pdev, int value)
802{ 781{
803 unsigned char buf; 782 unsigned char buf;
804 783
@@ -811,7 +790,7 @@ static inline int pwc_set_red_gain(struct pwc_device *pdev, int value)
811 return SendControlMsg(SET_CHROM_CTL, PRESET_MANUAL_RED_GAIN_FORMATTER, 1); 790 return SendControlMsg(SET_CHROM_CTL, PRESET_MANUAL_RED_GAIN_FORMATTER, 1);
812} 791}
813 792
814static inline int pwc_get_red_gain(struct pwc_device *pdev, int *value) 793int pwc_get_red_gain(struct pwc_device *pdev, int *value)
815{ 794{
816 unsigned char buf; 795 unsigned char buf;
817 int ret; 796 int ret;
@@ -824,7 +803,7 @@ static inline int pwc_get_red_gain(struct pwc_device *pdev, int *value)
824} 803}
825 804
826 805
827static inline int pwc_set_blue_gain(struct pwc_device *pdev, int value) 806int pwc_set_blue_gain(struct pwc_device *pdev, int value)
828{ 807{
829 unsigned char buf; 808 unsigned char buf;
830 809
@@ -837,7 +816,7 @@ static inline int pwc_set_blue_gain(struct pwc_device *pdev, int value)
837 return SendControlMsg(SET_CHROM_CTL, PRESET_MANUAL_BLUE_GAIN_FORMATTER, 1); 816 return SendControlMsg(SET_CHROM_CTL, PRESET_MANUAL_BLUE_GAIN_FORMATTER, 1);
838} 817}
839 818
840static inline int pwc_get_blue_gain(struct pwc_device *pdev, int *value) 819int pwc_get_blue_gain(struct pwc_device *pdev, int *value)
841{ 820{
842 unsigned char buf; 821 unsigned char buf;
843 int ret; 822 int ret;
@@ -854,7 +833,7 @@ static inline int pwc_get_blue_gain(struct pwc_device *pdev, int *value)
854 internal red/blue gains, which may be different from the manual 833 internal red/blue gains, which may be different from the manual
855 gains set or read above. 834 gains set or read above.
856 */ 835 */
857static inline int pwc_read_red_gain(struct pwc_device *pdev, int *value) 836static int pwc_read_red_gain(struct pwc_device *pdev, int *value)
858{ 837{
859 unsigned char buf; 838 unsigned char buf;
860 int ret; 839 int ret;
@@ -866,7 +845,7 @@ static inline int pwc_read_red_gain(struct pwc_device *pdev, int *value)
866 return 0; 845 return 0;
867} 846}
868 847
869static inline int pwc_read_blue_gain(struct pwc_device *pdev, int *value) 848static int pwc_read_blue_gain(struct pwc_device *pdev, int *value)
870{ 849{
871 unsigned char buf; 850 unsigned char buf;
872 int ret; 851 int ret;
@@ -879,7 +858,7 @@ static inline int pwc_read_blue_gain(struct pwc_device *pdev, int *value)
879} 858}
880 859
881 860
882static inline int pwc_set_wb_speed(struct pwc_device *pdev, int speed) 861static int pwc_set_wb_speed(struct pwc_device *pdev, int speed)
883{ 862{
884 unsigned char buf; 863 unsigned char buf;
885 864
@@ -888,7 +867,7 @@ static inline int pwc_set_wb_speed(struct pwc_device *pdev, int speed)
888 return SendControlMsg(SET_CHROM_CTL, AWB_CONTROL_SPEED_FORMATTER, 1); 867 return SendControlMsg(SET_CHROM_CTL, AWB_CONTROL_SPEED_FORMATTER, 1);
889} 868}
890 869
891static inline int pwc_get_wb_speed(struct pwc_device *pdev, int *value) 870static int pwc_get_wb_speed(struct pwc_device *pdev, int *value)
892{ 871{
893 unsigned char buf; 872 unsigned char buf;
894 int ret; 873 int ret;
@@ -901,7 +880,7 @@ static inline int pwc_get_wb_speed(struct pwc_device *pdev, int *value)
901} 880}
902 881
903 882
904static inline int pwc_set_wb_delay(struct pwc_device *pdev, int delay) 883static int pwc_set_wb_delay(struct pwc_device *pdev, int delay)
905{ 884{
906 unsigned char buf; 885 unsigned char buf;
907 886
@@ -910,7 +889,7 @@ static inline int pwc_set_wb_delay(struct pwc_device *pdev, int delay)
910 return SendControlMsg(SET_CHROM_CTL, AWB_CONTROL_DELAY_FORMATTER, 1); 889 return SendControlMsg(SET_CHROM_CTL, AWB_CONTROL_DELAY_FORMATTER, 1);
911} 890}
912 891
913static inline int pwc_get_wb_delay(struct pwc_device *pdev, int *value) 892static int pwc_get_wb_delay(struct pwc_device *pdev, int *value)
914{ 893{
915 unsigned char buf; 894 unsigned char buf;
916 int ret; 895 int ret;
@@ -965,7 +944,7 @@ static int pwc_get_leds(struct pwc_device *pdev, int *on_value, int *off_value)
965 return 0; 944 return 0;
966} 945}
967 946
968static inline int pwc_set_contour(struct pwc_device *pdev, int contour) 947int pwc_set_contour(struct pwc_device *pdev, int contour)
969{ 948{
970 unsigned char buf; 949 unsigned char buf;
971 int ret; 950 int ret;
@@ -990,7 +969,7 @@ static inline int pwc_set_contour(struct pwc_device *pdev, int contour)
990 return 0; 969 return 0;
991} 970}
992 971
993static inline int pwc_get_contour(struct pwc_device *pdev, int *contour) 972int pwc_get_contour(struct pwc_device *pdev, int *contour)
994{ 973{
995 unsigned char buf; 974 unsigned char buf;
996 int ret; 975 int ret;
@@ -1012,7 +991,7 @@ static inline int pwc_get_contour(struct pwc_device *pdev, int *contour)
1012} 991}
1013 992
1014 993
1015static inline int pwc_set_backlight(struct pwc_device *pdev, int backlight) 994int pwc_set_backlight(struct pwc_device *pdev, int backlight)
1016{ 995{
1017 unsigned char buf; 996 unsigned char buf;
1018 997
@@ -1023,7 +1002,7 @@ static inline int pwc_set_backlight(struct pwc_device *pdev, int backlight)
1023 return SendControlMsg(SET_LUM_CTL, BACK_LIGHT_COMPENSATION_FORMATTER, 1); 1002 return SendControlMsg(SET_LUM_CTL, BACK_LIGHT_COMPENSATION_FORMATTER, 1);
1024} 1003}
1025 1004
1026static inline int pwc_get_backlight(struct pwc_device *pdev, int *backlight) 1005int pwc_get_backlight(struct pwc_device *pdev, int *backlight)
1027{ 1006{
1028 int ret; 1007 int ret;
1029 unsigned char buf; 1008 unsigned char buf;
@@ -1031,12 +1010,35 @@ static inline int pwc_get_backlight(struct pwc_device *pdev, int *backlight)
1031 ret = RecvControlMsg(GET_LUM_CTL, BACK_LIGHT_COMPENSATION_FORMATTER, 1); 1010 ret = RecvControlMsg(GET_LUM_CTL, BACK_LIGHT_COMPENSATION_FORMATTER, 1);
1032 if (ret < 0) 1011 if (ret < 0)
1033 return ret; 1012 return ret;
1034 *backlight = buf; 1013 *backlight = !!buf;
1035 return 0; 1014 return 0;
1036} 1015}
1037 1016
1017int pwc_set_colour_mode(struct pwc_device *pdev, int colour)
1018{
1019 unsigned char buf;
1038 1020
1039static inline int pwc_set_flicker(struct pwc_device *pdev, int flicker) 1021 if (colour)
1022 buf = 0xff;
1023 else
1024 buf = 0x0;
1025 return SendControlMsg(SET_CHROM_CTL, COLOUR_MODE_FORMATTER, 1);
1026}
1027
1028int pwc_get_colour_mode(struct pwc_device *pdev, int *colour)
1029{
1030 int ret;
1031 unsigned char buf;
1032
1033 ret = RecvControlMsg(GET_CHROM_CTL, COLOUR_MODE_FORMATTER, 1);
1034 if (ret < 0)
1035 return ret;
1036 *colour = !!buf;
1037 return 0;
1038}
1039
1040
1041int pwc_set_flicker(struct pwc_device *pdev, int flicker)
1040{ 1042{
1041 unsigned char buf; 1043 unsigned char buf;
1042 1044
@@ -1047,7 +1049,7 @@ static inline int pwc_set_flicker(struct pwc_device *pdev, int flicker)
1047 return SendControlMsg(SET_LUM_CTL, FLICKERLESS_MODE_FORMATTER, 1); 1049 return SendControlMsg(SET_LUM_CTL, FLICKERLESS_MODE_FORMATTER, 1);
1048} 1050}
1049 1051
1050static inline int pwc_get_flicker(struct pwc_device *pdev, int *flicker) 1052int pwc_get_flicker(struct pwc_device *pdev, int *flicker)
1051{ 1053{
1052 int ret; 1054 int ret;
1053 unsigned char buf; 1055 unsigned char buf;
@@ -1055,12 +1057,11 @@ static inline int pwc_get_flicker(struct pwc_device *pdev, int *flicker)
1055 ret = RecvControlMsg(GET_LUM_CTL, FLICKERLESS_MODE_FORMATTER, 1); 1057 ret = RecvControlMsg(GET_LUM_CTL, FLICKERLESS_MODE_FORMATTER, 1);
1056 if (ret < 0) 1058 if (ret < 0)
1057 return ret; 1059 return ret;
1058 *flicker = buf; 1060 *flicker = !!buf;
1059 return 0; 1061 return 0;
1060} 1062}
1061 1063
1062 1064int pwc_set_dynamic_noise(struct pwc_device *pdev, int noise)
1063static inline int pwc_set_dynamic_noise(struct pwc_device *pdev, int noise)
1064{ 1065{
1065 unsigned char buf; 1066 unsigned char buf;
1066 1067
@@ -1072,7 +1073,7 @@ static inline int pwc_set_dynamic_noise(struct pwc_device *pdev, int noise)
1072 return SendControlMsg(SET_LUM_CTL, DYNAMIC_NOISE_CONTROL_FORMATTER, 1); 1073 return SendControlMsg(SET_LUM_CTL, DYNAMIC_NOISE_CONTROL_FORMATTER, 1);
1073} 1074}
1074 1075
1075static inline int pwc_get_dynamic_noise(struct pwc_device *pdev, int *noise) 1076int pwc_get_dynamic_noise(struct pwc_device *pdev, int *noise)
1076{ 1077{
1077 int ret; 1078 int ret;
1078 unsigned char buf; 1079 unsigned char buf;
@@ -1084,7 +1085,7 @@ static inline int pwc_get_dynamic_noise(struct pwc_device *pdev, int *noise)
1084 return 0; 1085 return 0;
1085} 1086}
1086 1087
1087static int pwc_mpt_reset(struct pwc_device *pdev, int flags) 1088static int _pwc_mpt_reset(struct pwc_device *pdev, int flags)
1088{ 1089{
1089 unsigned char buf; 1090 unsigned char buf;
1090 1091
@@ -1092,7 +1093,18 @@ static int pwc_mpt_reset(struct pwc_device *pdev, int flags)
1092 return SendControlMsg(SET_MPT_CTL, PT_RESET_CONTROL_FORMATTER, 1); 1093 return SendControlMsg(SET_MPT_CTL, PT_RESET_CONTROL_FORMATTER, 1);
1093} 1094}
1094 1095
1095static inline int pwc_mpt_set_angle(struct pwc_device *pdev, int pan, int tilt) 1096int pwc_mpt_reset(struct pwc_device *pdev, int flags)
1097{
1098 int ret;
1099 ret = _pwc_mpt_reset(pdev, flags);
1100 if (ret >= 0) {
1101 pdev->pan_angle = 0;
1102 pdev->tilt_angle = 0;
1103 }
1104 return ret;
1105}
1106
1107static int _pwc_mpt_set_angle(struct pwc_device *pdev, int pan, int tilt)
1096{ 1108{
1097 unsigned char buf[4]; 1109 unsigned char buf[4];
1098 1110
@@ -1110,7 +1122,35 @@ static inline int pwc_mpt_set_angle(struct pwc_device *pdev, int pan, int tilt)
1110 return SendControlMsg(SET_MPT_CTL, PT_RELATIVE_CONTROL_FORMATTER, 4); 1122 return SendControlMsg(SET_MPT_CTL, PT_RELATIVE_CONTROL_FORMATTER, 4);
1111} 1123}
1112 1124
1113static inline int pwc_mpt_get_status(struct pwc_device *pdev, struct pwc_mpt_status *status) 1125int pwc_mpt_set_angle(struct pwc_device *pdev, int pan, int tilt)
1126{
1127 int ret;
1128
1129 /* check absolute ranges */
1130 if (pan < pdev->angle_range.pan_min ||
1131 pan > pdev->angle_range.pan_max ||
1132 tilt < pdev->angle_range.tilt_min ||
1133 tilt > pdev->angle_range.tilt_max)
1134 return -ERANGE;
1135
1136 /* go to relative range, check again */
1137 pan -= pdev->pan_angle;
1138 tilt -= pdev->tilt_angle;
1139 /* angles are specified in degrees * 100, thus the limit = 36000 */
1140 if (pan < -36000 || pan > 36000 || tilt < -36000 || tilt > 36000)
1141 return -ERANGE;
1142
1143 ret = _pwc_mpt_set_angle(pdev, pan, tilt);
1144 if (ret >= 0) {
1145 pdev->pan_angle += pan;
1146 pdev->tilt_angle += tilt;
1147 }
1148 if (ret == -EPIPE) /* stall -> out of range */
1149 ret = -ERANGE;
1150 return ret;
1151}
1152
1153static int pwc_mpt_get_status(struct pwc_device *pdev, struct pwc_mpt_status *status)
1114{ 1154{
1115 int ret; 1155 int ret;
1116 unsigned char buf[5]; 1156 unsigned char buf[5];
@@ -1151,6 +1191,26 @@ int pwc_get_cmos_sensor(struct pwc_device *pdev, int *sensor)
1151 /* End of Add-Ons */ 1191 /* End of Add-Ons */
1152 /* ************************************************* */ 1192 /* ************************************************* */
1153 1193
1194/* Linux 2.5.something and 2.6 pass direct pointers to arguments of
1195 ioctl() calls. With 2.4, you have to do tedious copy_from_user()
1196 and copy_to_user() calls. With these macros we circumvent this,
1197 and let me maintain only one source file. The functionality is
1198 exactly the same otherwise.
1199 */
1200
1201
1202/* define local variable for arg */
1203#define ARG_DEF(ARG_type, ARG_name)\
1204 ARG_type *ARG_name = arg;
1205/* copy arg to local variable */
1206#define ARG_IN(ARG_name) /* nothing */
1207/* argument itself (referenced) */
1208#define ARGR(ARG_name) (*ARG_name)
1209/* argument address */
1210#define ARGA(ARG_name) ARG_name
1211/* copy local variable to arg */
1212#define ARG_OUT(ARG_name) /* nothing */
1213
1154 1214
1155int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg) 1215int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg)
1156{ 1216{
@@ -1180,206 +1240,243 @@ int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg)
1180 1240
1181 case VIDIOCPWCSCQUAL: 1241 case VIDIOCPWCSCQUAL:
1182 { 1242 {
1183 int *qual = arg; 1243 ARG_DEF(int, qual)
1184 1244
1185 if (*qual < 0 || *qual > 3) 1245 ARG_IN(qual)
1246 if (ARGR(qual) < 0 || ARGR(qual) > 3)
1186 ret = -EINVAL; 1247 ret = -EINVAL;
1187 else 1248 else
1188 ret = pwc_try_video_mode(pdev, pdev->view.x, pdev->view.y, pdev->vframes, *qual, pdev->vsnapshot); 1249 ret = pwc_try_video_mode(pdev, pdev->view.x, pdev->view.y, pdev->vframes, ARGR(qual), pdev->vsnapshot);
1189 if (ret >= 0) 1250 if (ret >= 0)
1190 pdev->vcompression = *qual; 1251 pdev->vcompression = ARGR(qual);
1191 break; 1252 break;
1192 } 1253 }
1193 1254
1194 case VIDIOCPWCGCQUAL: 1255 case VIDIOCPWCGCQUAL:
1195 { 1256 {
1196 int *qual = arg; 1257 ARG_DEF(int, qual)
1197 *qual = pdev->vcompression; 1258
1259 ARGR(qual) = pdev->vcompression;
1260 ARG_OUT(qual)
1198 break; 1261 break;
1199 } 1262 }
1200 1263
1201 case VIDIOCPWCPROBE: 1264 case VIDIOCPWCPROBE:
1202 { 1265 {
1203 struct pwc_probe *probe = arg; 1266 ARG_DEF(struct pwc_probe, probe)
1204 strcpy(probe->name, pdev->vdev->name); 1267
1205 probe->type = pdev->type; 1268 strcpy(ARGR(probe).name, pdev->vdev->name);
1269 ARGR(probe).type = pdev->type;
1270 ARG_OUT(probe)
1206 break; 1271 break;
1207 } 1272 }
1208 1273
1209 case VIDIOCPWCGSERIAL: 1274 case VIDIOCPWCGSERIAL:
1210 { 1275 {
1211 struct pwc_serial *serial = arg; 1276 ARG_DEF(struct pwc_serial, serial)
1212 strcpy(serial->serial, pdev->serial); 1277
1278 strcpy(ARGR(serial).serial, pdev->serial);
1279 ARG_OUT(serial)
1213 break; 1280 break;
1214 } 1281 }
1215 1282
1216 case VIDIOCPWCSAGC: 1283 case VIDIOCPWCSAGC:
1217 { 1284 {
1218 int *agc = arg; 1285 ARG_DEF(int, agc)
1219 if (pwc_set_agc(pdev, *agc < 0 ? 1 : 0, *agc)) 1286
1287 ARG_IN(agc)
1288 if (pwc_set_agc(pdev, ARGR(agc) < 0 ? 1 : 0, ARGR(agc)))
1220 ret = -EINVAL; 1289 ret = -EINVAL;
1221 break; 1290 break;
1222 } 1291 }
1223 1292
1224 case VIDIOCPWCGAGC: 1293 case VIDIOCPWCGAGC:
1225 { 1294 {
1226 int *agc = arg; 1295 ARG_DEF(int, agc)
1227 1296
1228 if (pwc_get_agc(pdev, agc)) 1297 if (pwc_get_agc(pdev, ARGA(agc)))
1229 ret = -EINVAL; 1298 ret = -EINVAL;
1299 ARG_OUT(agc)
1230 break; 1300 break;
1231 } 1301 }
1232 1302
1233 case VIDIOCPWCSSHUTTER: 1303 case VIDIOCPWCSSHUTTER:
1234 { 1304 {
1235 int *shutter_speed = arg; 1305 ARG_DEF(int, shutter_speed)
1236 ret = pwc_set_shutter_speed(pdev, *shutter_speed < 0 ? 1 : 0, *shutter_speed); 1306
1307 ARG_IN(shutter_speed)
1308 ret = pwc_set_shutter_speed(pdev, ARGR(shutter_speed) < 0 ? 1 : 0, ARGR(shutter_speed));
1237 break; 1309 break;
1238 } 1310 }
1239 1311
1240 case VIDIOCPWCSAWB: 1312 case VIDIOCPWCSAWB:
1241 { 1313 {
1242 struct pwc_whitebalance *wb = arg; 1314 ARG_DEF(struct pwc_whitebalance, wb)
1243 1315
1244 ret = pwc_set_awb(pdev, wb->mode); 1316 ARG_IN(wb)
1245 if (ret >= 0 && wb->mode == PWC_WB_MANUAL) { 1317 ret = pwc_set_awb(pdev, ARGR(wb).mode);
1246 pwc_set_red_gain(pdev, wb->manual_red); 1318 if (ret >= 0 && ARGR(wb).mode == PWC_WB_MANUAL) {
1247 pwc_set_blue_gain(pdev, wb->manual_blue); 1319 pwc_set_red_gain(pdev, ARGR(wb).manual_red);
1320 pwc_set_blue_gain(pdev, ARGR(wb).manual_blue);
1248 } 1321 }
1249 break; 1322 break;
1250 } 1323 }
1251 1324
1252 case VIDIOCPWCGAWB: 1325 case VIDIOCPWCGAWB:
1253 { 1326 {
1254 struct pwc_whitebalance *wb = arg; 1327 ARG_DEF(struct pwc_whitebalance, wb)
1255 1328
1256 memset(wb, 0, sizeof(struct pwc_whitebalance)); 1329 memset(ARGA(wb), 0, sizeof(struct pwc_whitebalance));
1257 wb->mode = pwc_get_awb(pdev); 1330 ARGR(wb).mode = pwc_get_awb(pdev);
1258 if (wb->mode < 0) 1331 if (ARGR(wb).mode < 0)
1259 ret = -EINVAL; 1332 ret = -EINVAL;
1260 else { 1333 else {
1261 if (wb->mode == PWC_WB_MANUAL) { 1334 if (ARGR(wb).mode == PWC_WB_MANUAL) {
1262 ret = pwc_get_red_gain(pdev, &wb->manual_red); 1335 ret = pwc_get_red_gain(pdev, &ARGR(wb).manual_red);
1263 if (ret < 0) 1336 if (ret < 0)
1264 break; 1337 break;
1265 ret = pwc_get_blue_gain(pdev, &wb->manual_blue); 1338 ret = pwc_get_blue_gain(pdev, &ARGR(wb).manual_blue);
1266 if (ret < 0) 1339 if (ret < 0)
1267 break; 1340 break;
1268 } 1341 }
1269 if (wb->mode == PWC_WB_AUTO) { 1342 if (ARGR(wb).mode == PWC_WB_AUTO) {
1270 ret = pwc_read_red_gain(pdev, &wb->read_red); 1343 ret = pwc_read_red_gain(pdev, &ARGR(wb).read_red);
1271 if (ret < 0) 1344 if (ret < 0)
1272 break; 1345 break;
1273 ret = pwc_read_blue_gain(pdev, &wb->read_blue); 1346 ret =pwc_read_blue_gain(pdev, &ARGR(wb).read_blue);
1274 if (ret < 0) 1347 if (ret < 0)
1275 break; 1348 break;
1276 } 1349 }
1277 } 1350 }
1351 ARG_OUT(wb)
1278 break; 1352 break;
1279 } 1353 }
1280 1354
1281 case VIDIOCPWCSAWBSPEED: 1355 case VIDIOCPWCSAWBSPEED:
1282 { 1356 {
1283 struct pwc_wb_speed *wbs = arg; 1357 ARG_DEF(struct pwc_wb_speed, wbs)
1284 1358
1285 if (wbs->control_speed > 0) { 1359 if (ARGR(wbs).control_speed > 0) {
1286 ret = pwc_set_wb_speed(pdev, wbs->control_speed); 1360 ret = pwc_set_wb_speed(pdev, ARGR(wbs).control_speed);
1287 } 1361 }
1288 if (wbs->control_delay > 0) { 1362 if (ARGR(wbs).control_delay > 0) {
1289 ret = pwc_set_wb_delay(pdev, wbs->control_delay); 1363 ret = pwc_set_wb_delay(pdev, ARGR(wbs).control_delay);
1290 } 1364 }
1291 break; 1365 break;
1292 } 1366 }
1293 1367
1294 case VIDIOCPWCGAWBSPEED: 1368 case VIDIOCPWCGAWBSPEED:
1295 { 1369 {
1296 struct pwc_wb_speed *wbs = arg; 1370 ARG_DEF(struct pwc_wb_speed, wbs)
1297 1371
1298 ret = pwc_get_wb_speed(pdev, &wbs->control_speed); 1372 ret = pwc_get_wb_speed(pdev, &ARGR(wbs).control_speed);
1299 if (ret < 0) 1373 if (ret < 0)
1300 break; 1374 break;
1301 ret = pwc_get_wb_delay(pdev, &wbs->control_delay); 1375 ret = pwc_get_wb_delay(pdev, &ARGR(wbs).control_delay);
1302 if (ret < 0) 1376 if (ret < 0)
1303 break; 1377 break;
1378 ARG_OUT(wbs)
1304 break; 1379 break;
1305 } 1380 }
1306 1381
1307 case VIDIOCPWCSLED: 1382 case VIDIOCPWCSLED:
1308 { 1383 {
1309 struct pwc_leds *leds = arg; 1384 ARG_DEF(struct pwc_leds, leds)
1310 ret = pwc_set_leds(pdev, leds->led_on, leds->led_off); 1385
1311 break; 1386 ARG_IN(leds)
1387 ret = pwc_set_leds(pdev, ARGR(leds).led_on, ARGR(leds).led_off);
1388 break;
1312 } 1389 }
1313 1390
1314 1391
1315 case VIDIOCPWCGLED: 1392 case VIDIOCPWCGLED:
1316 { 1393 {
1317 struct pwc_leds *leds = arg; 1394 ARG_DEF(struct pwc_leds, leds)
1318 ret = pwc_get_leds(pdev, &leds->led_on, &leds->led_off); 1395
1396 ret = pwc_get_leds(pdev, &ARGR(leds).led_on, &ARGR(leds).led_off);
1397 ARG_OUT(leds)
1319 break; 1398 break;
1320 } 1399 }
1321 1400
1322 case VIDIOCPWCSCONTOUR: 1401 case VIDIOCPWCSCONTOUR:
1323 { 1402 {
1324 int *contour = arg; 1403 ARG_DEF(int, contour)
1325 ret = pwc_set_contour(pdev, *contour); 1404
1405 ARG_IN(contour)
1406 ret = pwc_set_contour(pdev, ARGR(contour));
1326 break; 1407 break;
1327 } 1408 }
1328 1409
1329 case VIDIOCPWCGCONTOUR: 1410 case VIDIOCPWCGCONTOUR:
1330 { 1411 {
1331 int *contour = arg; 1412 ARG_DEF(int, contour)
1332 ret = pwc_get_contour(pdev, contour); 1413
1414 ret = pwc_get_contour(pdev, ARGA(contour));
1415 ARG_OUT(contour)
1333 break; 1416 break;
1334 } 1417 }
1335 1418
1336 case VIDIOCPWCSBACKLIGHT: 1419 case VIDIOCPWCSBACKLIGHT:
1337 { 1420 {
1338 int *backlight = arg; 1421 ARG_DEF(int, backlight)
1339 ret = pwc_set_backlight(pdev, *backlight); 1422
1423 ARG_IN(backlight)
1424 ret = pwc_set_backlight(pdev, ARGR(backlight));
1340 break; 1425 break;
1341 } 1426 }
1342 1427
1343 case VIDIOCPWCGBACKLIGHT: 1428 case VIDIOCPWCGBACKLIGHT:
1344 { 1429 {
1345 int *backlight = arg; 1430 ARG_DEF(int, backlight)
1346 ret = pwc_get_backlight(pdev, backlight); 1431
1432 ret = pwc_get_backlight(pdev, ARGA(backlight));
1433 ARG_OUT(backlight)
1347 break; 1434 break;
1348 } 1435 }
1349 1436
1350 case VIDIOCPWCSFLICKER: 1437 case VIDIOCPWCSFLICKER:
1351 { 1438 {
1352 int *flicker = arg; 1439 ARG_DEF(int, flicker)
1353 ret = pwc_set_flicker(pdev, *flicker); 1440
1441 ARG_IN(flicker)
1442 ret = pwc_set_flicker(pdev, ARGR(flicker));
1354 break; 1443 break;
1355 } 1444 }
1356 1445
1357 case VIDIOCPWCGFLICKER: 1446 case VIDIOCPWCGFLICKER:
1358 { 1447 {
1359 int *flicker = arg; 1448 ARG_DEF(int, flicker)
1360 ret = pwc_get_flicker(pdev, flicker); 1449
1450 ret = pwc_get_flicker(pdev, ARGA(flicker));
1451 ARG_OUT(flicker)
1361 break; 1452 break;
1362 } 1453 }
1363 1454
1364 case VIDIOCPWCSDYNNOISE: 1455 case VIDIOCPWCSDYNNOISE:
1365 { 1456 {
1366 int *dynnoise = arg; 1457 ARG_DEF(int, dynnoise)
1367 ret = pwc_set_dynamic_noise(pdev, *dynnoise); 1458
1459 ARG_IN(dynnoise)
1460 ret = pwc_set_dynamic_noise(pdev, ARGR(dynnoise));
1368 break; 1461 break;
1369 } 1462 }
1370 1463
1371 case VIDIOCPWCGDYNNOISE: 1464 case VIDIOCPWCGDYNNOISE:
1372 { 1465 {
1373 int *dynnoise = arg; 1466 ARG_DEF(int, dynnoise)
1374 ret = pwc_get_dynamic_noise(pdev, dynnoise); 1467
1468 ret = pwc_get_dynamic_noise(pdev, ARGA(dynnoise));
1469 ARG_OUT(dynnoise);
1375 break; 1470 break;
1376 } 1471 }
1377 1472
1378 case VIDIOCPWCGREALSIZE: 1473 case VIDIOCPWCGREALSIZE:
1379 { 1474 {
1380 struct pwc_imagesize *size = arg; 1475 ARG_DEF(struct pwc_imagesize, size)
1381 size->width = pdev->image.x; 1476
1382 size->height = pdev->image.y; 1477 ARGR(size).width = pdev->image.x;
1478 ARGR(size).height = pdev->image.y;
1479 ARG_OUT(size)
1383 break; 1480 break;
1384 } 1481 }
1385 1482
@@ -1387,14 +1484,10 @@ int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg)
1387 { 1484 {
1388 if (pdev->features & FEATURE_MOTOR_PANTILT) 1485 if (pdev->features & FEATURE_MOTOR_PANTILT)
1389 { 1486 {
1390 int *flags = arg; 1487 ARG_DEF(int, flags)
1391 1488
1392 ret = pwc_mpt_reset(pdev, *flags); 1489 ARG_IN(flags)
1393 if (ret >= 0) 1490 ret = pwc_mpt_reset(pdev, ARGR(flags));
1394 {
1395 pdev->pan_angle = 0;
1396 pdev->tilt_angle = 0;
1397 }
1398 } 1491 }
1399 else 1492 else
1400 { 1493 {
@@ -1407,8 +1500,10 @@ int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg)
1407 { 1500 {
1408 if (pdev->features & FEATURE_MOTOR_PANTILT) 1501 if (pdev->features & FEATURE_MOTOR_PANTILT)
1409 { 1502 {
1410 struct pwc_mpt_range *range = arg; 1503 ARG_DEF(struct pwc_mpt_range, range)
1411 *range = pdev->angle_range; 1504
1505 ARGR(range) = pdev->angle_range;
1506 ARG_OUT(range)
1412 } 1507 }
1413 else 1508 else
1414 { 1509 {
@@ -1423,48 +1518,23 @@ int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg)
1423 1518
1424 if (pdev->features & FEATURE_MOTOR_PANTILT) 1519 if (pdev->features & FEATURE_MOTOR_PANTILT)
1425 { 1520 {
1426 struct pwc_mpt_angles *angles = arg; 1521 ARG_DEF(struct pwc_mpt_angles, angles)
1522
1523 ARG_IN(angles)
1427 /* The camera can only set relative angles, so 1524 /* The camera can only set relative angles, so
1428 do some calculations when getting an absolute angle . 1525 do some calculations when getting an absolute angle .
1429 */ 1526 */
1430 if (angles->absolute) 1527 if (ARGR(angles).absolute)
1431 { 1528 {
1432 new_pan = angles->pan; 1529 new_pan = ARGR(angles).pan;
1433 new_tilt = angles->tilt; 1530 new_tilt = ARGR(angles).tilt;
1434 } 1531 }
1435 else 1532 else
1436 { 1533 {
1437 new_pan = pdev->pan_angle + angles->pan; 1534 new_pan = pdev->pan_angle + ARGR(angles).pan;
1438 new_tilt = pdev->tilt_angle + angles->tilt; 1535 new_tilt = pdev->tilt_angle + ARGR(angles).tilt;
1439 }
1440 /* check absolute ranges */
1441 if (new_pan < pdev->angle_range.pan_min ||
1442 new_pan > pdev->angle_range.pan_max ||
1443 new_tilt < pdev->angle_range.tilt_min ||
1444 new_tilt > pdev->angle_range.tilt_max)
1445 {
1446 ret = -ERANGE;
1447 }
1448 else
1449 {
1450 /* go to relative range, check again */
1451 new_pan -= pdev->pan_angle;
1452 new_tilt -= pdev->tilt_angle;
1453 /* angles are specified in degrees * 100, thus the limit = 36000 */
1454 if (new_pan < -36000 || new_pan > 36000 || new_tilt < -36000 || new_tilt > 36000)
1455 ret = -ERANGE;
1456 }
1457 if (ret == 0) /* no errors so far */
1458 {
1459 ret = pwc_mpt_set_angle(pdev, new_pan, new_tilt);
1460 if (ret >= 0)
1461 {
1462 pdev->pan_angle += new_pan;
1463 pdev->tilt_angle += new_tilt;
1464 }
1465 if (ret == -EPIPE) /* stall -> out of range */
1466 ret = -ERANGE;
1467 } 1536 }
1537 ret = pwc_mpt_set_angle(pdev, new_pan, new_tilt);
1468 } 1538 }
1469 else 1539 else
1470 { 1540 {
@@ -1478,11 +1548,12 @@ int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg)
1478 1548
1479 if (pdev->features & FEATURE_MOTOR_PANTILT) 1549 if (pdev->features & FEATURE_MOTOR_PANTILT)
1480 { 1550 {
1481 struct pwc_mpt_angles *angles = arg; 1551 ARG_DEF(struct pwc_mpt_angles, angles)
1482 1552
1483 angles->absolute = 1; 1553 ARGR(angles).absolute = 1;
1484 angles->pan = pdev->pan_angle; 1554 ARGR(angles).pan = pdev->pan_angle;
1485 angles->tilt = pdev->tilt_angle; 1555 ARGR(angles).tilt = pdev->tilt_angle;
1556 ARG_OUT(angles)
1486 } 1557 }
1487 else 1558 else
1488 { 1559 {
@@ -1495,8 +1566,10 @@ int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg)
1495 { 1566 {
1496 if (pdev->features & FEATURE_MOTOR_PANTILT) 1567 if (pdev->features & FEATURE_MOTOR_PANTILT)
1497 { 1568 {
1498 struct pwc_mpt_status *status = arg; 1569 ARG_DEF(struct pwc_mpt_status, status)
1499 ret = pwc_mpt_get_status(pdev, status); 1570
1571 ret = pwc_mpt_get_status(pdev, ARGA(status));
1572 ARG_OUT(status)
1500 } 1573 }
1501 else 1574 else
1502 { 1575 {
@@ -1507,22 +1580,24 @@ int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg)
1507 1580
1508 case VIDIOCPWCGVIDCMD: 1581 case VIDIOCPWCGVIDCMD:
1509 { 1582 {
1510 struct pwc_video_command *cmd = arg; 1583 ARG_DEF(struct pwc_video_command, cmd);
1511 1584
1512 cmd->type = pdev->type; 1585 ARGR(cmd).type = pdev->type;
1513 cmd->release = pdev->release; 1586 ARGR(cmd).release = pdev->release;
1514 cmd->command_len = pdev->cmd_len; 1587 ARGR(cmd).command_len = pdev->cmd_len;
1515 memcpy(&cmd->command_buf, pdev->cmd_buf, pdev->cmd_len); 1588 memcpy(&ARGR(cmd).command_buf, pdev->cmd_buf, pdev->cmd_len);
1516 cmd->bandlength = pdev->vbandlength; 1589 ARGR(cmd).bandlength = pdev->vbandlength;
1517 cmd->frame_size = pdev->frame_size; 1590 ARGR(cmd).frame_size = pdev->frame_size;
1591 ARG_OUT(cmd)
1518 break; 1592 break;
1519 } 1593 }
1520 /* 1594 /*
1521 case VIDIOCPWCGVIDTABLE: 1595 case VIDIOCPWCGVIDTABLE:
1522 { 1596 {
1523 struct pwc_table_init_buffer *table = arg; 1597 ARG_DEF(struct pwc_table_init_buffer, table);
1524 table->len = pdev->cmd_len; 1598 ARGR(table).len = pdev->cmd_len;
1525 memcpy(&table->buffer, pdev->decompress_data, pdev->decompressor->table_size); 1599 memcpy(&ARGR(table).buffer, pdev->decompress_data, pdev->decompressor->table_size);
1600 ARG_OUT(table)
1526 break; 1601 break;
1527 } 1602 }
1528 */ 1603 */
@@ -1538,4 +1613,4 @@ int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg)
1538} 1613}
1539 1614
1540 1615
1541 1616/* vim: set cinoptions= formatoptions=croql cindent shiftwidth=8 tabstop=8: */
diff --git a/drivers/media/video/pwc/pwc-dec1.c b/drivers/media/video/pwc/pwc-dec1.c
new file mode 100644
index 00000000000..c29593f589e
--- /dev/null
+++ b/drivers/media/video/pwc/pwc-dec1.c
@@ -0,0 +1,50 @@
1/* Linux driver for Philips webcam
2 Decompression for chipset version 1
3 (C) 2004-2006 Luc Saillard (luc@saillard.org)
4
5 NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx
6 driver and thus may have bugs that are not present in the original version.
7 Please send bug reports and support requests to <luc@saillard.org>.
8 The decompression routines have been implemented by reverse-engineering the
9 Nemosoft binary pwcx module. Caveat emptor.
10
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2 of the License, or
14 (at your option) any later version.
15
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
20
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24*/
25
26
27
28#include "pwc-dec1.h"
29
30
31void pwc_dec1_init(int type, int release, void *buffer, void *table)
32{
33
34}
35
36void pwc_dec1_exit(void)
37{
38
39
40
41}
42
43int pwc_dec1_alloc(struct pwc_device *pwc)
44{
45 pwc->decompress_data = kmalloc(sizeof(struct pwc_dec1_private), GFP_KERNEL);
46 if (pwc->decompress_data == NULL)
47 return -ENOMEM;
48 return 0;
49}
50
diff --git a/drivers/media/video/pwc/pwc-dec1.h b/drivers/media/video/pwc/pwc-dec1.h
new file mode 100644
index 00000000000..8b62ddcc5c7
--- /dev/null
+++ b/drivers/media/video/pwc/pwc-dec1.h
@@ -0,0 +1,43 @@
1/* Linux driver for Philips webcam
2 (C) 2004-2006 Luc Saillard (luc@saillard.org)
3
4 NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx
5 driver and thus may have bugs that are not present in the original version.
6 Please send bug reports and support requests to <luc@saillard.org>.
7 The decompression routines have been implemented by reverse-engineering the
8 Nemosoft binary pwcx module. Caveat emptor.
9
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23*/
24
25
26
27#ifndef PWC_DEC1_H
28#define PWC_DEC1_H
29
30#include "pwc.h"
31
32struct pwc_dec1_private
33{
34 int version;
35
36};
37
38int pwc_dec1_alloc(struct pwc_device *pwc);
39void pwc_dec1_init(int type, int release, void *buffer, void *private_data);
40void pwc_dec1_exit(void);
41
42#endif
43
diff --git a/drivers/media/video/pwc/pwc-dec23.c b/drivers/media/video/pwc/pwc-dec23.c
new file mode 100644
index 00000000000..9e2d91f26bf
--- /dev/null
+++ b/drivers/media/video/pwc/pwc-dec23.c
@@ -0,0 +1,941 @@
1/* Linux driver for Philips webcam
2 Decompression for chipset version 2 et 3
3 (C) 2004-2006 Luc Saillard (luc@saillard.org)
4
5 NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx
6 driver and thus may have bugs that are not present in the original version.
7 Please send bug reports and support requests to <luc@saillard.org>.
8 The decompression routines have been implemented by reverse-engineering the
9 Nemosoft binary pwcx module. Caveat emptor.
10
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2 of the License, or
14 (at your option) any later version.
15
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
20
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24
25*/
26
27#include "pwc-timon.h"
28#include "pwc-kiara.h"
29#include "pwc-dec23.h"
30#include <media/pwc-ioctl.h>
31
32#include <linux/string.h>
33
34/*
35 * USE_LOOKUP_TABLE_TO_CLAMP
36 * 0: use a C version of this tests: { a<0?0:(a>255?255:a) }
37 * 1: use a faster lookup table for cpu with a big cache (intel)
38 */
39#define USE_LOOKUP_TABLE_TO_CLAMP 1
40/*
41 * UNROLL_LOOP_FOR_COPYING_BLOCK
42 * 0: use a loop for a smaller code (but little slower)
43 * 1: when unrolling the loop, gcc produces some faster code (perhaps only
44 * valid for intel processor class). Activating this option, automaticaly
45 * activate USE_LOOKUP_TABLE_TO_CLAMP
46 */
47#define UNROLL_LOOP_FOR_COPY 1
48#if UNROLL_LOOP_FOR_COPY
49# undef USE_LOOKUP_TABLE_TO_CLAMP
50# define USE_LOOKUP_TABLE_TO_CLAMP 1
51#endif
52
53/*
54 * ENABLE_BAYER_DECODER
55 * 0: bayer decoder is not build (save some space)
56 * 1: bayer decoder is build and can be used
57 */
58#define ENABLE_BAYER_DECODER 0
59
60static void build_subblock_pattern(struct pwc_dec23_private *pdec)
61{
62 static const unsigned int initial_values[12] = {
63 -0x526500, -0x221200, 0x221200, 0x526500,
64 -0x3de200, 0x3de200,
65 -0x6db480, -0x2d5d00, 0x2d5d00, 0x6db480,
66 -0x12c200, 0x12c200
67
68 };
69 static const unsigned int values_derivated[12] = {
70 0xa4ca, 0x4424, -0x4424, -0xa4ca,
71 0x7bc4, -0x7bc4,
72 0xdb69, 0x5aba, -0x5aba, -0xdb69,
73 0x2584, -0x2584
74 };
75 unsigned int temp_values[12];
76 int i, j;
77
78 memcpy(temp_values, initial_values, sizeof(initial_values));
79 for (i = 0; i < 256; i++) {
80 for (j = 0; j < 12; j++) {
81 pdec->table_subblock[i][j] = temp_values[j];
82 temp_values[j] += values_derivated[j];
83 }
84 }
85}
86
87static void build_bit_powermask_table(struct pwc_dec23_private *pdec)
88{
89 unsigned char *p;
90 unsigned int bit, byte, mask, val;
91 unsigned int bitpower = 1;
92
93 for (bit = 0; bit < 8; bit++) {
94 mask = bitpower - 1;
95 p = pdec->table_bitpowermask[bit];
96 for (byte = 0; byte < 256; byte++) {
97 val = (byte & mask);
98 if (byte & bitpower)
99 val = -val;
100 *p++ = val;
101 }
102 bitpower<<=1;
103 }
104}
105
106
107static void build_table_color(const unsigned int romtable[16][8],
108 unsigned char p0004[16][1024],
109 unsigned char p8004[16][256])
110{
111 int compression_mode, j, k, bit, pw;
112 unsigned char *p0, *p8;
113 const unsigned int *r;
114
115 /* We have 16 compressions tables */
116 for (compression_mode = 0; compression_mode < 16; compression_mode++) {
117 p0 = p0004[compression_mode];
118 p8 = p8004[compression_mode];
119 r = romtable[compression_mode];
120
121 for (j = 0; j < 8; j++, r++, p0 += 128) {
122
123 for (k = 0; k < 16; k++) {
124 if (k == 0)
125 bit = 1;
126 else if (k >= 1 && k < 3)
127 bit = (r[0] >> 15) & 7;
128 else if (k >= 3 && k < 6)
129 bit = (r[0] >> 12) & 7;
130 else if (k >= 6 && k < 10)
131 bit = (r[0] >> 9) & 7;
132 else if (k >= 10 && k < 13)
133 bit = (r[0] >> 6) & 7;
134 else if (k >= 13 && k < 15)
135 bit = (r[0] >> 3) & 7;
136 else
137 bit = (r[0]) & 7;
138 if (k == 0)
139 *p8++ = 8;
140 else
141 *p8++ = j - bit;
142 *p8++ = bit;
143
144 pw = 1 << bit;
145 p0[k + 0x00] = (1 * pw) + 0x80;
146 p0[k + 0x10] = (2 * pw) + 0x80;
147 p0[k + 0x20] = (3 * pw) + 0x80;
148 p0[k + 0x30] = (4 * pw) + 0x80;
149 p0[k + 0x40] = (-1 * pw) + 0x80;
150 p0[k + 0x50] = (-2 * pw) + 0x80;
151 p0[k + 0x60] = (-3 * pw) + 0x80;
152 p0[k + 0x70] = (-4 * pw) + 0x80;
153 } /* end of for (k=0; k<16; k++, p8++) */
154 } /* end of for (j=0; j<8; j++ , table++) */
155 } /* end of foreach compression_mode */
156}
157
158/*
159 *
160 */
161static void fill_table_dc00_d800(struct pwc_dec23_private *pdec)
162{
163#define SCALEBITS 15
164#define ONE_HALF (1UL << (SCALEBITS - 1))
165 int i;
166 unsigned int offset1 = ONE_HALF;
167 unsigned int offset2 = 0x0000;
168
169 for (i=0; i<256; i++) {
170 pdec->table_dc00[i] = offset1 & ~(ONE_HALF);
171 pdec->table_d800[i] = offset2;
172
173 offset1 += 0x7bc4;
174 offset2 += 0x7bc4;
175 }
176}
177
178/*
179 * To decode the stream:
180 * if look_bits(2) == 0: # op == 2 in the lookup table
181 * skip_bits(2)
182 * end of the stream
183 * elif look_bits(3) == 7: # op == 1 in the lookup table
184 * skip_bits(3)
185 * yyyy = get_bits(4)
186 * xxxx = get_bits(8)
187 * else: # op == 0 in the lookup table
188 * skip_bits(x)
189 *
190 * For speedup processing, we build a lookup table and we takes the first 6 bits.
191 *
192 * struct {
193 * unsigned char op; // operation to execute
194 * unsigned char bits; // bits use to perform operation
195 * unsigned char offset1; // offset to add to access in the table_0004 % 16
196 * unsigned char offset2; // offset to add to access in the table_0004
197 * }
198 *
199 * How to build this table ?
200 * op == 2 when (i%4)==0
201 * op == 1 when (i%8)==7
202 * op == 0 otherwise
203 *
204 */
205static const unsigned char hash_table_ops[64*4] = {
206 0x02, 0x00, 0x00, 0x00,
207 0x00, 0x03, 0x01, 0x00,
208 0x00, 0x04, 0x01, 0x10,
209 0x00, 0x06, 0x01, 0x30,
210 0x02, 0x00, 0x00, 0x00,
211 0x00, 0x03, 0x01, 0x40,
212 0x00, 0x05, 0x01, 0x20,
213 0x01, 0x00, 0x00, 0x00,
214 0x02, 0x00, 0x00, 0x00,
215 0x00, 0x03, 0x01, 0x00,
216 0x00, 0x04, 0x01, 0x50,
217 0x00, 0x05, 0x02, 0x00,
218 0x02, 0x00, 0x00, 0x00,
219 0x00, 0x03, 0x01, 0x40,
220 0x00, 0x05, 0x03, 0x00,
221 0x01, 0x00, 0x00, 0x00,
222 0x02, 0x00, 0x00, 0x00,
223 0x00, 0x03, 0x01, 0x00,
224 0x00, 0x04, 0x01, 0x10,
225 0x00, 0x06, 0x02, 0x10,
226 0x02, 0x00, 0x00, 0x00,
227 0x00, 0x03, 0x01, 0x40,
228 0x00, 0x05, 0x01, 0x60,
229 0x01, 0x00, 0x00, 0x00,
230 0x02, 0x00, 0x00, 0x00,
231 0x00, 0x03, 0x01, 0x00,
232 0x00, 0x04, 0x01, 0x50,
233 0x00, 0x05, 0x02, 0x40,
234 0x02, 0x00, 0x00, 0x00,
235 0x00, 0x03, 0x01, 0x40,
236 0x00, 0x05, 0x03, 0x40,
237 0x01, 0x00, 0x00, 0x00,
238 0x02, 0x00, 0x00, 0x00,
239 0x00, 0x03, 0x01, 0x00,
240 0x00, 0x04, 0x01, 0x10,
241 0x00, 0x06, 0x01, 0x70,
242 0x02, 0x00, 0x00, 0x00,
243 0x00, 0x03, 0x01, 0x40,
244 0x00, 0x05, 0x01, 0x20,
245 0x01, 0x00, 0x00, 0x00,
246 0x02, 0x00, 0x00, 0x00,
247 0x00, 0x03, 0x01, 0x00,
248 0x00, 0x04, 0x01, 0x50,
249 0x00, 0x05, 0x02, 0x00,
250 0x02, 0x00, 0x00, 0x00,
251 0x00, 0x03, 0x01, 0x40,
252 0x00, 0x05, 0x03, 0x00,
253 0x01, 0x00, 0x00, 0x00,
254 0x02, 0x00, 0x00, 0x00,
255 0x00, 0x03, 0x01, 0x00,
256 0x00, 0x04, 0x01, 0x10,
257 0x00, 0x06, 0x02, 0x50,
258 0x02, 0x00, 0x00, 0x00,
259 0x00, 0x03, 0x01, 0x40,
260 0x00, 0x05, 0x01, 0x60,
261 0x01, 0x00, 0x00, 0x00,
262 0x02, 0x00, 0x00, 0x00,
263 0x00, 0x03, 0x01, 0x00,
264 0x00, 0x04, 0x01, 0x50,
265 0x00, 0x05, 0x02, 0x40,
266 0x02, 0x00, 0x00, 0x00,
267 0x00, 0x03, 0x01, 0x40,
268 0x00, 0x05, 0x03, 0x40,
269 0x01, 0x00, 0x00, 0x00
270};
271
272/*
273 *
274 */
275static const unsigned int MulIdx[16][16] = {
276 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,},
277 {0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3,},
278 {0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3,},
279 {4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4,},
280 {6, 7, 8, 9, 7, 10, 11, 8, 8, 11, 10, 7, 9, 8, 7, 6,},
281 {4, 5, 5, 4, 4, 5, 5, 4, 4, 5, 5, 4, 4, 5, 5, 4,},
282 {1, 3, 0, 2, 1, 3, 0, 2, 1, 3, 0, 2, 1, 3, 0, 2,},
283 {0, 3, 3, 0, 1, 2, 2, 1, 2, 1, 1, 2, 3, 0, 0, 3,},
284 {0, 1, 2, 3, 3, 2, 1, 0, 3, 2, 1, 0, 0, 1, 2, 3,},
285 {1, 1, 1, 1, 3, 3, 3, 3, 0, 0, 0, 0, 2, 2, 2, 2,},
286 {7, 10, 11, 8, 9, 8, 7, 6, 6, 7, 8, 9, 8, 11, 10, 7,},
287 {4, 5, 5, 4, 5, 4, 4, 5, 5, 4, 4, 5, 4, 5, 5, 4,},
288 {7, 9, 6, 8, 10, 8, 7, 11, 11, 7, 8, 10, 8, 6, 9, 7,},
289 {1, 3, 0, 2, 2, 0, 3, 1, 2, 0, 3, 1, 1, 3, 0, 2,},
290 {1, 2, 2, 1, 3, 0, 0, 3, 0, 3, 3, 0, 2, 1, 1, 2,},
291 {10, 8, 7, 11, 8, 6, 9, 7, 7, 9, 6, 8, 11, 7, 8, 10}
292};
293
294#if USE_LOOKUP_TABLE_TO_CLAMP
295#define MAX_OUTER_CROP_VALUE (512)
296static unsigned char pwc_crop_table[256 + 2*MAX_OUTER_CROP_VALUE];
297#define CLAMP(x) (pwc_crop_table[MAX_OUTER_CROP_VALUE+(x)])
298#else
299#define CLAMP(x) ((x)>255?255:((x)<0?0:x))
300#endif
301
302
303/* If the type or the command change, we rebuild the lookup table */
304int pwc_dec23_init(struct pwc_device *pwc, int type, unsigned char *cmd)
305{
306 int flags, version, shift, i;
307 struct pwc_dec23_private *pdec;
308
309 if (pwc->decompress_data == NULL) {
310 pdec = kmalloc(sizeof(struct pwc_dec23_private), GFP_KERNEL);
311 if (pdec == NULL)
312 return -ENOMEM;
313 pwc->decompress_data = pdec;
314 }
315 pdec = pwc->decompress_data;
316
317 if (DEVICE_USE_CODEC3(type)) {
318 flags = cmd[2] & 0x18;
319 if (flags == 8)
320 pdec->nbits = 7; /* More bits, mean more bits to encode the stream, but better quality */
321 else if (flags == 0x10)
322 pdec->nbits = 8;
323 else
324 pdec->nbits = 6;
325
326 version = cmd[2] >> 5;
327 build_table_color(KiaraRomTable[version][0], pdec->table_0004_pass1, pdec->table_8004_pass1);
328 build_table_color(KiaraRomTable[version][1], pdec->table_0004_pass2, pdec->table_8004_pass2);
329
330 } else {
331
332 flags = cmd[2] & 6;
333 if (flags == 2)
334 pdec->nbits = 7;
335 else if (flags == 4)
336 pdec->nbits = 8;
337 else
338 pdec->nbits = 6;
339
340 version = cmd[2] >> 3;
341 build_table_color(TimonRomTable[version][0], pdec->table_0004_pass1, pdec->table_8004_pass1);
342 build_table_color(TimonRomTable[version][1], pdec->table_0004_pass2, pdec->table_8004_pass2);
343 }
344
345 /* Informations can be coded on a variable number of bits but never less than 8 */
346 shift = 8 - pdec->nbits;
347 pdec->scalebits = SCALEBITS - shift;
348 pdec->nbitsmask = 0xFF >> shift;
349
350 fill_table_dc00_d800(pdec);
351 build_subblock_pattern(pdec);
352 build_bit_powermask_table(pdec);
353
354#if USE_LOOKUP_TABLE_TO_CLAMP
355 /* Build the static table to clamp value [0-255] */
356 for (i=0;i<MAX_OUTER_CROP_VALUE;i++)
357 pwc_crop_table[i] = 0;
358 for (i=0; i<256; i++)
359 pwc_crop_table[MAX_OUTER_CROP_VALUE+i] = i;
360 for (i=0; i<MAX_OUTER_CROP_VALUE; i++)
361 pwc_crop_table[MAX_OUTER_CROP_VALUE+256+i] = 255;
362#endif
363
364 return 0;
365}
366
367/*
368 * Copy the 4x4 image block to Y plane buffer
369 */
370static void copy_image_block_Y(const int *src, unsigned char *dst, unsigned int bytes_per_line, unsigned int scalebits)
371{
372#if UNROLL_LOOP_FOR_COPY
373 const unsigned char *cm = pwc_crop_table+MAX_OUTER_CROP_VALUE;
374 const int *c = src;
375 unsigned char *d = dst;
376
377 *d++ = cm[c[0] >> scalebits];
378 *d++ = cm[c[1] >> scalebits];
379 *d++ = cm[c[2] >> scalebits];
380 *d++ = cm[c[3] >> scalebits];
381
382 d = dst + bytes_per_line;
383 *d++ = cm[c[4] >> scalebits];
384 *d++ = cm[c[5] >> scalebits];
385 *d++ = cm[c[6] >> scalebits];
386 *d++ = cm[c[7] >> scalebits];
387
388 d = dst + bytes_per_line*2;
389 *d++ = cm[c[8] >> scalebits];
390 *d++ = cm[c[9] >> scalebits];
391 *d++ = cm[c[10] >> scalebits];
392 *d++ = cm[c[11] >> scalebits];
393
394 d = dst + bytes_per_line*3;
395 *d++ = cm[c[12] >> scalebits];
396 *d++ = cm[c[13] >> scalebits];
397 *d++ = cm[c[14] >> scalebits];
398 *d++ = cm[c[15] >> scalebits];
399#else
400 int i;
401 const int *c = src;
402 unsigned char *d = dst;
403 for (i = 0; i < 4; i++, c++)
404 *d++ = CLAMP((*c) >> scalebits);
405
406 d = dst + bytes_per_line;
407 for (i = 0; i < 4; i++, c++)
408 *d++ = CLAMP((*c) >> scalebits);
409
410 d = dst + bytes_per_line*2;
411 for (i = 0; i < 4; i++, c++)
412 *d++ = CLAMP((*c) >> scalebits);
413
414 d = dst + bytes_per_line*3;
415 for (i = 0; i < 4; i++, c++)
416 *d++ = CLAMP((*c) >> scalebits);
417#endif
418}
419
420/*
421 * Copy the 4x4 image block to a CrCb plane buffer
422 *
423 */
424static void copy_image_block_CrCb(const int *src, unsigned char *dst, unsigned int bytes_per_line, unsigned int scalebits)
425{
426#if UNROLL_LOOP_FOR_COPY
427 /* Unroll all loops */
428 const unsigned char *cm = pwc_crop_table+MAX_OUTER_CROP_VALUE;
429 const int *c = src;
430 unsigned char *d = dst;
431
432 *d++ = cm[c[0] >> scalebits];
433 *d++ = cm[c[4] >> scalebits];
434 *d++ = cm[c[1] >> scalebits];
435 *d++ = cm[c[5] >> scalebits];
436 *d++ = cm[c[2] >> scalebits];
437 *d++ = cm[c[6] >> scalebits];
438 *d++ = cm[c[3] >> scalebits];
439 *d++ = cm[c[7] >> scalebits];
440
441 d = dst + bytes_per_line;
442 *d++ = cm[c[12] >> scalebits];
443 *d++ = cm[c[8] >> scalebits];
444 *d++ = cm[c[13] >> scalebits];
445 *d++ = cm[c[9] >> scalebits];
446 *d++ = cm[c[14] >> scalebits];
447 *d++ = cm[c[10] >> scalebits];
448 *d++ = cm[c[15] >> scalebits];
449 *d++ = cm[c[11] >> scalebits];
450#else
451 int i;
452 const int *c1 = src;
453 const int *c2 = src + 4;
454 unsigned char *d = dst;
455
456 for (i = 0; i < 4; i++, c1++, c2++) {
457 *d++ = CLAMP((*c1) >> scalebits);
458 *d++ = CLAMP((*c2) >> scalebits);
459 }
460 c1 = src + 12;
461 d = dst + bytes_per_line;
462 for (i = 0; i < 4; i++, c1++, c2++) {
463 *d++ = CLAMP((*c1) >> scalebits);
464 *d++ = CLAMP((*c2) >> scalebits);
465 }
466#endif
467}
468
469#if ENABLE_BAYER_DECODER
470/*
471 * Format: 8x2 pixels
472 * . G . G . G . G . G . G . G
473 * . . . . . . . . . . . . . .
474 * . G . G . G . G . G . G . G
475 * . . . . . . . . . . . . . .
476 * or
477 * . . . . . . . . . . . . . .
478 * G . G . G . G . G . G . G .
479 * . . . . . . . . . . . . . .
480 * G . G . G . G . G . G . G .
481*/
482static void copy_image_block_Green(const int *src, unsigned char *dst, unsigned int bytes_per_line, unsigned int scalebits)
483{
484#if UNROLL_LOOP_FOR_COPY
485 /* Unroll all loops */
486 const unsigned char *cm = pwc_crop_table+MAX_OUTER_CROP_VALUE;
487 unsigned char *d = dst;
488 const int *c = src;
489
490 d[0] = cm[c[0] >> scalebits];
491 d[2] = cm[c[1] >> scalebits];
492 d[4] = cm[c[2] >> scalebits];
493 d[6] = cm[c[3] >> scalebits];
494 d[8] = cm[c[4] >> scalebits];
495 d[10] = cm[c[5] >> scalebits];
496 d[12] = cm[c[6] >> scalebits];
497 d[14] = cm[c[7] >> scalebits];
498
499 d = dst + bytes_per_line;
500 d[0] = cm[c[8] >> scalebits];
501 d[2] = cm[c[9] >> scalebits];
502 d[4] = cm[c[10] >> scalebits];
503 d[6] = cm[c[11] >> scalebits];
504 d[8] = cm[c[12] >> scalebits];
505 d[10] = cm[c[13] >> scalebits];
506 d[12] = cm[c[14] >> scalebits];
507 d[14] = cm[c[15] >> scalebits];
508#else
509 int i;
510 unsigned char *d;
511 const int *c = src;
512
513 d = dst;
514 for (i = 0; i < 8; i++, c++)
515 d[i*2] = CLAMP((*c) >> scalebits);
516
517 d = dst + bytes_per_line;
518 for (i = 0; i < 8; i++, c++)
519 d[i*2] = CLAMP((*c) >> scalebits);
520#endif
521}
522#endif
523
524#if ENABLE_BAYER_DECODER
525/*
526 * Format: 4x4 pixels
527 * R . R . R . R
528 * . B . B . B .
529 * R . R . R . R
530 * . B . B . B .
531 */
532static void copy_image_block_RedBlue(const int *src, unsigned char *dst, unsigned int bytes_per_line, unsigned int scalebits)
533{
534#if UNROLL_LOOP_FOR_COPY
535 /* Unroll all loops */
536 const unsigned char *cm = pwc_crop_table+MAX_OUTER_CROP_VALUE;
537 unsigned char *d = dst;
538 const int *c = src;
539
540 d[0] = cm[c[0] >> scalebits];
541 d[2] = cm[c[1] >> scalebits];
542 d[4] = cm[c[2] >> scalebits];
543 d[6] = cm[c[3] >> scalebits];
544
545 d = dst + bytes_per_line;
546 d[1] = cm[c[4] >> scalebits];
547 d[3] = cm[c[5] >> scalebits];
548 d[5] = cm[c[6] >> scalebits];
549 d[7] = cm[c[7] >> scalebits];
550
551 d = dst + bytes_per_line*2;
552 d[0] = cm[c[8] >> scalebits];
553 d[2] = cm[c[9] >> scalebits];
554 d[4] = cm[c[10] >> scalebits];
555 d[6] = cm[c[11] >> scalebits];
556
557 d = dst + bytes_per_line*3;
558 d[1] = cm[c[12] >> scalebits];
559 d[3] = cm[c[13] >> scalebits];
560 d[5] = cm[c[14] >> scalebits];
561 d[7] = cm[c[15] >> scalebits];
562#else
563 int i;
564 unsigned char *d;
565 const int *c = src;
566
567 d = dst;
568 for (i = 0; i < 4; i++, c++)
569 d[i*2] = CLAMP((*c) >> scalebits);
570
571 d = dst + bytes_per_line;
572 for (i = 0; i < 4; i++, c++)
573 d[i*2+1] = CLAMP((*c) >> scalebits);
574
575 d = dst + bytes_per_line*2;
576 for (i = 0; i < 4; i++, c++)
577 d[i*2] = CLAMP((*c) >> scalebits);
578
579 d = dst + bytes_per_line*3;
580 for (i = 0; i < 4; i++, c++)
581 d[i*2+1] = CLAMP((*c) >> scalebits);
582#endif
583}
584#endif
585
586/*
587 * To manage the stream, we keep bits in a 32 bits register.
588 * fill_nbits(n): fill the reservoir with at least n bits
589 * skip_bits(n): discard n bits from the reservoir
590 * get_bits(n): fill the reservoir, returns the first n bits and discard the
591 * bits from the reservoir.
592 * __get_nbits(n): faster version of get_bits(n), but asumes that the reservoir
593 * contains at least n bits. bits returned is discarded.
594 */
595#define fill_nbits(pdec, nbits_wanted) do { \
596 while (pdec->nbits_in_reservoir<(nbits_wanted)) \
597 { \
598 pdec->reservoir |= (*(pdec->stream)++) << (pdec->nbits_in_reservoir); \
599 pdec->nbits_in_reservoir += 8; \
600 } \
601} while(0);
602
603#define skip_nbits(pdec, nbits_to_skip) do { \
604 pdec->reservoir >>= (nbits_to_skip); \
605 pdec->nbits_in_reservoir -= (nbits_to_skip); \
606} while(0);
607
608#define get_nbits(pdec, nbits_wanted, result) do { \
609 fill_nbits(pdec, nbits_wanted); \
610 result = (pdec->reservoir) & ((1U<<(nbits_wanted))-1); \
611 skip_nbits(pdec, nbits_wanted); \
612} while(0);
613
614#define __get_nbits(pdec, nbits_wanted, result) do { \
615 result = (pdec->reservoir) & ((1U<<(nbits_wanted))-1); \
616 skip_nbits(pdec, nbits_wanted); \
617} while(0);
618
619#define look_nbits(pdec, nbits_wanted) \
620 ((pdec->reservoir) & ((1U<<(nbits_wanted))-1))
621
622/*
623 * Decode a 4x4 pixel block
624 */
625static void decode_block(struct pwc_dec23_private *pdec,
626 const unsigned char *ptable0004,
627 const unsigned char *ptable8004)
628{
629 unsigned int primary_color;
630 unsigned int channel_v, offset1, op;
631 int i;
632
633 fill_nbits(pdec, 16);
634 __get_nbits(pdec, pdec->nbits, primary_color);
635
636 if (look_nbits(pdec,2) == 0) {
637 skip_nbits(pdec, 2);
638 /* Very simple, the color is the same for all pixels of the square */
639 for (i = 0; i < 16; i++)
640 pdec->temp_colors[i] = pdec->table_dc00[primary_color];
641
642 return;
643 }
644
645 /* This block is encoded with small pattern */
646 for (i = 0; i < 16; i++)
647 pdec->temp_colors[i] = pdec->table_d800[primary_color];
648
649 __get_nbits(pdec, 3, channel_v);
650 channel_v = ((channel_v & 1) << 2) | (channel_v & 2) | ((channel_v & 4) >> 2);
651
652 ptable0004 += (channel_v * 128);
653 ptable8004 += (channel_v * 32);
654
655 offset1 = 0;
656 do
657 {
658 unsigned int htable_idx, rows = 0;
659 const unsigned int *block;
660
661 /* [ zzzz y x x ]
662 * xx == 00 :=> end of the block def, remove the two bits from the stream
663 * yxx == 111
664 * yxx == any other value
665 *
666 */
667 fill_nbits(pdec, 16);
668 htable_idx = look_nbits(pdec, 6);
669 op = hash_table_ops[htable_idx * 4];
670
671 if (op == 2) {
672 skip_nbits(pdec, 2);
673
674 } else if (op == 1) {
675 /* 15bits [ xxxx xxxx yyyy 111 ]
676 * yyy => offset in the table8004
677 * xxx => offset in the tabled004 (tree)
678 */
679 unsigned int mask, shift;
680 unsigned int nbits, col1;
681 unsigned int yyyy;
682
683 skip_nbits(pdec, 3);
684 /* offset1 += yyyy */
685 __get_nbits(pdec, 4, yyyy);
686 offset1 += 1 + yyyy;
687 offset1 &= 0x0F;
688 nbits = ptable8004[offset1 * 2];
689
690 /* col1 = xxxx xxxx */
691 __get_nbits(pdec, nbits+1, col1);
692
693 /* Bit mask table */
694 mask = pdec->table_bitpowermask[nbits][col1];
695 shift = ptable8004[offset1 * 2 + 1];
696 rows = ((mask << shift) + 0x80) & 0xFF;
697
698 block = pdec->table_subblock[rows];
699 for (i = 0; i < 16; i++)
700 pdec->temp_colors[i] += block[MulIdx[offset1][i]];
701
702 } else {
703 /* op == 0
704 * offset1 is coded on 3 bits
705 */
706 unsigned int shift;
707
708 offset1 += hash_table_ops [htable_idx * 4 + 2];
709 offset1 &= 0x0F;
710
711 rows = ptable0004[offset1 + hash_table_ops [htable_idx * 4 + 3]];
712 block = pdec->table_subblock[rows];
713 for (i = 0; i < 16; i++)
714 pdec->temp_colors[i] += block[MulIdx[offset1][i]];
715
716 shift = hash_table_ops[htable_idx * 4 + 1];
717 skip_nbits(pdec, shift);
718 }
719
720 } while (op != 2);
721
722}
723
724static void DecompressBand23(struct pwc_dec23_private *pdec,
725 const unsigned char *rawyuv,
726 unsigned char *planar_y,
727 unsigned char *planar_u,
728 unsigned char *planar_v,
729 unsigned int compressed_image_width,
730 unsigned int real_image_width)
731{
732 int compression_index, nblocks;
733 const unsigned char *ptable0004;
734 const unsigned char *ptable8004;
735
736 pdec->reservoir = 0;
737 pdec->nbits_in_reservoir = 0;
738 pdec->stream = rawyuv + 1; /* The first byte of the stream is skipped */
739
740 get_nbits(pdec, 4, compression_index);
741
742 /* pass 1: uncompress Y component */
743 nblocks = compressed_image_width / 4;
744
745 ptable0004 = pdec->table_0004_pass1[compression_index];
746 ptable8004 = pdec->table_8004_pass1[compression_index];
747
748 /* Each block decode a square of 4x4 */
749 while (nblocks) {
750 decode_block(pdec, ptable0004, ptable8004);
751 copy_image_block_Y(pdec->temp_colors, planar_y, real_image_width, pdec->scalebits);
752 planar_y += 4;
753 nblocks--;
754 }
755
756 /* pass 2: uncompress UV component */
757 nblocks = compressed_image_width / 8;
758
759 ptable0004 = pdec->table_0004_pass2[compression_index];
760 ptable8004 = pdec->table_8004_pass2[compression_index];
761
762 /* Each block decode a square of 4x4 */
763 while (nblocks) {
764 decode_block(pdec, ptable0004, ptable8004);
765 copy_image_block_CrCb(pdec->temp_colors, planar_u, real_image_width/2, pdec->scalebits);
766
767 decode_block(pdec, ptable0004, ptable8004);
768 copy_image_block_CrCb(pdec->temp_colors, planar_v, real_image_width/2, pdec->scalebits);
769
770 planar_v += 8;
771 planar_u += 8;
772 nblocks -= 2;
773 }
774
775}
776
777#if ENABLE_BAYER_DECODER
778/*
779 * Size need to be a multiple of 8 in width
780 *
781 * Return a block of four line encoded like this:
782 *
783 * G R G R G R G R G R G R G R G R
784 * B G B G B G B G B G B G B G B G
785 * G R G R G R G R G R G R G R G R
786 * B G B G B G B G B G B G B G B G
787 *
788 */
789static void DecompressBandBayer(struct pwc_dec23_private *pdec,
790 const unsigned char *rawyuv,
791 unsigned char *rgbbayer,
792 unsigned int compressed_image_width,
793 unsigned int real_image_width)
794{
795 int compression_index, nblocks;
796 const unsigned char *ptable0004;
797 const unsigned char *ptable8004;
798 unsigned char *dest;
799
800 pdec->reservoir = 0;
801 pdec->nbits_in_reservoir = 0;
802 pdec->stream = rawyuv + 1; /* The first byte of the stream is skipped */
803
804 get_nbits(pdec, 4, compression_index);
805
806 /* pass 1: uncompress RB component */
807 nblocks = compressed_image_width / 4;
808
809 ptable0004 = pdec->table_0004_pass1[compression_index];
810 ptable8004 = pdec->table_8004_pass1[compression_index];
811 dest = rgbbayer;
812
813 /* Each block decode a square of 4x4 */
814 while (nblocks) {
815 decode_block(pdec, ptable0004, ptable8004);
816 copy_image_block_RedBlue(pdec->temp_colors, rgbbayer, real_image_width, pdec->scalebits);
817 dest += 8;
818 nblocks--;
819 }
820
821 /* pass 2: uncompress G component */
822 nblocks = compressed_image_width / 8;
823
824 ptable0004 = pdec->table_0004_pass2[compression_index];
825 ptable8004 = pdec->table_8004_pass2[compression_index];
826
827 /* Each block decode a square of 4x4 */
828 while (nblocks) {
829 decode_block(pdec, ptable0004, ptable8004);
830 copy_image_block_Green(pdec->temp_colors, rgbbayer+1, real_image_width, pdec->scalebits);
831
832 decode_block(pdec, ptable0004, ptable8004);
833 copy_image_block_Green(pdec->temp_colors, rgbbayer+real_image_width, real_image_width, pdec->scalebits);
834
835 rgbbayer += 16;
836 nblocks -= 2;
837 }
838}
839#endif
840
841
842/**
843 *
844 * Uncompress a pwc23 buffer.
845 *
846 * pwc.view: size of the image wanted
847 * pwc.image: size of the image returned by the camera
848 * pwc.offset: (x,y) to displayer image in the view
849 *
850 * src: raw data
851 * dst: image output
852 * flags: PWCX_FLAG_PLANAR or PWCX_FLAG_BAYER
853 */
854void pwc_dec23_decompress(const struct pwc_device *pwc,
855 const void *src,
856 void *dst,
857 int flags)
858{
859 int bandlines_left, stride, bytes_per_block;
860
861 bandlines_left = pwc->image.y / 4;
862 bytes_per_block = pwc->view.x * 4;
863
864 if (flags & PWCX_FLAG_BAYER) {
865#if ENABLE_BAYER_DECODER
866 /* RGB Bayer format */
867 unsigned char *rgbout;
868
869 stride = pwc->view.x * pwc->offset.y;
870 rgbout = dst + stride + pwc->offset.x;
871
872
873 while (bandlines_left--) {
874
875 DecompressBandBayer(pwc->decompress_data,
876 src,
877 rgbout,
878 pwc->image.x, pwc->view.x);
879
880 src += pwc->vbandlength;
881 rgbout += bytes_per_block;
882
883 }
884#else
885 memset(dst, 0, pwc->view.x * pwc->view.y);
886#endif
887
888 } else {
889 /* YUV420P image format */
890 unsigned char *pout_planar_y;
891 unsigned char *pout_planar_u;
892 unsigned char *pout_planar_v;
893 unsigned int plane_size;
894
895 plane_size = pwc->view.x * pwc->view.y;
896
897 /* offset in Y plane */
898 stride = pwc->view.x * pwc->offset.y;
899 pout_planar_y = dst + stride + pwc->offset.x;
900
901 /* offsets in U/V planes */
902 stride = (pwc->view.x * pwc->offset.y) / 4 + pwc->offset.x / 2;
903 pout_planar_u = dst + plane_size + stride;
904 pout_planar_v = dst + plane_size + plane_size / 4 + stride;
905
906 while (bandlines_left--) {
907
908 DecompressBand23(pwc->decompress_data,
909 src,
910 pout_planar_y, pout_planar_u, pout_planar_v,
911 pwc->image.x, pwc->view.x);
912 src += pwc->vbandlength;
913 pout_planar_y += bytes_per_block;
914 pout_planar_u += pwc->view.x;
915 pout_planar_v += pwc->view.x;
916
917 }
918
919 }
920
921}
922
923void pwc_dec23_exit(void)
924{
925 /* Do nothing */
926
927}
928
929/**
930 * Allocate a private structure used by lookup table.
931 * You must call kfree() to free the memory allocated.
932 */
933int pwc_dec23_alloc(struct pwc_device *pwc)
934{
935 pwc->decompress_data = kmalloc(sizeof(struct pwc_dec23_private), GFP_KERNEL);
936 if (pwc->decompress_data == NULL)
937 return -ENOMEM;
938 return 0;
939}
940
941/* vim: set cino= formatoptions=croql cindent shiftwidth=8 tabstop=8: */
diff --git a/drivers/media/video/pwc/pwc-dec23.h b/drivers/media/video/pwc/pwc-dec23.h
new file mode 100644
index 00000000000..1c55298ad15
--- /dev/null
+++ b/drivers/media/video/pwc/pwc-dec23.h
@@ -0,0 +1,67 @@
1/* Linux driver for Philips webcam
2 (C) 2004-2006 Luc Saillard (luc@saillard.org)
3
4 NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx
5 driver and thus may have bugs that are not present in the original version.
6 Please send bug reports and support requests to <luc@saillard.org>.
7 The decompression routines have been implemented by reverse-engineering the
8 Nemosoft binary pwcx module. Caveat emptor.
9
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23*/
24
25#ifndef PWC_DEC23_H
26#define PWC_DEC23_H
27
28#include "pwc.h"
29
30struct pwc_dec23_private
31{
32 unsigned int scalebits;
33 unsigned int nbitsmask, nbits; /* Number of bits of a color in the compressed stream */
34
35 unsigned int reservoir;
36 unsigned int nbits_in_reservoir;
37 const unsigned char *stream;
38 int temp_colors[16];
39
40 unsigned char table_0004_pass1[16][1024];
41 unsigned char table_0004_pass2[16][1024];
42 unsigned char table_8004_pass1[16][256];
43 unsigned char table_8004_pass2[16][256];
44 unsigned int table_subblock[256][12];
45
46 unsigned char table_bitpowermask[8][256];
47 unsigned int table_d800[256];
48 unsigned int table_dc00[256];
49
50};
51
52
53int pwc_dec23_alloc(struct pwc_device *pwc);
54int pwc_dec23_init(struct pwc_device *pwc, int type, unsigned char *cmd);
55void pwc_dec23_exit(void);
56void pwc_dec23_decompress(const struct pwc_device *pwc,
57 const void *src,
58 void *dst,
59 int flags);
60
61
62
63#endif
64
65
66/* vim: set cino= formatoptions=croql cindent shiftwidth=8 tabstop=8: */
67
diff --git a/drivers/media/video/pwc/pwc-if.c b/drivers/media/video/pwc/pwc-if.c
index 41418294a32..47d0d83a026 100644
--- a/drivers/media/video/pwc/pwc-if.c
+++ b/drivers/media/video/pwc/pwc-if.c
@@ -1,7 +1,7 @@
1/* Linux driver for Philips webcam 1/* Linux driver for Philips webcam
2 USB and Video4Linux interface part. 2 USB and Video4Linux interface part.
3 (C) 1999-2004 Nemosoft Unv. 3 (C) 1999-2004 Nemosoft Unv.
4 (C) 2004 Luc Saillard (luc@saillard.org) 4 (C) 2004-2006 Luc Saillard (luc@saillard.org)
5 5
6 NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx 6 NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx
7 driver and thus may have bugs that are not present in the original version. 7 driver and thus may have bugs that are not present in the original version.
@@ -62,18 +62,21 @@
62#include <linux/poll.h> 62#include <linux/poll.h>
63#include <linux/slab.h> 63#include <linux/slab.h>
64#include <linux/vmalloc.h> 64#include <linux/vmalloc.h>
65#include <linux/version.h>
65#include <asm/io.h> 66#include <asm/io.h>
67#include <linux/moduleparam.h>
66 68
67#include "pwc.h" 69#include "pwc.h"
68#include "pwc-ioctl.h"
69#include "pwc-kiara.h" 70#include "pwc-kiara.h"
70#include "pwc-timon.h" 71#include "pwc-timon.h"
72#include "pwc-dec23.h"
73#include "pwc-dec1.h"
71#include "pwc-uncompress.h" 74#include "pwc-uncompress.h"
72 75
73/* Function prototypes and driver templates */ 76/* Function prototypes and driver templates */
74 77
75/* hotplug device table support */ 78/* hotplug device table support */
76static struct usb_device_id pwc_device_table [] = { 79static const struct usb_device_id pwc_device_table [] = {
77 { USB_DEVICE(0x0471, 0x0302) }, /* Philips models */ 80 { USB_DEVICE(0x0471, 0x0302) }, /* Philips models */
78 { USB_DEVICE(0x0471, 0x0303) }, 81 { USB_DEVICE(0x0471, 0x0303) },
79 { USB_DEVICE(0x0471, 0x0304) }, 82 { USB_DEVICE(0x0471, 0x0304) },
@@ -81,9 +84,10 @@ static struct usb_device_id pwc_device_table [] = {
81 { USB_DEVICE(0x0471, 0x0308) }, 84 { USB_DEVICE(0x0471, 0x0308) },
82 { USB_DEVICE(0x0471, 0x030C) }, 85 { USB_DEVICE(0x0471, 0x030C) },
83 { USB_DEVICE(0x0471, 0x0310) }, 86 { USB_DEVICE(0x0471, 0x0310) },
84 { USB_DEVICE(0x0471, 0x0311) }, 87 { USB_DEVICE(0x0471, 0x0311) }, /* Philips ToUcam PRO II */
85 { USB_DEVICE(0x0471, 0x0312) }, 88 { USB_DEVICE(0x0471, 0x0312) },
86 { USB_DEVICE(0x0471, 0x0313) }, /* the 'new' 720K */ 89 { USB_DEVICE(0x0471, 0x0313) }, /* the 'new' 720K */
90 { USB_DEVICE(0x0471, 0x0329) }, /* Philips SPC 900NC PC Camera */
87 { USB_DEVICE(0x069A, 0x0001) }, /* Askey */ 91 { USB_DEVICE(0x069A, 0x0001) }, /* Askey */
88 { USB_DEVICE(0x046D, 0x08B0) }, /* Logitech QuickCam Pro 3000 */ 92 { USB_DEVICE(0x046D, 0x08B0) }, /* Logitech QuickCam Pro 3000 */
89 { USB_DEVICE(0x046D, 0x08B1) }, /* Logitech QuickCam Notebook Pro */ 93 { USB_DEVICE(0x046D, 0x08B1) }, /* Logitech QuickCam Notebook Pro */
@@ -94,8 +98,9 @@ static struct usb_device_id pwc_device_table [] = {
94 { USB_DEVICE(0x046D, 0x08B6) }, /* Logitech (reserved) */ 98 { USB_DEVICE(0x046D, 0x08B6) }, /* Logitech (reserved) */
95 { USB_DEVICE(0x046D, 0x08B7) }, /* Logitech (reserved) */ 99 { USB_DEVICE(0x046D, 0x08B7) }, /* Logitech (reserved) */
96 { USB_DEVICE(0x046D, 0x08B8) }, /* Logitech (reserved) */ 100 { USB_DEVICE(0x046D, 0x08B8) }, /* Logitech (reserved) */
97 { USB_DEVICE(0x055D, 0x9000) }, /* Samsung */ 101 { USB_DEVICE(0x055D, 0x9000) }, /* Samsung MPC-C10 */
98 { USB_DEVICE(0x055D, 0x9001) }, 102 { USB_DEVICE(0x055D, 0x9001) }, /* Samsung MPC-C30 */
103 { USB_DEVICE(0x055D, 0x9002) }, /* Samsung SNC-35E (Ver3.0) */
99 { USB_DEVICE(0x041E, 0x400C) }, /* Creative Webcam 5 */ 104 { USB_DEVICE(0x041E, 0x400C) }, /* Creative Webcam 5 */
100 { USB_DEVICE(0x041E, 0x4011) }, /* Creative Webcam Pro Ex */ 105 { USB_DEVICE(0x041E, 0x4011) }, /* Creative Webcam Pro Ex */
101 { USB_DEVICE(0x04CC, 0x8116) }, /* Afina Eye */ 106 { USB_DEVICE(0x04CC, 0x8116) }, /* Afina Eye */
@@ -122,11 +127,13 @@ static struct usb_driver pwc_driver = {
122static int default_size = PSZ_QCIF; 127static int default_size = PSZ_QCIF;
123static int default_fps = 10; 128static int default_fps = 10;
124static int default_fbufs = 3; /* Default number of frame buffers */ 129static int default_fbufs = 3; /* Default number of frame buffers */
125static int default_mbufs = 2; /* Default number of mmap() buffers */ 130 int pwc_mbufs = 2; /* Default number of mmap() buffers */
126 int pwc_trace = TRACE_MODULE | TRACE_FLOW | TRACE_PWCX; 131#if CONFIG_PWC_DEBUG
132 int pwc_trace = PWC_DEBUG_LEVEL;
133#endif
127static int power_save = 0; 134static int power_save = 0;
128static int led_on = 100, led_off = 0; /* defaults to LED that is on while in use */ 135static int led_on = 100, led_off = 0; /* defaults to LED that is on while in use */
129static int pwc_preferred_compression = 2; /* 0..3 = uncompressed..high */ 136static int pwc_preferred_compression = 1; /* 0..3 = uncompressed..high */
130static struct { 137static struct {
131 int type; 138 int type;
132 char serial_number[30]; 139 char serial_number[30];
@@ -138,7 +145,7 @@ static struct {
138 145
139static int pwc_video_open(struct inode *inode, struct file *file); 146static int pwc_video_open(struct inode *inode, struct file *file);
140static int pwc_video_close(struct inode *inode, struct file *file); 147static int pwc_video_close(struct inode *inode, struct file *file);
141static ssize_t pwc_video_read(struct file *file, char __user * buf, 148static ssize_t pwc_video_read(struct file *file, char __user *buf,
142 size_t count, loff_t *ppos); 149 size_t count, loff_t *ppos);
143static unsigned int pwc_video_poll(struct file *file, poll_table *wait); 150static unsigned int pwc_video_poll(struct file *file, poll_table *wait);
144static int pwc_video_ioctl(struct inode *inode, struct file *file, 151static int pwc_video_ioctl(struct inode *inode, struct file *file,
@@ -153,7 +160,6 @@ static struct file_operations pwc_fops = {
153 .poll = pwc_video_poll, 160 .poll = pwc_video_poll,
154 .mmap = pwc_video_mmap, 161 .mmap = pwc_video_mmap,
155 .ioctl = pwc_video_ioctl, 162 .ioctl = pwc_video_ioctl,
156 .compat_ioctl = v4l_compat_ioctl32,
157 .llseek = no_llseek, 163 .llseek = no_llseek,
158}; 164};
159static struct video_device pwc_template = { 165static struct video_device pwc_template = {
@@ -203,52 +209,44 @@ static struct video_device pwc_template = {
203/* Here we want the physical address of the memory. 209/* Here we want the physical address of the memory.
204 * This is used when initializing the contents of the area. 210 * This is used when initializing the contents of the area.
205 */ 211 */
206static inline unsigned long kvirt_to_pa(unsigned long adr)
207{
208 unsigned long kva, ret;
209 212
210 kva = (unsigned long) page_address(vmalloc_to_page((void *)adr));
211 kva |= adr & (PAGE_SIZE-1); /* restore the offset */
212 ret = __pa(kva);
213 return ret;
214}
215 213
216static void * rvmalloc(unsigned long size) 214
215static void *pwc_rvmalloc(unsigned long size)
217{ 216{
218 void * mem; 217 void * mem;
219 unsigned long adr; 218 unsigned long adr;
220 219
221 size=PAGE_ALIGN(size);
222 mem=vmalloc_32(size); 220 mem=vmalloc_32(size);
223 if (mem) 221 if (!mem)
224 { 222 return NULL;
225 memset(mem, 0, size); /* Clear the ram out, no junk to the user */ 223
226 adr=(unsigned long) mem; 224 memset(mem, 0, size); /* Clear the ram out, no junk to the user */
227 while (size > 0) 225 adr=(unsigned long) mem;
228 { 226 while (size > 0)
229 SetPageReserved(vmalloc_to_page((void *)adr)); 227 {
230 adr+=PAGE_SIZE; 228 SetPageReserved(vmalloc_to_page((void *)adr));
231 size-=PAGE_SIZE; 229 adr += PAGE_SIZE;
232 } 230 size -= PAGE_SIZE;
233 } 231 }
234 return mem; 232 return mem;
235} 233}
236 234
237static void rvfree(void * mem, unsigned long size) 235static void pwc_rvfree(void * mem, unsigned long size)
238{ 236{
239 unsigned long adr; 237 unsigned long adr;
240 238
241 if (mem) 239 if (!mem)
242 { 240 return;
243 adr=(unsigned long) mem; 241
244 while ((long) size > 0) 242 adr=(unsigned long) mem;
245 { 243 while ((long) size > 0)
246 ClearPageReserved(vmalloc_to_page((void *)adr)); 244 {
247 adr+=PAGE_SIZE; 245 ClearPageReserved(vmalloc_to_page((void *)adr));
248 size-=PAGE_SIZE; 246 adr += PAGE_SIZE;
249 } 247 size -= PAGE_SIZE;
250 vfree(mem); 248 }
251 } 249 vfree(mem);
252} 250}
253 251
254 252
@@ -256,100 +254,83 @@ static void rvfree(void * mem, unsigned long size)
256 254
257static int pwc_allocate_buffers(struct pwc_device *pdev) 255static int pwc_allocate_buffers(struct pwc_device *pdev)
258{ 256{
259 int i; 257 int i, err;
260 void *kbuf; 258 void *kbuf;
261 259
262 Trace(TRACE_MEMORY, ">> pwc_allocate_buffers(pdev = 0x%p)\n", pdev); 260 PWC_DEBUG_MEMORY(">> pwc_allocate_buffers(pdev = 0x%p)\n", pdev);
263 261
264 if (pdev == NULL) 262 if (pdev == NULL)
265 return -ENXIO; 263 return -ENXIO;
266 264
267#ifdef PWC_MAGIC 265 /* Allocate Isochronuous pipe buffers */
268 if (pdev->magic != PWC_MAGIC) {
269 Err("allocate_buffers(): magic failed.\n");
270 return -ENXIO;
271 }
272#endif
273 /* Allocate Isochronous pipe buffers */
274 for (i = 0; i < MAX_ISO_BUFS; i++) { 266 for (i = 0; i < MAX_ISO_BUFS; i++) {
275 if (pdev->sbuf[i].data == NULL) { 267 if (pdev->sbuf[i].data == NULL) {
276 kbuf = kmalloc(ISO_BUFFER_SIZE, GFP_KERNEL); 268 kbuf = kzalloc(ISO_BUFFER_SIZE, GFP_KERNEL);
277 if (kbuf == NULL) { 269 if (kbuf == NULL) {
278 Err("Failed to allocate iso buffer %d.\n", i); 270 PWC_ERROR("Failed to allocate iso buffer %d.\n", i);
279 return -ENOMEM; 271 return -ENOMEM;
280 } 272 }
281 Trace(TRACE_MEMORY, "Allocated iso buffer at %p.\n", kbuf); 273 PWC_DEBUG_MEMORY("Allocated iso buffer at %p.\n", kbuf);
282 pdev->sbuf[i].data = kbuf; 274 pdev->sbuf[i].data = kbuf;
283 memset(kbuf, 0, ISO_BUFFER_SIZE);
284 } 275 }
285 } 276 }
286 277
287 /* Allocate frame buffer structure */ 278 /* Allocate frame buffer structure */
288 if (pdev->fbuf == NULL) { 279 if (pdev->fbuf == NULL) {
289 kbuf = kmalloc(default_fbufs * sizeof(struct pwc_frame_buf), GFP_KERNEL); 280 kbuf = kzalloc(default_fbufs * sizeof(struct pwc_frame_buf), GFP_KERNEL);
290 if (kbuf == NULL) { 281 if (kbuf == NULL) {
291 Err("Failed to allocate frame buffer structure.\n"); 282 PWC_ERROR("Failed to allocate frame buffer structure.\n");
292 return -ENOMEM; 283 return -ENOMEM;
293 } 284 }
294 Trace(TRACE_MEMORY, "Allocated frame buffer structure at %p.\n", kbuf); 285 PWC_DEBUG_MEMORY("Allocated frame buffer structure at %p.\n", kbuf);
295 pdev->fbuf = kbuf; 286 pdev->fbuf = kbuf;
296 memset(kbuf, 0, default_fbufs * sizeof(struct pwc_frame_buf));
297 } 287 }
288
298 /* create frame buffers, and make circular ring */ 289 /* create frame buffers, and make circular ring */
299 for (i = 0; i < default_fbufs; i++) { 290 for (i = 0; i < default_fbufs; i++) {
300 if (pdev->fbuf[i].data == NULL) { 291 if (pdev->fbuf[i].data == NULL) {
301 kbuf = vmalloc(PWC_FRAME_SIZE); /* need vmalloc since frame buffer > 128K */ 292 kbuf = vmalloc(PWC_FRAME_SIZE); /* need vmalloc since frame buffer > 128K */
302 if (kbuf == NULL) { 293 if (kbuf == NULL) {
303 Err("Failed to allocate frame buffer %d.\n", i); 294 PWC_ERROR("Failed to allocate frame buffer %d.\n", i);
304 return -ENOMEM; 295 return -ENOMEM;
305 } 296 }
306 Trace(TRACE_MEMORY, "Allocated frame buffer %d at %p.\n", i, kbuf); 297 PWC_DEBUG_MEMORY("Allocated frame buffer %d at %p.\n", i, kbuf);
307 pdev->fbuf[i].data = kbuf; 298 pdev->fbuf[i].data = kbuf;
308 memset(kbuf, 128, PWC_FRAME_SIZE); 299 memset(kbuf, 0, PWC_FRAME_SIZE);
309 } 300 }
310 } 301 }
311 302
312 /* Allocate decompressor table space */ 303 /* Allocate decompressor table space */
313 kbuf = NULL; 304 if (DEVICE_USE_CODEC1(pdev->type))
314 switch (pdev->type) 305 err = pwc_dec1_alloc(pdev);
315 { 306 else
316 case 675: 307 err = pwc_dec23_alloc(pdev);
317 case 680: 308
318 case 690: 309 if (err) {
319 case 720: 310 PWC_ERROR("Failed to allocate decompress table.\n");
320 case 730: 311 return err;
321 case 740: 312 }
322 case 750:
323#if 0
324 Trace(TRACE_MEMORY,"private_data(%zu)\n",sizeof(struct pwc_dec23_private));
325 kbuf = kmalloc(sizeof(struct pwc_dec23_private), GFP_KERNEL); /* Timon & Kiara */
326 break;
327 case 645:
328 case 646:
329 /* TODO & FIXME */
330 kbuf = kmalloc(sizeof(struct pwc_dec23_private), GFP_KERNEL);
331 break;
332#endif
333 ;
334 }
335 pdev->decompress_data = kbuf;
336 313
337 /* Allocate image buffer; double buffer for mmap() */ 314 /* Allocate image buffer; double buffer for mmap() */
338 kbuf = rvmalloc(default_mbufs * pdev->len_per_image); 315 kbuf = pwc_rvmalloc(pwc_mbufs * pdev->len_per_image);
339 if (kbuf == NULL) { 316 if (kbuf == NULL) {
340 Err("Failed to allocate image buffer(s). needed (%d)\n",default_mbufs * pdev->len_per_image); 317 PWC_ERROR("Failed to allocate image buffer(s). needed (%d)\n",
318 pwc_mbufs * pdev->len_per_image);
341 return -ENOMEM; 319 return -ENOMEM;
342 } 320 }
343 Trace(TRACE_MEMORY, "Allocated image buffer at %p.\n", kbuf); 321 PWC_DEBUG_MEMORY("Allocated image buffer at %p.\n", kbuf);
344 pdev->image_data = kbuf; 322 pdev->image_data = kbuf;
345 for (i = 0; i < default_mbufs; i++) 323 for (i = 0; i < pwc_mbufs; i++) {
346 pdev->image_ptr[i] = kbuf + i * pdev->len_per_image; 324 pdev->images[i].offset = i * pdev->len_per_image;
347 for (; i < MAX_IMAGES; i++) 325 pdev->images[i].vma_use_count = 0;
348 pdev->image_ptr[i] = NULL; 326 }
327 for (; i < MAX_IMAGES; i++) {
328 pdev->images[i].offset = 0;
329 }
349 330
350 kbuf = NULL; 331 kbuf = NULL;
351 332
352 Trace(TRACE_MEMORY, "<< pwc_allocate_buffers()\n"); 333 PWC_DEBUG_MEMORY("<< pwc_allocate_buffers()\n");
353 return 0; 334 return 0;
354} 335}
355 336
@@ -357,21 +338,14 @@ static void pwc_free_buffers(struct pwc_device *pdev)
357{ 338{
358 int i; 339 int i;
359 340
360 Trace(TRACE_MEMORY, "Entering free_buffers(%p).\n", pdev); 341 PWC_DEBUG_MEMORY("Entering free_buffers(%p).\n", pdev);
361 342
362 if (pdev == NULL) 343 if (pdev == NULL)
363 return; 344 return;
364#ifdef PWC_MAGIC
365 if (pdev->magic != PWC_MAGIC) {
366 Err("free_buffers(): magic failed.\n");
367 return;
368 }
369#endif
370
371 /* Release Iso-pipe buffers */ 345 /* Release Iso-pipe buffers */
372 for (i = 0; i < MAX_ISO_BUFS; i++) 346 for (i = 0; i < MAX_ISO_BUFS; i++)
373 if (pdev->sbuf[i].data != NULL) { 347 if (pdev->sbuf[i].data != NULL) {
374 Trace(TRACE_MEMORY, "Freeing ISO buffer at %p.\n", pdev->sbuf[i].data); 348 PWC_DEBUG_MEMORY("Freeing ISO buffer at %p.\n", pdev->sbuf[i].data);
375 kfree(pdev->sbuf[i].data); 349 kfree(pdev->sbuf[i].data);
376 pdev->sbuf[i].data = NULL; 350 pdev->sbuf[i].data = NULL;
377 } 351 }
@@ -380,7 +354,7 @@ static void pwc_free_buffers(struct pwc_device *pdev)
380 if (pdev->fbuf != NULL) { 354 if (pdev->fbuf != NULL) {
381 for (i = 0; i < default_fbufs; i++) { 355 for (i = 0; i < default_fbufs; i++) {
382 if (pdev->fbuf[i].data != NULL) { 356 if (pdev->fbuf[i].data != NULL) {
383 Trace(TRACE_MEMORY, "Freeing frame buffer %d at %p.\n", i, pdev->fbuf[i].data); 357 PWC_DEBUG_MEMORY("Freeing frame buffer %d at %p.\n", i, pdev->fbuf[i].data);
384 vfree(pdev->fbuf[i].data); 358 vfree(pdev->fbuf[i].data);
385 pdev->fbuf[i].data = NULL; 359 pdev->fbuf[i].data = NULL;
386 } 360 }
@@ -391,20 +365,19 @@ static void pwc_free_buffers(struct pwc_device *pdev)
391 365
392 /* Intermediate decompression buffer & tables */ 366 /* Intermediate decompression buffer & tables */
393 if (pdev->decompress_data != NULL) { 367 if (pdev->decompress_data != NULL) {
394 Trace(TRACE_MEMORY, "Freeing decompression buffer at %p.\n", pdev->decompress_data); 368 PWC_DEBUG_MEMORY("Freeing decompression buffer at %p.\n", pdev->decompress_data);
395 kfree(pdev->decompress_data); 369 kfree(pdev->decompress_data);
396 pdev->decompress_data = NULL; 370 pdev->decompress_data = NULL;
397 } 371 }
398 pdev->decompressor = NULL;
399 372
400 /* Release image buffers */ 373 /* Release image buffers */
401 if (pdev->image_data != NULL) { 374 if (pdev->image_data != NULL) {
402 Trace(TRACE_MEMORY, "Freeing image buffer at %p.\n", pdev->image_data); 375 PWC_DEBUG_MEMORY("Freeing image buffer at %p.\n", pdev->image_data);
403 rvfree(pdev->image_data, default_mbufs * pdev->len_per_image); 376 pwc_rvfree(pdev->image_data, pwc_mbufs * pdev->len_per_image);
404 } 377 }
405 pdev->image_data = NULL; 378 pdev->image_data = NULL;
406 379
407 Trace(TRACE_MEMORY, "Leaving free_buffers().\n"); 380 PWC_DEBUG_MEMORY("Leaving free_buffers().\n");
408} 381}
409 382
410/* The frame & image buffer mess. 383/* The frame & image buffer mess.
@@ -464,7 +437,7 @@ static void pwc_free_buffers(struct pwc_device *pdev)
464/** 437/**
465 \brief Find next frame buffer to fill. Take from empty or full list, whichever comes first. 438 \brief Find next frame buffer to fill. Take from empty or full list, whichever comes first.
466 */ 439 */
467static inline int pwc_next_fill_frame(struct pwc_device *pdev) 440static int pwc_next_fill_frame(struct pwc_device *pdev)
468{ 441{
469 int ret; 442 int ret;
470 unsigned long flags; 443 unsigned long flags;
@@ -489,23 +462,17 @@ static inline int pwc_next_fill_frame(struct pwc_device *pdev)
489 } 462 }
490 else { 463 else {
491 /* Hmm. Take it from the full list */ 464 /* Hmm. Take it from the full list */
492#if PWC_DEBUG
493 /* sanity check */ 465 /* sanity check */
494 if (pdev->full_frames == NULL) { 466 if (pdev->full_frames == NULL) {
495 Err("Neither empty or full frames available!\n"); 467 PWC_ERROR("Neither empty or full frames available!\n");
496 spin_unlock_irqrestore(&pdev->ptrlock, flags); 468 spin_unlock_irqrestore(&pdev->ptrlock, flags);
497 return -EINVAL; 469 return -EINVAL;
498 } 470 }
499#endif
500 pdev->fill_frame = pdev->full_frames; 471 pdev->fill_frame = pdev->full_frames;
501 pdev->full_frames = pdev->full_frames->next; 472 pdev->full_frames = pdev->full_frames->next;
502 ret = 1; 473 ret = 1;
503 } 474 }
504 pdev->fill_frame->next = NULL; 475 pdev->fill_frame->next = NULL;
505#if PWC_DEBUG
506 Trace(TRACE_SEQUENCE, "Assigning sequence number %d.\n", pdev->sequence);
507 pdev->fill_frame->sequence = pdev->sequence++;
508#endif
509 spin_unlock_irqrestore(&pdev->ptrlock, flags); 476 spin_unlock_irqrestore(&pdev->ptrlock, flags);
510 return ret; 477 return ret;
511} 478}
@@ -521,6 +488,8 @@ static void pwc_reset_buffers(struct pwc_device *pdev)
521 int i; 488 int i;
522 unsigned long flags; 489 unsigned long flags;
523 490
491 PWC_DEBUG_MEMORY(">> %s __enter__\n", __FUNCTION__);
492
524 spin_lock_irqsave(&pdev->ptrlock, flags); 493 spin_lock_irqsave(&pdev->ptrlock, flags);
525 pdev->full_frames = NULL; 494 pdev->full_frames = NULL;
526 pdev->full_frames_tail = NULL; 495 pdev->full_frames_tail = NULL;
@@ -540,13 +509,15 @@ static void pwc_reset_buffers(struct pwc_device *pdev)
540 pdev->image_read_pos = 0; 509 pdev->image_read_pos = 0;
541 pdev->fill_image = 0; 510 pdev->fill_image = 0;
542 spin_unlock_irqrestore(&pdev->ptrlock, flags); 511 spin_unlock_irqrestore(&pdev->ptrlock, flags);
512
513 PWC_DEBUG_MEMORY("<< %s __leaving__\n", __FUNCTION__);
543} 514}
544 515
545 516
546/** 517/**
547 \brief Do all the handling for getting one frame: get pointer, decompress, advance pointers. 518 \brief Do all the handling for getting one frame: get pointer, decompress, advance pointers.
548 */ 519 */
549static int pwc_handle_frame(struct pwc_device *pdev) 520int pwc_handle_frame(struct pwc_device *pdev)
550{ 521{
551 int ret = 0; 522 int ret = 0;
552 unsigned long flags; 523 unsigned long flags;
@@ -556,41 +527,40 @@ static int pwc_handle_frame(struct pwc_device *pdev)
556 we can release the lock after this without problems */ 527 we can release the lock after this without problems */
557 if (pdev->read_frame != NULL) { 528 if (pdev->read_frame != NULL) {
558 /* This can't theoretically happen */ 529 /* This can't theoretically happen */
559 Err("Huh? Read frame still in use?\n"); 530 PWC_ERROR("Huh? Read frame still in use?\n");
531 spin_unlock_irqrestore(&pdev->ptrlock, flags);
532 return ret;
533 }
534
535
536 if (pdev->full_frames == NULL) {
537 PWC_ERROR("Woops. No frames ready.\n");
560 } 538 }
561 else { 539 else {
562 if (pdev->full_frames == NULL) { 540 pdev->read_frame = pdev->full_frames;
563 Err("Woops. No frames ready.\n"); 541 pdev->full_frames = pdev->full_frames->next;
542 pdev->read_frame->next = NULL;
543 }
544
545 if (pdev->read_frame != NULL) {
546 /* Decompression is a lenghty process, so it's outside of the lock.
547 This gives the isoc_handler the opportunity to fill more frames
548 in the mean time.
549 */
550 spin_unlock_irqrestore(&pdev->ptrlock, flags);
551 ret = pwc_decompress(pdev);
552 spin_lock_irqsave(&pdev->ptrlock, flags);
553
554 /* We're done with read_buffer, tack it to the end of the empty buffer list */
555 if (pdev->empty_frames == NULL) {
556 pdev->empty_frames = pdev->read_frame;
557 pdev->empty_frames_tail = pdev->empty_frames;
564 } 558 }
565 else { 559 else {
566 pdev->read_frame = pdev->full_frames; 560 pdev->empty_frames_tail->next = pdev->read_frame;
567 pdev->full_frames = pdev->full_frames->next; 561 pdev->empty_frames_tail = pdev->read_frame;
568 pdev->read_frame->next = NULL;
569 }
570
571 if (pdev->read_frame != NULL) {
572#if PWC_DEBUG
573 Trace(TRACE_SEQUENCE, "Decompressing frame %d\n", pdev->read_frame->sequence);
574#endif
575 /* Decompression is a lenghty process, so it's outside of the lock.
576 This gives the isoc_handler the opportunity to fill more frames
577 in the mean time.
578 */
579 spin_unlock_irqrestore(&pdev->ptrlock, flags);
580 ret = pwc_decompress(pdev);
581 spin_lock_irqsave(&pdev->ptrlock, flags);
582
583 /* We're done with read_buffer, tack it to the end of the empty buffer list */
584 if (pdev->empty_frames == NULL) {
585 pdev->empty_frames = pdev->read_frame;
586 pdev->empty_frames_tail = pdev->empty_frames;
587 }
588 else {
589 pdev->empty_frames_tail->next = pdev->read_frame;
590 pdev->empty_frames_tail = pdev->read_frame;
591 }
592 pdev->read_frame = NULL;
593 } 562 }
563 pdev->read_frame = NULL;
594 } 564 }
595 spin_unlock_irqrestore(&pdev->ptrlock, flags); 565 spin_unlock_irqrestore(&pdev->ptrlock, flags);
596 return ret; 566 return ret;
@@ -599,12 +569,114 @@ static int pwc_handle_frame(struct pwc_device *pdev)
599/** 569/**
600 \brief Advance pointers of image buffer (after each user request) 570 \brief Advance pointers of image buffer (after each user request)
601*/ 571*/
602static inline void pwc_next_image(struct pwc_device *pdev) 572void pwc_next_image(struct pwc_device *pdev)
603{ 573{
604 pdev->image_used[pdev->fill_image] = 0; 574 pdev->image_used[pdev->fill_image] = 0;
605 pdev->fill_image = (pdev->fill_image + 1) % default_mbufs; 575 pdev->fill_image = (pdev->fill_image + 1) % pwc_mbufs;
606} 576}
607 577
578/**
579 * Print debug information when a frame is discarded because all of our buffer
580 * is full
581 */
582static void pwc_frame_dumped(struct pwc_device *pdev)
583{
584 pdev->vframes_dumped++;
585 if (pdev->vframe_count < FRAME_LOWMARK)
586 return;
587
588 if (pdev->vframes_dumped < 20)
589 PWC_DEBUG_FLOW("Dumping frame %d\n", pdev->vframe_count);
590 else if (pdev->vframes_dumped == 20)
591 PWC_DEBUG_FLOW("Dumping frame %d (last message)\n",
592 pdev->vframe_count);
593}
594
595static int pwc_rcv_short_packet(struct pwc_device *pdev, const struct pwc_frame_buf *fbuf)
596{
597 int awake = 0;
598
599 /* The ToUCam Fun CMOS sensor causes the firmware to send 2 or 3 bogus
600 frames on the USB wire after an exposure change. This conditition is
601 however detected in the cam and a bit is set in the header.
602 */
603 if (pdev->type == 730) {
604 unsigned char *ptr = (unsigned char *)fbuf->data;
605
606 if (ptr[1] == 1 && ptr[0] & 0x10) {
607 PWC_TRACE("Hyundai CMOS sensor bug. Dropping frame.\n");
608 pdev->drop_frames += 2;
609 pdev->vframes_error++;
610 }
611 if ((ptr[0] ^ pdev->vmirror) & 0x01) {
612 if (ptr[0] & 0x01) {
613 pdev->snapshot_button_status = 1;
614 PWC_TRACE("Snapshot button pressed.\n");
615 }
616 else {
617 PWC_TRACE("Snapshot button released.\n");
618 }
619 }
620 if ((ptr[0] ^ pdev->vmirror) & 0x02) {
621 if (ptr[0] & 0x02)
622 PWC_TRACE("Image is mirrored.\n");
623 else
624 PWC_TRACE("Image is normal.\n");
625 }
626 pdev->vmirror = ptr[0] & 0x03;
627 /* Sometimes the trailer of the 730 is still sent as a 4 byte packet
628 after a short frame; this condition is filtered out specifically. A 4 byte
629 frame doesn't make sense anyway.
630 So we get either this sequence:
631 drop_bit set -> 4 byte frame -> short frame -> good frame
632 Or this one:
633 drop_bit set -> short frame -> good frame
634 So we drop either 3 or 2 frames in all!
635 */
636 if (fbuf->filled == 4)
637 pdev->drop_frames++;
638 }
639 else if (pdev->type == 740 || pdev->type == 720) {
640 unsigned char *ptr = (unsigned char *)fbuf->data;
641 if ((ptr[0] ^ pdev->vmirror) & 0x01) {
642 if (ptr[0] & 0x01) {
643 pdev->snapshot_button_status = 1;
644 PWC_TRACE("Snapshot button pressed.\n");
645 }
646 else
647 PWC_TRACE("Snapshot button released.\n");
648 }
649 pdev->vmirror = ptr[0] & 0x03;
650 }
651
652 /* In case we were instructed to drop the frame, do so silently.
653 The buffer pointers are not updated either (but the counters are reset below).
654 */
655 if (pdev->drop_frames > 0)
656 pdev->drop_frames--;
657 else {
658 /* Check for underflow first */
659 if (fbuf->filled < pdev->frame_total_size) {
660 PWC_DEBUG_FLOW("Frame buffer underflow (%d bytes);"
661 " discarded.\n", fbuf->filled);
662 pdev->vframes_error++;
663 }
664 else {
665 /* Send only once per EOF */
666 awake = 1; /* delay wake_ups */
667
668 /* Find our next frame to fill. This will always succeed, since we
669 * nick a frame from either empty or full list, but if we had to
670 * take it from the full list, it means a frame got dropped.
671 */
672 if (pwc_next_fill_frame(pdev))
673 pwc_frame_dumped(pdev);
674
675 }
676 } /* !drop_frames */
677 pdev->vframe_count++;
678 return awake;
679}
608 680
609/* This gets called for the Isochronous pipe (video). This is done in 681/* This gets called for the Isochronous pipe (video). This is done in
610 * interrupt time, so it has to be fast, not crash, and not stall. Neat. 682 * interrupt time, so it has to be fast, not crash, and not stall. Neat.
@@ -620,17 +692,12 @@ static void pwc_isoc_handler(struct urb *urb, struct pt_regs *regs)
620 awake = 0; 692 awake = 0;
621 pdev = (struct pwc_device *)urb->context; 693 pdev = (struct pwc_device *)urb->context;
622 if (pdev == NULL) { 694 if (pdev == NULL) {
623 Err("isoc_handler() called with NULL device?!\n"); 695 PWC_ERROR("isoc_handler() called with NULL device?!\n");
624 return;
625 }
626#ifdef PWC_MAGIC
627 if (pdev->magic != PWC_MAGIC) {
628 Err("isoc_handler() called with bad magic!\n");
629 return; 696 return;
630 } 697 }
631#endif 698
632 if (urb->status == -ENOENT || urb->status == -ECONNRESET) { 699 if (urb->status == -ENOENT || urb->status == -ECONNRESET) {
633 Trace(TRACE_OPEN, "pwc_isoc_handler(): URB (%p) unlinked %ssynchronuously.\n", urb, urb->status == -ENOENT ? "" : "a"); 700 PWC_DEBUG_OPEN("URB (%p) unlinked %ssynchronuously.\n", urb, urb->status == -ENOENT ? "" : "a");
634 return; 701 return;
635 } 702 }
636 if (urb->status != -EINPROGRESS && urb->status != 0) { 703 if (urb->status != -EINPROGRESS && urb->status != 0) {
@@ -645,13 +712,13 @@ static void pwc_isoc_handler(struct urb *urb, struct pt_regs *regs)
645 case -EILSEQ: errmsg = "CRC/Timeout (could be anything)"; break; 712 case -EILSEQ: errmsg = "CRC/Timeout (could be anything)"; break;
646 case -ETIMEDOUT: errmsg = "NAK (device does not respond)"; break; 713 case -ETIMEDOUT: errmsg = "NAK (device does not respond)"; break;
647 } 714 }
648 Trace(TRACE_FLOW, "pwc_isoc_handler() called with status %d [%s].\n", urb->status, errmsg); 715 PWC_DEBUG_FLOW("pwc_isoc_handler() called with status %d [%s].\n", urb->status, errmsg);
649 /* Give up after a number of contiguous errors on the USB bus. 716 /* Give up after a number of contiguous errors on the USB bus.
650 Appearantly something is wrong so we simulate an unplug event. 717 Appearantly something is wrong so we simulate an unplug event.
651 */ 718 */
652 if (++pdev->visoc_errors > MAX_ISOC_ERRORS) 719 if (++pdev->visoc_errors > MAX_ISOC_ERRORS)
653 { 720 {
654 Info("Too many ISOC errors, bailing out.\n"); 721 PWC_INFO("Too many ISOC errors, bailing out.\n");
655 pdev->error_status = EIO; 722 pdev->error_status = EIO;
656 awake = 1; 723 awake = 1;
657 wake_up_interruptible(&pdev->frameq); 724 wake_up_interruptible(&pdev->frameq);
@@ -661,7 +728,7 @@ static void pwc_isoc_handler(struct urb *urb, struct pt_regs *regs)
661 728
662 fbuf = pdev->fill_frame; 729 fbuf = pdev->fill_frame;
663 if (fbuf == NULL) { 730 if (fbuf == NULL) {
664 Err("pwc_isoc_handler without valid fill frame.\n"); 731 PWC_ERROR("pwc_isoc_handler without valid fill frame.\n");
665 awake = 1; 732 awake = 1;
666 goto handler_end; 733 goto handler_end;
667 } 734 }
@@ -688,7 +755,7 @@ static void pwc_isoc_handler(struct urb *urb, struct pt_regs *regs)
688 755
689 /* ...copy data to frame buffer, if possible */ 756 /* ...copy data to frame buffer, if possible */
690 if (flen + fbuf->filled > pdev->frame_total_size) { 757 if (flen + fbuf->filled > pdev->frame_total_size) {
691 Trace(TRACE_FLOW, "Frame buffer overflow (flen = %d, frame_total_size = %d).\n", flen, pdev->frame_total_size); 758 PWC_DEBUG_FLOW("Frame buffer overflow (flen = %d, frame_total_size = %d).\n", flen, pdev->frame_total_size);
692 pdev->vsync = 0; /* Hmm, let's wait for an EOF (end-of-frame) */ 759 pdev->vsync = 0; /* Hmm, let's wait for an EOF (end-of-frame) */
693 pdev->vframes_error++; 760 pdev->vframes_error++;
694 } 761 }
@@ -704,96 +771,28 @@ static void pwc_isoc_handler(struct urb *urb, struct pt_regs *regs)
704 /* Shorter packet... We probably have the end of an image-frame; 771 /* Shorter packet... We probably have the end of an image-frame;
705 wake up read() process and let select()/poll() do something. 772 wake up read() process and let select()/poll() do something.
706 Decompression is done in user time over there. 773 Decompression is done in user time over there.
707 */ 774 */
708 if (pdev->vsync == 2) { 775 if (pdev->vsync == 2) {
709 /* The ToUCam Fun CMOS sensor causes the firmware to send 2 or 3 bogus 776 if (pwc_rcv_short_packet(pdev, fbuf)) {
710 frames on the USB wire after an exposure change. This conditition is 777 awake = 1;
711 however detected in the cam and a bit is set in the header. 778 fbuf = pdev->fill_frame;
712 */
713 if (pdev->type == 730) {
714 unsigned char *ptr = (unsigned char *)fbuf->data;
715
716 if (ptr[1] == 1 && ptr[0] & 0x10) {
717#if PWC_DEBUG
718 Debug("Hyundai CMOS sensor bug. Dropping frame %d.\n", fbuf->sequence);
719#endif
720 pdev->drop_frames += 2;
721 pdev->vframes_error++;
722 }
723 if ((ptr[0] ^ pdev->vmirror) & 0x01) {
724 if (ptr[0] & 0x01)
725 Info("Snapshot button pressed.\n");
726 else
727 Info("Snapshot button released.\n");
728 }
729 if ((ptr[0] ^ pdev->vmirror) & 0x02) {
730 if (ptr[0] & 0x02)
731 Info("Image is mirrored.\n");
732 else
733 Info("Image is normal.\n");
734 }
735 pdev->vmirror = ptr[0] & 0x03;
736 /* Sometimes the trailer of the 730 is still sent as a 4 byte packet
737 after a short frame; this condition is filtered out specifically. A 4 byte
738 frame doesn't make sense anyway.
739 So we get either this sequence:
740 drop_bit set -> 4 byte frame -> short frame -> good frame
741 Or this one:
742 drop_bit set -> short frame -> good frame
743 So we drop either 3 or 2 frames in all!
744 */
745 if (fbuf->filled == 4)
746 pdev->drop_frames++;
747 } 779 }
748
749 /* In case we were instructed to drop the frame, do so silently.
750 The buffer pointers are not updated either (but the counters are reset below).
751 */
752 if (pdev->drop_frames > 0)
753 pdev->drop_frames--;
754 else {
755 /* Check for underflow first */
756 if (fbuf->filled < pdev->frame_total_size) {
757 Trace(TRACE_FLOW, "Frame buffer underflow (%d bytes); discarded.\n", fbuf->filled);
758 pdev->vframes_error++;
759 }
760 else {
761 /* Send only once per EOF */
762 awake = 1; /* delay wake_ups */
763
764 /* Find our next frame to fill. This will always succeed, since we
765 * nick a frame from either empty or full list, but if we had to
766 * take it from the full list, it means a frame got dropped.
767 */
768 if (pwc_next_fill_frame(pdev)) {
769 pdev->vframes_dumped++;
770 if ((pdev->vframe_count > FRAME_LOWMARK) && (pwc_trace & TRACE_FLOW)) {
771 if (pdev->vframes_dumped < 20)
772 Trace(TRACE_FLOW, "Dumping frame %d.\n", pdev->vframe_count);
773 if (pdev->vframes_dumped == 20)
774 Trace(TRACE_FLOW, "Dumping frame %d (last message).\n", pdev->vframe_count);
775 }
776 }
777 fbuf = pdev->fill_frame;
778 }
779 } /* !drop_frames */
780 pdev->vframe_count++;
781 } 780 }
782 fbuf->filled = 0; 781 fbuf->filled = 0;
783 fillptr = fbuf->data; 782 fillptr = fbuf->data;
784 pdev->vsync = 1; 783 pdev->vsync = 1;
785 } /* .. flen < last_packet_size */ 784 }
785
786 pdev->vlast_packet_size = flen; 786 pdev->vlast_packet_size = flen;
787 } /* ..status == 0 */ 787 } /* ..status == 0 */
788#if PWC_DEBUG
789 /* This is normally not interesting to the user, unless you are really debugging something */
790 else { 788 else {
789 /* This is normally not interesting to the user, unless
790 * you are really debugging something */
791 static int iso_error = 0; 791 static int iso_error = 0;
792 iso_error++; 792 iso_error++;
793 if (iso_error < 20) 793 if (iso_error < 20)
794 Trace(TRACE_FLOW, "Iso frame %d of USB has error %d\n", i, fst); 794 PWC_DEBUG_FLOW("Iso frame %d of USB has error %d\n", i, fst);
795 } 795 }
796#endif
797 } 796 }
798 797
799handler_end: 798handler_end:
@@ -803,11 +802,11 @@ handler_end:
803 urb->dev = pdev->udev; 802 urb->dev = pdev->udev;
804 i = usb_submit_urb(urb, GFP_ATOMIC); 803 i = usb_submit_urb(urb, GFP_ATOMIC);
805 if (i != 0) 804 if (i != 0)
806 Err("Error (%d) re-submitting urb in pwc_isoc_handler.\n", i); 805 PWC_ERROR("Error (%d) re-submitting urb in pwc_isoc_handler.\n", i);
807} 806}
808 807
809 808
810static int pwc_isoc_init(struct pwc_device *pdev) 809int pwc_isoc_init(struct pwc_device *pdev)
811{ 810{
812 struct usb_device *udev; 811 struct usb_device *udev;
813 struct urb *urb; 812 struct urb *urb;
@@ -826,7 +825,6 @@ static int pwc_isoc_init(struct pwc_device *pdev)
826 /* Get the current alternate interface, adjust packet size */ 825 /* Get the current alternate interface, adjust packet size */
827 if (!udev->actconfig) 826 if (!udev->actconfig)
828 return -EFAULT; 827 return -EFAULT;
829
830 intf = usb_ifnum_to_if(udev, 0); 828 intf = usb_ifnum_to_if(udev, 0);
831 if (intf) 829 if (intf)
832 idesc = usb_altnum_to_altsetting(intf, pdev->valternate); 830 idesc = usb_altnum_to_altsetting(intf, pdev->valternate);
@@ -836,20 +834,21 @@ static int pwc_isoc_init(struct pwc_device *pdev)
836 834
837 /* Search video endpoint */ 835 /* Search video endpoint */
838 pdev->vmax_packet_size = -1; 836 pdev->vmax_packet_size = -1;
839 for (i = 0; i < idesc->desc.bNumEndpoints; i++) 837 for (i = 0; i < idesc->desc.bNumEndpoints; i++) {
840 if ((idesc->endpoint[i].desc.bEndpointAddress & 0xF) == pdev->vendpoint) { 838 if ((idesc->endpoint[i].desc.bEndpointAddress & 0xF) == pdev->vendpoint) {
841 pdev->vmax_packet_size = le16_to_cpu(idesc->endpoint[i].desc.wMaxPacketSize); 839 pdev->vmax_packet_size = le16_to_cpu(idesc->endpoint[i].desc.wMaxPacketSize);
842 break; 840 break;
843 } 841 }
842 }
844 843
845 if (pdev->vmax_packet_size < 0 || pdev->vmax_packet_size > ISO_MAX_FRAME_SIZE) { 844 if (pdev->vmax_packet_size < 0 || pdev->vmax_packet_size > ISO_MAX_FRAME_SIZE) {
846 Err("Failed to find packet size for video endpoint in current alternate setting.\n"); 845 PWC_ERROR("Failed to find packet size for video endpoint in current alternate setting.\n");
847 return -ENFILE; /* Odd error, that should be noticeable */ 846 return -ENFILE; /* Odd error, that should be noticeable */
848 } 847 }
849 848
850 /* Set alternate interface */ 849 /* Set alternate interface */
851 ret = 0; 850 ret = 0;
852 Trace(TRACE_OPEN, "Setting alternate interface %d\n", pdev->valternate); 851 PWC_DEBUG_OPEN("Setting alternate interface %d\n", pdev->valternate);
853 ret = usb_set_interface(pdev->udev, 0, pdev->valternate); 852 ret = usb_set_interface(pdev->udev, 0, pdev->valternate);
854 if (ret < 0) 853 if (ret < 0)
855 return ret; 854 return ret;
@@ -857,12 +856,12 @@ static int pwc_isoc_init(struct pwc_device *pdev)
857 for (i = 0; i < MAX_ISO_BUFS; i++) { 856 for (i = 0; i < MAX_ISO_BUFS; i++) {
858 urb = usb_alloc_urb(ISO_FRAMES_PER_DESC, GFP_KERNEL); 857 urb = usb_alloc_urb(ISO_FRAMES_PER_DESC, GFP_KERNEL);
859 if (urb == NULL) { 858 if (urb == NULL) {
860 Err("Failed to allocate urb %d\n", i); 859 PWC_ERROR("Failed to allocate urb %d\n", i);
861 ret = -ENOMEM; 860 ret = -ENOMEM;
862 break; 861 break;
863 } 862 }
864 pdev->sbuf[i].urb = urb; 863 pdev->sbuf[i].urb = urb;
865 Trace(TRACE_MEMORY, "Allocated URB at 0x%p\n", urb); 864 PWC_DEBUG_MEMORY("Allocated URB at 0x%p\n", urb);
866 } 865 }
867 if (ret) { 866 if (ret) {
868 /* De-allocate in reverse order */ 867 /* De-allocate in reverse order */
@@ -899,24 +898,26 @@ static int pwc_isoc_init(struct pwc_device *pdev)
899 for (i = 0; i < MAX_ISO_BUFS; i++) { 898 for (i = 0; i < MAX_ISO_BUFS; i++) {
900 ret = usb_submit_urb(pdev->sbuf[i].urb, GFP_KERNEL); 899 ret = usb_submit_urb(pdev->sbuf[i].urb, GFP_KERNEL);
901 if (ret) 900 if (ret)
902 Err("isoc_init() submit_urb %d failed with error %d\n", i, ret); 901 PWC_ERROR("isoc_init() submit_urb %d failed with error %d\n", i, ret);
903 else 902 else
904 Trace(TRACE_MEMORY, "URB 0x%p submitted.\n", pdev->sbuf[i].urb); 903 PWC_DEBUG_MEMORY("URB 0x%p submitted.\n", pdev->sbuf[i].urb);
905 } 904 }
906 905
907 /* All is done... */ 906 /* All is done... */
908 pdev->iso_init = 1; 907 pdev->iso_init = 1;
909 Trace(TRACE_OPEN, "<< pwc_isoc_init()\n"); 908 PWC_DEBUG_OPEN("<< pwc_isoc_init()\n");
910 return 0; 909 return 0;
911} 910}
912 911
913static void pwc_isoc_cleanup(struct pwc_device *pdev) 912void pwc_isoc_cleanup(struct pwc_device *pdev)
914{ 913{
915 int i; 914 int i;
916 915
917 Trace(TRACE_OPEN, ">> pwc_isoc_cleanup()\n"); 916 PWC_DEBUG_OPEN(">> pwc_isoc_cleanup()\n");
918 if (pdev == NULL) 917 if (pdev == NULL)
919 return; 918 return;
919 if (pdev->iso_init == 0)
920 return;
920 921
921 /* Unlinking ISOC buffers one by one */ 922 /* Unlinking ISOC buffers one by one */
922 for (i = 0; i < MAX_ISO_BUFS; i++) { 923 for (i = 0; i < MAX_ISO_BUFS; i++) {
@@ -925,10 +926,10 @@ static void pwc_isoc_cleanup(struct pwc_device *pdev)
925 urb = pdev->sbuf[i].urb; 926 urb = pdev->sbuf[i].urb;
926 if (urb != 0) { 927 if (urb != 0) {
927 if (pdev->iso_init) { 928 if (pdev->iso_init) {
928 Trace(TRACE_MEMORY, "Unlinking URB %p\n", urb); 929 PWC_DEBUG_MEMORY("Unlinking URB %p\n", urb);
929 usb_kill_urb(urb); 930 usb_kill_urb(urb);
930 } 931 }
931 Trace(TRACE_MEMORY, "Freeing URB\n"); 932 PWC_DEBUG_MEMORY("Freeing URB\n");
932 usb_free_urb(urb); 933 usb_free_urb(urb);
933 pdev->sbuf[i].urb = NULL; 934 pdev->sbuf[i].urb = NULL;
934 } 935 }
@@ -938,12 +939,12 @@ static void pwc_isoc_cleanup(struct pwc_device *pdev)
938 is signalled by EPIPE) 939 is signalled by EPIPE)
939 */ 940 */
940 if (pdev->error_status && pdev->error_status != EPIPE) { 941 if (pdev->error_status && pdev->error_status != EPIPE) {
941 Trace(TRACE_OPEN, "Setting alternate interface 0.\n"); 942 PWC_DEBUG_OPEN("Setting alternate interface 0.\n");
942 usb_set_interface(pdev->udev, 0, 0); 943 usb_set_interface(pdev->udev, 0, 0);
943 } 944 }
944 945
945 pdev->iso_init = 0; 946 pdev->iso_init = 0;
946 Trace(TRACE_OPEN, "<< pwc_isoc_cleanup()\n"); 947 PWC_DEBUG_OPEN("<< pwc_isoc_cleanup()\n");
947} 948}
948 949
949int pwc_try_video_mode(struct pwc_device *pdev, int width, int height, int new_fps, int new_compression, int new_snapshot) 950int pwc_try_video_mode(struct pwc_device *pdev, int width, int height, int new_fps, int new_compression, int new_snapshot)
@@ -957,18 +958,18 @@ int pwc_try_video_mode(struct pwc_device *pdev, int width, int height, int new_f
957 /* Try to set video mode... */ 958 /* Try to set video mode... */
958 start = ret = pwc_set_video_mode(pdev, width, height, new_fps, new_compression, new_snapshot); 959 start = ret = pwc_set_video_mode(pdev, width, height, new_fps, new_compression, new_snapshot);
959 if (ret) { 960 if (ret) {
960 Trace(TRACE_FLOW, "pwc_set_video_mode attempt 1 failed.\n"); 961 PWC_DEBUG_FLOW("pwc_set_video_mode attempt 1 failed.\n");
961 /* That failed... restore old mode (we know that worked) */ 962 /* That failed... restore old mode (we know that worked) */
962 start = pwc_set_video_mode(pdev, pdev->view.x, pdev->view.y, pdev->vframes, pdev->vcompression, pdev->vsnapshot); 963 start = pwc_set_video_mode(pdev, pdev->view.x, pdev->view.y, pdev->vframes, pdev->vcompression, pdev->vsnapshot);
963 if (start) { 964 if (start) {
964 Trace(TRACE_FLOW, "pwc_set_video_mode attempt 2 failed.\n"); 965 PWC_DEBUG_FLOW("pwc_set_video_mode attempt 2 failed.\n");
965 } 966 }
966 } 967 }
967 if (start == 0) 968 if (start == 0)
968 { 969 {
969 if (pwc_isoc_init(pdev) < 0) 970 if (pwc_isoc_init(pdev) < 0)
970 { 971 {
971 Info("Failed to restart ISOC transfers in pwc_try_video_mode.\n"); 972 PWC_WARNING("Failed to restart ISOC transfers in pwc_try_video_mode.\n");
972 ret = -EAGAIN; /* let's try again, who knows if it works a second time */ 973 ret = -EAGAIN; /* let's try again, who knows if it works a second time */
973 } 974 }
974 } 975 }
@@ -976,54 +977,129 @@ int pwc_try_video_mode(struct pwc_device *pdev, int width, int height, int new_f
976 return ret; /* Return original error code */ 977 return ret; /* Return original error code */
977} 978}
978 979
980/*********
981 * sysfs
982 *********/
983static struct pwc_device *cd_to_pwc(struct class_device *cd)
984{
985 struct video_device *vdev = to_video_device(cd);
986 return video_get_drvdata(vdev);
987}
988
989static ssize_t show_pan_tilt(struct class_device *class_dev, char *buf)
990{
991 struct pwc_device *pdev = cd_to_pwc(class_dev);
992 return sprintf(buf, "%d %d\n", pdev->pan_angle, pdev->tilt_angle);
993}
994
995static ssize_t store_pan_tilt(struct class_device *class_dev, const char *buf,
996 size_t count)
997{
998 struct pwc_device *pdev = cd_to_pwc(class_dev);
999 int pan, tilt;
1000 int ret = -EINVAL;
1001
1002 if (strncmp(buf, "reset", 5) == 0)
1003 ret = pwc_mpt_reset(pdev, 0x3);
1004
1005 else if (sscanf(buf, "%d %d", &pan, &tilt) > 0)
1006 ret = pwc_mpt_set_angle(pdev, pan, tilt);
1007
1008 if (ret < 0)
1009 return ret;
1010 return strlen(buf);
1011}
1012static CLASS_DEVICE_ATTR(pan_tilt, S_IRUGO | S_IWUSR, show_pan_tilt,
1013 store_pan_tilt);
1014
1015static ssize_t show_snapshot_button_status(struct class_device *class_dev, char *buf)
1016{
1017 struct pwc_device *pdev = cd_to_pwc(class_dev);
1018 int status = pdev->snapshot_button_status;
1019 pdev->snapshot_button_status = 0;
1020 return sprintf(buf, "%d\n", status);
1021}
1022
1023static CLASS_DEVICE_ATTR(button, S_IRUGO | S_IWUSR, show_snapshot_button_status,
1024 NULL);
1025
1026static void pwc_create_sysfs_files(struct video_device *vdev)
1027{
1028 struct pwc_device *pdev = video_get_drvdata(vdev);
1029 if (pdev->features & FEATURE_MOTOR_PANTILT)
1030 video_device_create_file(vdev, &class_device_attr_pan_tilt);
1031 video_device_create_file(vdev, &class_device_attr_button);
1032}
1033
1034static void pwc_remove_sysfs_files(struct video_device *vdev)
1035{
1036 struct pwc_device *pdev = video_get_drvdata(vdev);
1037 if (pdev->features & FEATURE_MOTOR_PANTILT)
1038 video_device_remove_file(vdev, &class_device_attr_pan_tilt);
1039 video_device_remove_file(vdev, &class_device_attr_button);
1040}
1041
1042#if CONFIG_PWC_DEBUG
1043static const char *pwc_sensor_type_to_string(unsigned int sensor_type)
1044{
1045 switch(sensor_type) {
1046 case 0x00:
1047 return "Hyundai CMOS sensor";
1048 case 0x20:
1049 return "Sony CCD sensor + TDA8787";
1050 case 0x2E:
1051 return "Sony CCD sensor + Exas 98L59";
1052 case 0x2F:
1053 return "Sony CCD sensor + ADI 9804";
1054 case 0x30:
1055 return "Sharp CCD sensor + TDA8787";
1056 case 0x3E:
1057 return "Sharp CCD sensor + Exas 98L59";
1058 case 0x3F:
1059 return "Sharp CCD sensor + ADI 9804";
1060 case 0x40:
1061 return "UPA 1021 sensor";
1062 case 0x100:
1063 return "VGA sensor";
1064 case 0x101:
1065 return "PAL MR sensor";
1066 default:
1067 return "unknown type of sensor";
1068 }
1069}
1070#endif
979 1071
980/***************************************************************************/ 1072/***************************************************************************/
981/* Video4Linux functions */ 1073/* Video4Linux functions */
982 1074
983static int pwc_video_open(struct inode *inode, struct file *file) 1075static int pwc_video_open(struct inode *inode, struct file *file)
984{ 1076{
985 int i; 1077 int i, ret;
986 struct video_device *vdev = video_devdata(file); 1078 struct video_device *vdev = video_devdata(file);
987 struct pwc_device *pdev; 1079 struct pwc_device *pdev;
988 1080
989 Trace(TRACE_OPEN, ">> video_open called(vdev = 0x%p).\n", vdev); 1081 PWC_DEBUG_OPEN(">> video_open called(vdev = 0x%p).\n", vdev);
990 1082
991 pdev = (struct pwc_device *)vdev->priv; 1083 pdev = (struct pwc_device *)vdev->priv;
992 if (pdev == NULL) 1084 if (pdev == NULL)
993 BUG(); 1085 BUG();
994 if (pdev->vopen) 1086 if (pdev->vopen) {
1087 PWC_DEBUG_OPEN("I'm busy, someone is using the device.\n");
995 return -EBUSY; 1088 return -EBUSY;
1089 }
996 1090
997 down(&pdev->modlock); 1091 down(&pdev->modlock);
998 if (!pdev->usb_init) { 1092 if (!pdev->usb_init) {
999 Trace(TRACE_OPEN, "Doing first time initialization.\n"); 1093 PWC_DEBUG_OPEN("Doing first time initialization.\n");
1000 pdev->usb_init = 1; 1094 pdev->usb_init = 1;
1001 1095
1002 if (pwc_trace & TRACE_OPEN) 1096 /* Query sensor type */
1097 ret = pwc_get_cmos_sensor(pdev, &i);
1098 if (ret >= 0)
1003 { 1099 {
1004 /* Query sensor type */ 1100 PWC_DEBUG_OPEN("This %s camera is equipped with a %s (%d).\n",
1005 const char *sensor_type = NULL; 1101 pdev->vdev->name,
1006 int ret; 1102 pwc_sensor_type_to_string(i), i);
1007
1008 ret = pwc_get_cmos_sensor(pdev, &i);
1009 if (ret >= 0)
1010 {
1011 switch(i) {
1012 case 0x00: sensor_type = "Hyundai CMOS sensor"; break;
1013 case 0x20: sensor_type = "Sony CCD sensor + TDA8787"; break;
1014 case 0x2E: sensor_type = "Sony CCD sensor + Exas 98L59"; break;
1015 case 0x2F: sensor_type = "Sony CCD sensor + ADI 9804"; break;
1016 case 0x30: sensor_type = "Sharp CCD sensor + TDA8787"; break;
1017 case 0x3E: sensor_type = "Sharp CCD sensor + Exas 98L59"; break;
1018 case 0x3F: sensor_type = "Sharp CCD sensor + ADI 9804"; break;
1019 case 0x40: sensor_type = "UPA 1021 sensor"; break;
1020 case 0x100: sensor_type = "VGA sensor"; break;
1021 case 0x101: sensor_type = "PAL MR sensor"; break;
1022 default: sensor_type = "unknown type of sensor"; break;
1023 }
1024 }
1025 if (sensor_type != NULL)
1026 Info("This %s camera is equipped with a %s (%d).\n", pdev->vdev->name, sensor_type, i);
1027 } 1103 }
1028 } 1104 }
1029 1105
@@ -1031,34 +1107,32 @@ static int pwc_video_open(struct inode *inode, struct file *file)
1031 if (power_save) { 1107 if (power_save) {
1032 i = pwc_camera_power(pdev, 1); 1108 i = pwc_camera_power(pdev, 1);
1033 if (i < 0) 1109 if (i < 0)
1034 Info("Failed to restore power to the camera! (%d)\n", i); 1110 PWC_DEBUG_OPEN("Failed to restore power to the camera! (%d)\n", i);
1035 } 1111 }
1036 /* Set LED on/off time */ 1112 /* Set LED on/off time */
1037 if (pwc_set_leds(pdev, led_on, led_off) < 0) 1113 if (pwc_set_leds(pdev, led_on, led_off) < 0)
1038 Info("Failed to set LED on/off time.\n"); 1114 PWC_DEBUG_OPEN("Failed to set LED on/off time.\n");
1039 1115
1040 pwc_construct(pdev); /* set min/max sizes correct */ 1116 pwc_construct(pdev); /* set min/max sizes correct */
1041 1117
1042 /* So far, so good. Allocate memory. */ 1118 /* So far, so good. Allocate memory. */
1043 i = pwc_allocate_buffers(pdev); 1119 i = pwc_allocate_buffers(pdev);
1044 if (i < 0) { 1120 if (i < 0) {
1045 Trace(TRACE_OPEN, "Failed to allocate buffer memory.\n"); 1121 PWC_DEBUG_OPEN("Failed to allocate buffers memory.\n");
1122 pwc_free_buffers(pdev);
1046 up(&pdev->modlock); 1123 up(&pdev->modlock);
1047 return i; 1124 return i;
1048 } 1125 }
1049 1126
1050 /* Reset buffers & parameters */ 1127 /* Reset buffers & parameters */
1051 pwc_reset_buffers(pdev); 1128 pwc_reset_buffers(pdev);
1052 for (i = 0; i < default_mbufs; i++) 1129 for (i = 0; i < pwc_mbufs; i++)
1053 pdev->image_used[i] = 0; 1130 pdev->image_used[i] = 0;
1054 pdev->vframe_count = 0; 1131 pdev->vframe_count = 0;
1055 pdev->vframes_dumped = 0; 1132 pdev->vframes_dumped = 0;
1056 pdev->vframes_error = 0; 1133 pdev->vframes_error = 0;
1057 pdev->visoc_errors = 0; 1134 pdev->visoc_errors = 0;
1058 pdev->error_status = 0; 1135 pdev->error_status = 0;
1059#if PWC_DEBUG
1060 pdev->sequence = 0;
1061#endif
1062 pwc_construct(pdev); /* set min/max sizes correct */ 1136 pwc_construct(pdev); /* set min/max sizes correct */
1063 1137
1064 /* Set some defaults */ 1138 /* Set some defaults */
@@ -1070,29 +1144,44 @@ static int pwc_video_open(struct inode *inode, struct file *file)
1070 */ 1144 */
1071 i = pwc_set_video_mode(pdev, pwc_image_sizes[pdev->vsize].x, pwc_image_sizes[pdev->vsize].y, pdev->vframes, pdev->vcompression, 0); 1145 i = pwc_set_video_mode(pdev, pwc_image_sizes[pdev->vsize].x, pwc_image_sizes[pdev->vsize].y, pdev->vframes, pdev->vcompression, 0);
1072 if (i) { 1146 if (i) {
1073 Trace(TRACE_OPEN, "First attempt at set_video_mode failed.\n"); 1147 unsigned int default_resolution;
1074 if (pdev->type == 730 || pdev->type == 740 || pdev->type == 750) 1148 PWC_DEBUG_OPEN("First attempt at set_video_mode failed.\n");
1075 i = pwc_set_video_mode(pdev, pwc_image_sizes[PSZ_QSIF].x, pwc_image_sizes[PSZ_QSIF].y, 10, pdev->vcompression, 0); 1149 if (pdev->type>= 730)
1150 default_resolution = PSZ_QSIF;
1076 else 1151 else
1077 i = pwc_set_video_mode(pdev, pwc_image_sizes[PSZ_QCIF].x, pwc_image_sizes[PSZ_QCIF].y, 10, pdev->vcompression, 0); 1152 default_resolution = PSZ_QCIF;
1153
1154 i = pwc_set_video_mode(pdev,
1155 pwc_image_sizes[default_resolution].x,
1156 pwc_image_sizes[default_resolution].y,
1157 10,
1158 pdev->vcompression,
1159 0);
1078 } 1160 }
1079 if (i) { 1161 if (i) {
1080 Trace(TRACE_OPEN, "Second attempt at set_video_mode failed.\n"); 1162 PWC_DEBUG_OPEN("Second attempt at set_video_mode failed.\n");
1163 pwc_free_buffers(pdev);
1081 up(&pdev->modlock); 1164 up(&pdev->modlock);
1082 return i; 1165 return i;
1083 } 1166 }
1084 1167
1085 i = pwc_isoc_init(pdev); 1168 i = pwc_isoc_init(pdev);
1086 if (i) { 1169 if (i) {
1087 Trace(TRACE_OPEN, "Failed to init ISOC stuff = %d.\n", i); 1170 PWC_DEBUG_OPEN("Failed to init ISOC stuff = %d.\n", i);
1171 pwc_isoc_cleanup(pdev);
1172 pwc_free_buffers(pdev);
1088 up(&pdev->modlock); 1173 up(&pdev->modlock);
1089 return i; 1174 return i;
1090 } 1175 }
1091 1176
1177 /* Initialize the webcam to sane value */
1178 pwc_set_brightness(pdev, 0x7fff);
1179 pwc_set_agc(pdev, 1, 0);
1180
1092 pdev->vopen++; 1181 pdev->vopen++;
1093 file->private_data = vdev; 1182 file->private_data = vdev;
1094 up(&pdev->modlock); 1183 up(&pdev->modlock);
1095 Trace(TRACE_OPEN, "<< video_open() returns 0.\n"); 1184 PWC_DEBUG_OPEN("<< video_open() returns 0.\n");
1096 return 0; 1185 return 0;
1097} 1186}
1098 1187
@@ -1103,35 +1192,23 @@ static int pwc_video_close(struct inode *inode, struct file *file)
1103 struct pwc_device *pdev; 1192 struct pwc_device *pdev;
1104 int i; 1193 int i;
1105 1194
1106 Trace(TRACE_OPEN, ">> video_close called(vdev = 0x%p).\n", vdev); 1195 PWC_DEBUG_OPEN(">> video_close called(vdev = 0x%p).\n", vdev);
1107 1196
1108 pdev = (struct pwc_device *)vdev->priv; 1197 pdev = (struct pwc_device *)vdev->priv;
1109 if (pdev->vopen == 0) 1198 if (pdev->vopen == 0)
1110 Info("video_close() called on closed device?\n"); 1199 PWC_DEBUG_MODULE("video_close() called on closed device?\n");
1111 1200
1112 /* Dump statistics, but only if a reasonable amount of frames were 1201 /* Dump statistics, but only if a reasonable amount of frames were
1113 processed (to prevent endless log-entries in case of snap-shot 1202 processed (to prevent endless log-entries in case of snap-shot
1114 programs) 1203 programs)
1115 */ 1204 */
1116 if (pdev->vframe_count > 20) 1205 if (pdev->vframe_count > 20)
1117 Info("Closing video device: %d frames received, dumped %d frames, %d frames with errors.\n", pdev->vframe_count, pdev->vframes_dumped, pdev->vframes_error); 1206 PWC_DEBUG_MODULE("Closing video device: %d frames received, dumped %d frames, %d frames with errors.\n", pdev->vframe_count, pdev->vframes_dumped, pdev->vframes_error);
1118 1207
1119 switch (pdev->type) 1208 if (DEVICE_USE_CODEC1(pdev->type))
1120 { 1209 pwc_dec1_exit();
1121 case 675: 1210 else
1122 case 680: 1211 pwc_dec23_exit();
1123 case 690:
1124 case 720:
1125 case 730:
1126 case 740:
1127 case 750:
1128/* pwc_dec23_exit(); *//* Timon & Kiara */
1129 break;
1130 case 645:
1131 case 646:
1132/* pwc_dec1_exit(); */
1133 break;
1134 }
1135 1212
1136 pwc_isoc_cleanup(pdev); 1213 pwc_isoc_cleanup(pdev);
1137 pwc_free_buffers(pdev); 1214 pwc_free_buffers(pdev);
@@ -1140,15 +1217,15 @@ static int pwc_video_close(struct inode *inode, struct file *file)
1140 if (pdev->error_status != EPIPE) { 1217 if (pdev->error_status != EPIPE) {
1141 /* Turn LEDs off */ 1218 /* Turn LEDs off */
1142 if (pwc_set_leds(pdev, 0, 0) < 0) 1219 if (pwc_set_leds(pdev, 0, 0) < 0)
1143 Info("Failed to set LED on/off time.\n"); 1220 PWC_DEBUG_MODULE("Failed to set LED on/off time.\n");
1144 if (power_save) { 1221 if (power_save) {
1145 i = pwc_camera_power(pdev, 0); 1222 i = pwc_camera_power(pdev, 0);
1146 if (i < 0) 1223 if (i < 0)
1147 Err("Failed to power down camera (%d)\n", i); 1224 PWC_ERROR("Failed to power down camera (%d)\n", i);
1148 } 1225 }
1149 } 1226 }
1150 pdev->vopen = 0; 1227 pdev->vopen--;
1151 Trace(TRACE_OPEN, "<< video_close()\n"); 1228 PWC_DEBUG_OPEN("<< video_close() vopen=%d\n", pdev->vopen);
1152 return 0; 1229 return 0;
1153} 1230}
1154 1231
@@ -1164,7 +1241,7 @@ static int pwc_video_close(struct inode *inode, struct file *file)
1164 device is tricky anyhow. 1241 device is tricky anyhow.
1165 */ 1242 */
1166 1243
1167static ssize_t pwc_video_read(struct file *file, char __user * buf, 1244static ssize_t pwc_video_read(struct file *file, char __user *buf,
1168 size_t count, loff_t *ppos) 1245 size_t count, loff_t *ppos)
1169{ 1246{
1170 struct video_device *vdev = file->private_data; 1247 struct video_device *vdev = file->private_data;
@@ -1172,8 +1249,10 @@ static ssize_t pwc_video_read(struct file *file, char __user * buf,
1172 int noblock = file->f_flags & O_NONBLOCK; 1249 int noblock = file->f_flags & O_NONBLOCK;
1173 DECLARE_WAITQUEUE(wait, current); 1250 DECLARE_WAITQUEUE(wait, current);
1174 int bytes_to_read; 1251 int bytes_to_read;
1252 void *image_buffer_addr;
1175 1253
1176 Trace(TRACE_READ, "video_read(0x%p, %p, %zu) called.\n", vdev, buf, count); 1254 PWC_DEBUG_READ("pwc_video_read(vdev=0x%p, buf=%p, count=%zd) called.\n",
1255 vdev, buf, count);
1177 if (vdev == NULL) 1256 if (vdev == NULL)
1178 return -EFAULT; 1257 return -EFAULT;
1179 pdev = vdev->priv; 1258 pdev = vdev->priv;
@@ -1214,16 +1293,19 @@ static ssize_t pwc_video_read(struct file *file, char __user * buf,
1214 return -EFAULT; 1293 return -EFAULT;
1215 } 1294 }
1216 1295
1217 Trace(TRACE_READ, "Copying data to user space.\n"); 1296 PWC_DEBUG_READ("Copying data to user space.\n");
1218 if (pdev->vpalette == VIDEO_PALETTE_RAW) 1297 if (pdev->vpalette == VIDEO_PALETTE_RAW)
1219 bytes_to_read = pdev->frame_size; 1298 bytes_to_read = pdev->frame_size + sizeof(struct pwc_raw_frame);
1220 else 1299 else
1221 bytes_to_read = pdev->view.size; 1300 bytes_to_read = pdev->view.size;
1222 1301
1223 /* copy bytes to user space; we allow for partial reads */ 1302 /* copy bytes to user space; we allow for partial reads */
1224 if (count + pdev->image_read_pos > bytes_to_read) 1303 if (count + pdev->image_read_pos > bytes_to_read)
1225 count = bytes_to_read - pdev->image_read_pos; 1304 count = bytes_to_read - pdev->image_read_pos;
1226 if (copy_to_user(buf, pdev->image_ptr[pdev->fill_image] + pdev->image_read_pos, count)) 1305 image_buffer_addr = pdev->image_data;
1306 image_buffer_addr += pdev->images[pdev->fill_image].offset;
1307 image_buffer_addr += pdev->image_read_pos;
1308 if (copy_to_user(buf, image_buffer_addr, count))
1227 return -EFAULT; 1309 return -EFAULT;
1228 pdev->image_read_pos += count; 1310 pdev->image_read_pos += count;
1229 if (pdev->image_read_pos >= bytes_to_read) { /* All data has been read */ 1311 if (pdev->image_read_pos >= bytes_to_read) { /* All data has been read */
@@ -1253,370 +1335,56 @@ static unsigned int pwc_video_poll(struct file *file, poll_table *wait)
1253 return 0; 1335 return 0;
1254} 1336}
1255 1337
1256static int pwc_video_do_ioctl(struct inode *inode, struct file *file,
1257 unsigned int cmd, void *arg)
1258{
1259 struct video_device *vdev = file->private_data;
1260 struct pwc_device *pdev;
1261 DECLARE_WAITQUEUE(wait, current);
1262
1263 if (vdev == NULL)
1264 return -EFAULT;
1265 pdev = vdev->priv;
1266 if (pdev == NULL)
1267 return -EFAULT;
1268
1269 switch (cmd) {
1270 /* Query cabapilities */
1271 case VIDIOCGCAP:
1272 {
1273 struct video_capability *caps = arg;
1274
1275 strcpy(caps->name, vdev->name);
1276 caps->type = VID_TYPE_CAPTURE;
1277 caps->channels = 1;
1278 caps->audios = 1;
1279 caps->minwidth = pdev->view_min.x;
1280 caps->minheight = pdev->view_min.y;
1281 caps->maxwidth = pdev->view_max.x;
1282 caps->maxheight = pdev->view_max.y;
1283 break;
1284 }
1285
1286 /* Channel functions (simulate 1 channel) */
1287 case VIDIOCGCHAN:
1288 {
1289 struct video_channel *v = arg;
1290
1291 if (v->channel != 0)
1292 return -EINVAL;
1293 v->flags = 0;
1294 v->tuners = 0;
1295 v->type = VIDEO_TYPE_CAMERA;
1296 strcpy(v->name, "Webcam");
1297 return 0;
1298 }
1299
1300 case VIDIOCSCHAN:
1301 {
1302 /* The spec says the argument is an integer, but
1303 the bttv driver uses a video_channel arg, which
1304 makes sense becasue it also has the norm flag.
1305 */
1306 struct video_channel *v = arg;
1307 if (v->channel != 0)
1308 return -EINVAL;
1309 return 0;
1310 }
1311
1312
1313 /* Picture functions; contrast etc. */
1314 case VIDIOCGPICT:
1315 {
1316 struct video_picture *p = arg;
1317 int val;
1318
1319 val = pwc_get_brightness(pdev);
1320 if (val >= 0)
1321 p->brightness = val;
1322 else
1323 p->brightness = 0xffff;
1324 val = pwc_get_contrast(pdev);
1325 if (val >= 0)
1326 p->contrast = val;
1327 else
1328 p->contrast = 0xffff;
1329 /* Gamma, Whiteness, what's the difference? :) */
1330 val = pwc_get_gamma(pdev);
1331 if (val >= 0)
1332 p->whiteness = val;
1333 else
1334 p->whiteness = 0xffff;
1335 val = pwc_get_saturation(pdev);
1336 if (val >= 0)
1337 p->colour = val;
1338 else
1339 p->colour = 0xffff;
1340 p->depth = 24;
1341 p->palette = pdev->vpalette;
1342 p->hue = 0xFFFF; /* N/A */
1343 break;
1344 }
1345
1346 case VIDIOCSPICT:
1347 {
1348 struct video_picture *p = arg;
1349 /*
1350 * FIXME: Suppose we are mid read
1351 ANSWER: No problem: the firmware of the camera
1352 can handle brightness/contrast/etc
1353 changes at _any_ time, and the palette
1354 is used exactly once in the uncompress
1355 routine.
1356 */
1357 pwc_set_brightness(pdev, p->brightness);
1358 pwc_set_contrast(pdev, p->contrast);
1359 pwc_set_gamma(pdev, p->whiteness);
1360 pwc_set_saturation(pdev, p->colour);
1361 if (p->palette && p->palette != pdev->vpalette) {
1362 switch (p->palette) {
1363 case VIDEO_PALETTE_YUV420P:
1364 case VIDEO_PALETTE_RAW:
1365 pdev->vpalette = p->palette;
1366 return pwc_try_video_mode(pdev, pdev->image.x, pdev->image.y, pdev->vframes, pdev->vcompression, pdev->vsnapshot);
1367 break;
1368 default:
1369 return -EINVAL;
1370 break;
1371 }
1372 }
1373 break;
1374 }
1375
1376 /* Window/size parameters */
1377 case VIDIOCGWIN:
1378 {
1379 struct video_window *vw = arg;
1380
1381 vw->x = 0;
1382 vw->y = 0;
1383 vw->width = pdev->view.x;
1384 vw->height = pdev->view.y;
1385 vw->chromakey = 0;
1386 vw->flags = (pdev->vframes << PWC_FPS_SHIFT) |
1387 (pdev->vsnapshot ? PWC_FPS_SNAPSHOT : 0);
1388 break;
1389 }
1390
1391 case VIDIOCSWIN:
1392 {
1393 struct video_window *vw = arg;
1394 int fps, snapshot, ret;
1395
1396 fps = (vw->flags & PWC_FPS_FRMASK) >> PWC_FPS_SHIFT;
1397 snapshot = vw->flags & PWC_FPS_SNAPSHOT;
1398 if (fps == 0)
1399 fps = pdev->vframes;
1400 if (pdev->view.x == vw->width && pdev->view.y && fps == pdev->vframes && snapshot == pdev->vsnapshot)
1401 return 0;
1402 ret = pwc_try_video_mode(pdev, vw->width, vw->height, fps, pdev->vcompression, snapshot);
1403 if (ret)
1404 return ret;
1405 break;
1406 }
1407
1408 /* We don't have overlay support (yet) */
1409 case VIDIOCGFBUF:
1410 {
1411 struct video_buffer *vb = arg;
1412
1413 memset(vb,0,sizeof(*vb));
1414 break;
1415 }
1416
1417 /* mmap() functions */
1418 case VIDIOCGMBUF:
1419 {
1420 /* Tell the user program how much memory is needed for a mmap() */
1421 struct video_mbuf *vm = arg;
1422 int i;
1423
1424 memset(vm, 0, sizeof(*vm));
1425 vm->size = default_mbufs * pdev->len_per_image;
1426 vm->frames = default_mbufs; /* double buffering should be enough for most applications */
1427 for (i = 0; i < default_mbufs; i++)
1428 vm->offsets[i] = i * pdev->len_per_image;
1429 break;
1430 }
1431
1432 case VIDIOCMCAPTURE:
1433 {
1434 /* Start capture into a given image buffer (called 'frame' in video_mmap structure) */
1435 struct video_mmap *vm = arg;
1436
1437 Trace(TRACE_READ, "VIDIOCMCAPTURE: %dx%d, frame %d, format %d\n", vm->width, vm->height, vm->frame, vm->format);
1438 if (vm->frame < 0 || vm->frame >= default_mbufs)
1439 return -EINVAL;
1440
1441 /* xawtv is nasty. It probes the available palettes
1442 by setting a very small image size and trying
1443 various palettes... The driver doesn't support
1444 such small images, so I'm working around it.
1445 */
1446 if (vm->format)
1447 {
1448 switch (vm->format)
1449 {
1450 case VIDEO_PALETTE_YUV420P:
1451 case VIDEO_PALETTE_RAW:
1452 break;
1453 default:
1454 return -EINVAL;
1455 break;
1456 }
1457 }
1458
1459 if ((vm->width != pdev->view.x || vm->height != pdev->view.y) &&
1460 (vm->width >= pdev->view_min.x && vm->height >= pdev->view_min.y)) {
1461 int ret;
1462
1463 Trace(TRACE_OPEN, "VIDIOCMCAPTURE: changing size to please xawtv :-(.\n");
1464 ret = pwc_try_video_mode(pdev, vm->width, vm->height, pdev->vframes, pdev->vcompression, pdev->vsnapshot);
1465 if (ret)
1466 return ret;
1467 } /* ... size mismatch */
1468
1469 /* FIXME: should we lock here? */
1470 if (pdev->image_used[vm->frame])
1471 return -EBUSY; /* buffer wasn't available. Bummer */
1472 pdev->image_used[vm->frame] = 1;
1473
1474 /* Okay, we're done here. In the SYNC call we wait until a
1475 frame comes available, then expand image into the given
1476 buffer.
1477 In contrast to the CPiA cam the Philips cams deliver a
1478 constant stream, almost like a grabber card. Also,
1479 we have separate buffers for the rawdata and the image,
1480 meaning we can nearly always expand into the requested buffer.
1481 */
1482 Trace(TRACE_READ, "VIDIOCMCAPTURE done.\n");
1483 break;
1484 }
1485
1486 case VIDIOCSYNC:
1487 {
1488 /* The doc says: "Whenever a buffer is used it should
1489 call VIDIOCSYNC to free this frame up and continue."
1490
1491 The only odd thing about this whole procedure is
1492 that MCAPTURE flags the buffer as "in use", and
1493 SYNC immediately unmarks it, while it isn't
1494 after SYNC that you know that the buffer actually
1495 got filled! So you better not start a CAPTURE in
1496 the same frame immediately (use double buffering).
1497 This is not a problem for this cam, since it has
1498 extra intermediate buffers, but a hardware
1499 grabber card will then overwrite the buffer
1500 you're working on.
1501 */
1502 int *mbuf = arg;
1503 int ret;
1504
1505 Trace(TRACE_READ, "VIDIOCSYNC called (%d).\n", *mbuf);
1506
1507 /* bounds check */
1508 if (*mbuf < 0 || *mbuf >= default_mbufs)
1509 return -EINVAL;
1510 /* check if this buffer was requested anyway */
1511 if (pdev->image_used[*mbuf] == 0)
1512 return -EINVAL;
1513
1514 /* Add ourselves to the frame wait-queue.
1515
1516 FIXME: needs auditing for safety.
1517 QUESTION: In what respect? I think that using the
1518 frameq is safe now.
1519 */
1520 add_wait_queue(&pdev->frameq, &wait);
1521 while (pdev->full_frames == NULL) {
1522 if (pdev->error_status) {
1523 remove_wait_queue(&pdev->frameq, &wait);
1524 set_current_state(TASK_RUNNING);
1525 return -pdev->error_status;
1526 }
1527
1528 if (signal_pending(current)) {
1529 remove_wait_queue(&pdev->frameq, &wait);
1530 set_current_state(TASK_RUNNING);
1531 return -ERESTARTSYS;
1532 }
1533 schedule();
1534 set_current_state(TASK_INTERRUPTIBLE);
1535 }
1536 remove_wait_queue(&pdev->frameq, &wait);
1537 set_current_state(TASK_RUNNING);
1538
1539 /* The frame is ready. Expand in the image buffer
1540 requested by the user. I don't care if you
1541 mmap() 5 buffers and request data in this order:
1542 buffer 4 2 3 0 1 2 3 0 4 3 1 . . .
1543 Grabber hardware may not be so forgiving.
1544 */
1545 Trace(TRACE_READ, "VIDIOCSYNC: frame ready.\n");
1546 pdev->fill_image = *mbuf; /* tell in which buffer we want the image to be expanded */
1547 /* Decompress, etc */
1548 ret = pwc_handle_frame(pdev);
1549 pdev->image_used[*mbuf] = 0;
1550 if (ret)
1551 return -EFAULT;
1552 break;
1553 }
1554
1555 case VIDIOCGAUDIO:
1556 {
1557 struct video_audio *v = arg;
1558
1559 strcpy(v->name, "Microphone");
1560 v->audio = -1; /* unknown audio minor */
1561 v->flags = 0;
1562 v->mode = VIDEO_SOUND_MONO;
1563 v->volume = 0;
1564 v->bass = 0;
1565 v->treble = 0;
1566 v->balance = 0x8000;
1567 v->step = 1;
1568 break;
1569 }
1570
1571 case VIDIOCSAUDIO:
1572 {
1573 /* Dummy: nothing can be set */
1574 break;
1575 }
1576
1577 case VIDIOCGUNIT:
1578 {
1579 struct video_unit *vu = arg;
1580
1581 vu->video = pdev->vdev->minor & 0x3F;
1582 vu->audio = -1; /* not known yet */
1583 vu->vbi = -1;
1584 vu->radio = -1;
1585 vu->teletext = -1;
1586 break;
1587 }
1588 default:
1589 return pwc_ioctl(pdev, cmd, arg);
1590 } /* ..switch */
1591 return 0;
1592}
1593
1594static int pwc_video_ioctl(struct inode *inode, struct file *file, 1338static int pwc_video_ioctl(struct inode *inode, struct file *file,
1595 unsigned int cmd, unsigned long arg) 1339 unsigned int cmd, unsigned long arg)
1596{ 1340{
1597 return video_usercopy(inode, file, cmd, arg, pwc_video_do_ioctl); 1341 return video_usercopy(inode, file, cmd, arg, pwc_video_do_ioctl);
1598} 1342}
1599 1343
1600
1601static int pwc_video_mmap(struct file *file, struct vm_area_struct *vma) 1344static int pwc_video_mmap(struct file *file, struct vm_area_struct *vma)
1602{ 1345{
1603 struct video_device *vdev = file->private_data; 1346 struct video_device *vdev = file->private_data;
1604 struct pwc_device *pdev; 1347 struct pwc_device *pdev;
1605 unsigned long start = vma->vm_start; 1348 unsigned long start;
1606 unsigned long size = vma->vm_end-vma->vm_start; 1349 unsigned long size;
1607 unsigned long page, pos; 1350 unsigned long page, pos = 0;
1351 int index;
1608 1352
1609 Trace(TRACE_MEMORY, "mmap(0x%p, 0x%lx, %lu) called.\n", vdev, start, size); 1353 PWC_DEBUG_MEMORY(">> %s\n", __FUNCTION__);
1610 pdev = vdev->priv; 1354 pdev = vdev->priv;
1355 size = vma->vm_end - vma->vm_start;
1356 start = vma->vm_start;
1611 1357
1612 vma->vm_flags |= VM_IO; 1358 /* Find the idx buffer for this mapping */
1359 for (index = 0; index < pwc_mbufs; index++) {
1360 pos = pdev->images[index].offset;
1361 if ((pos>>PAGE_SHIFT) == vma->vm_pgoff)
1362 break;
1363 }
1364 if (index == MAX_IMAGES)
1365 return -EINVAL;
1366 if (index == 0) {
1367 /*
1368 * Special case for v4l1. In v4l1, we map only one big buffer,
1369 * but in v4l2 each buffer is mapped
1370 */
1371 unsigned long total_size;
1372 total_size = pwc_mbufs * pdev->len_per_image;
1373 if (size != pdev->len_per_image && size != total_size) {
1374 PWC_ERROR("Wrong size (%lu) needed to be len_per_image=%d or total_size=%lu\n",
1375 size, pdev->len_per_image, total_size);
1376 return -EINVAL;
1377 }
1378 } else if (size > pdev->len_per_image)
1379 return -EINVAL;
1613 1380
1614 pos = (unsigned long)pdev->image_data; 1381 vma->vm_flags |= VM_IO; /* from 2.6.9-acX */
1382
1383 pos += (unsigned long)pdev->image_data;
1615 while (size > 0) { 1384 while (size > 0) {
1616 page = vmalloc_to_pfn((void *)pos); 1385 page = vmalloc_to_pfn((void *)pos);
1617 if (remap_pfn_range(vma, start, page, PAGE_SIZE, PAGE_SHARED)) 1386 if (remap_pfn_range(vma, start, page, PAGE_SIZE, PAGE_SHARED))
1618 return -EAGAIN; 1387 return -EAGAIN;
1619
1620 start += PAGE_SIZE; 1388 start += PAGE_SIZE;
1621 pos += PAGE_SIZE; 1389 pos += PAGE_SIZE;
1622 if (size > PAGE_SIZE) 1390 if (size > PAGE_SIZE)
@@ -1624,7 +1392,6 @@ static int pwc_video_mmap(struct file *file, struct vm_area_struct *vma)
1624 else 1392 else
1625 size = 0; 1393 size = 0;
1626 } 1394 }
1627
1628 return 0; 1395 return 0;
1629} 1396}
1630 1397
@@ -1645,10 +1412,12 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
1645 int video_nr = -1; /* default: use next available device */ 1412 int video_nr = -1; /* default: use next available device */
1646 char serial_number[30], *name; 1413 char serial_number[30], *name;
1647 1414
1415 vendor_id = le16_to_cpu(udev->descriptor.idVendor);
1416 product_id = le16_to_cpu(udev->descriptor.idProduct);
1417
1648 /* Check if we can handle this device */ 1418 /* Check if we can handle this device */
1649 Trace(TRACE_PROBE, "probe() called [%04X %04X], if %d\n", 1419 PWC_DEBUG_PROBE("probe() called [%04X %04X], if %d\n",
1650 le16_to_cpu(udev->descriptor.idVendor), 1420 vendor_id, product_id,
1651 le16_to_cpu(udev->descriptor.idProduct),
1652 intf->altsetting->desc.bInterfaceNumber); 1421 intf->altsetting->desc.bInterfaceNumber);
1653 1422
1654 /* the interfaces are probed one by one. We are only interested in the 1423 /* the interfaces are probed one by one. We are only interested in the
@@ -1658,61 +1427,63 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
1658 if (intf->altsetting->desc.bInterfaceNumber > 0) 1427 if (intf->altsetting->desc.bInterfaceNumber > 0)
1659 return -ENODEV; 1428 return -ENODEV;
1660 1429
1661 vendor_id = le16_to_cpu(udev->descriptor.idVendor);
1662 product_id = le16_to_cpu(udev->descriptor.idProduct);
1663
1664 if (vendor_id == 0x0471) { 1430 if (vendor_id == 0x0471) {
1665 switch (product_id) { 1431 switch (product_id) {
1666 case 0x0302: 1432 case 0x0302:
1667 Info("Philips PCA645VC USB webcam detected.\n"); 1433 PWC_INFO("Philips PCA645VC USB webcam detected.\n");
1668 name = "Philips 645 webcam"; 1434 name = "Philips 645 webcam";
1669 type_id = 645; 1435 type_id = 645;
1670 break; 1436 break;
1671 case 0x0303: 1437 case 0x0303:
1672 Info("Philips PCA646VC USB webcam detected.\n"); 1438 PWC_INFO("Philips PCA646VC USB webcam detected.\n");
1673 name = "Philips 646 webcam"; 1439 name = "Philips 646 webcam";
1674 type_id = 646; 1440 type_id = 646;
1675 break; 1441 break;
1676 case 0x0304: 1442 case 0x0304:
1677 Info("Askey VC010 type 2 USB webcam detected.\n"); 1443 PWC_INFO("Askey VC010 type 2 USB webcam detected.\n");
1678 name = "Askey VC010 webcam"; 1444 name = "Askey VC010 webcam";
1679 type_id = 646; 1445 type_id = 646;
1680 break; 1446 break;
1681 case 0x0307: 1447 case 0x0307:
1682 Info("Philips PCVC675K (Vesta) USB webcam detected.\n"); 1448 PWC_INFO("Philips PCVC675K (Vesta) USB webcam detected.\n");
1683 name = "Philips 675 webcam"; 1449 name = "Philips 675 webcam";
1684 type_id = 675; 1450 type_id = 675;
1685 break; 1451 break;
1686 case 0x0308: 1452 case 0x0308:
1687 Info("Philips PCVC680K (Vesta Pro) USB webcam detected.\n"); 1453 PWC_INFO("Philips PCVC680K (Vesta Pro) USB webcam detected.\n");
1688 name = "Philips 680 webcam"; 1454 name = "Philips 680 webcam";
1689 type_id = 680; 1455 type_id = 680;
1690 break; 1456 break;
1691 case 0x030C: 1457 case 0x030C:
1692 Info("Philips PCVC690K (Vesta Pro Scan) USB webcam detected.\n"); 1458 PWC_INFO("Philips PCVC690K (Vesta Pro Scan) USB webcam detected.\n");
1693 name = "Philips 690 webcam"; 1459 name = "Philips 690 webcam";
1694 type_id = 690; 1460 type_id = 690;
1695 break; 1461 break;
1696 case 0x0310: 1462 case 0x0310:
1697 Info("Philips PCVC730K (ToUCam Fun)/PCVC830 (ToUCam II) USB webcam detected.\n"); 1463 PWC_INFO("Philips PCVC730K (ToUCam Fun)/PCVC830 (ToUCam II) USB webcam detected.\n");
1698 name = "Philips 730 webcam"; 1464 name = "Philips 730 webcam";
1699 type_id = 730; 1465 type_id = 730;
1700 break; 1466 break;
1701 case 0x0311: 1467 case 0x0311:
1702 Info("Philips PCVC740K (ToUCam Pro)/PCVC840 (ToUCam II) USB webcam detected.\n"); 1468 PWC_INFO("Philips PCVC740K (ToUCam Pro)/PCVC840 (ToUCam II) USB webcam detected.\n");
1703 name = "Philips 740 webcam"; 1469 name = "Philips 740 webcam";
1704 type_id = 740; 1470 type_id = 740;
1705 break; 1471 break;
1706 case 0x0312: 1472 case 0x0312:
1707 Info("Philips PCVC750K (ToUCam Pro Scan) USB webcam detected.\n"); 1473 PWC_INFO("Philips PCVC750K (ToUCam Pro Scan) USB webcam detected.\n");
1708 name = "Philips 750 webcam"; 1474 name = "Philips 750 webcam";
1709 type_id = 750; 1475 type_id = 750;
1710 break; 1476 break;
1711 case 0x0313: 1477 case 0x0313:
1712 Info("Philips PCVC720K/40 (ToUCam XS) USB webcam detected.\n"); 1478 PWC_INFO("Philips PCVC720K/40 (ToUCam XS) USB webcam detected.\n");
1713 name = "Philips 720K/40 webcam"; 1479 name = "Philips 720K/40 webcam";
1714 type_id = 720; 1480 type_id = 720;
1715 break; 1481 break;
1482 case 0x0329:
1483 PWC_INFO("Philips SPC 900NC USB webcam detected.\n");
1484 name = "Philips SPC 900NC webcam";
1485 type_id = 720;
1486 break;
1716 default: 1487 default:
1717 return -ENODEV; 1488 return -ENODEV;
1718 break; 1489 break;
@@ -1721,7 +1492,7 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
1721 else if (vendor_id == 0x069A) { 1492 else if (vendor_id == 0x069A) {
1722 switch(product_id) { 1493 switch(product_id) {
1723 case 0x0001: 1494 case 0x0001:
1724 Info("Askey VC010 type 1 USB webcam detected.\n"); 1495 PWC_INFO("Askey VC010 type 1 USB webcam detected.\n");
1725 name = "Askey VC010 webcam"; 1496 name = "Askey VC010 webcam";
1726 type_id = 645; 1497 type_id = 645;
1727 break; 1498 break;
@@ -1733,32 +1504,33 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
1733 else if (vendor_id == 0x046d) { 1504 else if (vendor_id == 0x046d) {
1734 switch(product_id) { 1505 switch(product_id) {
1735 case 0x08b0: 1506 case 0x08b0:
1736 Info("Logitech QuickCam Pro 3000 USB webcam detected.\n"); 1507 PWC_INFO("Logitech QuickCam Pro 3000 USB webcam detected.\n");
1737 name = "Logitech QuickCam Pro 3000"; 1508 name = "Logitech QuickCam Pro 3000";
1738 type_id = 740; /* CCD sensor */ 1509 type_id = 740; /* CCD sensor */
1739 break; 1510 break;
1740 case 0x08b1: 1511 case 0x08b1:
1741 Info("Logitech QuickCam Notebook Pro USB webcam detected.\n"); 1512 PWC_INFO("Logitech QuickCam Notebook Pro USB webcam detected.\n");
1742 name = "Logitech QuickCam Notebook Pro"; 1513 name = "Logitech QuickCam Notebook Pro";
1743 type_id = 740; /* CCD sensor */ 1514 type_id = 740; /* CCD sensor */
1744 break; 1515 break;
1745 case 0x08b2: 1516 case 0x08b2:
1746 Info("Logitech QuickCam 4000 Pro USB webcam detected.\n"); 1517 PWC_INFO("Logitech QuickCam 4000 Pro USB webcam detected.\n");
1747 name = "Logitech QuickCam Pro 4000"; 1518 name = "Logitech QuickCam Pro 4000";
1748 type_id = 740; /* CCD sensor */ 1519 type_id = 740; /* CCD sensor */
1749 break; 1520 break;
1750 case 0x08b3: 1521 case 0x08b3:
1751 Info("Logitech QuickCam Zoom USB webcam detected.\n"); 1522 PWC_INFO("Logitech QuickCam Zoom USB webcam detected.\n");
1752 name = "Logitech QuickCam Zoom"; 1523 name = "Logitech QuickCam Zoom";
1753 type_id = 740; /* CCD sensor */ 1524 type_id = 740; /* CCD sensor */
1754 break; 1525 break;
1755 case 0x08B4: 1526 case 0x08B4:
1756 Info("Logitech QuickCam Zoom (new model) USB webcam detected.\n"); 1527 PWC_INFO("Logitech QuickCam Zoom (new model) USB webcam detected.\n");
1757 name = "Logitech QuickCam Zoom"; 1528 name = "Logitech QuickCam Zoom";
1758 type_id = 740; /* CCD sensor */ 1529 type_id = 740; /* CCD sensor */
1530 power_save = 1;
1759 break; 1531 break;
1760 case 0x08b5: 1532 case 0x08b5:
1761 Info("Logitech QuickCam Orbit/Sphere USB webcam detected.\n"); 1533 PWC_INFO("Logitech QuickCam Orbit/Sphere USB webcam detected.\n");
1762 name = "Logitech QuickCam Orbit"; 1534 name = "Logitech QuickCam Orbit";
1763 type_id = 740; /* CCD sensor */ 1535 type_id = 740; /* CCD sensor */
1764 features |= FEATURE_MOTOR_PANTILT; 1536 features |= FEATURE_MOTOR_PANTILT;
@@ -1766,7 +1538,7 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
1766 case 0x08b6: 1538 case 0x08b6:
1767 case 0x08b7: 1539 case 0x08b7:
1768 case 0x08b8: 1540 case 0x08b8:
1769 Info("Logitech QuickCam detected (reserved ID).\n"); 1541 PWC_INFO("Logitech QuickCam detected (reserved ID).\n");
1770 name = "Logitech QuickCam (res.)"; 1542 name = "Logitech QuickCam (res.)";
1771 type_id = 730; /* Assuming CMOS */ 1543 type_id = 730; /* Assuming CMOS */
1772 break; 1544 break;
@@ -1782,15 +1554,20 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
1782 */ 1554 */
1783 switch(product_id) { 1555 switch(product_id) {
1784 case 0x9000: 1556 case 0x9000:
1785 Info("Samsung MPC-C10 USB webcam detected.\n"); 1557 PWC_INFO("Samsung MPC-C10 USB webcam detected.\n");
1786 name = "Samsung MPC-C10"; 1558 name = "Samsung MPC-C10";
1787 type_id = 675; 1559 type_id = 675;
1788 break; 1560 break;
1789 case 0x9001: 1561 case 0x9001:
1790 Info("Samsung MPC-C30 USB webcam detected.\n"); 1562 PWC_INFO("Samsung MPC-C30 USB webcam detected.\n");
1791 name = "Samsung MPC-C30"; 1563 name = "Samsung MPC-C30";
1792 type_id = 675; 1564 type_id = 675;
1793 break; 1565 break;
1566 case 0x9002:
1567 PWC_INFO("Samsung SNC-35E (v3.0) USB webcam detected.\n");
1568 name = "Samsung MPC-C30";
1569 type_id = 740;
1570 break;
1794 default: 1571 default:
1795 return -ENODEV; 1572 return -ENODEV;
1796 break; 1573 break;
@@ -1799,12 +1576,12 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
1799 else if (vendor_id == 0x041e) { 1576 else if (vendor_id == 0x041e) {
1800 switch(product_id) { 1577 switch(product_id) {
1801 case 0x400c: 1578 case 0x400c:
1802 Info("Creative Labs Webcam 5 detected.\n"); 1579 PWC_INFO("Creative Labs Webcam 5 detected.\n");
1803 name = "Creative Labs Webcam 5"; 1580 name = "Creative Labs Webcam 5";
1804 type_id = 730; 1581 type_id = 730;
1805 break; 1582 break;
1806 case 0x4011: 1583 case 0x4011:
1807 Info("Creative Labs Webcam Pro Ex detected.\n"); 1584 PWC_INFO("Creative Labs Webcam Pro Ex detected.\n");
1808 name = "Creative Labs Webcam Pro Ex"; 1585 name = "Creative Labs Webcam Pro Ex";
1809 type_id = 740; 1586 type_id = 740;
1810 break; 1587 break;
@@ -1816,7 +1593,7 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
1816 else if (vendor_id == 0x04cc) { 1593 else if (vendor_id == 0x04cc) {
1817 switch(product_id) { 1594 switch(product_id) {
1818 case 0x8116: 1595 case 0x8116:
1819 Info("Sotec Afina Eye USB webcam detected.\n"); 1596 PWC_INFO("Sotec Afina Eye USB webcam detected.\n");
1820 name = "Sotec Afina Eye"; 1597 name = "Sotec Afina Eye";
1821 type_id = 730; 1598 type_id = 730;
1822 break; 1599 break;
@@ -1829,7 +1606,7 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
1829 switch(product_id) { 1606 switch(product_id) {
1830 case 0x8116: 1607 case 0x8116:
1831 /* This is essentially the same cam as the Sotec Afina Eye */ 1608 /* This is essentially the same cam as the Sotec Afina Eye */
1832 Info("AME Co. Afina Eye USB webcam detected.\n"); 1609 PWC_INFO("AME Co. Afina Eye USB webcam detected.\n");
1833 name = "AME Co. Afina Eye"; 1610 name = "AME Co. Afina Eye";
1834 type_id = 750; 1611 type_id = 750;
1835 break; 1612 break;
@@ -1842,12 +1619,12 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
1842 else if (vendor_id == 0x0d81) { 1619 else if (vendor_id == 0x0d81) {
1843 switch(product_id) { 1620 switch(product_id) {
1844 case 0x1900: 1621 case 0x1900:
1845 Info("Visionite VCS-UC300 USB webcam detected.\n"); 1622 PWC_INFO("Visionite VCS-UC300 USB webcam detected.\n");
1846 name = "Visionite VCS-UC300"; 1623 name = "Visionite VCS-UC300";
1847 type_id = 740; /* CCD sensor */ 1624 type_id = 740; /* CCD sensor */
1848 break; 1625 break;
1849 case 0x1910: 1626 case 0x1910:
1850 Info("Visionite VCS-UM100 USB webcam detected.\n"); 1627 PWC_INFO("Visionite VCS-UM100 USB webcam detected.\n");
1851 name = "Visionite VCS-UM100"; 1628 name = "Visionite VCS-UM100";
1852 type_id = 730; /* CMOS sensor */ 1629 type_id = 730; /* CMOS sensor */
1853 break; 1630 break;
@@ -1861,15 +1638,15 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
1861 1638
1862 memset(serial_number, 0, 30); 1639 memset(serial_number, 0, 30);
1863 usb_string(udev, udev->descriptor.iSerialNumber, serial_number, 29); 1640 usb_string(udev, udev->descriptor.iSerialNumber, serial_number, 29);
1864 Trace(TRACE_PROBE, "Device serial number is %s\n", serial_number); 1641 PWC_DEBUG_PROBE("Device serial number is %s\n", serial_number);
1865 1642
1866 if (udev->descriptor.bNumConfigurations > 1) 1643 if (udev->descriptor.bNumConfigurations > 1)
1867 Info("Warning: more than 1 configuration available.\n"); 1644 PWC_WARNING("Warning: more than 1 configuration available.\n");
1868 1645
1869 /* Allocate structure, initialize pointers, mutexes, etc. and link it to the usb_device */ 1646 /* Allocate structure, initialize pointers, mutexes, etc. and link it to the usb_device */
1870 pdev = kzalloc(sizeof(struct pwc_device), GFP_KERNEL); 1647 pdev = kzalloc(sizeof(struct pwc_device), GFP_KERNEL);
1871 if (pdev == NULL) { 1648 if (pdev == NULL) {
1872 Err("Oops, could not allocate memory for pwc_device.\n"); 1649 PWC_ERROR("Oops, could not allocate memory for pwc_device.\n");
1873 return -ENOMEM; 1650 return -ENOMEM;
1874 } 1651 }
1875 pdev->type = type_id; 1652 pdev->type = type_id;
@@ -1900,17 +1677,18 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
1900 pdev->vdev = video_device_alloc(); 1677 pdev->vdev = video_device_alloc();
1901 if (pdev->vdev == 0) 1678 if (pdev->vdev == 0)
1902 { 1679 {
1903 Err("Err, cannot allocate video_device struture. Failing probe."); 1680 PWC_ERROR("Err, cannot allocate video_device struture. Failing probe.");
1904 kfree(pdev); 1681 kfree(pdev);
1905 return -ENOMEM; 1682 return -ENOMEM;
1906 } 1683 }
1907 memcpy(pdev->vdev, &pwc_template, sizeof(pwc_template)); 1684 memcpy(pdev->vdev, &pwc_template, sizeof(pwc_template));
1685 pdev->vdev->dev = &(udev->dev);
1908 strcpy(pdev->vdev->name, name); 1686 strcpy(pdev->vdev->name, name);
1909 pdev->vdev->owner = THIS_MODULE; 1687 pdev->vdev->owner = THIS_MODULE;
1910 video_set_drvdata(pdev->vdev, pdev); 1688 video_set_drvdata(pdev->vdev, pdev);
1911 1689
1912 pdev->release = le16_to_cpu(udev->descriptor.bcdDevice); 1690 pdev->release = le16_to_cpu(udev->descriptor.bcdDevice);
1913 Trace(TRACE_PROBE, "Release: %04x\n", pdev->release); 1691 PWC_DEBUG_PROBE("Release: %04x\n", pdev->release);
1914 1692
1915 /* Now search device_hint[] table for a match, so we can hint a node number. */ 1693 /* Now search device_hint[] table for a match, so we can hint a node number. */
1916 for (hint = 0; hint < MAX_DEV_HINTS; hint++) { 1694 for (hint = 0; hint < MAX_DEV_HINTS; hint++) {
@@ -1918,10 +1696,10 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
1918 (device_hint[hint].pdev == NULL)) { 1696 (device_hint[hint].pdev == NULL)) {
1919 /* so far, so good... try serial number */ 1697 /* so far, so good... try serial number */
1920 if ((device_hint[hint].serial_number[0] == '*') || !strcmp(device_hint[hint].serial_number, serial_number)) { 1698 if ((device_hint[hint].serial_number[0] == '*') || !strcmp(device_hint[hint].serial_number, serial_number)) {
1921 /* match! */ 1699 /* match! */
1922 video_nr = device_hint[hint].device_node; 1700 video_nr = device_hint[hint].device_node;
1923 Trace(TRACE_PROBE, "Found hint, will try to register as /dev/video%d\n", video_nr); 1701 PWC_DEBUG_PROBE("Found hint, will try to register as /dev/video%d\n", video_nr);
1924 break; 1702 break;
1925 } 1703 }
1926 } 1704 }
1927 } 1705 }
@@ -1929,21 +1707,27 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
1929 pdev->vdev->release = video_device_release; 1707 pdev->vdev->release = video_device_release;
1930 i = video_register_device(pdev->vdev, VFL_TYPE_GRABBER, video_nr); 1708 i = video_register_device(pdev->vdev, VFL_TYPE_GRABBER, video_nr);
1931 if (i < 0) { 1709 if (i < 0) {
1932 Err("Failed to register as video device (%d).\n", i); 1710 PWC_ERROR("Failed to register as video device (%d).\n", i);
1933 video_device_release(pdev->vdev); /* Drip... drip... drip... */ 1711 video_device_release(pdev->vdev); /* Drip... drip... drip... */
1934 kfree(pdev); /* Oops, no memory leaks please */ 1712 kfree(pdev); /* Oops, no memory leaks please */
1935 return -EIO; 1713 return -EIO;
1936 } 1714 }
1937 else { 1715 else {
1938 Info("Registered as /dev/video%d.\n", pdev->vdev->minor & 0x3F); 1716 PWC_INFO("Registered as /dev/video%d.\n", pdev->vdev->minor & 0x3F);
1939 } 1717 }
1940 1718
1941 /* occupy slot */ 1719 /* occupy slot */
1942 if (hint < MAX_DEV_HINTS) 1720 if (hint < MAX_DEV_HINTS)
1943 device_hint[hint].pdev = pdev; 1721 device_hint[hint].pdev = pdev;
1944 1722
1945 Trace(TRACE_PROBE, "probe() function returning struct at 0x%p.\n", pdev); 1723 PWC_DEBUG_PROBE("probe() function returning struct at 0x%p.\n", pdev);
1946 usb_set_intfdata (intf, pdev); 1724 usb_set_intfdata (intf, pdev);
1725 pwc_create_sysfs_files(pdev->vdev);
1726
1727 /* Set the leds off */
1728 pwc_set_leds(pdev, 0, 0);
1729 pwc_camera_power(pdev, 0);
1730
1947 return 0; 1731 return 0;
1948} 1732}
1949 1733
@@ -1957,27 +1741,21 @@ static void usb_pwc_disconnect(struct usb_interface *intf)
1957 pdev = usb_get_intfdata (intf); 1741 pdev = usb_get_intfdata (intf);
1958 usb_set_intfdata (intf, NULL); 1742 usb_set_intfdata (intf, NULL);
1959 if (pdev == NULL) { 1743 if (pdev == NULL) {
1960 Err("pwc_disconnect() Called without private pointer.\n"); 1744 PWC_ERROR("pwc_disconnect() Called without private pointer.\n");
1961 goto disconnect_out; 1745 goto disconnect_out;
1962 } 1746 }
1963 if (pdev->udev == NULL) { 1747 if (pdev->udev == NULL) {
1964 Err("pwc_disconnect() already called for %p\n", pdev); 1748 PWC_ERROR("pwc_disconnect() already called for %p\n", pdev);
1965 goto disconnect_out; 1749 goto disconnect_out;
1966 } 1750 }
1967 if (pdev->udev != interface_to_usbdev(intf)) { 1751 if (pdev->udev != interface_to_usbdev(intf)) {
1968 Err("pwc_disconnect() Woops: pointer mismatch udev/pdev.\n"); 1752 PWC_ERROR("pwc_disconnect() Woops: pointer mismatch udev/pdev.\n");
1969 goto disconnect_out;
1970 }
1971#ifdef PWC_MAGIC
1972 if (pdev->magic != PWC_MAGIC) {
1973 Err("pwc_disconnect() Magic number failed. Consult your scrolls and try again.\n");
1974 goto disconnect_out; 1753 goto disconnect_out;
1975 } 1754 }
1976#endif
1977 1755
1978 /* We got unplugged; this is signalled by an EPIPE error code */ 1756 /* We got unplugged; this is signalled by an EPIPE error code */
1979 if (pdev->vopen) { 1757 if (pdev->vopen) {
1980 Info("Disconnected while webcam is in use!\n"); 1758 PWC_INFO("Disconnected while webcam is in use!\n");
1981 pdev->error_status = EPIPE; 1759 pdev->error_status = EPIPE;
1982 } 1760 }
1983 1761
@@ -1987,7 +1765,8 @@ static void usb_pwc_disconnect(struct usb_interface *intf)
1987 while (pdev->vopen) 1765 while (pdev->vopen)
1988 schedule(); 1766 schedule();
1989 /* Device is now closed, so we can safely unregister it */ 1767 /* Device is now closed, so we can safely unregister it */
1990 Trace(TRACE_PROBE, "Unregistering video device in disconnect().\n"); 1768 PWC_DEBUG_PROBE("Unregistering video device in disconnect().\n");
1769 pwc_remove_sysfs_files(pdev->vdev);
1991 video_unregister_device(pdev->vdev); 1770 video_unregister_device(pdev->vdev);
1992 1771
1993 /* Free memory (don't set pdev to 0 just yet) */ 1772 /* Free memory (don't set pdev to 0 just yet) */
@@ -2021,58 +1800,64 @@ static int pwc_atoi(const char *s)
2021 * Initialization code & module stuff 1800 * Initialization code & module stuff
2022 */ 1801 */
2023 1802
2024static char size[10]; 1803static char *size;
2025static int fps = 0; 1804static int fps;
2026static int fbufs = 0; 1805static int fbufs;
2027static int mbufs = 0; 1806static int mbufs;
2028static int trace = -1;
2029static int compression = -1; 1807static int compression = -1;
2030static int leds[2] = { -1, -1 }; 1808static int leds[2] = { -1, -1 };
2031static char *dev_hint[MAX_DEV_HINTS] = { }; 1809static int leds_nargs;
1810static char *dev_hint[MAX_DEV_HINTS];
1811static int dev_hint_nargs;
1812
1813module_param(size, charp, 0444);
1814module_param(fps, int, 0444);
1815module_param(fbufs, int, 0444);
1816module_param(mbufs, int, 0444);
1817#if CONFIG_PWC_DEBUG
1818module_param_named(trace, pwc_trace, int, 0644);
1819#endif
1820module_param(power_save, int, 0444);
1821module_param(compression, int, 0444);
1822module_param_array(leds, int, &leds_nargs, 0444);
1823module_param_array(dev_hint, charp, &dev_hint_nargs, 0444);
2032 1824
2033module_param_string(size, size, sizeof(size), 0);
2034MODULE_PARM_DESC(size, "Initial image size. One of sqcif, qsif, qcif, sif, cif, vga"); 1825MODULE_PARM_DESC(size, "Initial image size. One of sqcif, qsif, qcif, sif, cif, vga");
2035module_param(fps, int, 0000);
2036MODULE_PARM_DESC(fps, "Initial frames per second. Varies with model, useful range 5-30"); 1826MODULE_PARM_DESC(fps, "Initial frames per second. Varies with model, useful range 5-30");
2037module_param(fbufs, int, 0000);
2038MODULE_PARM_DESC(fbufs, "Number of internal frame buffers to reserve"); 1827MODULE_PARM_DESC(fbufs, "Number of internal frame buffers to reserve");
2039module_param(mbufs, int, 0000);
2040MODULE_PARM_DESC(mbufs, "Number of external (mmap()ed) image buffers"); 1828MODULE_PARM_DESC(mbufs, "Number of external (mmap()ed) image buffers");
2041module_param(trace, int, 0000);
2042MODULE_PARM_DESC(trace, "For debugging purposes"); 1829MODULE_PARM_DESC(trace, "For debugging purposes");
2043module_param(power_save, bool, 0000);
2044MODULE_PARM_DESC(power_save, "Turn power save feature in camera on or off"); 1830MODULE_PARM_DESC(power_save, "Turn power save feature in camera on or off");
2045module_param(compression, int, 0000);
2046MODULE_PARM_DESC(compression, "Preferred compression quality. Range 0 (uncompressed) to 3 (high compression)"); 1831MODULE_PARM_DESC(compression, "Preferred compression quality. Range 0 (uncompressed) to 3 (high compression)");
2047module_param_array(leds, int, NULL, 0000);
2048MODULE_PARM_DESC(leds, "LED on,off time in milliseconds"); 1832MODULE_PARM_DESC(leds, "LED on,off time in milliseconds");
2049module_param_array(dev_hint, charp, NULL, 0000);
2050MODULE_PARM_DESC(dev_hint, "Device node hints"); 1833MODULE_PARM_DESC(dev_hint, "Device node hints");
2051 1834
2052MODULE_DESCRIPTION("Philips & OEM USB webcam driver"); 1835MODULE_DESCRIPTION("Philips & OEM USB webcam driver");
2053MODULE_AUTHOR("Luc Saillard <luc@saillard.org>"); 1836MODULE_AUTHOR("Luc Saillard <luc@saillard.org>");
2054MODULE_LICENSE("GPL"); 1837MODULE_LICENSE("GPL");
1838MODULE_ALIAS("pwcx");
1839MODULE_VERSION( PWC_VERSION );
2055 1840
2056static int __init usb_pwc_init(void) 1841static int __init usb_pwc_init(void)
2057{ 1842{
2058 int i, sz; 1843 int i, sz;
2059 char *sizenames[PSZ_MAX] = { "sqcif", "qsif", "qcif", "sif", "cif", "vga" }; 1844 char *sizenames[PSZ_MAX] = { "sqcif", "qsif", "qcif", "sif", "cif", "vga" };
2060 1845
2061 Info("Philips webcam module version " PWC_VERSION " loaded.\n"); 1846 PWC_INFO("Philips webcam module version " PWC_VERSION " loaded.\n");
2062 Info("Supports Philips PCA645/646, PCVC675/680/690, PCVC720[40]/730/740/750 & PCVC830/840.\n"); 1847 PWC_INFO("Supports Philips PCA645/646, PCVC675/680/690, PCVC720[40]/730/740/750 & PCVC830/840.\n");
2063 Info("Also supports the Askey VC010, various Logitech Quickcams, Samsung MPC-C10 and MPC-C30,\n"); 1848 PWC_INFO("Also supports the Askey VC010, various Logitech Quickcams, Samsung MPC-C10 and MPC-C30,\n");
2064 Info("the Creative WebCam 5 & Pro Ex, SOTEC Afina Eye and Visionite VCS-UC300 and VCS-UM100.\n"); 1849 PWC_INFO("the Creative WebCam 5 & Pro Ex, SOTEC Afina Eye and Visionite VCS-UC300 and VCS-UM100.\n");
2065 1850
2066 if (fps) { 1851 if (fps) {
2067 if (fps < 4 || fps > 30) { 1852 if (fps < 4 || fps > 30) {
2068 Err("Framerate out of bounds (4-30).\n"); 1853 PWC_ERROR("Framerate out of bounds (4-30).\n");
2069 return -EINVAL; 1854 return -EINVAL;
2070 } 1855 }
2071 default_fps = fps; 1856 default_fps = fps;
2072 Info("Default framerate set to %d.\n", default_fps); 1857 PWC_DEBUG_MODULE("Default framerate set to %d.\n", default_fps);
2073 } 1858 }
2074 1859
2075 if (size[0]) { 1860 if (size) {
2076 /* string; try matching with array */ 1861 /* string; try matching with array */
2077 for (sz = 0; sz < PSZ_MAX; sz++) { 1862 for (sz = 0; sz < PSZ_MAX; sz++) {
2078 if (!strcmp(sizenames[sz], size)) { /* Found! */ 1863 if (!strcmp(sizenames[sz], size)) { /* Found! */
@@ -2081,41 +1866,42 @@ static int __init usb_pwc_init(void)
2081 } 1866 }
2082 } 1867 }
2083 if (sz == PSZ_MAX) { 1868 if (sz == PSZ_MAX) {
2084 Err("Size not recognized; try size=[sqcif | qsif | qcif | sif | cif | vga].\n"); 1869 PWC_ERROR("Size not recognized; try size=[sqcif | qsif | qcif | sif | cif | vga].\n");
2085 return -EINVAL; 1870 return -EINVAL;
2086 } 1871 }
2087 Info("Default image size set to %s [%dx%d].\n", sizenames[default_size], pwc_image_sizes[default_size].x, pwc_image_sizes[default_size].y); 1872 PWC_DEBUG_MODULE("Default image size set to %s [%dx%d].\n", sizenames[default_size], pwc_image_sizes[default_size].x, pwc_image_sizes[default_size].y);
2088 } 1873 }
2089 if (mbufs) { 1874 if (mbufs) {
2090 if (mbufs < 1 || mbufs > MAX_IMAGES) { 1875 if (mbufs < 1 || mbufs > MAX_IMAGES) {
2091 Err("Illegal number of mmap() buffers; use a number between 1 and %d.\n", MAX_IMAGES); 1876 PWC_ERROR("Illegal number of mmap() buffers; use a number between 1 and %d.\n", MAX_IMAGES);
2092 return -EINVAL; 1877 return -EINVAL;
2093 } 1878 }
2094 default_mbufs = mbufs; 1879 pwc_mbufs = mbufs;
2095 Info("Number of image buffers set to %d.\n", default_mbufs); 1880 PWC_DEBUG_MODULE("Number of image buffers set to %d.\n", pwc_mbufs);
2096 } 1881 }
2097 if (fbufs) { 1882 if (fbufs) {
2098 if (fbufs < 2 || fbufs > MAX_FRAMES) { 1883 if (fbufs < 2 || fbufs > MAX_FRAMES) {
2099 Err("Illegal number of frame buffers; use a number between 2 and %d.\n", MAX_FRAMES); 1884 PWC_ERROR("Illegal number of frame buffers; use a number between 2 and %d.\n", MAX_FRAMES);
2100 return -EINVAL; 1885 return -EINVAL;
2101 } 1886 }
2102 default_fbufs = fbufs; 1887 default_fbufs = fbufs;
2103 Info("Number of frame buffers set to %d.\n", default_fbufs); 1888 PWC_DEBUG_MODULE("Number of frame buffers set to %d.\n", default_fbufs);
2104 } 1889 }
2105 if (trace >= 0) { 1890#if CONFIG_PWC_DEBUG
2106 Info("Trace options: 0x%04x\n", trace); 1891 if (pwc_trace >= 0) {
2107 pwc_trace = trace; 1892 PWC_DEBUG_MODULE("Trace options: 0x%04x\n", pwc_trace);
2108 } 1893 }
1894#endif
2109 if (compression >= 0) { 1895 if (compression >= 0) {
2110 if (compression > 3) { 1896 if (compression > 3) {
2111 Err("Invalid compression setting; use a number between 0 (uncompressed) and 3 (high).\n"); 1897 PWC_ERROR("Invalid compression setting; use a number between 0 (uncompressed) and 3 (high).\n");
2112 return -EINVAL; 1898 return -EINVAL;
2113 } 1899 }
2114 pwc_preferred_compression = compression; 1900 pwc_preferred_compression = compression;
2115 Info("Preferred compression set to %d.\n", pwc_preferred_compression); 1901 PWC_DEBUG_MODULE("Preferred compression set to %d.\n", pwc_preferred_compression);
2116 } 1902 }
2117 if (power_save) 1903 if (power_save)
2118 Info("Enabling power save on open/close.\n"); 1904 PWC_DEBUG_MODULE("Enabling power save on open/close.\n");
2119 if (leds[0] >= 0) 1905 if (leds[0] >= 0)
2120 led_on = leds[0]; 1906 led_on = leds[0];
2121 if (leds[1] >= 0) 1907 if (leds[1] >= 0)
@@ -2146,14 +1932,14 @@ static int __init usb_pwc_init(void)
2146 dot++; 1932 dot++;
2147 /* Few sanity checks */ 1933 /* Few sanity checks */
2148 if (*dot != '\0' && dot > colon) { 1934 if (*dot != '\0' && dot > colon) {
2149 Err("Malformed camera hint: the colon must be after the dot.\n"); 1935 PWC_ERROR("Malformed camera hint: the colon must be after the dot.\n");
2150 return -EINVAL; 1936 return -EINVAL;
2151 } 1937 }
2152 1938
2153 if (*colon == '\0') { 1939 if (*colon == '\0') {
2154 /* No colon */ 1940 /* No colon */
2155 if (*dot != '\0') { 1941 if (*dot != '\0') {
2156 Err("Malformed camera hint: no colon + device node given.\n"); 1942 PWC_ERROR("Malformed camera hint: no colon + device node given.\n");
2157 return -EINVAL; 1943 return -EINVAL;
2158 } 1944 }
2159 else { 1945 else {
@@ -2178,28 +1964,27 @@ static int __init usb_pwc_init(void)
2178 device_hint[i].serial_number[k] = '\0'; 1964 device_hint[i].serial_number[k] = '\0';
2179 } 1965 }
2180 } 1966 }
2181#if PWC_DEBUG 1967 PWC_TRACE("device_hint[%d]:\n", i);
2182 Debug("device_hint[%d]:\n", i); 1968 PWC_TRACE(" type : %d\n", device_hint[i].type);
2183 Debug(" type : %d\n", device_hint[i].type); 1969 PWC_TRACE(" serial# : %s\n", device_hint[i].serial_number);
2184 Debug(" serial# : %s\n", device_hint[i].serial_number); 1970 PWC_TRACE(" node : %d\n", device_hint[i].device_node);
2185 Debug(" node : %d\n", device_hint[i].device_node);
2186#endif
2187 } 1971 }
2188 else 1972 else
2189 device_hint[i].type = 0; /* not filled */ 1973 device_hint[i].type = 0; /* not filled */
2190 } /* ..for MAX_DEV_HINTS */ 1974 } /* ..for MAX_DEV_HINTS */
2191 1975
2192 Trace(TRACE_PROBE, "Registering driver at address 0x%p.\n", &pwc_driver); 1976 PWC_DEBUG_PROBE("Registering driver at address 0x%p.\n", &pwc_driver);
2193 return usb_register(&pwc_driver); 1977 return usb_register(&pwc_driver);
2194} 1978}
2195 1979
2196static void __exit usb_pwc_exit(void) 1980static void __exit usb_pwc_exit(void)
2197{ 1981{
2198 Trace(TRACE_MODULE, "Deregistering driver.\n"); 1982 PWC_DEBUG_MODULE("Deregistering driver.\n");
2199 usb_deregister(&pwc_driver); 1983 usb_deregister(&pwc_driver);
2200 Info("Philips webcam module removed.\n"); 1984 PWC_INFO("Philips webcam module removed.\n");
2201} 1985}
2202 1986
2203module_init(usb_pwc_init); 1987module_init(usb_pwc_init);
2204module_exit(usb_pwc_exit); 1988module_exit(usb_pwc_exit);
2205 1989
1990/* vim: set cino= formatoptions=croql cindent shiftwidth=8 tabstop=8: */
diff --git a/drivers/media/video/pwc/pwc-kiara.c b/drivers/media/video/pwc/pwc-kiara.c
index 4c96037f7be..fec39cc5a9f 100644
--- a/drivers/media/video/pwc/pwc-kiara.c
+++ b/drivers/media/video/pwc/pwc-kiara.c
@@ -1,5 +1,5 @@
1/* Linux driver for Philips webcam 1/* Linux driver for Philips webcam
2 (C) 2004 Luc Saillard (luc@saillard.org) 2 (C) 2004-2006 Luc Saillard (luc@saillard.org)
3 3
4 NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx 4 NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx
5 driver and thus may have bugs that are not present in the original version. 5 driver and thus may have bugs that are not present in the original version.
@@ -316,3 +316,576 @@ const struct Kiara_table_entry Kiara_table[PSZ_MAX][6][4] =
316 }, 316 },
317}; 317};
318 318
319
320/*
321 * Rom table for kiara chips
322 *
323 * 32 roms tables (one for each resolution ?)
324 * 2 tables per roms (one for each passes) (Y, and U&V)
325 * 128 bytes per passes
326 */
327
328const unsigned int KiaraRomTable [8][2][16][8] =
329{
330 { /* version 0 */
331 { /* version 0, passes 0 */
332 {0x00000000,0x00000000,0x00000000,0x00000000,
333 0x00000000,0x00000000,0x00000001,0x00000001},
334 {0x00000000,0x00000000,0x00000009,0x00000009,
335 0x00000009,0x00000009,0x00000009,0x00000009},
336 {0x00000000,0x00000000,0x00000009,0x00000049,
337 0x00000049,0x00000049,0x00000049,0x00000049},
338 {0x00000000,0x00000000,0x00000049,0x00000049,
339 0x00000049,0x00000249,0x0000024a,0x00000049},
340 {0x00000000,0x00000000,0x00000049,0x00000049,
341 0x00000249,0x00000249,0x0000024a,0x0000024a},
342 {0x00000000,0x00000000,0x00000049,0x00000249,
343 0x00000249,0x0000124a,0x0000024a,0x0000024a},
344 {0x00000000,0x00000000,0x00000049,0x00000249,
345 0x0000124a,0x00009252,0x00001252,0x00001252},
346 {0x00000000,0x00000000,0x00000249,0x00000249,
347 0x00009252,0x00009292,0x00009292,0x00009292},
348 {0x00000000,0x00000000,0x00000249,0x00001249,
349 0x00009292,0x00009292,0x00009493,0x000124db},
350 {0x00000000,0x00000000,0x00000249,0x0000924a,
351 0x00009492,0x0000a49b,0x0000a49b,0x000124db},
352 {0x00000000,0x00000000,0x00001249,0x00009252,
353 0x0000a493,0x000124db,0x000124db,0x000126dc},
354 {0x00000000,0x00000000,0x00001249,0x00009493,
355 0x000124db,0x000126dc,0x000136e4,0x000126dc},
356 {0x00000000,0x00000000,0x00009292,0x0000a49b,
357 0x000124db,0x000136e4,0x000136e4,0x000136e4},
358 {0x00000000,0x00000000,0x00009292,0x0000a49b,
359 0x000126dc,0x0001b724,0x0001b92d,0x0001b925},
360 {0x00000000,0x00000000,0x00009492,0x000124db,
361 0x000136e4,0x0001b925,0x0001c96e,0x0001c92d},
362 {0x00000000,0x00000000,0x00000000,0x00000000,
363 0x00000000,0x00000000,0x00000000,0x00000000}
364 },
365 { /* version 0, passes 1 */
366 {0x00000000,0x00000000,0x00000000,0x00000000,
367 0x00000000,0x00000000,0x00000000,0x00000000},
368 {0x00000000,0x00000000,0x00000000,0x00000000,
369 0x00000000,0x00000000,0x00000000,0x00000000},
370 {0x00000000,0x00000000,0x00000001,0x00000009,
371 0x00000009,0x00000009,0x00000009,0x00000001},
372 {0x00000000,0x00000000,0x00000009,0x00000009,
373 0x00000049,0x00000049,0x00000049,0x00000049},
374 {0x00000000,0x00000000,0x00000049,0x00000049,
375 0x00000049,0x00000049,0x0000024a,0x0000024a},
376 {0x00000000,0x00000000,0x00000049,0x00000049,
377 0x00000249,0x00000249,0x0000024a,0x0000024a},
378 {0x00000000,0x00000000,0x00000049,0x00000249,
379 0x00000249,0x00000249,0x0000024a,0x00001252},
380 {0x00000000,0x00000000,0x00000049,0x00001249,
381 0x0000124a,0x0000124a,0x00001252,0x00009292},
382 {0x00000000,0x00000000,0x00000249,0x00001249,
383 0x00009252,0x00009252,0x00009292,0x00009493},
384 {0x00000000,0x00000000,0x00000249,0x0000924a,
385 0x00009292,0x00009292,0x00009292,0x00009493},
386 {0x00000000,0x00000000,0x00000249,0x00009292,
387 0x00009492,0x00009493,0x0000a49b,0x00009493},
388 {0x00000000,0x00000000,0x00001249,0x00009292,
389 0x0000a493,0x000124db,0x000126dc,0x000126dc},
390 {0x00000000,0x00000000,0x0000924a,0x00009493,
391 0x0000a493,0x000126dc,0x000136e4,0x000136e4},
392 {0x00000000,0x00000000,0x00009252,0x00009493,
393 0x000126dc,0x000126dc,0x000136e4,0x000136e4},
394 {0x00000000,0x00000000,0x00009292,0x0000a49b,
395 0x000136e4,0x000136e4,0x0001b725,0x0001b724},
396 {0x00000000,0x00000000,0x00000000,0x00000000,
397 0x00000000,0x00000000,0x00000000,0x00000000}
398 }
399 },
400 { /* version 1 */
401 { /* version 1, passes 0 */
402 {0x00000000,0x00000000,0x00000000,0x00000000,
403 0x00000000,0x00000000,0x00000000,0x00000001},
404 {0x00000000,0x00000000,0x00000009,0x00000009,
405 0x00000009,0x00000009,0x00000009,0x00000009},
406 {0x00000000,0x00000000,0x00000049,0x00000049,
407 0x00000049,0x00000049,0x00000049,0x00000049},
408 {0x00000000,0x00000000,0x00000049,0x00000049,
409 0x00000049,0x00000249,0x0000024a,0x0000024a},
410 {0x00000000,0x00000000,0x00000049,0x00000249,
411 0x00000249,0x00000249,0x0000024a,0x00001252},
412 {0x00000000,0x00000000,0x00000249,0x00000249,
413 0x00000249,0x0000124a,0x00001252,0x00001252},
414 {0x00000000,0x00000000,0x00000249,0x00000249,
415 0x0000124a,0x0000124a,0x00009292,0x00009292},
416 {0x00000000,0x00000000,0x00000249,0x00001249,
417 0x0000124a,0x00009252,0x00009292,0x00009292},
418 {0x00000000,0x00000000,0x00000249,0x00001249,
419 0x00009252,0x00009292,0x00009292,0x00009292},
420 {0x00000000,0x00000000,0x00000249,0x00001249,
421 0x00009252,0x00009292,0x00009493,0x00009493},
422 {0x00000000,0x00000000,0x00000249,0x0000924a,
423 0x00009252,0x00009493,0x00009493,0x00009493},
424 {0x00000000,0x00000000,0x00000249,0x0000924a,
425 0x00009292,0x00009493,0x00009493,0x00009493},
426 {0x00000000,0x00000000,0x00000249,0x00009252,
427 0x00009492,0x00009493,0x0000a49b,0x0000a49b},
428 {0x00000000,0x00000000,0x00001249,0x00009292,
429 0x00009492,0x000124db,0x000124db,0x000124db},
430 {0x00000000,0x00000000,0x0000924a,0x00009493,
431 0x0000a493,0x000126dc,0x000126dc,0x000126dc},
432 {0x00000000,0x00000000,0x00000000,0x00000000,
433 0x00000000,0x00000000,0x00000000,0x00000000}
434 },
435 { /* version 1, passes 1 */
436 {0x00000000,0x00000000,0x00000000,0x00000000,
437 0x00000000,0x00000000,0x00000000,0x00000000},
438 {0x00000000,0x00000000,0x00000049,0x00000009,
439 0x00000049,0x00000009,0x00000001,0x00000000},
440 {0x00000000,0x00000000,0x00000049,0x00000049,
441 0x00000049,0x00000049,0x00000049,0x00000000},
442 {0x00000000,0x00000000,0x00000249,0x00000049,
443 0x00000249,0x00000049,0x0000024a,0x00000001},
444 {0x00000000,0x00000000,0x00000249,0x00000249,
445 0x00000249,0x00000249,0x0000024a,0x00000001},
446 {0x00000000,0x00000000,0x00000249,0x00000249,
447 0x00000249,0x00000249,0x0000024a,0x00000001},
448 {0x00000000,0x00000000,0x00000249,0x00000249,
449 0x00000249,0x00000249,0x0000024a,0x00000009},
450 {0x00000000,0x00000000,0x00000249,0x00000249,
451 0x0000124a,0x0000124a,0x0000024a,0x00000009},
452 {0x00000000,0x00000000,0x00000249,0x00000249,
453 0x0000124a,0x0000124a,0x0000024a,0x00000009},
454 {0x00000000,0x00000000,0x00001249,0x00001249,
455 0x0000124a,0x00009252,0x00001252,0x00000049},
456 {0x00000000,0x00000000,0x00001249,0x00001249,
457 0x0000124a,0x00009292,0x00001252,0x00000049},
458 {0x00000000,0x00000000,0x00001249,0x00001249,
459 0x0000124a,0x00009292,0x00001252,0x00000049},
460 {0x00000000,0x00000000,0x00001249,0x00001249,
461 0x00009252,0x00009292,0x00001252,0x0000024a},
462 {0x00000000,0x00000000,0x00001249,0x00001249,
463 0x00009292,0x00009292,0x00001252,0x0000024a},
464 {0x00000000,0x00000000,0x0000924a,0x0000924a,
465 0x00009492,0x00009493,0x00009292,0x00001252},
466 {0x00000000,0x00000000,0x00000000,0x00000000,
467 0x00000000,0x00000000,0x00000000,0x00000000}
468 }
469 },
470 { /* version 2 */
471 { /* version 2, passes 0 */
472 {0x00000000,0x00000000,0x00000049,0x00000049,
473 0x00000049,0x00000049,0x0000024a,0x0000024a},
474 {0x00000000,0x00000000,0x00000249,0x00000249,
475 0x00000249,0x0000124a,0x00001252,0x00009292},
476 {0x00000000,0x00000000,0x00000249,0x00000249,
477 0x0000124a,0x00009252,0x00009292,0x00009292},
478 {0x00000000,0x00000000,0x00000249,0x00001249,
479 0x0000124a,0x00009292,0x00009493,0x00009493},
480 {0x00000000,0x00000000,0x00000249,0x00001249,
481 0x00009252,0x00009493,0x00009493,0x0000a49b},
482 {0x00000000,0x00000000,0x00000249,0x0000924a,
483 0x00009292,0x00009493,0x0000a49b,0x0000a49b},
484 {0x00000000,0x00000000,0x00001249,0x0000924a,
485 0x00009292,0x00009493,0x0000a49b,0x000124db},
486 {0x00000000,0x00000000,0x00001249,0x00009252,
487 0x00009492,0x0000a49b,0x0000a49b,0x000124db},
488 {0x00000000,0x00000000,0x00001249,0x00009292,
489 0x00009492,0x000124db,0x000124db,0x000126dc},
490 {0x00000000,0x00000000,0x00001249,0x00009292,
491 0x0000a493,0x000124db,0x000126dc,0x000126dc},
492 {0x00000000,0x00000000,0x00001249,0x00009493,
493 0x0000a493,0x000124db,0x000126dc,0x000136e4},
494 {0x00000000,0x00000000,0x00001249,0x00009493,
495 0x0000a493,0x000126dc,0x000136e4,0x000136e4},
496 {0x00000000,0x00000000,0x0000924a,0x00009493,
497 0x0001249b,0x000126dc,0x000136e4,0x000136e4},
498 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
499 0x000124db,0x000136e4,0x000136e4,0x0001b724},
500 {0x00000000,0x00000000,0x00009252,0x000124db,
501 0x000126dc,0x0001b724,0x0001b725,0x0001b925},
502 {0x00000000,0x00000000,0x00000000,0x00000000,
503 0x00000000,0x00000000,0x00000000,0x00000000}
504 },
505 { /* version 2, passes 1 */
506 {0x00000000,0x00000000,0x00000049,0x00000049,
507 0x00000049,0x00000049,0x00000049,0x00000049},
508 {0x00000000,0x00000000,0x00000249,0x00000249,
509 0x00000249,0x00000249,0x0000024a,0x00000049},
510 {0x00000000,0x00000000,0x00001249,0x00000249,
511 0x0000124a,0x0000124a,0x00001252,0x00000049},
512 {0x00000000,0x00000000,0x00001249,0x00001249,
513 0x0000124a,0x0000124a,0x00009292,0x0000024a},
514 {0x00000000,0x00000000,0x00001249,0x00001249,
515 0x00009252,0x00009292,0x00009292,0x0000024a},
516 {0x00000000,0x00000000,0x00001249,0x00001249,
517 0x00009252,0x00009292,0x0000a49b,0x0000024a},
518 {0x00000000,0x00000000,0x00001249,0x00001249,
519 0x00009292,0x00009493,0x0000a49b,0x00001252},
520 {0x00000000,0x00000000,0x00001249,0x00001249,
521 0x00009292,0x00009493,0x0000a49b,0x00001252},
522 {0x00000000,0x00000000,0x00001249,0x0000924a,
523 0x00009492,0x0000a49b,0x0000a49b,0x00001252},
524 {0x00000000,0x00000000,0x00001249,0x00009252,
525 0x00009492,0x0000a49b,0x0000a49b,0x00009292},
526 {0x00000000,0x00000000,0x00001249,0x00009292,
527 0x00009492,0x0000a49b,0x0000a49b,0x00009292},
528 {0x00000000,0x00000000,0x00001249,0x00009493,
529 0x0000a493,0x0000a49b,0x0000a49b,0x00009292},
530 {0x00000000,0x00000000,0x00001249,0x00009493,
531 0x0000a493,0x0000a49b,0x0000a49b,0x00009493},
532 {0x00000000,0x00000000,0x0000924a,0x00009493,
533 0x0000a493,0x000124db,0x0000a49b,0x00009493},
534 {0x00000000,0x00000000,0x00009252,0x0000a49b,
535 0x0001249b,0x000126dc,0x000124db,0x0000a49b},
536 {0x00000000,0x00000000,0x00000000,0x00000000,
537 0x00000000,0x00000000,0x00000000,0x00000000}
538 }
539 },
540 { /* version 3 */
541 { /* version 3, passes 0 */
542 {0x00000000,0x00000000,0x00000249,0x00000249,
543 0x0000124a,0x0000124a,0x00009292,0x00009292},
544 {0x00000000,0x00000000,0x00001249,0x00001249,
545 0x00009292,0x00009493,0x0000a49b,0x0000a49b},
546 {0x00000000,0x00000000,0x00001249,0x0000924a,
547 0x00009492,0x0000a49b,0x0000a49b,0x000124db},
548 {0x00000000,0x00000000,0x00001249,0x00009292,
549 0x00009492,0x000124db,0x000126dc,0x000126dc},
550 {0x00000000,0x00000000,0x00001249,0x00009493,
551 0x0000a493,0x000124db,0x000126dc,0x000126dc},
552 {0x00000000,0x00000000,0x00001249,0x00009493,
553 0x0000a493,0x000126dc,0x000136e4,0x000136e4},
554 {0x00000000,0x00000000,0x00001249,0x00009493,
555 0x0000a493,0x000126dc,0x000136e4,0x0001b724},
556 {0x00000000,0x00000000,0x00001249,0x00009493,
557 0x0001249b,0x000126dc,0x000136e4,0x0001b724},
558 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
559 0x0001249b,0x000126dc,0x000136e4,0x0001b724},
560 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
561 0x0001249b,0x000136e4,0x0001b725,0x0001b724},
562 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
563 0x000124db,0x000136e4,0x0001b725,0x0001b925},
564 {0x00000000,0x00000000,0x00009292,0x0000a49b,
565 0x000126dc,0x000136e4,0x0001b92d,0x0001b925},
566 {0x00000000,0x00000000,0x00009292,0x0000a49b,
567 0x000126dc,0x0001b724,0x0001b92d,0x0001c92d},
568 {0x00000000,0x00000000,0x00009492,0x000124db,
569 0x000126dc,0x0001b724,0x0001c96e,0x0001c92d},
570 {0x00000000,0x00000000,0x0000a492,0x000126db,
571 0x000136e4,0x0001b925,0x00025bb6,0x00024b77},
572 {0x00000000,0x00000000,0x00000000,0x00000000,
573 0x00000000,0x00000000,0x00000000,0x00000000}
574 },
575 { /* version 3, passes 1 */
576 {0x00000000,0x00000000,0x00001249,0x00000249,
577 0x0000124a,0x0000124a,0x00001252,0x00001252},
578 {0x00000000,0x00000000,0x00001249,0x00001249,
579 0x00009252,0x00009292,0x00009292,0x00001252},
580 {0x00000000,0x00000000,0x00001249,0x0000924a,
581 0x00009492,0x00009493,0x0000a49b,0x00001252},
582 {0x00000000,0x00000000,0x00001249,0x00009252,
583 0x00009492,0x0000a49b,0x0000a49b,0x00009292},
584 {0x00000000,0x00000000,0x00001249,0x00009292,
585 0x00009492,0x0000a49b,0x0000a49b,0x00009292},
586 {0x00000000,0x00000000,0x00001249,0x00009493,
587 0x0000a493,0x0000a49b,0x000126dc,0x00009292},
588 {0x00000000,0x00000000,0x0000924a,0x00009493,
589 0x0000a493,0x0000a49b,0x000126dc,0x00009493},
590 {0x00000000,0x00000000,0x0000924a,0x00009493,
591 0x0000a493,0x0000a49b,0x000126dc,0x00009493},
592 {0x00000000,0x00000000,0x0000924a,0x00009493,
593 0x0000a493,0x000124db,0x000126dc,0x00009493},
594 {0x00000000,0x00000000,0x0000924a,0x00009493,
595 0x0000a493,0x000124db,0x000126dc,0x0000a49b},
596 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
597 0x0000a493,0x000124db,0x000126dc,0x0000a49b},
598 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
599 0x0001249b,0x000126dc,0x000126dc,0x0000a49b},
600 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
601 0x000124db,0x000136e4,0x000126dc,0x000124db},
602 {0x00000000,0x00000000,0x00009492,0x0000a49b,
603 0x000136e4,0x000136e4,0x000126dc,0x000124db},
604 {0x00000000,0x00000000,0x0000a492,0x000124db,
605 0x0001b724,0x0001b724,0x000136e4,0x000126dc},
606 {0x00000000,0x00000000,0x00000000,0x00000000,
607 0x00000000,0x00000000,0x00000000,0x00000000}
608 }
609 },
610 { /* version 4 */
611 { /* version 4, passes 0 */
612 {0x00000000,0x00000000,0x00000049,0x00000049,
613 0x00000049,0x00000049,0x00000049,0x00000049},
614 {0x00000000,0x00000000,0x00000249,0x00000049,
615 0x00000249,0x00000249,0x0000024a,0x00000049},
616 {0x00000000,0x00000000,0x00000249,0x00000249,
617 0x0000124a,0x00009252,0x00001252,0x0000024a},
618 {0x00000000,0x00000000,0x00001249,0x00001249,
619 0x00009252,0x00009292,0x00009493,0x00001252},
620 {0x00000000,0x00000000,0x00001249,0x0000924a,
621 0x00009292,0x00009493,0x00009493,0x00001252},
622 {0x00000000,0x00000000,0x00001249,0x00009292,
623 0x00009492,0x0000a49b,0x0000a49b,0x00009292},
624 {0x00000000,0x00000000,0x00001249,0x00009493,
625 0x0000a493,0x000124db,0x000124db,0x00009493},
626 {0x00000000,0x00000000,0x0000924a,0x00009493,
627 0x0000a493,0x000124db,0x000126dc,0x0000a49b},
628 {0x00000000,0x00000000,0x0000924a,0x00009493,
629 0x0000a493,0x000124db,0x000126dc,0x0000a49b},
630 {0x00000000,0x00000000,0x0000924a,0x00009493,
631 0x0001249b,0x000126dc,0x000126dc,0x000124db},
632 {0x00000000,0x00000000,0x00009252,0x00009493,
633 0x000124db,0x000136e4,0x000136e4,0x000126dc},
634 {0x00000000,0x00000000,0x00009252,0x0000a49b,
635 0x000124db,0x000136e4,0x000136e4,0x000126dc},
636 {0x00000000,0x00000000,0x00009292,0x0000a49b,
637 0x000126dc,0x000136e4,0x000136e4,0x000136e4},
638 {0x00000000,0x00000000,0x00009492,0x0000a49b,
639 0x000126dc,0x0001b724,0x0001b725,0x0001b724},
640 {0x00000000,0x00000000,0x0000a492,0x000124db,
641 0x000136e4,0x0001b925,0x0001b92d,0x0001b925},
642 {0x00000000,0x00000000,0x00000000,0x00000000,
643 0x00000000,0x00000000,0x00000000,0x00000000}
644 },
645 { /* version 4, passes 1 */
646 {0x00000000,0x00000000,0x00000249,0x00000049,
647 0x00000009,0x00000009,0x00000009,0x00000009},
648 {0x00000000,0x00000000,0x00000249,0x00000249,
649 0x00000049,0x00000049,0x00000009,0x00000009},
650 {0x00000000,0x00000000,0x00001249,0x00001249,
651 0x0000124a,0x00000249,0x00000049,0x00000049},
652 {0x00000000,0x00000000,0x00001249,0x00001249,
653 0x0000124a,0x0000124a,0x00000049,0x00000049},
654 {0x00000000,0x00000000,0x00001249,0x00001249,
655 0x00009252,0x0000124a,0x0000024a,0x0000024a},
656 {0x00000000,0x00000000,0x00001249,0x0000924a,
657 0x00009252,0x0000124a,0x0000024a,0x0000024a},
658 {0x00000000,0x00000000,0x00001249,0x00009292,
659 0x00009492,0x00009252,0x00001252,0x00001252},
660 {0x00000000,0x00000000,0x00001249,0x00009493,
661 0x0000a493,0x00009292,0x00009292,0x00001252},
662 {0x00000000,0x00000000,0x0000924a,0x00009493,
663 0x0000a493,0x00009292,0x00009292,0x00009292},
664 {0x00000000,0x00000000,0x0000924a,0x00009493,
665 0x0000a493,0x00009493,0x00009493,0x00009292},
666 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
667 0x0000a493,0x0000a49b,0x00009493,0x00009493},
668 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
669 0x0000a493,0x0000a49b,0x0000a49b,0x00009493},
670 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
671 0x0001249b,0x000124db,0x0000a49b,0x0000a49b},
672 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
673 0x000136e4,0x000126dc,0x000124db,0x0000a49b},
674 {0x00000000,0x00000000,0x00009252,0x000124db,
675 0x0001b724,0x000136e4,0x000126dc,0x000124db},
676 {0x00000000,0x00000000,0x00000000,0x00000000,
677 0x00000000,0x00000000,0x00000000,0x00000000}
678 }
679 },
680 { /* version 5 */
681 { /* version 5, passes 0 */
682 {0x00000000,0x00000000,0x00000249,0x00000249,
683 0x00000249,0x00000249,0x00001252,0x00001252},
684 {0x00000000,0x00000000,0x00001249,0x00001249,
685 0x00009252,0x00009292,0x00009292,0x00001252},
686 {0x00000000,0x00000000,0x00001249,0x0000924a,
687 0x00009492,0x0000a49b,0x0000a49b,0x00009292},
688 {0x00000000,0x00000000,0x00001249,0x00009493,
689 0x0000a493,0x0000a49b,0x000124db,0x00009493},
690 {0x00000000,0x00000000,0x00001249,0x00009493,
691 0x0000a493,0x000124db,0x000126dc,0x00009493},
692 {0x00000000,0x00000000,0x0000924a,0x00009493,
693 0x0000a493,0x000126dc,0x000126dc,0x0000a49b},
694 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
695 0x0001249b,0x000126dc,0x000136e4,0x000124db},
696 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
697 0x000126dc,0x000136e4,0x000136e4,0x000126dc},
698 {0x00000000,0x00000000,0x00009292,0x0000a49b,
699 0x000126dc,0x000136e4,0x000136e4,0x000126dc},
700 {0x00000000,0x00000000,0x00009292,0x0000a49b,
701 0x000126dc,0x0001b724,0x0001b725,0x000136e4},
702 {0x00000000,0x00000000,0x00009292,0x0000a49b,
703 0x000136e4,0x0001b724,0x0001b92d,0x0001b724},
704 {0x00000000,0x00000000,0x00009492,0x0000a49b,
705 0x000136e4,0x0001b724,0x0001b92d,0x0001b724},
706 {0x00000000,0x00000000,0x00009492,0x000124db,
707 0x000136e4,0x0001b925,0x0001c96e,0x0001b925},
708 {0x00000000,0x00000000,0x00009492,0x000124db,
709 0x0001b724,0x0001b925,0x0001c96e,0x0001c92d},
710 {0x00000000,0x00000000,0x0000a492,0x000126db,
711 0x0001c924,0x0002496d,0x00025bb6,0x00024b77},
712 {0x00000000,0x00000000,0x00000000,0x00000000,
713 0x00000000,0x00000000,0x00000000,0x00000000}
714 },
715 { /* version 5, passes 1 */
716 {0x00000000,0x00000000,0x00001249,0x00000249,
717 0x00000249,0x00000249,0x0000024a,0x0000024a},
718 {0x00000000,0x00000000,0x00001249,0x00001249,
719 0x0000124a,0x0000124a,0x0000024a,0x0000024a},
720 {0x00000000,0x00000000,0x00001249,0x0000924a,
721 0x00009252,0x00009252,0x0000024a,0x0000024a},
722 {0x00000000,0x00000000,0x00001249,0x00009292,
723 0x00009492,0x0000a49b,0x00001252,0x00001252},
724 {0x00000000,0x00000000,0x0000924a,0x00009493,
725 0x0000a493,0x0000a49b,0x00001252,0x00001252},
726 {0x00000000,0x00000000,0x0000924a,0x00009493,
727 0x0000a493,0x0000a49b,0x00009292,0x00001252},
728 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
729 0x0000a493,0x0000a49b,0x00009292,0x00009292},
730 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
731 0x0000a493,0x0000a49b,0x00009493,0x00009292},
732 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
733 0x0001249b,0x000124db,0x00009493,0x00009292},
734 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
735 0x0001249b,0x000124db,0x00009493,0x00009493},
736 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
737 0x000124db,0x000124db,0x0000a49b,0x00009493},
738 {0x00000000,0x00000000,0x0000924a,0x000124db,
739 0x000126dc,0x000126dc,0x0000a49b,0x00009493},
740 {0x00000000,0x00000000,0x0000924a,0x000124db,
741 0x000136e4,0x000126dc,0x000124db,0x0000a49b},
742 {0x00000000,0x00000000,0x00009292,0x000124db,
743 0x000136e4,0x000126dc,0x000124db,0x0000a49b},
744 {0x00000000,0x00000000,0x00009492,0x000126db,
745 0x0001b724,0x000136e4,0x000126dc,0x000124db},
746 {0x00000000,0x00000000,0x00000000,0x00000000,
747 0x00000000,0x00000000,0x00000000,0x00000000}
748 }
749 },
750 { /* version 6 */
751 { /* version 6, passes 0 */
752 {0x00000000,0x00000000,0x00001249,0x00001249,
753 0x00009252,0x00009292,0x00009493,0x00009493},
754 {0x00000000,0x00000000,0x00001249,0x00009292,
755 0x0000a493,0x0000a49b,0x0000a49b,0x00009493},
756 {0x00000000,0x00000000,0x00001249,0x00009493,
757 0x0000a493,0x000124db,0x000124db,0x0000a49b},
758 {0x00000000,0x00000000,0x0000924a,0x00009493,
759 0x0000a493,0x000126dc,0x000126dc,0x0000a49b},
760 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
761 0x0001249b,0x000126dc,0x000136e4,0x000124db},
762 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
763 0x000126dc,0x000136e4,0x000136e4,0x000126dc},
764 {0x00000000,0x00000000,0x00009292,0x0000a49b,
765 0x000126dc,0x0001b724,0x0001b725,0x000126dc},
766 {0x00000000,0x00000000,0x00009292,0x0000a49b,
767 0x000136e4,0x0001b724,0x0001b92d,0x000136e4},
768 {0x00000000,0x00000000,0x00009492,0x0000a49b,
769 0x000136e4,0x0001b724,0x0001b92d,0x0001b724},
770 {0x00000000,0x00000000,0x00009492,0x000124db,
771 0x000136e4,0x0001b724,0x0001b92d,0x0001b724},
772 {0x00000000,0x00000000,0x00009492,0x000124db,
773 0x000136e4,0x0001b925,0x0001b92d,0x0001b925},
774 {0x00000000,0x00000000,0x00009492,0x000124db,
775 0x0001b724,0x0001b925,0x0001c96e,0x0001c92d},
776 {0x00000000,0x00000000,0x0000a492,0x000124db,
777 0x0001b724,0x0001c92d,0x0001c96e,0x0001c92d},
778 {0x00000000,0x00000000,0x0000a492,0x000124db,
779 0x0001b724,0x0001c92d,0x00024b76,0x0002496e},
780 {0x00000000,0x00000000,0x00012492,0x000126db,
781 0x0001c924,0x00024b6d,0x0002ddb6,0x00025bbf},
782 {0x00000000,0x00000000,0x00000000,0x00000000,
783 0x00000000,0x00000000,0x00000000,0x00000000}
784 },
785 { /* version 6, passes 1 */
786 {0x00000000,0x00000000,0x00001249,0x00001249,
787 0x0000124a,0x0000124a,0x00001252,0x00001252},
788 {0x00000000,0x00000000,0x00001249,0x00009292,
789 0x00009492,0x00009252,0x00001252,0x00001252},
790 {0x00000000,0x00000000,0x0000924a,0x00009493,
791 0x0000a493,0x00009292,0x00001252,0x00001252},
792 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
793 0x0000a493,0x0000a49b,0x00009292,0x00009292},
794 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
795 0x0000a493,0x0000a49b,0x00009292,0x00009292},
796 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
797 0x0001249b,0x0000a49b,0x00009493,0x00009292},
798 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
799 0x000124db,0x000124db,0x00009493,0x00009493},
800 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
801 0x000124db,0x000124db,0x0000a49b,0x00009493},
802 {0x00000000,0x00000000,0x0000924a,0x000124db,
803 0x000126dc,0x000124db,0x0000a49b,0x00009493},
804 {0x00000000,0x00000000,0x0000924a,0x000124db,
805 0x000126dc,0x000126dc,0x0000a49b,0x0000a49b},
806 {0x00000000,0x00000000,0x0000924a,0x000124db,
807 0x000136e4,0x000126dc,0x000124db,0x0000a49b},
808 {0x00000000,0x00000000,0x00009492,0x000126db,
809 0x000136e4,0x000126dc,0x000124db,0x0000a49b},
810 {0x00000000,0x00000000,0x00009492,0x000126db,
811 0x0001b724,0x000136e4,0x000126dc,0x000124db},
812 {0x00000000,0x00000000,0x00009492,0x000126db,
813 0x0001b724,0x000136e4,0x000126dc,0x000124db},
814 {0x00000000,0x00000000,0x0000a492,0x000136db,
815 0x0001c924,0x0001b724,0x000136e4,0x000126dc},
816 {0x00000000,0x00000000,0x00000000,0x00000000,
817 0x00000000,0x00000000,0x00000000,0x00000000}
818 }
819 },
820 { /* version 7 */
821 { /* version 7, passes 0 */
822 {0x00000000,0x00000000,0x00001249,0x00001249,
823 0x00009252,0x00009292,0x00009493,0x00009493},
824 {0x00000000,0x00000000,0x00001249,0x00009493,
825 0x0000a493,0x000124db,0x000126dc,0x00009493},
826 {0x00000000,0x00000000,0x00001249,0x0000a49b,
827 0x0001249b,0x000126dc,0x000126dc,0x0000a49b},
828 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
829 0x0001249b,0x000126dc,0x000136e4,0x0000a49b},
830 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
831 0x000126dc,0x000136e4,0x0001b725,0x000124db},
832 {0x00000000,0x00000000,0x00009292,0x0000a49b,
833 0x000136e4,0x0001b724,0x0001b725,0x000126dc},
834 {0x00000000,0x00000000,0x00009292,0x000124db,
835 0x000136e4,0x0001b724,0x0001b725,0x000126dc},
836 {0x00000000,0x00000000,0x00009492,0x000124db,
837 0x000136e4,0x0001b724,0x0001c96e,0x000136e4},
838 {0x00000000,0x00000000,0x00009492,0x000124db,
839 0x000136e4,0x0001c92d,0x0001c96e,0x0001b724},
840 {0x00000000,0x00000000,0x0000a492,0x000124db,
841 0x000136e4,0x0001c92d,0x0001c96e,0x0001b724},
842 {0x00000000,0x00000000,0x0000a492,0x000124db,
843 0x0001b724,0x0001c92d,0x0001c96e,0x0001b925},
844 {0x00000000,0x00000000,0x0000a492,0x000126db,
845 0x0001b724,0x0001c92d,0x00024b76,0x0001c92d},
846 {0x00000000,0x00000000,0x0000a492,0x000126db,
847 0x0001b924,0x0001c92d,0x00024b76,0x0001c92d},
848 {0x00000000,0x00000000,0x0000a492,0x000126db,
849 0x0001b924,0x0001c92d,0x00024b76,0x0002496e},
850 {0x00000000,0x00000000,0x00012492,0x000136db,
851 0x00024924,0x00024b6d,0x0002ddb6,0x00025bbf},
852 {0x00000000,0x00000000,0x00000000,0x00000000,
853 0x00000000,0x00000000,0x00000000,0x00000000}
854 },
855 { /* version 7, passes 1 */
856 {0x00000000,0x00000000,0x00001249,0x00001249,
857 0x0000124a,0x0000124a,0x00001252,0x00001252},
858 {0x00000000,0x00000000,0x0000924a,0x00009493,
859 0x00009492,0x00009292,0x00001252,0x00001252},
860 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
861 0x0000a493,0x0000a49b,0x00001252,0x00001252},
862 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
863 0x0000a493,0x0000a49b,0x00009292,0x00009292},
864 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
865 0x0000a493,0x0000a49b,0x00009292,0x00009292},
866 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
867 0x000126dc,0x0000a49b,0x00009493,0x00009292},
868 {0x00000000,0x00000000,0x0000924a,0x000124db,
869 0x000126dc,0x000124db,0x00009493,0x00009493},
870 {0x00000000,0x00000000,0x0000924a,0x000124db,
871 0x000136e4,0x000124db,0x0000a49b,0x00009493},
872 {0x00000000,0x00000000,0x0000924a,0x000136db,
873 0x0001b724,0x000124db,0x0000a49b,0x00009493},
874 {0x00000000,0x00000000,0x0000924a,0x000136db,
875 0x0001b724,0x000126dc,0x0000a49b,0x0000a49b},
876 {0x00000000,0x00000000,0x00009292,0x000136db,
877 0x0001b724,0x000126dc,0x000124db,0x0000a49b},
878 {0x00000000,0x00000000,0x00009492,0x000136db,
879 0x0001b724,0x000126dc,0x000124db,0x0000a49b},
880 {0x00000000,0x00000000,0x0000a492,0x000136db,
881 0x0001b724,0x000136e4,0x000126dc,0x000124db},
882 {0x00000000,0x00000000,0x0000a492,0x000136db,
883 0x0001b724,0x000136e4,0x000126dc,0x000124db},
884 {0x00000000,0x00000000,0x00012492,0x0001b6db,
885 0x0001c924,0x0001b724,0x000136e4,0x000126dc},
886 {0x00000000,0x00000000,0x00000000,0x00000000,
887 0x00000000,0x00000000,0x00000000,0x00000000}
888 }
889 }
890};
891
diff --git a/drivers/media/video/pwc/pwc-kiara.h b/drivers/media/video/pwc/pwc-kiara.h
index 12929abbb1f..0bdb22547d8 100644
--- a/drivers/media/video/pwc/pwc-kiara.h
+++ b/drivers/media/video/pwc/pwc-kiara.h
@@ -1,5 +1,5 @@
1/* Linux driver for Philips webcam 1/* Linux driver for Philips webcam
2 (C) 2004 Luc Saillard (luc@saillard.org) 2 (C) 2004-2006 Luc Saillard (luc@saillard.org)
3 3
4 NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx 4 NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx
5 driver and thus may have bugs that are not present in the original version. 5 driver and thus may have bugs that are not present in the original version.
@@ -27,7 +27,7 @@
27#ifndef PWC_KIARA_H 27#ifndef PWC_KIARA_H
28#define PWC_KIARA_H 28#define PWC_KIARA_H
29 29
30#include "pwc-ioctl.h" 30#include <media/pwc-ioctl.h>
31 31
32struct Kiara_table_entry 32struct Kiara_table_entry
33{ 33{
@@ -37,8 +37,8 @@ struct Kiara_table_entry
37 unsigned char mode[12]; /* precomputed mode settings for cam */ 37 unsigned char mode[12]; /* precomputed mode settings for cam */
38}; 38};
39 39
40const extern struct Kiara_table_entry Kiara_table[PSZ_MAX][6][4]; 40extern const struct Kiara_table_entry Kiara_table[PSZ_MAX][6][4];
41const extern unsigned int KiaraRomTable[8][2][16][8]; 41extern const unsigned int KiaraRomTable[8][2][16][8];
42 42
43#endif 43#endif
44 44
diff --git a/drivers/media/video/pwc/pwc-misc.c b/drivers/media/video/pwc/pwc-misc.c
index 58fe7974799..589c687439d 100644
--- a/drivers/media/video/pwc/pwc-misc.c
+++ b/drivers/media/video/pwc/pwc-misc.c
@@ -1,7 +1,7 @@
1/* Linux driver for Philips webcam 1/* Linux driver for Philips webcam
2 Various miscellaneous functions and tables. 2 Various miscellaneous functions and tables.
3 (C) 1999-2003 Nemosoft Unv. 3 (C) 1999-2003 Nemosoft Unv.
4 (C) 2004 Luc Saillard (luc@saillard.org) 4 (C) 2004-2006 Luc Saillard (luc@saillard.org)
5 5
6 NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx 6 NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx
7 driver and thus may have bugs that are not present in the original version. 7 driver and thus may have bugs that are not present in the original version.
@@ -24,18 +24,17 @@
24 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 24 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25*/ 25*/
26 26
27#include <linux/slab.h>
28 27
29#include "pwc.h" 28#include "pwc.h"
30 29
31struct pwc_coord pwc_image_sizes[PSZ_MAX] = 30const struct pwc_coord pwc_image_sizes[PSZ_MAX] =
32{ 31{
33 { 128, 96, 0 }, 32 { 128, 96, 0 }, /* sqcif */
34 { 160, 120, 0 }, 33 { 160, 120, 0 }, /* qsif */
35 { 176, 144, 0 }, 34 { 176, 144, 0 }, /* qcif */
36 { 320, 240, 0 }, 35 { 320, 240, 0 }, /* sif */
37 { 352, 288, 0 }, 36 { 352, 288, 0 }, /* cif */
38 { 640, 480, 0 }, 37 { 640, 480, 0 }, /* vga */
39}; 38};
40 39
41/* x,y -> PSZ_ */ 40/* x,y -> PSZ_ */
@@ -52,7 +51,7 @@ int pwc_decode_size(struct pwc_device *pdev, int width, int height)
52 { 51 {
53 if (width > pdev->abs_max.x || height > pdev->abs_max.y) 52 if (width > pdev->abs_max.x || height > pdev->abs_max.y)
54 { 53 {
55 Debug("VIDEO_PALETTE_RAW: going beyond abs_max.\n"); 54 PWC_DEBUG_SIZE("VIDEO_PALETTE_RAW: going beyond abs_max.\n");
56 return -1; 55 return -1;
57 } 56 }
58 } 57 }
@@ -60,7 +59,7 @@ int pwc_decode_size(struct pwc_device *pdev, int width, int height)
60 { 59 {
61 if (width > pdev->view_max.x || height > pdev->view_max.y) 60 if (width > pdev->view_max.x || height > pdev->view_max.y)
62 { 61 {
63 Debug("VIDEO_PALETTE_ not RAW: going beyond view_max.\n"); 62 PWC_DEBUG_SIZE("VIDEO_PALETTE_not RAW: going beyond view_max.\n");
64 return -1; 63 return -1;
65 } 64 }
66 } 65 }
@@ -81,9 +80,8 @@ int pwc_decode_size(struct pwc_device *pdev, int width, int height)
81/* initialize variables depending on type and decompressor*/ 80/* initialize variables depending on type and decompressor*/
82void pwc_construct(struct pwc_device *pdev) 81void pwc_construct(struct pwc_device *pdev)
83{ 82{
84 switch(pdev->type) { 83 if (DEVICE_USE_CODEC1(pdev->type)) {
85 case 645: 84
86 case 646:
87 pdev->view_min.x = 128; 85 pdev->view_min.x = 128;
88 pdev->view_min.y = 96; 86 pdev->view_min.y = 96;
89 pdev->view_max.x = 352; 87 pdev->view_max.x = 352;
@@ -95,10 +93,23 @@ void pwc_construct(struct pwc_device *pdev)
95 pdev->vendpoint = 4; 93 pdev->vendpoint = 4;
96 pdev->frame_header_size = 0; 94 pdev->frame_header_size = 0;
97 pdev->frame_trailer_size = 0; 95 pdev->frame_trailer_size = 0;
98 break; 96
99 case 675: 97 } else if (DEVICE_USE_CODEC3(pdev->type)) {
100 case 680: 98
101 case 690: 99 pdev->view_min.x = 160;
100 pdev->view_min.y = 120;
101 pdev->view_max.x = 640;
102 pdev->view_max.y = 480;
103 pdev->image_mask = 1 << PSZ_QSIF | 1 << PSZ_SIF | 1 << PSZ_VGA;
104 pdev->abs_max.x = 640;
105 pdev->abs_max.y = 480;
106 pdev->vcinterface = 3;
107 pdev->vendpoint = 5;
108 pdev->frame_header_size = TOUCAM_HEADER_SIZE;
109 pdev->frame_trailer_size = TOUCAM_TRAILER_SIZE;
110
111 } else /* if (DEVICE_USE_CODEC2(pdev->type)) */ {
112
102 pdev->view_min.x = 128; 113 pdev->view_min.x = 128;
103 pdev->view_min.y = 96; 114 pdev->view_min.y = 96;
104 /* Anthill bug #38: PWC always reports max size, even without PWCX */ 115 /* Anthill bug #38: PWC always reports max size, even without PWCX */
@@ -111,30 +122,12 @@ void pwc_construct(struct pwc_device *pdev)
111 pdev->vendpoint = 4; 122 pdev->vendpoint = 4;
112 pdev->frame_header_size = 0; 123 pdev->frame_header_size = 0;
113 pdev->frame_trailer_size = 0; 124 pdev->frame_trailer_size = 0;
114 break;
115 case 720:
116 case 730:
117 case 740:
118 case 750:
119 pdev->view_min.x = 160;
120 pdev->view_min.y = 120;
121 pdev->view_max.x = 640;
122 pdev->view_max.y = 480;
123 pdev->image_mask = 1 << PSZ_QSIF | 1 << PSZ_SIF | 1 << PSZ_VGA;
124 pdev->abs_max.x = 640;
125 pdev->abs_max.y = 480;
126 pdev->vcinterface = 3;
127 pdev->vendpoint = 5;
128 pdev->frame_header_size = TOUCAM_HEADER_SIZE;
129 pdev->frame_trailer_size = TOUCAM_TRAILER_SIZE;
130 break;
131 } 125 }
132 Debug("type = %d\n",pdev->type);
133 pdev->vpalette = VIDEO_PALETTE_YUV420P; /* default */ 126 pdev->vpalette = VIDEO_PALETTE_YUV420P; /* default */
134 pdev->view_min.size = pdev->view_min.x * pdev->view_min.y; 127 pdev->view_min.size = pdev->view_min.x * pdev->view_min.y;
135 pdev->view_max.size = pdev->view_max.x * pdev->view_max.y; 128 pdev->view_max.size = pdev->view_max.x * pdev->view_max.y;
136 /* length of image, in YUV format; always allocate enough memory. */ 129 /* length of image, in YUV format; always allocate enough memory. */
137 pdev->len_per_image = (pdev->abs_max.x * pdev->abs_max.y * 3) / 2; 130 pdev->len_per_image = PAGE_ALIGN((pdev->abs_max.x * pdev->abs_max.y * 3) / 2);
138} 131}
139 132
140 133
diff --git a/drivers/media/video/pwc/pwc-timon.c b/drivers/media/video/pwc/pwc-timon.c
index 175250d089c..be65bdcd195 100644
--- a/drivers/media/video/pwc/pwc-timon.c
+++ b/drivers/media/video/pwc/pwc-timon.c
@@ -1,5 +1,5 @@
1/* Linux driver for Philips webcam 1/* Linux driver for Philips webcam
2 (C) 2004 Luc Saillard (luc@saillard.org) 2 (C) 2004-2006 Luc Saillard (luc@saillard.org)
3 3
4 NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx 4 NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx
5 driver and thus may have bugs that are not present in the original version. 5 driver and thus may have bugs that are not present in the original version.
@@ -314,3 +314,1133 @@ const struct Timon_table_entry Timon_table[PSZ_MAX][6][4] =
314 }, 314 },
315}; 315};
316 316
317/*
318 * 16 versions:
319 * 2 tables (one for Y, and one for U&V)
320 * 16 levels of details per tables
321 * 8 blocs
322 */
323
324const unsigned int TimonRomTable [16][2][16][8] =
325{
326 { /* version 0 */
327 { /* version 0, passes 0 */
328 {0x00000000,0x00000000,0x00000000,0x00000000,
329 0x00000000,0x00000000,0x00000000,0x00000001},
330 {0x00000000,0x00000000,0x00000001,0x00000001,
331 0x00000001,0x00000001,0x00000001,0x00000001},
332 {0x00000000,0x00000000,0x00000001,0x00000001,
333 0x00000001,0x00000009,0x00000009,0x00000009},
334 {0x00000000,0x00000000,0x00000009,0x00000001,
335 0x00000009,0x00000009,0x00000009,0x00000009},
336 {0x00000000,0x00000000,0x00000009,0x00000009,
337 0x00000009,0x00000009,0x00000049,0x00000009},
338 {0x00000000,0x00000000,0x00000009,0x00000009,
339 0x00000009,0x00000049,0x00000049,0x00000049},
340 {0x00000000,0x00000000,0x00000009,0x00000009,
341 0x00000049,0x00000049,0x00000049,0x00000049},
342 {0x00000000,0x00000000,0x00000009,0x00000049,
343 0x00000049,0x00000049,0x00000049,0x00000049},
344 {0x00000000,0x00000000,0x00000049,0x00000049,
345 0x00000049,0x00000049,0x0000024a,0x0000024a},
346 {0x00000000,0x00000000,0x00000049,0x00000049,
347 0x00000049,0x00000249,0x0000024a,0x0000024a},
348 {0x00000000,0x00000000,0x00000049,0x00000049,
349 0x00000249,0x00000249,0x0000024a,0x0000024a},
350 {0x00000000,0x00000000,0x00000049,0x00000049,
351 0x00000249,0x00000249,0x00001252,0x0000024a},
352 {0x00000000,0x00000000,0x00000049,0x00000049,
353 0x00000249,0x0000124a,0x00001252,0x0000024a},
354 {0x00000000,0x00000000,0x00000049,0x00000249,
355 0x00000249,0x0000124a,0x00001252,0x0000024a},
356 {0x00000000,0x00000000,0x00000249,0x00001249,
357 0x0000124a,0x00009252,0x00009292,0x00001252},
358 {0x00000000,0x00000000,0x00000000,0x00000000,
359 0x00000000,0x00000000,0x00000000,0x00000000}
360 },
361 { /* version 0, passes 1 */
362 {0x00000000,0x00000000,0x00000000,0x00000000,
363 0x00000000,0x00000000,0x00000000,0x00000000},
364 {0x00000000,0x00000000,0x00000001,0x00000001,
365 0x00000001,0x00000001,0x00000000,0x00000000},
366 {0x00000000,0x00000000,0x00000009,0x00000001,
367 0x00000001,0x00000009,0x00000000,0x00000000},
368 {0x00000000,0x00000000,0x00000009,0x00000009,
369 0x00000009,0x00000009,0x00000000,0x00000000},
370 {0x00000000,0x00000000,0x00000009,0x00000009,
371 0x00000009,0x00000009,0x00000001,0x00000000},
372 {0x00000000,0x00000000,0x00000049,0x00000009,
373 0x00000009,0x00000049,0x00000001,0x00000001},
374 {0x00000000,0x00000000,0x00000049,0x00000009,
375 0x00000009,0x00000049,0x00000001,0x00000001},
376 {0x00000000,0x00000000,0x00000049,0x00000049,
377 0x00000049,0x00000049,0x00000009,0x00000001},
378 {0x00000000,0x00000000,0x00000049,0x00000049,
379 0x00000049,0x00000049,0x00000009,0x00000001},
380 {0x00000000,0x00000000,0x00000049,0x00000049,
381 0x00000049,0x00000049,0x00000009,0x00000001},
382 {0x00000000,0x00000000,0x00000049,0x00000049,
383 0x00000049,0x00000049,0x00000009,0x00000009},
384 {0x00000000,0x00000000,0x00000049,0x00000049,
385 0x00000049,0x00000249,0x00000049,0x00000009},
386 {0x00000000,0x00000000,0x00000049,0x00000049,
387 0x00000049,0x00000249,0x00000049,0x00000009},
388 {0x00000000,0x00000000,0x00000249,0x00000049,
389 0x00000249,0x00000249,0x00000049,0x00000009},
390 {0x00000000,0x00000000,0x00001249,0x00000249,
391 0x0000124a,0x0000124a,0x0000024a,0x00000049},
392 {0x00000000,0x00000000,0x00000000,0x00000000,
393 0x00000000,0x00000000,0x00000000,0x00000000}
394 }
395 },
396 { /* version 1 */
397 { /* version 1, passes 0 */
398 {0x00000000,0x00000000,0x00000000,0x00000000,
399 0x00000000,0x00000000,0x00000000,0x00000001},
400 {0x00000000,0x00000000,0x00000001,0x00000001,
401 0x00000001,0x00000009,0x00000009,0x00000009},
402 {0x00000000,0x00000000,0x00000009,0x00000009,
403 0x00000009,0x00000009,0x00000009,0x00000009},
404 {0x00000000,0x00000000,0x00000009,0x00000009,
405 0x00000009,0x00000049,0x00000049,0x00000049},
406 {0x00000000,0x00000000,0x00000009,0x00000049,
407 0x00000049,0x00000049,0x00000049,0x00000049},
408 {0x00000000,0x00000000,0x00000049,0x00000049,
409 0x00000049,0x00000249,0x0000024a,0x0000024a},
410 {0x00000000,0x00000000,0x00000049,0x00000049,
411 0x00000249,0x00000249,0x0000024a,0x0000024a},
412 {0x00000000,0x00000000,0x00000049,0x00000249,
413 0x00000249,0x00000249,0x0000024a,0x00001252},
414 {0x00000000,0x00000000,0x00000049,0x00000249,
415 0x00000249,0x0000124a,0x00001252,0x00001252},
416 {0x00000000,0x00000000,0x00000049,0x00000249,
417 0x0000124a,0x0000124a,0x00001252,0x00001252},
418 {0x00000000,0x00000000,0x00000249,0x00000249,
419 0x0000124a,0x0000124a,0x00009292,0x00009292},
420 {0x00000000,0x00000000,0x00000249,0x00001249,
421 0x0000124a,0x00009252,0x00009292,0x00009292},
422 {0x00000000,0x00000000,0x00000249,0x00001249,
423 0x00009252,0x00009252,0x00009292,0x00009292},
424 {0x00000000,0x00000000,0x00000249,0x0000924a,
425 0x00009292,0x00009493,0x00009493,0x00009493},
426 {0x00000000,0x00000000,0x00001249,0x00009252,
427 0x00009492,0x0000a49b,0x0000a49b,0x0000a49b},
428 {0x00000000,0x00000000,0x00000000,0x00000000,
429 0x00000000,0x00000000,0x00000000,0x00000000}
430 },
431 { /* version 1, passes 1 */
432 {0x00000000,0x00000000,0x00000000,0x00000000,
433 0x00000000,0x00000000,0x00000000,0x00000000},
434 {0x00000000,0x00000000,0x00000009,0x00000009,
435 0x00000009,0x00000001,0x00000001,0x00000000},
436 {0x00000000,0x00000000,0x00000009,0x00000009,
437 0x00000009,0x00000009,0x00000001,0x00000000},
438 {0x00000000,0x00000000,0x00000049,0x00000049,
439 0x00000049,0x00000009,0x00000001,0x00000000},
440 {0x00000000,0x00000000,0x00000049,0x00000049,
441 0x00000049,0x00000049,0x00000001,0x00000001},
442 {0x00000000,0x00000000,0x00000049,0x00000049,
443 0x00000049,0x00000049,0x00000009,0x00000001},
444 {0x00000000,0x00000000,0x00000249,0x00000049,
445 0x00000049,0x00000249,0x00000009,0x00000001},
446 {0x00000000,0x00000000,0x00000249,0x00000049,
447 0x00000249,0x00000249,0x00000009,0x00000009},
448 {0x00000000,0x00000000,0x00000249,0x00000249,
449 0x00000249,0x00000249,0x00000049,0x00000009},
450 {0x00000000,0x00000000,0x00000249,0x00000249,
451 0x00000249,0x0000124a,0x00000049,0x00000009},
452 {0x00000000,0x00000000,0x00000249,0x00000249,
453 0x00000249,0x0000124a,0x00000049,0x00000009},
454 {0x00000000,0x00000000,0x00000249,0x00000249,
455 0x00000249,0x0000124a,0x0000024a,0x00000049},
456 {0x00000000,0x00000000,0x00000249,0x00000249,
457 0x0000124a,0x0000124a,0x0000024a,0x00000049},
458 {0x00000000,0x00000000,0x00000249,0x00000249,
459 0x0000124a,0x0000124a,0x0000024a,0x00000049},
460 {0x00000000,0x00000000,0x00001249,0x00001249,
461 0x00009252,0x00009252,0x00001252,0x0000024a},
462 {0x00000000,0x00000000,0x00000000,0x00000000,
463 0x00000000,0x00000000,0x00000000,0x00000000}
464 }
465 },
466 { /* version 2 */
467 { /* version 2, passes 0 */
468 {0x00000000,0x00000000,0x00000000,0x00000000,
469 0x00000000,0x00000000,0x00000000,0x00000001},
470 {0x00000000,0x00000000,0x00000009,0x00000009,
471 0x00000009,0x00000009,0x00000009,0x00000009},
472 {0x00000000,0x00000000,0x00000049,0x00000049,
473 0x00000049,0x00000049,0x00000049,0x00000049},
474 {0x00000000,0x00000000,0x00000049,0x00000049,
475 0x00000049,0x00000249,0x0000024a,0x0000024a},
476 {0x00000000,0x00000000,0x00000049,0x00000249,
477 0x00000249,0x00000249,0x0000024a,0x00001252},
478 {0x00000000,0x00000000,0x00000249,0x00000249,
479 0x00000249,0x0000124a,0x00001252,0x00001252},
480 {0x00000000,0x00000000,0x00000249,0x00000249,
481 0x0000124a,0x0000124a,0x00009292,0x00009292},
482 {0x00000000,0x00000000,0x00000249,0x00001249,
483 0x0000124a,0x00009252,0x00009292,0x00009292},
484 {0x00000000,0x00000000,0x00000249,0x00001249,
485 0x00009252,0x00009292,0x00009292,0x00009292},
486 {0x00000000,0x00000000,0x00000249,0x00001249,
487 0x00009252,0x00009292,0x00009493,0x00009493},
488 {0x00000000,0x00000000,0x00000249,0x0000924a,
489 0x00009252,0x00009493,0x00009493,0x00009493},
490 {0x00000000,0x00000000,0x00000249,0x0000924a,
491 0x00009292,0x00009493,0x00009493,0x00009493},
492 {0x00000000,0x00000000,0x00000249,0x00009252,
493 0x00009492,0x00009493,0x0000a49b,0x0000a49b},
494 {0x00000000,0x00000000,0x00001249,0x00009292,
495 0x00009492,0x000124db,0x000124db,0x000124db},
496 {0x00000000,0x00000000,0x0000924a,0x00009493,
497 0x0000a493,0x000126dc,0x000126dc,0x000126dc},
498 {0x00000000,0x00000000,0x00000000,0x00000000,
499 0x00000000,0x00000000,0x00000000,0x00000000}
500 },
501 { /* version 2, passes 1 */
502 {0x00000000,0x00000000,0x00000000,0x00000000,
503 0x00000000,0x00000000,0x00000000,0x00000000},
504 {0x00000000,0x00000000,0x00000049,0x00000009,
505 0x00000049,0x00000009,0x00000001,0x00000000},
506 {0x00000000,0x00000000,0x00000049,0x00000049,
507 0x00000049,0x00000049,0x00000049,0x00000000},
508 {0x00000000,0x00000000,0x00000249,0x00000049,
509 0x00000249,0x00000049,0x0000024a,0x00000001},
510 {0x00000000,0x00000000,0x00000249,0x00000249,
511 0x00000249,0x00000249,0x0000024a,0x00000001},
512 {0x00000000,0x00000000,0x00000249,0x00000249,
513 0x00000249,0x00000249,0x0000024a,0x00000001},
514 {0x00000000,0x00000000,0x00000249,0x00000249,
515 0x00000249,0x00000249,0x0000024a,0x00000009},
516 {0x00000000,0x00000000,0x00000249,0x00000249,
517 0x0000124a,0x0000124a,0x0000024a,0x00000009},
518 {0x00000000,0x00000000,0x00000249,0x00000249,
519 0x0000124a,0x0000124a,0x0000024a,0x00000009},
520 {0x00000000,0x00000000,0x00001249,0x00001249,
521 0x0000124a,0x00009252,0x00001252,0x00000049},
522 {0x00000000,0x00000000,0x00001249,0x00001249,
523 0x0000124a,0x00009292,0x00001252,0x00000049},
524 {0x00000000,0x00000000,0x00001249,0x00001249,
525 0x0000124a,0x00009292,0x00001252,0x00000049},
526 {0x00000000,0x00000000,0x00001249,0x00001249,
527 0x00009252,0x00009292,0x00001252,0x0000024a},
528 {0x00000000,0x00000000,0x00001249,0x00001249,
529 0x00009292,0x00009292,0x00001252,0x0000024a},
530 {0x00000000,0x00000000,0x0000924a,0x0000924a,
531 0x00009492,0x00009493,0x00009292,0x00001252},
532 {0x00000000,0x00000000,0x00000000,0x00000000,
533 0x00000000,0x00000000,0x00000000,0x00000000}
534 }
535 },
536 { /* version 3 */
537 { /* version 3, passes 0 */
538 {0x00000000,0x00000000,0x00000000,0x00000000,
539 0x00000000,0x00000000,0x00000000,0x00000001},
540 {0x00000000,0x00000000,0x00000049,0x00000049,
541 0x00000049,0x00000049,0x00000049,0x00000049},
542 {0x00000000,0x00000000,0x00000049,0x00000249,
543 0x00000249,0x00000249,0x00001252,0x0000024a},
544 {0x00000000,0x00000000,0x00000249,0x00000249,
545 0x00000249,0x0000124a,0x00001252,0x00001252},
546 {0x00000000,0x00000000,0x00000249,0x00000249,
547 0x0000124a,0x00009252,0x00009292,0x00009292},
548 {0x00000000,0x00000000,0x00000249,0x00001249,
549 0x0000124a,0x00009292,0x00009292,0x00009493},
550 {0x00000000,0x00000000,0x00000249,0x00001249,
551 0x00009252,0x00009292,0x00009493,0x00009493},
552 {0x00000000,0x00000000,0x00000249,0x00001249,
553 0x00009292,0x00009493,0x00009493,0x00009493},
554 {0x00000000,0x00000000,0x00000249,0x00009252,
555 0x00009292,0x00009493,0x0000a49b,0x0000a49b},
556 {0x00000000,0x00000000,0x00001249,0x00009252,
557 0x00009292,0x0000a49b,0x0000a49b,0x0000a49b},
558 {0x00000000,0x00000000,0x00001249,0x00009252,
559 0x00009492,0x0000a49b,0x0000a49b,0x0000a49b},
560 {0x00000000,0x00000000,0x00001249,0x00009292,
561 0x00009492,0x0000a49b,0x000124db,0x000124db},
562 {0x00000000,0x00000000,0x00001249,0x00009292,
563 0x0000a493,0x0000a49b,0x000124db,0x000124db},
564 {0x00000000,0x00000000,0x00001249,0x00009493,
565 0x0001249b,0x000126dc,0x000136e4,0x000126dc},
566 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
567 0x000124db,0x000136e4,0x0001b725,0x000136e4},
568 {0x00000000,0x00000000,0x00000000,0x00000000,
569 0x00000000,0x00000000,0x00000000,0x00000000}
570 },
571 { /* version 3, passes 1 */
572 {0x00000000,0x00000000,0x00000000,0x00000000,
573 0x00000000,0x00000000,0x00000000,0x00000000},
574 {0x00000000,0x00000000,0x00000049,0x00000049,
575 0x00000049,0x00000049,0x00000001,0x00000000},
576 {0x00000000,0x00000000,0x00000249,0x00000249,
577 0x00000249,0x00000249,0x00000049,0x00000001},
578 {0x00000000,0x00000000,0x00000249,0x00000249,
579 0x00000249,0x0000124a,0x00001252,0x00000001},
580 {0x00000000,0x00000000,0x00000249,0x00000249,
581 0x0000124a,0x0000124a,0x00001252,0x00000009},
582 {0x00000000,0x00000000,0x00000249,0x00001249,
583 0x0000124a,0x00009252,0x00009292,0x00000009},
584 {0x00000000,0x00000000,0x00001249,0x00001249,
585 0x0000124a,0x00009252,0x00009292,0x00000049},
586 {0x00000000,0x00000000,0x00001249,0x00001249,
587 0x00009252,0x00009252,0x00009292,0x00000049},
588 {0x00000000,0x00000000,0x00001249,0x00001249,
589 0x00009252,0x00009493,0x00009292,0x0000024a},
590 {0x00000000,0x00000000,0x00001249,0x00001249,
591 0x00009252,0x00009493,0x00009292,0x0000024a},
592 {0x00000000,0x00000000,0x00001249,0x00001249,
593 0x00009252,0x00009493,0x00009493,0x00001252},
594 {0x00000000,0x00000000,0x00001249,0x0000924a,
595 0x00009292,0x00009493,0x00009493,0x00001252},
596 {0x00000000,0x00000000,0x00001249,0x0000924a,
597 0x00009492,0x00009493,0x00009493,0x00009292},
598 {0x00000000,0x00000000,0x00001249,0x00009252,
599 0x00009492,0x0000a49b,0x00009493,0x00009292},
600 {0x00000000,0x00000000,0x0000924a,0x00009292,
601 0x0000a493,0x000124db,0x0000a49b,0x00009493},
602 {0x00000000,0x00000000,0x00000000,0x00000000,
603 0x00000000,0x00000000,0x00000000,0x00000000}
604 }
605 },
606 { /* version 4 */
607 { /* version 4, passes 0 */
608 {0x00000000,0x00000000,0x00000049,0x00000049,
609 0x00000049,0x00000049,0x0000024a,0x0000024a},
610 {0x00000000,0x00000000,0x00000249,0x00000249,
611 0x00000249,0x0000124a,0x00001252,0x00009292},
612 {0x00000000,0x00000000,0x00000249,0x00000249,
613 0x0000124a,0x00009252,0x00009292,0x00009292},
614 {0x00000000,0x00000000,0x00000249,0x00001249,
615 0x0000124a,0x00009292,0x00009493,0x00009493},
616 {0x00000000,0x00000000,0x00000249,0x00001249,
617 0x00009252,0x00009493,0x00009493,0x0000a49b},
618 {0x00000000,0x00000000,0x00000249,0x0000924a,
619 0x00009292,0x00009493,0x0000a49b,0x0000a49b},
620 {0x00000000,0x00000000,0x00001249,0x0000924a,
621 0x00009292,0x00009493,0x0000a49b,0x000124db},
622 {0x00000000,0x00000000,0x00001249,0x00009252,
623 0x00009492,0x0000a49b,0x0000a49b,0x000124db},
624 {0x00000000,0x00000000,0x00001249,0x00009292,
625 0x00009492,0x000124db,0x000124db,0x000126dc},
626 {0x00000000,0x00000000,0x00001249,0x00009292,
627 0x0000a493,0x000124db,0x000126dc,0x000126dc},
628 {0x00000000,0x00000000,0x00001249,0x00009493,
629 0x0000a493,0x000124db,0x000126dc,0x000136e4},
630 {0x00000000,0x00000000,0x00001249,0x00009493,
631 0x0000a493,0x000126dc,0x000136e4,0x000136e4},
632 {0x00000000,0x00000000,0x0000924a,0x00009493,
633 0x0001249b,0x000126dc,0x000136e4,0x000136e4},
634 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
635 0x000124db,0x000136e4,0x000136e4,0x0001b724},
636 {0x00000000,0x00000000,0x00009252,0x000124db,
637 0x000126dc,0x0001b724,0x0001b725,0x0001b925},
638 {0x00000000,0x00000000,0x00000000,0x00000000,
639 0x00000000,0x00000000,0x00000000,0x00000000}
640 },
641 { /* version 4, passes 1 */
642 {0x00000000,0x00000000,0x00000049,0x00000049,
643 0x00000049,0x00000049,0x00000049,0x00000049},
644 {0x00000000,0x00000000,0x00000249,0x00000249,
645 0x00000249,0x00000249,0x0000024a,0x00000049},
646 {0x00000000,0x00000000,0x00001249,0x00000249,
647 0x0000124a,0x0000124a,0x00001252,0x00000049},
648 {0x00000000,0x00000000,0x00001249,0x00001249,
649 0x0000124a,0x0000124a,0x00009292,0x0000024a},
650 {0x00000000,0x00000000,0x00001249,0x00001249,
651 0x00009252,0x00009292,0x00009292,0x0000024a},
652 {0x00000000,0x00000000,0x00001249,0x00001249,
653 0x00009252,0x00009292,0x0000a49b,0x0000024a},
654 {0x00000000,0x00000000,0x00001249,0x00001249,
655 0x00009292,0x00009493,0x0000a49b,0x00001252},
656 {0x00000000,0x00000000,0x00001249,0x00001249,
657 0x00009292,0x00009493,0x0000a49b,0x00001252},
658 {0x00000000,0x00000000,0x00001249,0x0000924a,
659 0x00009492,0x0000a49b,0x0000a49b,0x00001252},
660 {0x00000000,0x00000000,0x00001249,0x00009252,
661 0x00009492,0x0000a49b,0x0000a49b,0x00009292},
662 {0x00000000,0x00000000,0x00001249,0x00009292,
663 0x00009492,0x0000a49b,0x0000a49b,0x00009292},
664 {0x00000000,0x00000000,0x00001249,0x00009493,
665 0x0000a493,0x0000a49b,0x0000a49b,0x00009292},
666 {0x00000000,0x00000000,0x00001249,0x00009493,
667 0x0000a493,0x0000a49b,0x0000a49b,0x00009493},
668 {0x00000000,0x00000000,0x0000924a,0x00009493,
669 0x0000a493,0x000124db,0x0000a49b,0x00009493},
670 {0x00000000,0x00000000,0x00009252,0x0000a49b,
671 0x0001249b,0x000126dc,0x000124db,0x0000a49b},
672 {0x00000000,0x00000000,0x00000000,0x00000000,
673 0x00000000,0x00000000,0x00000000,0x00000000}
674 }
675 },
676 { /* version 5 */
677 { /* version 5, passes 0 */
678 {0x00000000,0x00000000,0x00000249,0x00000249,
679 0x00000249,0x0000124a,0x00001252,0x00009292},
680 {0x00000000,0x00000000,0x00000249,0x00001249,
681 0x0000124a,0x00009292,0x00009292,0x00009493},
682 {0x00000000,0x00000000,0x00000249,0x0000924a,
683 0x00009292,0x00009493,0x0000a49b,0x0000a49b},
684 {0x00000000,0x00000000,0x00001249,0x0000924a,
685 0x00009292,0x00009493,0x0000a49b,0x0000a49b},
686 {0x00000000,0x00000000,0x00001249,0x0000924a,
687 0x00009492,0x0000a49b,0x0000a49b,0x000124db},
688 {0x00000000,0x00000000,0x00001249,0x00009292,
689 0x00009492,0x0000a49b,0x000124db,0x000124db},
690 {0x00000000,0x00000000,0x00001249,0x00009292,
691 0x0000a493,0x000124db,0x000124db,0x000126dc},
692 {0x00000000,0x00000000,0x00001249,0x00009493,
693 0x0000a493,0x000124db,0x000126dc,0x000126dc},
694 {0x00000000,0x00000000,0x00001249,0x00009493,
695 0x0000a493,0x000126dc,0x000136e4,0x000136e4},
696 {0x00000000,0x00000000,0x00001249,0x00009493,
697 0x0001249b,0x000126dc,0x000136e4,0x000136e4},
698 {0x00000000,0x00000000,0x00001249,0x00009493,
699 0x0001249b,0x000126dc,0x000136e4,0x000136e4},
700 {0x00000000,0x00000000,0x0000924a,0x00009493,
701 0x0001249b,0x000126dc,0x0001b725,0x0001b724},
702 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
703 0x000124db,0x000126dc,0x0001b725,0x0001b724},
704 {0x00000000,0x00000000,0x00009292,0x0000a49b,
705 0x000126dc,0x000136e4,0x0001b92d,0x0001b925},
706 {0x00000000,0x00000000,0x00009492,0x000124db,
707 0x000136e4,0x0001b724,0x0001c96e,0x0001c92d},
708 {0x00000000,0x00000000,0x00000000,0x00000000,
709 0x00000000,0x00000000,0x00000000,0x00000000}
710 },
711 { /* version 5, passes 1 */
712 {0x00000000,0x00000000,0x00000249,0x00000249,
713 0x0000124a,0x00000249,0x0000024a,0x0000024a},
714 {0x00000000,0x00000000,0x00001249,0x00001249,
715 0x0000124a,0x0000124a,0x00001252,0x0000024a},
716 {0x00000000,0x00000000,0x00001249,0x00001249,
717 0x00009292,0x00009493,0x00009493,0x0000024a},
718 {0x00000000,0x00000000,0x00001249,0x00001249,
719 0x00009292,0x00009493,0x00009493,0x00001252},
720 {0x00000000,0x00000000,0x00001249,0x00001249,
721 0x00009292,0x00009493,0x0000a49b,0x00001252},
722 {0x00000000,0x00000000,0x00001249,0x0000924a,
723 0x00009492,0x00009493,0x000124db,0x00001252},
724 {0x00000000,0x00000000,0x00001249,0x00009292,
725 0x00009492,0x00009493,0x000124db,0x00009292},
726 {0x00000000,0x00000000,0x00001249,0x00009292,
727 0x00009492,0x0000a49b,0x000124db,0x00009292},
728 {0x00000000,0x00000000,0x00001249,0x00009493,
729 0x0000a493,0x0000a49b,0x000124db,0x00009292},
730 {0x00000000,0x00000000,0x00001249,0x00009493,
731 0x0000a493,0x000124db,0x000124db,0x00009493},
732 {0x00000000,0x00000000,0x0000924a,0x00009493,
733 0x0000a493,0x000124db,0x000124db,0x00009493},
734 {0x00000000,0x00000000,0x0000924a,0x00009493,
735 0x0000a493,0x000124db,0x000124db,0x00009493},
736 {0x00000000,0x00000000,0x0000924a,0x00009493,
737 0x0000a493,0x000124db,0x000124db,0x0000a49b},
738 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
739 0x000124db,0x000126dc,0x000124db,0x0000a49b},
740 {0x00000000,0x00000000,0x00009252,0x000124db,
741 0x000126dc,0x000136e4,0x000126dc,0x000124db},
742 {0x00000000,0x00000000,0x00000000,0x00000000,
743 0x00000000,0x00000000,0x00000000,0x00000000}
744 }
745 },
746 { /* version 6 */
747 { /* version 6, passes 0 */
748 {0x00000000,0x00000000,0x00000249,0x00000249,
749 0x0000124a,0x0000124a,0x00009292,0x00009292},
750 {0x00000000,0x00000000,0x00001249,0x00001249,
751 0x00009292,0x00009493,0x0000a49b,0x0000a49b},
752 {0x00000000,0x00000000,0x00001249,0x0000924a,
753 0x00009492,0x0000a49b,0x0000a49b,0x000124db},
754 {0x00000000,0x00000000,0x00001249,0x00009292,
755 0x00009492,0x000124db,0x000126dc,0x000126dc},
756 {0x00000000,0x00000000,0x00001249,0x00009493,
757 0x0000a493,0x000124db,0x000126dc,0x000126dc},
758 {0x00000000,0x00000000,0x00001249,0x00009493,
759 0x0000a493,0x000126dc,0x000136e4,0x000136e4},
760 {0x00000000,0x00000000,0x00001249,0x00009493,
761 0x0000a493,0x000126dc,0x000136e4,0x0001b724},
762 {0x00000000,0x00000000,0x00001249,0x00009493,
763 0x0001249b,0x000126dc,0x000136e4,0x0001b724},
764 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
765 0x0001249b,0x000126dc,0x000136e4,0x0001b724},
766 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
767 0x0001249b,0x000136e4,0x0001b725,0x0001b724},
768 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
769 0x000124db,0x000136e4,0x0001b725,0x0001b925},
770 {0x00000000,0x00000000,0x00009292,0x0000a49b,
771 0x000126dc,0x000136e4,0x0001b92d,0x0001b925},
772 {0x00000000,0x00000000,0x00009292,0x0000a49b,
773 0x000126dc,0x0001b724,0x0001b92d,0x0001c92d},
774 {0x00000000,0x00000000,0x00009492,0x000124db,
775 0x000126dc,0x0001b724,0x0001c96e,0x0001c92d},
776 {0x00000000,0x00000000,0x0000a492,0x000126db,
777 0x000136e4,0x0001b925,0x00025bb6,0x00024b77},
778 {0x00000000,0x00000000,0x00000000,0x00000000,
779 0x00000000,0x00000000,0x00000000,0x00000000}
780 },
781 { /* version 6, passes 1 */
782 {0x00000000,0x00000000,0x00001249,0x00000249,
783 0x0000124a,0x0000124a,0x00001252,0x00001252},
784 {0x00000000,0x00000000,0x00001249,0x00001249,
785 0x00009252,0x00009292,0x00009292,0x00001252},
786 {0x00000000,0x00000000,0x00001249,0x0000924a,
787 0x00009492,0x00009493,0x0000a49b,0x00001252},
788 {0x00000000,0x00000000,0x00001249,0x00009252,
789 0x00009492,0x0000a49b,0x0000a49b,0x00009292},
790 {0x00000000,0x00000000,0x00001249,0x00009292,
791 0x00009492,0x0000a49b,0x0000a49b,0x00009292},
792 {0x00000000,0x00000000,0x00001249,0x00009493,
793 0x0000a493,0x0000a49b,0x000126dc,0x00009292},
794 {0x00000000,0x00000000,0x0000924a,0x00009493,
795 0x0000a493,0x0000a49b,0x000126dc,0x00009493},
796 {0x00000000,0x00000000,0x0000924a,0x00009493,
797 0x0000a493,0x0000a49b,0x000126dc,0x00009493},
798 {0x00000000,0x00000000,0x0000924a,0x00009493,
799 0x0000a493,0x000124db,0x000126dc,0x00009493},
800 {0x00000000,0x00000000,0x0000924a,0x00009493,
801 0x0000a493,0x000124db,0x000126dc,0x0000a49b},
802 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
803 0x0000a493,0x000124db,0x000126dc,0x0000a49b},
804 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
805 0x0001249b,0x000126dc,0x000126dc,0x0000a49b},
806 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
807 0x000124db,0x000136e4,0x000126dc,0x000124db},
808 {0x00000000,0x00000000,0x00009492,0x0000a49b,
809 0x000136e4,0x000136e4,0x000126dc,0x000124db},
810 {0x00000000,0x00000000,0x0000a492,0x000124db,
811 0x0001b724,0x0001b724,0x000136e4,0x000126dc},
812 {0x00000000,0x00000000,0x00000000,0x00000000,
813 0x00000000,0x00000000,0x00000000,0x00000000}
814 }
815 },
816 { /* version 7 */
817 { /* version 7, passes 0 */
818 {0x00000000,0x00000000,0x00001249,0x00001249,
819 0x00009292,0x00009493,0x0000a49b,0x000124db},
820 {0x00000000,0x00000000,0x00001249,0x00009292,
821 0x0000a493,0x0000a49b,0x000124db,0x000126dc},
822 {0x00000000,0x00000000,0x00001249,0x00009493,
823 0x0000a493,0x000124db,0x000126dc,0x000136e4},
824 {0x00000000,0x00000000,0x00001249,0x00009493,
825 0x0000a493,0x000124db,0x000136e4,0x000136e4},
826 {0x00000000,0x00000000,0x00001249,0x00009493,
827 0x0001249b,0x000126dc,0x000136e4,0x000136e4},
828 {0x00000000,0x00000000,0x00001249,0x0000a49b,
829 0x0001249b,0x000126dc,0x000136e4,0x0001b724},
830 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
831 0x0001249b,0x000126dc,0x000136e4,0x0001b724},
832 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
833 0x000124db,0x000136e4,0x0001b725,0x0001b724},
834 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
835 0x000126dc,0x000136e4,0x0001b725,0x0001b925},
836 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
837 0x000126dc,0x0001b724,0x0001b92d,0x0001b925},
838 {0x00000000,0x00000000,0x00009292,0x0000a49b,
839 0x000126dc,0x0001b724,0x0001c96e,0x0001c92d},
840 {0x00000000,0x00000000,0x00009292,0x000124db,
841 0x000126dc,0x0001b724,0x0001c96e,0x0001c92d},
842 {0x00000000,0x00000000,0x00009492,0x000124db,
843 0x000136e4,0x0001b724,0x0001c96e,0x0002496e},
844 {0x00000000,0x00000000,0x00009492,0x000126db,
845 0x000136e4,0x0001b925,0x0001c96e,0x0002496e},
846 {0x00000000,0x00000000,0x0000a492,0x000136db,
847 0x0001b724,0x0002496d,0x00025bb6,0x00025bbf},
848 {0x00000000,0x00000000,0x00000000,0x00000000,
849 0x00000000,0x00000000,0x00000000,0x00000000}
850 },
851 { /* version 7, passes 1 */
852 {0x00000000,0x00000000,0x00001249,0x00001249,
853 0x00009252,0x00009292,0x00009292,0x00009292},
854 {0x00000000,0x00000000,0x00001249,0x0000924a,
855 0x00009492,0x00009493,0x00009493,0x00009292},
856 {0x00000000,0x00000000,0x00001249,0x00009493,
857 0x0000a493,0x0000a49b,0x0000a49b,0x00009292},
858 {0x00000000,0x00000000,0x0000924a,0x00009493,
859 0x0000a493,0x0000a49b,0x000124db,0x00009493},
860 {0x00000000,0x00000000,0x0000924a,0x00009493,
861 0x0000a493,0x000124db,0x000124db,0x00009493},
862 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
863 0x0000a493,0x000124db,0x000136e4,0x00009493},
864 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
865 0x0000a493,0x000124db,0x000136e4,0x0000a49b},
866 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
867 0x0001249b,0x000124db,0x000136e4,0x0000a49b},
868 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
869 0x0001249b,0x000126dc,0x000136e4,0x0000a49b},
870 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
871 0x0001249b,0x000126dc,0x000136e4,0x000124db},
872 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
873 0x000126dc,0x000136e4,0x000136e4,0x000124db},
874 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
875 0x000126dc,0x000136e4,0x000136e4,0x000124db},
876 {0x00000000,0x00000000,0x0000924a,0x000124db,
877 0x000136e4,0x000136e4,0x000136e4,0x000126dc},
878 {0x00000000,0x00000000,0x0000a492,0x000124db,
879 0x000136e4,0x0001b724,0x000136e4,0x000126dc},
880 {0x00000000,0x00000000,0x00012492,0x000126db,
881 0x0001b724,0x0001b925,0x0001b725,0x000136e4},
882 {0x00000000,0x00000000,0x00000000,0x00000000,
883 0x00000000,0x00000000,0x00000000,0x00000000}
884 }
885 },
886 { /* version 8 */
887 { /* version 8, passes 0 */
888 {0x00000000,0x00000000,0x00001249,0x00001249,
889 0x00009292,0x00009493,0x0000a49b,0x000124db},
890 {0x00000000,0x00000000,0x00001249,0x00009292,
891 0x0000a493,0x000124db,0x000126dc,0x000126dc},
892 {0x00000000,0x00000000,0x00001249,0x00009493,
893 0x0000a493,0x000124db,0x000126dc,0x000136e4},
894 {0x00000000,0x00000000,0x00001249,0x0000a49b,
895 0x0001249b,0x000126dc,0x000136e4,0x0001b724},
896 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
897 0x0001249b,0x000126dc,0x000136e4,0x0001b724},
898 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
899 0x000124db,0x000136e4,0x0001b725,0x0001b724},
900 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
901 0x000126dc,0x000136e4,0x0001b725,0x0001b925},
902 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
903 0x000126dc,0x0001b724,0x0001b92d,0x0001c92d},
904 {0x00000000,0x00000000,0x00009252,0x000124db,
905 0x000126dc,0x0001b724,0x0001b92d,0x0001c92d},
906 {0x00000000,0x00000000,0x00009292,0x000124db,
907 0x000126dc,0x0001b925,0x0001c96e,0x0001c92d},
908 {0x00000000,0x00000000,0x00009492,0x000124db,
909 0x000136e4,0x0001b925,0x0001c96e,0x0001c92d},
910 {0x00000000,0x00000000,0x00009492,0x000124db,
911 0x000136e4,0x0001b925,0x00024b76,0x00024b77},
912 {0x00000000,0x00000000,0x00009492,0x000126db,
913 0x000136e4,0x0001b925,0x00024b76,0x00025bbf},
914 {0x00000000,0x00000000,0x0000a492,0x000126db,
915 0x000136e4,0x0001c92d,0x00024b76,0x00025bbf},
916 {0x00000000,0x00000000,0x00012492,0x000136db,
917 0x0001b724,0x00024b6d,0x0002ddb6,0x0002efff},
918 {0x00000000,0x00000000,0x00000000,0x00000000,
919 0x00000000,0x00000000,0x00000000,0x00000000}
920 },
921 { /* version 8, passes 1 */
922 {0x00000000,0x00000000,0x00001249,0x00001249,
923 0x00009252,0x00009493,0x00009493,0x00009493},
924 {0x00000000,0x00000000,0x00001249,0x00009292,
925 0x0000a493,0x0000a49b,0x0000a49b,0x00009493},
926 {0x00000000,0x00000000,0x0000924a,0x00009493,
927 0x0000a493,0x0000a49b,0x000124db,0x00009493},
928 {0x00000000,0x00000000,0x0000924a,0x00009493,
929 0x0000a493,0x000124db,0x000126dc,0x0000a49b},
930 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
931 0x0000a493,0x000124db,0x000126dc,0x0000a49b},
932 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
933 0x0000a493,0x000124db,0x000136e4,0x000124db},
934 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
935 0x0001249b,0x000126dc,0x000136e4,0x000124db},
936 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
937 0x000126dc,0x000126dc,0x000136e4,0x000126dc},
938 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
939 0x000126dc,0x000136e4,0x000136e4,0x000126dc},
940 {0x00000000,0x00000000,0x0000924a,0x000124db,
941 0x000126dc,0x000136e4,0x000136e4,0x000126dc},
942 {0x00000000,0x00000000,0x0000924a,0x000124db,
943 0x000126dc,0x000136e4,0x000136e4,0x000136e4},
944 {0x00000000,0x00000000,0x00009292,0x000124db,
945 0x000136e4,0x0001b724,0x0001b725,0x000136e4},
946 {0x00000000,0x00000000,0x00009492,0x000126db,
947 0x000136e4,0x0001b925,0x0001b725,0x0001b724},
948 {0x00000000,0x00000000,0x00009492,0x000126db,
949 0x000136e4,0x0001b925,0x0001b725,0x0001b724},
950 {0x00000000,0x00000000,0x0000a492,0x000136db,
951 0x0001b724,0x0002496d,0x0001b92d,0x0001b925},
952 {0x00000000,0x00000000,0x00000000,0x00000000,
953 0x00000000,0x00000000,0x00000000,0x00000000}
954 }
955 },
956 { /* version 9 */
957 { /* version 9, passes 0 */
958 {0x00000000,0x00000000,0x00000049,0x00000049,
959 0x00000049,0x00000049,0x00000049,0x00000049},
960 {0x00000000,0x00000000,0x00000249,0x00000049,
961 0x00000249,0x00000249,0x0000024a,0x00000049},
962 {0x00000000,0x00000000,0x00000249,0x00000249,
963 0x0000124a,0x00009252,0x00001252,0x0000024a},
964 {0x00000000,0x00000000,0x00001249,0x00001249,
965 0x00009252,0x00009292,0x00009493,0x00001252},
966 {0x00000000,0x00000000,0x00001249,0x0000924a,
967 0x00009292,0x00009493,0x00009493,0x00001252},
968 {0x00000000,0x00000000,0x00001249,0x00009292,
969 0x00009492,0x0000a49b,0x0000a49b,0x00009292},
970 {0x00000000,0x00000000,0x00001249,0x00009493,
971 0x0000a493,0x000124db,0x000124db,0x00009493},
972 {0x00000000,0x00000000,0x0000924a,0x00009493,
973 0x0000a493,0x000124db,0x000126dc,0x0000a49b},
974 {0x00000000,0x00000000,0x0000924a,0x00009493,
975 0x0000a493,0x000124db,0x000126dc,0x0000a49b},
976 {0x00000000,0x00000000,0x0000924a,0x00009493,
977 0x0001249b,0x000126dc,0x000126dc,0x000124db},
978 {0x00000000,0x00000000,0x00009252,0x00009493,
979 0x000124db,0x000136e4,0x000136e4,0x000126dc},
980 {0x00000000,0x00000000,0x00009252,0x0000a49b,
981 0x000124db,0x000136e4,0x000136e4,0x000126dc},
982 {0x00000000,0x00000000,0x00009292,0x0000a49b,
983 0x000126dc,0x000136e4,0x000136e4,0x000136e4},
984 {0x00000000,0x00000000,0x00009492,0x0000a49b,
985 0x000126dc,0x0001b724,0x0001b725,0x0001b724},
986 {0x00000000,0x00000000,0x0000a492,0x000124db,
987 0x000136e4,0x0001b925,0x0001b92d,0x0001b925},
988 {0x00000000,0x00000000,0x00000000,0x00000000,
989 0x00000000,0x00000000,0x00000000,0x00000000}
990 },
991 { /* version 9, passes 1 */
992 {0x00000000,0x00000000,0x00000249,0x00000049,
993 0x00000009,0x00000009,0x00000009,0x00000009},
994 {0x00000000,0x00000000,0x00000249,0x00000249,
995 0x00000049,0x00000049,0x00000009,0x00000009},
996 {0x00000000,0x00000000,0x00001249,0x00001249,
997 0x0000124a,0x00000249,0x00000049,0x00000049},
998 {0x00000000,0x00000000,0x00001249,0x00001249,
999 0x0000124a,0x0000124a,0x00000049,0x00000049},
1000 {0x00000000,0x00000000,0x00001249,0x00001249,
1001 0x00009252,0x0000124a,0x0000024a,0x0000024a},
1002 {0x00000000,0x00000000,0x00001249,0x0000924a,
1003 0x00009252,0x0000124a,0x0000024a,0x0000024a},
1004 {0x00000000,0x00000000,0x00001249,0x00009292,
1005 0x00009492,0x00009252,0x00001252,0x00001252},
1006 {0x00000000,0x00000000,0x00001249,0x00009493,
1007 0x0000a493,0x00009292,0x00009292,0x00001252},
1008 {0x00000000,0x00000000,0x0000924a,0x00009493,
1009 0x0000a493,0x00009292,0x00009292,0x00009292},
1010 {0x00000000,0x00000000,0x0000924a,0x00009493,
1011 0x0000a493,0x00009493,0x00009493,0x00009292},
1012 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1013 0x0000a493,0x0000a49b,0x00009493,0x00009493},
1014 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1015 0x0000a493,0x0000a49b,0x0000a49b,0x00009493},
1016 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1017 0x0001249b,0x000124db,0x0000a49b,0x0000a49b},
1018 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1019 0x000136e4,0x000126dc,0x000124db,0x0000a49b},
1020 {0x00000000,0x00000000,0x00009252,0x000124db,
1021 0x0001b724,0x000136e4,0x000126dc,0x000124db},
1022 {0x00000000,0x00000000,0x00000000,0x00000000,
1023 0x00000000,0x00000000,0x00000000,0x00000000}
1024 }
1025 },
1026 { /* version 10 */
1027 { /* version 10, passes 0 */
1028 {0x00000000,0x00000000,0x00000249,0x00000249,
1029 0x00000249,0x00000249,0x0000024a,0x0000024a},
1030 {0x00000000,0x00000000,0x00000249,0x00001249,
1031 0x00009252,0x00009292,0x00009292,0x0000024a},
1032 {0x00000000,0x00000000,0x00001249,0x00001249,
1033 0x00009252,0x00009292,0x00009292,0x00001252},
1034 {0x00000000,0x00000000,0x00001249,0x0000924a,
1035 0x00009492,0x00009493,0x0000a49b,0x00009292},
1036 {0x00000000,0x00000000,0x00001249,0x00009292,
1037 0x00009492,0x000124db,0x000124db,0x00009292},
1038 {0x00000000,0x00000000,0x00001249,0x00009493,
1039 0x0000a493,0x000124db,0x000124db,0x00009493},
1040 {0x00000000,0x00000000,0x00001249,0x00009493,
1041 0x0000a493,0x000124db,0x000126dc,0x0000a49b},
1042 {0x00000000,0x00000000,0x0000924a,0x00009493,
1043 0x0000a493,0x000124db,0x000126dc,0x000124db},
1044 {0x00000000,0x00000000,0x0000924a,0x00009493,
1045 0x0001249b,0x000126dc,0x000126dc,0x000124db},
1046 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1047 0x000124db,0x000126dc,0x000136e4,0x000126dc},
1048 {0x00000000,0x00000000,0x00009252,0x0000a49b,
1049 0x000124db,0x000136e4,0x000136e4,0x000136e4},
1050 {0x00000000,0x00000000,0x00009292,0x0000a49b,
1051 0x000126dc,0x000136e4,0x000136e4,0x000136e4},
1052 {0x00000000,0x00000000,0x00009492,0x0000a49b,
1053 0x000126dc,0x0001b724,0x0001b92d,0x0001b724},
1054 {0x00000000,0x00000000,0x00009492,0x000124db,
1055 0x000126dc,0x0001b925,0x0001b92d,0x0001b925},
1056 {0x00000000,0x00000000,0x0000a492,0x000126db,
1057 0x000136e4,0x0002496d,0x0001c96e,0x0001c92d},
1058 {0x00000000,0x00000000,0x00000000,0x00000000,
1059 0x00000000,0x00000000,0x00000000,0x00000000}
1060 },
1061 { /* version 10, passes 1 */
1062 {0x00000000,0x00000000,0x00000249,0x00000249,
1063 0x00000049,0x00000049,0x00000049,0x00000049},
1064 {0x00000000,0x00000000,0x00001249,0x00001249,
1065 0x0000124a,0x00000249,0x00000049,0x00000049},
1066 {0x00000000,0x00000000,0x00001249,0x00001249,
1067 0x0000124a,0x00009252,0x0000024a,0x00000049},
1068 {0x00000000,0x00000000,0x00001249,0x00001249,
1069 0x00009252,0x00009493,0x0000024a,0x0000024a},
1070 {0x00000000,0x00000000,0x00001249,0x00009252,
1071 0x00009492,0x00009493,0x00001252,0x0000024a},
1072 {0x00000000,0x00000000,0x00001249,0x00009292,
1073 0x00009492,0x00009493,0x00001252,0x00001252},
1074 {0x00000000,0x00000000,0x0000924a,0x00009493,
1075 0x00009492,0x00009493,0x00009292,0x00001252},
1076 {0x00000000,0x00000000,0x0000924a,0x00009493,
1077 0x0000a493,0x00009493,0x00009292,0x00009292},
1078 {0x00000000,0x00000000,0x0000924a,0x00009493,
1079 0x0000a493,0x0000a49b,0x00009493,0x00009292},
1080 {0x00000000,0x00000000,0x0000924a,0x00009493,
1081 0x0000a493,0x0000a49b,0x00009493,0x00009292},
1082 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1083 0x0000a493,0x000124db,0x0000a49b,0x00009493},
1084 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1085 0x0000a493,0x000124db,0x0000a49b,0x00009493},
1086 {0x00000000,0x00000000,0x0000924a,0x000124db,
1087 0x000136e4,0x000126dc,0x000124db,0x0000a49b},
1088 {0x00000000,0x00000000,0x0000924a,0x000124db,
1089 0x000136e4,0x000126dc,0x000124db,0x0000a49b},
1090 {0x00000000,0x00000000,0x00009252,0x000126db,
1091 0x0001b724,0x000136e4,0x000126dc,0x000124db},
1092 {0x00000000,0x00000000,0x00000000,0x00000000,
1093 0x00000000,0x00000000,0x00000000,0x00000000}
1094 }
1095 },
1096 { /* version 11 */
1097 { /* version 11, passes 0 */
1098 {0x00000000,0x00000000,0x00000249,0x00000249,
1099 0x00000249,0x00000249,0x00001252,0x00001252},
1100 {0x00000000,0x00000000,0x00001249,0x00001249,
1101 0x00009252,0x00009292,0x00009292,0x00001252},
1102 {0x00000000,0x00000000,0x00001249,0x0000924a,
1103 0x00009492,0x0000a49b,0x0000a49b,0x00009292},
1104 {0x00000000,0x00000000,0x00001249,0x00009493,
1105 0x0000a493,0x0000a49b,0x000124db,0x00009493},
1106 {0x00000000,0x00000000,0x00001249,0x00009493,
1107 0x0000a493,0x000124db,0x000126dc,0x00009493},
1108 {0x00000000,0x00000000,0x0000924a,0x00009493,
1109 0x0000a493,0x000126dc,0x000126dc,0x0000a49b},
1110 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1111 0x0001249b,0x000126dc,0x000136e4,0x000124db},
1112 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1113 0x000126dc,0x000136e4,0x000136e4,0x000126dc},
1114 {0x00000000,0x00000000,0x00009292,0x0000a49b,
1115 0x000126dc,0x000136e4,0x000136e4,0x000126dc},
1116 {0x00000000,0x00000000,0x00009292,0x0000a49b,
1117 0x000126dc,0x0001b724,0x0001b725,0x000136e4},
1118 {0x00000000,0x00000000,0x00009292,0x0000a49b,
1119 0x000136e4,0x0001b724,0x0001b92d,0x0001b724},
1120 {0x00000000,0x00000000,0x00009492,0x0000a49b,
1121 0x000136e4,0x0001b724,0x0001b92d,0x0001b724},
1122 {0x00000000,0x00000000,0x00009492,0x000124db,
1123 0x000136e4,0x0001b925,0x0001c96e,0x0001b925},
1124 {0x00000000,0x00000000,0x00009492,0x000124db,
1125 0x0001b724,0x0001b925,0x0001c96e,0x0001c92d},
1126 {0x00000000,0x00000000,0x0000a492,0x000126db,
1127 0x0001c924,0x0002496d,0x00025bb6,0x00024b77},
1128 {0x00000000,0x00000000,0x00000000,0x00000000,
1129 0x00000000,0x00000000,0x00000000,0x00000000}
1130 },
1131 { /* version 11, passes 1 */
1132 {0x00000000,0x00000000,0x00001249,0x00000249,
1133 0x00000249,0x00000249,0x0000024a,0x0000024a},
1134 {0x00000000,0x00000000,0x00001249,0x00001249,
1135 0x0000124a,0x0000124a,0x0000024a,0x0000024a},
1136 {0x00000000,0x00000000,0x00001249,0x0000924a,
1137 0x00009252,0x00009252,0x0000024a,0x0000024a},
1138 {0x00000000,0x00000000,0x00001249,0x00009292,
1139 0x00009492,0x0000a49b,0x00001252,0x00001252},
1140 {0x00000000,0x00000000,0x0000924a,0x00009493,
1141 0x0000a493,0x0000a49b,0x00001252,0x00001252},
1142 {0x00000000,0x00000000,0x0000924a,0x00009493,
1143 0x0000a493,0x0000a49b,0x00009292,0x00001252},
1144 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1145 0x0000a493,0x0000a49b,0x00009292,0x00009292},
1146 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1147 0x0000a493,0x0000a49b,0x00009493,0x00009292},
1148 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1149 0x0001249b,0x000124db,0x00009493,0x00009292},
1150 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1151 0x0001249b,0x000124db,0x00009493,0x00009493},
1152 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1153 0x000124db,0x000124db,0x0000a49b,0x00009493},
1154 {0x00000000,0x00000000,0x0000924a,0x000124db,
1155 0x000126dc,0x000126dc,0x0000a49b,0x00009493},
1156 {0x00000000,0x00000000,0x0000924a,0x000124db,
1157 0x000136e4,0x000126dc,0x000124db,0x0000a49b},
1158 {0x00000000,0x00000000,0x00009292,0x000124db,
1159 0x000136e4,0x000126dc,0x000124db,0x0000a49b},
1160 {0x00000000,0x00000000,0x00009492,0x000126db,
1161 0x0001b724,0x000136e4,0x000126dc,0x000124db},
1162 {0x00000000,0x00000000,0x00000000,0x00000000,
1163 0x00000000,0x00000000,0x00000000,0x00000000}
1164 }
1165 },
1166 { /* version 12 */
1167 { /* version 12, passes 0 */
1168 {0x00000000,0x00000000,0x00001249,0x00001249,
1169 0x00009252,0x00009292,0x00009493,0x00009493},
1170 {0x00000000,0x00000000,0x00001249,0x00009292,
1171 0x0000a493,0x0000a49b,0x0000a49b,0x00009493},
1172 {0x00000000,0x00000000,0x00001249,0x00009493,
1173 0x0000a493,0x000124db,0x000124db,0x0000a49b},
1174 {0x00000000,0x00000000,0x0000924a,0x00009493,
1175 0x0000a493,0x000126dc,0x000126dc,0x0000a49b},
1176 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1177 0x0001249b,0x000126dc,0x000136e4,0x000124db},
1178 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1179 0x000126dc,0x000136e4,0x000136e4,0x000126dc},
1180 {0x00000000,0x00000000,0x00009292,0x0000a49b,
1181 0x000126dc,0x0001b724,0x0001b725,0x000126dc},
1182 {0x00000000,0x00000000,0x00009292,0x0000a49b,
1183 0x000136e4,0x0001b724,0x0001b92d,0x000136e4},
1184 {0x00000000,0x00000000,0x00009492,0x0000a49b,
1185 0x000136e4,0x0001b724,0x0001b92d,0x0001b724},
1186 {0x00000000,0x00000000,0x00009492,0x000124db,
1187 0x000136e4,0x0001b724,0x0001b92d,0x0001b724},
1188 {0x00000000,0x00000000,0x00009492,0x000124db,
1189 0x000136e4,0x0001b925,0x0001b92d,0x0001b925},
1190 {0x00000000,0x00000000,0x00009492,0x000124db,
1191 0x0001b724,0x0001b925,0x0001c96e,0x0001c92d},
1192 {0x00000000,0x00000000,0x0000a492,0x000124db,
1193 0x0001b724,0x0001c92d,0x0001c96e,0x0001c92d},
1194 {0x00000000,0x00000000,0x0000a492,0x000124db,
1195 0x0001b724,0x0001c92d,0x00024b76,0x0002496e},
1196 {0x00000000,0x00000000,0x00012492,0x000126db,
1197 0x0001c924,0x00024b6d,0x0002ddb6,0x00025bbf},
1198 {0x00000000,0x00000000,0x00000000,0x00000000,
1199 0x00000000,0x00000000,0x00000000,0x00000000}
1200 },
1201 { /* version 12, passes 1 */
1202 {0x00000000,0x00000000,0x00001249,0x00001249,
1203 0x0000124a,0x0000124a,0x00001252,0x00001252},
1204 {0x00000000,0x00000000,0x00001249,0x00009292,
1205 0x00009492,0x00009252,0x00001252,0x00001252},
1206 {0x00000000,0x00000000,0x0000924a,0x00009493,
1207 0x0000a493,0x00009292,0x00001252,0x00001252},
1208 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1209 0x0000a493,0x0000a49b,0x00009292,0x00009292},
1210 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1211 0x0000a493,0x0000a49b,0x00009292,0x00009292},
1212 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1213 0x0001249b,0x0000a49b,0x00009493,0x00009292},
1214 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1215 0x000124db,0x000124db,0x00009493,0x00009493},
1216 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1217 0x000124db,0x000124db,0x0000a49b,0x00009493},
1218 {0x00000000,0x00000000,0x0000924a,0x000124db,
1219 0x000126dc,0x000124db,0x0000a49b,0x00009493},
1220 {0x00000000,0x00000000,0x0000924a,0x000124db,
1221 0x000126dc,0x000126dc,0x0000a49b,0x0000a49b},
1222 {0x00000000,0x00000000,0x0000924a,0x000124db,
1223 0x000136e4,0x000126dc,0x000124db,0x0000a49b},
1224 {0x00000000,0x00000000,0x00009492,0x000126db,
1225 0x000136e4,0x000126dc,0x000124db,0x0000a49b},
1226 {0x00000000,0x00000000,0x00009492,0x000126db,
1227 0x0001b724,0x000136e4,0x000126dc,0x000124db},
1228 {0x00000000,0x00000000,0x00009492,0x000126db,
1229 0x0001b724,0x000136e4,0x000126dc,0x000124db},
1230 {0x00000000,0x00000000,0x0000a492,0x000136db,
1231 0x0001c924,0x0001b724,0x000136e4,0x000126dc},
1232 {0x00000000,0x00000000,0x00000000,0x00000000,
1233 0x00000000,0x00000000,0x00000000,0x00000000}
1234 }
1235 },
1236 { /* version 13 */
1237 { /* version 13, passes 0 */
1238 {0x00000000,0x00000000,0x00001249,0x00001249,
1239 0x00009252,0x00009292,0x00009493,0x00009493},
1240 {0x00000000,0x00000000,0x00001249,0x00009493,
1241 0x0000a493,0x000124db,0x000126dc,0x00009493},
1242 {0x00000000,0x00000000,0x00001249,0x0000a49b,
1243 0x0001249b,0x000126dc,0x000126dc,0x0000a49b},
1244 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1245 0x0001249b,0x000126dc,0x000136e4,0x0000a49b},
1246 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1247 0x000126dc,0x000136e4,0x0001b725,0x000124db},
1248 {0x00000000,0x00000000,0x00009292,0x0000a49b,
1249 0x000136e4,0x0001b724,0x0001b725,0x000126dc},
1250 {0x00000000,0x00000000,0x00009292,0x000124db,
1251 0x000136e4,0x0001b724,0x0001b725,0x000126dc},
1252 {0x00000000,0x00000000,0x00009492,0x000124db,
1253 0x000136e4,0x0001b724,0x0001c96e,0x000136e4},
1254 {0x00000000,0x00000000,0x00009492,0x000124db,
1255 0x000136e4,0x0001c92d,0x0001c96e,0x0001b724},
1256 {0x00000000,0x00000000,0x0000a492,0x000124db,
1257 0x000136e4,0x0001c92d,0x0001c96e,0x0001b724},
1258 {0x00000000,0x00000000,0x0000a492,0x000124db,
1259 0x0001b724,0x0001c92d,0x0001c96e,0x0001b925},
1260 {0x00000000,0x00000000,0x0000a492,0x000126db,
1261 0x0001b724,0x0001c92d,0x00024b76,0x0001c92d},
1262 {0x00000000,0x00000000,0x0000a492,0x000126db,
1263 0x0001b924,0x0001c92d,0x00024b76,0x0001c92d},
1264 {0x00000000,0x00000000,0x0000a492,0x000126db,
1265 0x0001b924,0x0001c92d,0x00024b76,0x0002496e},
1266 {0x00000000,0x00000000,0x00012492,0x000136db,
1267 0x00024924,0x00024b6d,0x0002ddb6,0x00025bbf},
1268 {0x00000000,0x00000000,0x00000000,0x00000000,
1269 0x00000000,0x00000000,0x00000000,0x00000000}
1270 },
1271 { /* version 13, passes 1 */
1272 {0x00000000,0x00000000,0x00001249,0x00001249,
1273 0x0000124a,0x0000124a,0x00001252,0x00001252},
1274 {0x00000000,0x00000000,0x0000924a,0x00009493,
1275 0x00009492,0x00009292,0x00001252,0x00001252},
1276 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1277 0x0000a493,0x0000a49b,0x00001252,0x00001252},
1278 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1279 0x0000a493,0x0000a49b,0x00009292,0x00009292},
1280 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1281 0x0000a493,0x0000a49b,0x00009292,0x00009292},
1282 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1283 0x000126dc,0x0000a49b,0x00009493,0x00009292},
1284 {0x00000000,0x00000000,0x0000924a,0x000124db,
1285 0x000126dc,0x000124db,0x00009493,0x00009493},
1286 {0x00000000,0x00000000,0x0000924a,0x000124db,
1287 0x000136e4,0x000124db,0x0000a49b,0x00009493},
1288 {0x00000000,0x00000000,0x0000924a,0x000136db,
1289 0x0001b724,0x000124db,0x0000a49b,0x00009493},
1290 {0x00000000,0x00000000,0x0000924a,0x000136db,
1291 0x0001b724,0x000126dc,0x0000a49b,0x0000a49b},
1292 {0x00000000,0x00000000,0x00009292,0x000136db,
1293 0x0001b724,0x000126dc,0x000124db,0x0000a49b},
1294 {0x00000000,0x00000000,0x00009492,0x000136db,
1295 0x0001b724,0x000126dc,0x000124db,0x0000a49b},
1296 {0x00000000,0x00000000,0x0000a492,0x000136db,
1297 0x0001b724,0x000136e4,0x000126dc,0x000124db},
1298 {0x00000000,0x00000000,0x0000a492,0x000136db,
1299 0x0001b724,0x000136e4,0x000126dc,0x000124db},
1300 {0x00000000,0x00000000,0x00012492,0x0001b6db,
1301 0x0001c924,0x0001b724,0x000136e4,0x000126dc},
1302 {0x00000000,0x00000000,0x00000000,0x00000000,
1303 0x00000000,0x00000000,0x00000000,0x00000000}
1304 }
1305 },
1306 { /* version 14 */
1307 { /* version 14, passes 0 */
1308 {0x00000000,0x00000000,0x00001249,0x0000924a,
1309 0x00009292,0x00009493,0x00009493,0x00009493},
1310 {0x00000000,0x00000000,0x00001249,0x0000a49b,
1311 0x0000a493,0x000124db,0x000126dc,0x00009493},
1312 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1313 0x0001249b,0x000126dc,0x000136e4,0x0000a49b},
1314 {0x00000000,0x00000000,0x0000924a,0x000124db,
1315 0x000126dc,0x000136e4,0x0001b725,0x000124db},
1316 {0x00000000,0x00000000,0x00009292,0x000124db,
1317 0x000126dc,0x0001b724,0x0001b92d,0x000126dc},
1318 {0x00000000,0x00000000,0x00009492,0x000124db,
1319 0x000136e4,0x0001b724,0x0001b92d,0x000126dc},
1320 {0x00000000,0x00000000,0x00009492,0x000124db,
1321 0x000136e4,0x0001c92d,0x0001c96e,0x000136e4},
1322 {0x00000000,0x00000000,0x00009492,0x000124db,
1323 0x0001b724,0x0001c92d,0x0001c96e,0x0001b724},
1324 {0x00000000,0x00000000,0x0000a492,0x000124db,
1325 0x0001b724,0x0001c92d,0x00024b76,0x0001b925},
1326 {0x00000000,0x00000000,0x0000a492,0x000126db,
1327 0x0001b724,0x0001c92d,0x00024b76,0x0001c92d},
1328 {0x00000000,0x00000000,0x0000a492,0x000126db,
1329 0x0001b724,0x0001c92d,0x00024b76,0x0001c92d},
1330 {0x00000000,0x00000000,0x0000a492,0x000136db,
1331 0x0001b724,0x0001c92d,0x00024b76,0x0002496e},
1332 {0x00000000,0x00000000,0x0000a492,0x000136db,
1333 0x0001b924,0x0002496d,0x00024b76,0x00024b77},
1334 {0x00000000,0x00000000,0x0000a492,0x000136db,
1335 0x0001b924,0x00024b6d,0x0002ddb6,0x00025bbf},
1336 {0x00000000,0x00000000,0x00012492,0x0001b6db,
1337 0x00024924,0x0002db6d,0x00036db6,0x0002efff},
1338 {0x00000000,0x00000000,0x00000000,0x00000000,
1339 0x00000000,0x00000000,0x00000000,0x00000000}
1340 },
1341 { /* version 14, passes 1 */
1342 {0x00000000,0x00000000,0x00001249,0x00001249,
1343 0x0000124a,0x0000124a,0x00001252,0x00001252},
1344 {0x00000000,0x00000000,0x0000924a,0x00009493,
1345 0x0000a493,0x00009292,0x00001252,0x00001252},
1346 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1347 0x0000a493,0x0000a49b,0x00001252,0x00001252},
1348 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1349 0x0001249b,0x000136e4,0x00009292,0x00009292},
1350 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1351 0x0001249b,0x000136e4,0x00009292,0x00009292},
1352 {0x00000000,0x00000000,0x0000924a,0x000124db,
1353 0x000136e4,0x000136e4,0x00009493,0x00009292},
1354 {0x00000000,0x00000000,0x00009492,0x000136db,
1355 0x0001b724,0x000136e4,0x00009493,0x00009493},
1356 {0x00000000,0x00000000,0x00009492,0x000136db,
1357 0x0001b724,0x000136e4,0x0000a49b,0x00009493},
1358 {0x00000000,0x00000000,0x00009492,0x000136db,
1359 0x0001b724,0x000136e4,0x0000a49b,0x00009493},
1360 {0x00000000,0x00000000,0x00009492,0x000136db,
1361 0x0001b724,0x000136e4,0x0000a49b,0x0000a49b},
1362 {0x00000000,0x00000000,0x0000a492,0x000136db,
1363 0x0001b724,0x000136e4,0x000124db,0x0000a49b},
1364 {0x00000000,0x00000000,0x0000a492,0x000136db,
1365 0x0001b724,0x000136e4,0x000124db,0x0000a49b},
1366 {0x00000000,0x00000000,0x0000a492,0x000136db,
1367 0x0001b724,0x000136e4,0x000126dc,0x000124db},
1368 {0x00000000,0x00000000,0x0000a492,0x000136db,
1369 0x0001b724,0x000136e4,0x000126dc,0x000124db},
1370 {0x00000000,0x00000000,0x00012492,0x0001b6db,
1371 0x0001c924,0x0001b724,0x000136e4,0x000126dc},
1372 {0x00000000,0x00000000,0x00000000,0x00000000,
1373 0x00000000,0x00000000,0x00000000,0x00000000}
1374 }
1375 },
1376 { /* version 15 */
1377 { /* version 15, passes 0 */
1378 {0x00000000,0x00000000,0x00001249,0x00009493,
1379 0x0000a493,0x0000a49b,0x000124db,0x000124db},
1380 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1381 0x0001249b,0x000126dc,0x000136e4,0x000124db},
1382 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1383 0x000126dc,0x0001b724,0x0001b725,0x000126dc},
1384 {0x00000000,0x00000000,0x0000924a,0x000124db,
1385 0x000136e4,0x0001b724,0x0001b92d,0x000126dc},
1386 {0x00000000,0x00000000,0x00009492,0x000124db,
1387 0x000136e4,0x0001b925,0x0001c96e,0x000136e4},
1388 {0x00000000,0x00000000,0x00009492,0x000124db,
1389 0x0001b724,0x0001c92d,0x0001c96e,0x0001b724},
1390 {0x00000000,0x00000000,0x0000a492,0x000124db,
1391 0x0001b724,0x0001c92d,0x0001c96e,0x0001b724},
1392 {0x00000000,0x00000000,0x0000a492,0x000126db,
1393 0x0001b724,0x0001c92d,0x0001c96e,0x0001b925},
1394 {0x00000000,0x00000000,0x0000a492,0x000126db,
1395 0x0001b924,0x0001c92d,0x00024b76,0x0001c92d},
1396 {0x00000000,0x00000000,0x0000a492,0x000136db,
1397 0x0001b924,0x0001c92d,0x00024b76,0x0001c92d},
1398 {0x00000000,0x00000000,0x0000a492,0x000136db,
1399 0x0001b924,0x0002496d,0x00024b76,0x0002496e},
1400 {0x00000000,0x00000000,0x0000a492,0x000136db,
1401 0x0001c924,0x0002496d,0x00025bb6,0x00024b77},
1402 {0x00000000,0x00000000,0x0000a492,0x000136db,
1403 0x0001c924,0x00024b6d,0x00025bb6,0x00024b77},
1404 {0x00000000,0x00000000,0x00012492,0x000136db,
1405 0x0001c924,0x00024b6d,0x0002ddb6,0x00025bbf},
1406 {0x00000000,0x00000000,0x00012492,0x0001b6db,
1407 0x00024924,0x0002db6d,0x00036db6,0x0002efff},
1408 {0x00000000,0x00000000,0x00000000,0x00000000,
1409 0x00000000,0x00000000,0x00000000,0x00000000}
1410 },
1411 { /* version 15, passes 1 */
1412 {0x00000000,0x00000000,0x0000924a,0x0000924a,
1413 0x00009292,0x00009292,0x00009292,0x00009292},
1414 {0x00000000,0x00000000,0x0000924a,0x0000a49b,
1415 0x0000a493,0x000124db,0x00009292,0x00009292},
1416 {0x00000000,0x00000000,0x0000924a,0x000124db,
1417 0x000124db,0x0001b724,0x00009493,0x00009493},
1418 {0x00000000,0x00000000,0x0000924a,0x000124db,
1419 0x000126dc,0x0001b724,0x00009493,0x00009493},
1420 {0x00000000,0x00000000,0x0000924a,0x000124db,
1421 0x000136e4,0x0001b724,0x0000a49b,0x0000a49b},
1422 {0x00000000,0x00000000,0x00009292,0x000136db,
1423 0x0001b724,0x0001b724,0x0000a49b,0x0000a49b},
1424 {0x00000000,0x00000000,0x00009492,0x000136db,
1425 0x0001c924,0x0001b724,0x000124db,0x000124db},
1426 {0x00000000,0x00000000,0x00009492,0x000136db,
1427 0x0001c924,0x0001b724,0x000124db,0x000124db},
1428 {0x00000000,0x00000000,0x0000a492,0x000136db,
1429 0x0001c924,0x0001b724,0x000126dc,0x000126dc},
1430 {0x00000000,0x00000000,0x0000a492,0x000136db,
1431 0x0001c924,0x0001b925,0x000126dc,0x000126dc},
1432 {0x00000000,0x00000000,0x0000a492,0x000136db,
1433 0x0001c924,0x0001b925,0x000136e4,0x000136e4},
1434 {0x00000000,0x00000000,0x0000a492,0x000136db,
1435 0x0001c924,0x0001b925,0x000136e4,0x000136e4},
1436 {0x00000000,0x00000000,0x0000a492,0x000136db,
1437 0x0001c924,0x0001b925,0x0001b725,0x0001b724},
1438 {0x00000000,0x00000000,0x00012492,0x000136db,
1439 0x0001c924,0x0001b925,0x0001b725,0x0001b724},
1440 {0x00000000,0x00000000,0x00012492,0x0001b6db,
1441 0x00024924,0x0002496d,0x0001b92d,0x0001b925},
1442 {0x00000000,0x00000000,0x00000000,0x00000000,
1443 0x00000000,0x00000000,0x00000000,0x00000000}
1444 }
1445 }
1446};
diff --git a/drivers/media/video/pwc/pwc-timon.h b/drivers/media/video/pwc/pwc-timon.h
index a86b3782a08..eef9e2cd432 100644
--- a/drivers/media/video/pwc/pwc-timon.h
+++ b/drivers/media/video/pwc/pwc-timon.h
@@ -1,5 +1,5 @@
1/* Linux driver for Philips webcam 1/* Linux driver for Philips webcam
2 (C) 2004 Luc Saillard (luc@saillard.org) 2 (C) 2004-2006 Luc Saillard (luc@saillard.org)
3 3
4 NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx 4 NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx
5 driver and thus may have bugs that are not present in the original version. 5 driver and thus may have bugs that are not present in the original version.
@@ -42,7 +42,7 @@
42#ifndef PWC_TIMON_H 42#ifndef PWC_TIMON_H
43#define PWC_TIMON_H 43#define PWC_TIMON_H
44 44
45#include "pwc-ioctl.h" 45#include <media/pwc-ioctl.h>
46 46
47struct Timon_table_entry 47struct Timon_table_entry
48{ 48{
@@ -52,8 +52,8 @@ struct Timon_table_entry
52 unsigned char mode[13]; /* precomputed mode settings for cam */ 52 unsigned char mode[13]; /* precomputed mode settings for cam */
53}; 53};
54 54
55const extern struct Timon_table_entry Timon_table[PSZ_MAX][6][4]; 55extern const struct Timon_table_entry Timon_table[PSZ_MAX][6][4];
56const extern unsigned int TimonRomTable [16][2][16][8]; 56extern const unsigned int TimonRomTable [16][2][16][8];
57 57
58 58
59#endif 59#endif
diff --git a/drivers/media/video/pwc/pwc-uncompress.c b/drivers/media/video/pwc/pwc-uncompress.c
index b37a89a163f..5d82028ef94 100644
--- a/drivers/media/video/pwc/pwc-uncompress.c
+++ b/drivers/media/video/pwc/pwc-uncompress.c
@@ -1,7 +1,7 @@
1/* Linux driver for Philips webcam 1/* Linux driver for Philips webcam
2 Decompression frontend. 2 Decompression frontend.
3 (C) 1999-2003 Nemosoft Unv. 3 (C) 1999-2003 Nemosoft Unv.
4 (C) 2004 Luc Saillard (luc@saillard.org) 4 (C) 2004-2006 Luc Saillard (luc@saillard.org)
5 5
6 NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx 6 NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx
7 driver and thus may have bugs that are not present in the original version. 7 driver and thus may have bugs that are not present in the original version.
@@ -22,6 +22,8 @@
22 You should have received a copy of the GNU General Public License 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 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 24 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25
26 vim: set ts=8:
25*/ 27*/
26 28
27#include <asm/current.h> 29#include <asm/current.h>
@@ -29,6 +31,8 @@
29 31
30#include "pwc.h" 32#include "pwc.h"
31#include "pwc-uncompress.h" 33#include "pwc-uncompress.h"
34#include "pwc-dec1.h"
35#include "pwc-dec23.h"
32 36
33int pwc_decompress(struct pwc_device *pdev) 37int pwc_decompress(struct pwc_device *pdev)
34{ 38{
@@ -40,107 +44,95 @@ int pwc_decompress(struct pwc_device *pdev)
40 44
41 if (pdev == NULL) 45 if (pdev == NULL)
42 return -EFAULT; 46 return -EFAULT;
43#if defined(__KERNEL__) && defined(PWC_MAGIC)
44 if (pdev->magic != PWC_MAGIC) {
45 Err("pwc_decompress(): magic failed.\n");
46 return -EFAULT;
47 }
48#endif
49 47
50 fbuf = pdev->read_frame; 48 fbuf = pdev->read_frame;
51 if (fbuf == NULL) 49 if (fbuf == NULL)
52 return -EFAULT; 50 return -EFAULT;
53 image = pdev->image_ptr[pdev->fill_image]; 51 image = pdev->image_data;
54 if (!image) 52 image += pdev->images[pdev->fill_image].offset;
55 return -EFAULT;
56 53
57 yuv = fbuf->data + pdev->frame_header_size; /* Skip header */ 54 yuv = fbuf->data + pdev->frame_header_size; /* Skip header */
58 55
59 /* Raw format; that's easy... */ 56 /* Raw format; that's easy... */
60 if (pdev->vpalette == VIDEO_PALETTE_RAW) 57 if (pdev->vpalette == VIDEO_PALETTE_RAW)
61 { 58 {
62 memcpy(image, yuv, pdev->frame_size); 59 struct pwc_raw_frame *raw_frame = image;
60 raw_frame->type = cpu_to_le16(pdev->type);
61 raw_frame->vbandlength = cpu_to_le16(pdev->vbandlength);
62 /* cmd_buf is always 4 bytes, but sometimes, only the
63 * first 3 bytes is filled (Nala case). We can
64 * determine this using the type of the webcam */
65 memcpy(raw_frame->cmd, pdev->cmd_buf, 4);
66 memcpy(raw_frame+1, yuv, pdev->frame_size);
63 return 0; 67 return 0;
64 } 68 }
65 69
66 if (pdev->vbandlength == 0) { 70 if (pdev->vbandlength == 0) {
67 /* Uncompressed mode. We copy the data into the output buffer, 71 /* Uncompressed mode.
68 using the viewport size (which may be larger than the image 72 * We copy the data into the output buffer, using the viewport
69 size). Unfortunately we have to do a bit of byte stuffing 73 * size (which may be larger than the image size).
70 to get the desired output format/size. 74 * Unfortunately we have to do a bit of byte stuffing to get
75 * the desired output format/size.
76 *
77 * We do some byte shuffling here to go from the
78 * native format to YUV420P.
71 */ 79 */
72 /* 80 src = (u16 *)yuv;
73 * We do some byte shuffling here to go from the 81 n = pdev->view.x * pdev->view.y;
74 * native format to YUV420P. 82
75 */ 83 /* offset in Y plane */
76 src = (u16 *)yuv; 84 stride = pdev->view.x * pdev->offset.y + pdev->offset.x;
77 n = pdev->view.x * pdev->view.y; 85 dsty = (u16 *)(image + stride);
78 86
79 /* offset in Y plane */ 87 /* offsets in U/V planes */
80 stride = pdev->view.x * pdev->offset.y + pdev->offset.x; 88 stride = pdev->view.x * pdev->offset.y / 4 + pdev->offset.x / 2;
81 dsty = (u16 *)(image + stride); 89 dstu = (u16 *)(image + n + stride);
82 90 dstv = (u16 *)(image + n + n / 4 + stride);
83 /* offsets in U/V planes */ 91
84 stride = pdev->view.x * pdev->offset.y / 4 + pdev->offset.x / 2; 92 /* increment after each line */
85 dstu = (u16 *)(image + n + stride); 93 stride = (pdev->view.x - pdev->image.x) / 2; /* u16 is 2 bytes */
86 dstv = (u16 *)(image + n + n / 4 + stride); 94
87 95 for (line = 0; line < pdev->image.y; line++) {
88 /* increment after each line */ 96 for (col = 0; col < pdev->image.x; col += 4) {
89 stride = (pdev->view.x - pdev->image.x) / 2; /* u16 is 2 bytes */ 97 *dsty++ = *src++;
90 98 *dsty++ = *src++;
91 for (line = 0; line < pdev->image.y; line++) {
92 for (col = 0; col < pdev->image.x; col += 4) {
93 *dsty++ = *src++;
94 *dsty++ = *src++;
95 if (line & 1)
96 *dstv++ = *src++;
97 else
98 *dstu++ = *src++;
99 }
100 dsty += stride;
101 if (line & 1) 99 if (line & 1)
102 dstv += (stride >> 1); 100 *dstv++ = *src++;
103 else 101 else
104 dstu += (stride >> 1); 102 *dstu++ = *src++;
105 } 103 }
104 dsty += stride;
105 if (line & 1)
106 dstv += (stride >> 1);
107 else
108 dstu += (stride >> 1);
109 }
110
111 return 0;
106 } 112 }
107 else { 113
108 /* Compressed; the decompressor routines will write the data 114 /*
109 in planar format immediately. 115 * Compressed;
110 */ 116 * the decompressor routines will write the data in planar format
111 int flags; 117 * immediately.
112 118 */
113 flags = PWCX_FLAG_PLANAR; 119 if (pdev->vsize == PSZ_VGA && pdev->vframes == 5 && pdev->vsnapshot) {
114 if (pdev->vsize == PSZ_VGA && pdev->vframes == 5 && pdev->vsnapshot) 120 PWC_ERROR("Mode Bayer is not supported for now\n");
115 { 121 /* flags |= PWCX_FLAG_BAYER; */
116 printk(KERN_ERR "pwc: Mode Bayer is not supported for now\n"); 122 return -ENXIO; /* No such device or address: missing decompressor */
117 flags |= PWCX_FLAG_BAYER; 123 }
118 return -ENXIO; /* No such device or address: missing decompressor */ 124
119 } 125 if (DEVICE_USE_CODEC1(pdev->type)) {
120 126
121#if 0 127 /* TODO & FIXME */
122 switch (pdev->type) 128 PWC_ERROR("This chipset is not supported for now\n");
123 { 129 return -ENXIO; /* No such device or address: missing decompressor */
124 case 675: 130
125 case 680: 131 } else {
126 case 690: 132 pwc_dec23_decompress(pdev, yuv, image, PWCX_FLAG_PLANAR);
127 case 720:
128 case 730:
129 case 740:
130 case 750:
131 pwc_dec23_decompress(&pdev->image, &pdev->view,
132 &pdev->offset, yuv, image, flags,
133 pdev->decompress_data, pdev->vbandlength);
134 break;
135 case 645:
136 case 646:
137 /* TODO & FIXME */
138 return -ENXIO; /* Missing decompressor */
139 break;
140 }
141#endif
142 } 133 }
143 return 0; 134 return 0;
144} 135}
145 136
146 137
138/* vim: set cino= formatoptions=croql cindent shiftwidth=8 tabstop=8: */
diff --git a/drivers/media/video/pwc/pwc-uncompress.h b/drivers/media/video/pwc/pwc-uncompress.h
index f75e1b6cbe1..041227f6524 100644
--- a/drivers/media/video/pwc/pwc-uncompress.h
+++ b/drivers/media/video/pwc/pwc-uncompress.h
@@ -1,5 +1,5 @@
1/* (C) 1999-2003 Nemosoft Unv. 1/* (C) 1999-2003 Nemosoft Unv.
2 (C) 2004 Luc Saillard (luc@saillard.org) 2 (C) 2004-2006 Luc Saillard (luc@saillard.org)
3 3
4 NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx 4 NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx
5 driver and thus may have bugs that are not present in the original version. 5 driver and thus may have bugs that are not present in the original version.
@@ -32,7 +32,7 @@
32 32
33#include <linux/config.h> 33#include <linux/config.h>
34 34
35#include "pwc-ioctl.h" 35#include <media/pwc-ioctl.h>
36 36
37/* from pwc-dec.h */ 37/* from pwc-dec.h */
38#define PWCX_FLAG_PLANAR 0x0001 38#define PWCX_FLAG_PLANAR 0x0001
diff --git a/drivers/media/video/pwc/pwc-v4l.c b/drivers/media/video/pwc/pwc-v4l.c
new file mode 100644
index 00000000000..b7eb3ce3b96
--- /dev/null
+++ b/drivers/media/video/pwc/pwc-v4l.c
@@ -0,0 +1,1202 @@
1/* Linux driver for Philips webcam
2 USB and Video4Linux interface part.
3 (C) 1999-2004 Nemosoft Unv.
4 (C) 2004-2006 Luc Saillard (luc@saillard.org)
5
6 NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx
7 driver and thus may have bugs that are not present in the original version.
8 Please send bug reports and support requests to <luc@saillard.org>.
9 The decompression routines have been implemented by reverse-engineering the
10 Nemosoft binary pwcx module. Caveat emptor.
11
12 This program is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 2 of the License, or
15 (at your option) any later version.
16
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details.
21
22 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software
24 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25
26*/
27
28#include <linux/errno.h>
29#include <linux/init.h>
30#include <linux/mm.h>
31#include <linux/module.h>
32#include <linux/poll.h>
33#include <linux/slab.h>
34#include <linux/vmalloc.h>
35#include <asm/io.h>
36
37#include "pwc.h"
38
39static struct v4l2_queryctrl pwc_controls[] = {
40 {
41 .id = V4L2_CID_BRIGHTNESS,
42 .type = V4L2_CTRL_TYPE_INTEGER,
43 .name = "Brightness",
44 .minimum = 0,
45 .maximum = 128,
46 .step = 1,
47 .default_value = 64,
48 },
49 {
50 .id = V4L2_CID_CONTRAST,
51 .type = V4L2_CTRL_TYPE_INTEGER,
52 .name = "Contrast",
53 .minimum = 0,
54 .maximum = 64,
55 .step = 1,
56 .default_value = 0,
57 },
58 {
59 .id = V4L2_CID_SATURATION,
60 .type = V4L2_CTRL_TYPE_INTEGER,
61 .name = "Saturation",
62 .minimum = -100,
63 .maximum = 100,
64 .step = 1,
65 .default_value = 0,
66 },
67 {
68 .id = V4L2_CID_GAMMA,
69 .type = V4L2_CTRL_TYPE_INTEGER,
70 .name = "Gamma",
71 .minimum = 0,
72 .maximum = 32,
73 .step = 1,
74 .default_value = 0,
75 },
76 {
77 .id = V4L2_CID_RED_BALANCE,
78 .type = V4L2_CTRL_TYPE_INTEGER,
79 .name = "Red Gain",
80 .minimum = 0,
81 .maximum = 256,
82 .step = 1,
83 .default_value = 0,
84 },
85 {
86 .id = V4L2_CID_BLUE_BALANCE,
87 .type = V4L2_CTRL_TYPE_INTEGER,
88 .name = "Blue Gain",
89 .minimum = 0,
90 .maximum = 256,
91 .step = 1,
92 .default_value = 0,
93 },
94 {
95 .id = V4L2_CID_AUTO_WHITE_BALANCE,
96 .type = V4L2_CTRL_TYPE_BOOLEAN,
97 .name = "Auto White Balance",
98 .minimum = 0,
99 .maximum = 1,
100 .step = 1,
101 .default_value = 0,
102 },
103 {
104 .id = V4L2_CID_EXPOSURE,
105 .type = V4L2_CTRL_TYPE_INTEGER,
106 .name = "Shutter Speed (Exposure)",
107 .minimum = 0,
108 .maximum = 256,
109 .step = 1,
110 .default_value = 200,
111 },
112 {
113 .id = V4L2_CID_AUTOGAIN,
114 .type = V4L2_CTRL_TYPE_BOOLEAN,
115 .name = "Auto Gain Enabled",
116 .minimum = 0,
117 .maximum = 1,
118 .step = 1,
119 .default_value = 1,
120 },
121 {
122 .id = V4L2_CID_GAIN,
123 .type = V4L2_CTRL_TYPE_INTEGER,
124 .name = "Gain Level",
125 .minimum = 0,
126 .maximum = 256,
127 .step = 1,
128 .default_value = 0,
129 },
130 {
131 .id = V4L2_CID_PRIVATE_SAVE_USER,
132 .type = V4L2_CTRL_TYPE_BUTTON,
133 .name = "Save User Settings",
134 .minimum = 0,
135 .maximum = 0,
136 .step = 0,
137 .default_value = 0,
138 },
139 {
140 .id = V4L2_CID_PRIVATE_RESTORE_USER,
141 .type = V4L2_CTRL_TYPE_BUTTON,
142 .name = "Restore User Settings",
143 .minimum = 0,
144 .maximum = 0,
145 .step = 0,
146 .default_value = 0,
147 },
148 {
149 .id = V4L2_CID_PRIVATE_RESTORE_FACTORY,
150 .type = V4L2_CTRL_TYPE_BUTTON,
151 .name = "Restore Factory Settings",
152 .minimum = 0,
153 .maximum = 0,
154 .step = 0,
155 .default_value = 0,
156 },
157 {
158 .id = V4L2_CID_PRIVATE_COLOUR_MODE,
159 .type = V4L2_CTRL_TYPE_BOOLEAN,
160 .name = "Colour mode",
161 .minimum = 0,
162 .maximum = 1,
163 .step = 1,
164 .default_value = 0,
165 },
166 {
167 .id = V4L2_CID_PRIVATE_AUTOCONTOUR,
168 .type = V4L2_CTRL_TYPE_BOOLEAN,
169 .name = "Auto contour",
170 .minimum = 0,
171 .maximum = 1,
172 .step = 1,
173 .default_value = 0,
174 },
175 {
176 .id = V4L2_CID_PRIVATE_CONTOUR,
177 .type = V4L2_CTRL_TYPE_INTEGER,
178 .name = "Contour",
179 .minimum = 0,
180 .maximum = 63,
181 .step = 1,
182 .default_value = 0,
183 },
184 {
185 .id = V4L2_CID_PRIVATE_BACKLIGHT,
186 .type = V4L2_CTRL_TYPE_BOOLEAN,
187 .name = "Backlight compensation",
188 .minimum = 0,
189 .maximum = 1,
190 .step = 1,
191 .default_value = 0,
192 },
193 {
194 .id = V4L2_CID_PRIVATE_FLICKERLESS,
195 .type = V4L2_CTRL_TYPE_BOOLEAN,
196 .name = "Flickerless",
197 .minimum = 0,
198 .maximum = 1,
199 .step = 1,
200 .default_value = 0,
201 },
202 {
203 .id = V4L2_CID_PRIVATE_NOISE_REDUCTION,
204 .type = V4L2_CTRL_TYPE_INTEGER,
205 .name = "Noise reduction",
206 .minimum = 0,
207 .maximum = 3,
208 .step = 1,
209 .default_value = 0,
210 },
211};
212
213
214static void pwc_vidioc_fill_fmt(const struct pwc_device *pdev, struct v4l2_format *f)
215{
216 memset(&f->fmt.pix, 0, sizeof(struct v4l2_pix_format));
217 f->fmt.pix.width = pdev->view.x;
218 f->fmt.pix.height = pdev->view.y;
219 f->fmt.pix.field = V4L2_FIELD_NONE;
220 if (pdev->vpalette == VIDEO_PALETTE_YUV420P) {
221 f->fmt.pix.pixelformat = V4L2_PIX_FMT_YUV420;
222 f->fmt.pix.bytesperline = (f->fmt.pix.width * 3)/2;
223 f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
224 } else {
225 /* vbandlength contains 4 lines ... */
226 f->fmt.pix.bytesperline = pdev->vbandlength/4;
227 f->fmt.pix.sizeimage = pdev->frame_size + sizeof(struct pwc_raw_frame);
228 if (DEVICE_USE_CODEC1(pdev->type))
229 f->fmt.pix.pixelformat = V4L2_PIX_FMT_PWC1;
230 else
231 f->fmt.pix.pixelformat = V4L2_PIX_FMT_PWC2;
232 }
233 PWC_DEBUG_IOCTL("pwc_vidioc_fill_fmt() "
234 "width=%d, height=%d, bytesperline=%d, sizeimage=%d, pixelformat=%c%c%c%c\n",
235 f->fmt.pix.width,
236 f->fmt.pix.height,
237 f->fmt.pix.bytesperline,
238 f->fmt.pix.sizeimage,
239 (f->fmt.pix.pixelformat)&255,
240 (f->fmt.pix.pixelformat>>8)&255,
241 (f->fmt.pix.pixelformat>>16)&255,
242 (f->fmt.pix.pixelformat>>24)&255);
243}
244
245/* ioctl(VIDIOC_TRY_FMT) */
246static int pwc_vidioc_try_fmt(struct pwc_device *pdev, struct v4l2_format *f)
247{
248 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
249 PWC_DEBUG_IOCTL("Bad video type must be V4L2_BUF_TYPE_VIDEO_CAPTURE\n");
250 return -EINVAL;
251 }
252
253 switch (f->fmt.pix.pixelformat) {
254 case V4L2_PIX_FMT_YUV420:
255 break;
256 case V4L2_PIX_FMT_PWC1:
257 if (DEVICE_USE_CODEC23(pdev->type)) {
258 PWC_DEBUG_IOCTL("codec1 is only supported for old pwc webcam\n");
259 return -EINVAL;
260 }
261 break;
262 case V4L2_PIX_FMT_PWC2:
263 if (DEVICE_USE_CODEC1(pdev->type)) {
264 PWC_DEBUG_IOCTL("codec23 is only supported for new pwc webcam\n");
265 return -EINVAL;
266 }
267 break;
268 default:
269 PWC_DEBUG_IOCTL("Unsupported pixel format\n");
270 return -EINVAL;
271
272 }
273
274 if (f->fmt.pix.width > pdev->view_max.x)
275 f->fmt.pix.width = pdev->view_max.x;
276 else if (f->fmt.pix.width < pdev->view_min.x)
277 f->fmt.pix.width = pdev->view_min.x;
278
279 if (f->fmt.pix.height > pdev->view_max.y)
280 f->fmt.pix.height = pdev->view_max.y;
281 else if (f->fmt.pix.height < pdev->view_min.y)
282 f->fmt.pix.height = pdev->view_min.y;
283
284 return 0;
285}
286
287/* ioctl(VIDIOC_SET_FMT) */
288static int pwc_vidioc_set_fmt(struct pwc_device *pdev, struct v4l2_format *f)
289{
290 int ret, fps, snapshot, compression, pixelformat;
291
292 ret = pwc_vidioc_try_fmt(pdev, f);
293 if (ret<0)
294 return ret;
295
296 pixelformat = f->fmt.pix.pixelformat;
297 compression = pdev->vcompression;
298 snapshot = 0;
299 fps = pdev->vframes;
300 if (f->fmt.pix.priv) {
301 compression = (f->fmt.pix.priv & PWC_QLT_MASK) >> PWC_QLT_SHIFT;
302 snapshot = !!(f->fmt.pix.priv & PWC_FPS_SNAPSHOT);
303 fps = (f->fmt.pix.priv & PWC_FPS_FRMASK) >> PWC_FPS_SHIFT;
304 if (fps == 0)
305 fps = pdev->vframes;
306 }
307
308 if (pixelformat == V4L2_PIX_FMT_YUV420)
309 pdev->vpalette = VIDEO_PALETTE_YUV420P;
310 else
311 pdev->vpalette = VIDEO_PALETTE_RAW;
312
313 PWC_DEBUG_IOCTL("Try to change format to: width=%d height=%d fps=%d "
314 "compression=%d snapshot=%d format=%c%c%c%c\n",
315 f->fmt.pix.width, f->fmt.pix.height, fps,
316 compression, snapshot,
317 (pixelformat)&255,
318 (pixelformat>>8)&255,
319 (pixelformat>>16)&255,
320 (pixelformat>>24)&255);
321
322 ret = pwc_try_video_mode(pdev,
323 f->fmt.pix.width,
324 f->fmt.pix.height,
325 fps,
326 compression,
327 snapshot);
328
329 PWC_DEBUG_IOCTL("pwc_try_video_mode(), return=%d\n", ret);
330
331 if (ret)
332 return ret;
333
334 pwc_vidioc_fill_fmt(pdev, f);
335
336 return 0;
337
338}
339
340int pwc_video_do_ioctl(struct inode *inode, struct file *file,
341 unsigned int cmd, void *arg)
342{
343 struct video_device *vdev = video_devdata(file);
344 struct pwc_device *pdev;
345 DECLARE_WAITQUEUE(wait, current);
346
347 if (vdev == NULL)
348 return -EFAULT;
349 pdev = vdev->priv;
350 if (pdev == NULL)
351 return -EFAULT;
352
353#if CONFIG_PWC_DEBUG
354 if (PWC_DEBUG_LEVEL_IOCTL & pwc_trace)
355 v4l_printk_ioctl(cmd);
356#endif
357
358
359 switch (cmd) {
360 /* Query cabapilities */
361 case VIDIOCGCAP:
362 {
363 struct video_capability *caps = arg;
364
365 strcpy(caps->name, vdev->name);
366 caps->type = VID_TYPE_CAPTURE;
367 caps->channels = 1;
368 caps->audios = 1;
369 caps->minwidth = pdev->view_min.x;
370 caps->minheight = pdev->view_min.y;
371 caps->maxwidth = pdev->view_max.x;
372 caps->maxheight = pdev->view_max.y;
373 break;
374 }
375
376 /* Channel functions (simulate 1 channel) */
377 case VIDIOCGCHAN:
378 {
379 struct video_channel *v = arg;
380
381 if (v->channel != 0)
382 return -EINVAL;
383 v->flags = 0;
384 v->tuners = 0;
385 v->type = VIDEO_TYPE_CAMERA;
386 strcpy(v->name, "Webcam");
387 return 0;
388 }
389
390 case VIDIOCSCHAN:
391 {
392 /* The spec says the argument is an integer, but
393 the bttv driver uses a video_channel arg, which
394 makes sense becasue it also has the norm flag.
395 */
396 struct video_channel *v = arg;
397 if (v->channel != 0)
398 return -EINVAL;
399 return 0;
400 }
401
402
403 /* Picture functions; contrast etc. */
404 case VIDIOCGPICT:
405 {
406 struct video_picture *p = arg;
407 int val;
408
409 val = pwc_get_brightness(pdev);
410 if (val >= 0)
411 p->brightness = (val<<9);
412 else
413 p->brightness = 0xffff;
414 val = pwc_get_contrast(pdev);
415 if (val >= 0)
416 p->contrast = (val<<10);
417 else
418 p->contrast = 0xffff;
419 /* Gamma, Whiteness, what's the difference? :) */
420 val = pwc_get_gamma(pdev);
421 if (val >= 0)
422 p->whiteness = (val<<11);
423 else
424 p->whiteness = 0xffff;
425 if (pwc_get_saturation(pdev, &val)<0)
426 p->colour = 0xffff;
427 else
428 p->colour = 32768 + val * 327;
429 p->depth = 24;
430 p->palette = pdev->vpalette;
431 p->hue = 0xFFFF; /* N/A */
432 break;
433 }
434
435 case VIDIOCSPICT:
436 {
437 struct video_picture *p = arg;
438 /*
439 * FIXME: Suppose we are mid read
440 ANSWER: No problem: the firmware of the camera
441 can handle brightness/contrast/etc
442 changes at _any_ time, and the palette
443 is used exactly once in the uncompress
444 routine.
445 */
446 pwc_set_brightness(pdev, p->brightness);
447 pwc_set_contrast(pdev, p->contrast);
448 pwc_set_gamma(pdev, p->whiteness);
449 pwc_set_saturation(pdev, (p->colour-32768)/327);
450 if (p->palette && p->palette != pdev->vpalette) {
451 switch (p->palette) {
452 case VIDEO_PALETTE_YUV420P:
453 case VIDEO_PALETTE_RAW:
454 pdev->vpalette = p->palette;
455 return pwc_try_video_mode(pdev, pdev->image.x, pdev->image.y, pdev->vframes, pdev->vcompression, pdev->vsnapshot);
456 break;
457 default:
458 return -EINVAL;
459 break;
460 }
461 }
462 break;
463 }
464
465 /* Window/size parameters */
466 case VIDIOCGWIN:
467 {
468 struct video_window *vw = arg;
469
470 vw->x = 0;
471 vw->y = 0;
472 vw->width = pdev->view.x;
473 vw->height = pdev->view.y;
474 vw->chromakey = 0;
475 vw->flags = (pdev->vframes << PWC_FPS_SHIFT) |
476 (pdev->vsnapshot ? PWC_FPS_SNAPSHOT : 0);
477 break;
478 }
479
480 case VIDIOCSWIN:
481 {
482 struct video_window *vw = arg;
483 int fps, snapshot, ret;
484
485 fps = (vw->flags & PWC_FPS_FRMASK) >> PWC_FPS_SHIFT;
486 snapshot = vw->flags & PWC_FPS_SNAPSHOT;
487 if (fps == 0)
488 fps = pdev->vframes;
489 if (pdev->view.x == vw->width && pdev->view.y && fps == pdev->vframes && snapshot == pdev->vsnapshot)
490 return 0;
491 ret = pwc_try_video_mode(pdev, vw->width, vw->height, fps, pdev->vcompression, snapshot);
492 if (ret)
493 return ret;
494 break;
495 }
496
497 /* We don't have overlay support (yet) */
498 case VIDIOCGFBUF:
499 {
500 struct video_buffer *vb = arg;
501
502 memset(vb,0,sizeof(*vb));
503 break;
504 }
505
506 /* mmap() functions */
507 case VIDIOCGMBUF:
508 {
509 /* Tell the user program how much memory is needed for a mmap() */
510 struct video_mbuf *vm = arg;
511 int i;
512
513 memset(vm, 0, sizeof(*vm));
514 vm->size = pwc_mbufs * pdev->len_per_image;
515 vm->frames = pwc_mbufs; /* double buffering should be enough for most applications */
516 for (i = 0; i < pwc_mbufs; i++)
517 vm->offsets[i] = i * pdev->len_per_image;
518 break;
519 }
520
521 case VIDIOCMCAPTURE:
522 {
523 /* Start capture into a given image buffer (called 'frame' in video_mmap structure) */
524 struct video_mmap *vm = arg;
525
526 PWC_DEBUG_READ("VIDIOCMCAPTURE: %dx%d, frame %d, format %d\n", vm->width, vm->height, vm->frame, vm->format);
527 if (vm->frame < 0 || vm->frame >= pwc_mbufs)
528 return -EINVAL;
529
530 /* xawtv is nasty. It probes the available palettes
531 by setting a very small image size and trying
532 various palettes... The driver doesn't support
533 such small images, so I'm working around it.
534 */
535 if (vm->format)
536 {
537 switch (vm->format)
538 {
539 case VIDEO_PALETTE_YUV420P:
540 case VIDEO_PALETTE_RAW:
541 break;
542 default:
543 return -EINVAL;
544 break;
545 }
546 }
547
548 if ((vm->width != pdev->view.x || vm->height != pdev->view.y) &&
549 (vm->width >= pdev->view_min.x && vm->height >= pdev->view_min.y)) {
550 int ret;
551
552 PWC_DEBUG_OPEN("VIDIOCMCAPTURE: changing size to please xawtv :-(.\n");
553 ret = pwc_try_video_mode(pdev, vm->width, vm->height, pdev->vframes, pdev->vcompression, pdev->vsnapshot);
554 if (ret)
555 return ret;
556 } /* ... size mismatch */
557
558 /* FIXME: should we lock here? */
559 if (pdev->image_used[vm->frame])
560 return -EBUSY; /* buffer wasn't available. Bummer */
561 pdev->image_used[vm->frame] = 1;
562
563 /* Okay, we're done here. In the SYNC call we wait until a
564 frame comes available, then expand image into the given
565 buffer.
566 In contrast to the CPiA cam the Philips cams deliver a
567 constant stream, almost like a grabber card. Also,
568 we have separate buffers for the rawdata and the image,
569 meaning we can nearly always expand into the requested buffer.
570 */
571 PWC_DEBUG_READ("VIDIOCMCAPTURE done.\n");
572 break;
573 }
574
575 case VIDIOCSYNC:
576 {
577 /* The doc says: "Whenever a buffer is used it should
578 call VIDIOCSYNC to free this frame up and continue."
579
580 The only odd thing about this whole procedure is
581 that MCAPTURE flags the buffer as "in use", and
582 SYNC immediately unmarks it, while it isn't
583 after SYNC that you know that the buffer actually
584 got filled! So you better not start a CAPTURE in
585 the same frame immediately (use double buffering).
586 This is not a problem for this cam, since it has
587 extra intermediate buffers, but a hardware
588 grabber card will then overwrite the buffer
589 you're working on.
590 */
591 int *mbuf = arg;
592 int ret;
593
594 PWC_DEBUG_READ("VIDIOCSYNC called (%d).\n", *mbuf);
595
596 /* bounds check */
597 if (*mbuf < 0 || *mbuf >= pwc_mbufs)
598 return -EINVAL;
599 /* check if this buffer was requested anyway */
600 if (pdev->image_used[*mbuf] == 0)
601 return -EINVAL;
602
603 /* Add ourselves to the frame wait-queue.
604
605 FIXME: needs auditing for safety.
606 QUESTION: In what respect? I think that using the
607 frameq is safe now.
608 */
609 add_wait_queue(&pdev->frameq, &wait);
610 while (pdev->full_frames == NULL) {
611 /* Check for unplugged/etc. here */
612 if (pdev->error_status) {
613 remove_wait_queue(&pdev->frameq, &wait);
614 set_current_state(TASK_RUNNING);
615 return -pdev->error_status;
616 }
617
618 if (signal_pending(current)) {
619 remove_wait_queue(&pdev->frameq, &wait);
620 set_current_state(TASK_RUNNING);
621 return -ERESTARTSYS;
622 }
623 schedule();
624 set_current_state(TASK_INTERRUPTIBLE);
625 }
626 remove_wait_queue(&pdev->frameq, &wait);
627 set_current_state(TASK_RUNNING);
628
629 /* The frame is ready. Expand in the image buffer
630 requested by the user. I don't care if you
631 mmap() 5 buffers and request data in this order:
632 buffer 4 2 3 0 1 2 3 0 4 3 1 . . .
633 Grabber hardware may not be so forgiving.
634 */
635 PWC_DEBUG_READ("VIDIOCSYNC: frame ready.\n");
636 pdev->fill_image = *mbuf; /* tell in which buffer we want the image to be expanded */
637 /* Decompress, etc */
638 ret = pwc_handle_frame(pdev);
639 pdev->image_used[*mbuf] = 0;
640 if (ret)
641 return -EFAULT;
642 break;
643 }
644
645 case VIDIOCGAUDIO:
646 {
647 struct video_audio *v = arg;
648
649 strcpy(v->name, "Microphone");
650 v->audio = -1; /* unknown audio minor */
651 v->flags = 0;
652 v->mode = VIDEO_SOUND_MONO;
653 v->volume = 0;
654 v->bass = 0;
655 v->treble = 0;
656 v->balance = 0x8000;
657 v->step = 1;
658 break;
659 }
660
661 case VIDIOCSAUDIO:
662 {
663 /* Dummy: nothing can be set */
664 break;
665 }
666
667 case VIDIOCGUNIT:
668 {
669 struct video_unit *vu = arg;
670
671 vu->video = pdev->vdev->minor & 0x3F;
672 vu->audio = -1; /* not known yet */
673 vu->vbi = -1;
674 vu->radio = -1;
675 vu->teletext = -1;
676 break;
677 }
678
679 /* V4L2 Layer */
680 case VIDIOC_QUERYCAP:
681 {
682 struct v4l2_capability *cap = arg;
683
684 PWC_DEBUG_IOCTL("ioctl(VIDIOC_QUERYCAP) This application "\
685 "try to use the v4l2 layer\n");
686 strcpy(cap->driver,PWC_NAME);
687 strlcpy(cap->card, vdev->name, sizeof(cap->card));
688 usb_make_path(pdev->udev,cap->bus_info,sizeof(cap->bus_info));
689 cap->version = PWC_VERSION_CODE;
690 cap->capabilities =
691 V4L2_CAP_VIDEO_CAPTURE |
692 V4L2_CAP_STREAMING |
693 V4L2_CAP_READWRITE;
694 return 0;
695 }
696
697 case VIDIOC_ENUMINPUT:
698 {
699 struct v4l2_input *i = arg;
700
701 if ( i->index ) /* Only one INPUT is supported */
702 return -EINVAL;
703
704 memset(i, 0, sizeof(struct v4l2_input));
705 strcpy(i->name, "usb");
706 return 0;
707 }
708
709 case VIDIOC_G_INPUT:
710 {
711 int *i = arg;
712 *i = 0; /* Only one INPUT is supported */
713 return 0;
714 }
715 case VIDIOC_S_INPUT:
716 {
717 int *i = arg;
718
719 if ( *i ) { /* Only one INPUT is supported */
720 PWC_DEBUG_IOCTL("Only one input source is"\
721 " supported with this webcam.\n");
722 return -EINVAL;
723 }
724 return 0;
725 }
726
727 /* TODO: */
728 case VIDIOC_QUERYCTRL:
729 {
730 struct v4l2_queryctrl *c = arg;
731 int i;
732
733 PWC_DEBUG_IOCTL("ioctl(VIDIOC_QUERYCTRL) query id=%d\n", c->id);
734 for (i=0; i<sizeof(pwc_controls)/sizeof(struct v4l2_queryctrl); i++) {
735 if (pwc_controls[i].id == c->id) {
736 PWC_DEBUG_IOCTL("ioctl(VIDIOC_QUERYCTRL) found\n");
737 memcpy(c,&pwc_controls[i],sizeof(struct v4l2_queryctrl));
738 return 0;
739 }
740 }
741 PWC_DEBUG_IOCTL("ioctl(VIDIOC_QUERYCTRL) not found\n");
742
743 return -EINVAL;
744 }
745 case VIDIOC_G_CTRL:
746 {
747 struct v4l2_control *c = arg;
748 int ret;
749
750 switch (c->id)
751 {
752 case V4L2_CID_BRIGHTNESS:
753 c->value = pwc_get_brightness(pdev);
754 if (c->value<0)
755 return -EINVAL;
756 return 0;
757 case V4L2_CID_CONTRAST:
758 c->value = pwc_get_contrast(pdev);
759 if (c->value<0)
760 return -EINVAL;
761 return 0;
762 case V4L2_CID_SATURATION:
763 ret = pwc_get_saturation(pdev, &c->value);
764 if (ret<0)
765 return -EINVAL;
766 return 0;
767 case V4L2_CID_GAMMA:
768 c->value = pwc_get_gamma(pdev);
769 if (c->value<0)
770 return -EINVAL;
771 return 0;
772 case V4L2_CID_RED_BALANCE:
773 ret = pwc_get_red_gain(pdev, &c->value);
774 if (ret<0)
775 return -EINVAL;
776 c->value >>= 8;
777 return 0;
778 case V4L2_CID_BLUE_BALANCE:
779 ret = pwc_get_blue_gain(pdev, &c->value);
780 if (ret<0)
781 return -EINVAL;
782 c->value >>= 8;
783 return 0;
784 case V4L2_CID_AUTO_WHITE_BALANCE:
785 ret = pwc_get_awb(pdev);
786 if (ret<0)
787 return -EINVAL;
788 c->value = (ret == PWC_WB_MANUAL)?0:1;
789 return 0;
790 case V4L2_CID_GAIN:
791 ret = pwc_get_agc(pdev, &c->value);
792 if (ret<0)
793 return -EINVAL;
794 c->value >>= 8;
795 return 0;
796 case V4L2_CID_AUTOGAIN:
797 ret = pwc_get_agc(pdev, &c->value);
798 if (ret<0)
799 return -EINVAL;
800 c->value = (c->value < 0)?1:0;
801 return 0;
802 case V4L2_CID_EXPOSURE:
803 ret = pwc_get_shutter_speed(pdev, &c->value);
804 if (ret<0)
805 return -EINVAL;
806 return 0;
807 case V4L2_CID_PRIVATE_COLOUR_MODE:
808 ret = pwc_get_colour_mode(pdev, &c->value);
809 if (ret < 0)
810 return -EINVAL;
811 return 0;
812 case V4L2_CID_PRIVATE_AUTOCONTOUR:
813 ret = pwc_get_contour(pdev, &c->value);
814 if (ret < 0)
815 return -EINVAL;
816 c->value=(c->value == -1?1:0);
817 return 0;
818 case V4L2_CID_PRIVATE_CONTOUR:
819 ret = pwc_get_contour(pdev, &c->value);
820 if (ret < 0)
821 return -EINVAL;
822 c->value >>= 10;
823 return 0;
824 case V4L2_CID_PRIVATE_BACKLIGHT:
825 ret = pwc_get_backlight(pdev, &c->value);
826 if (ret < 0)
827 return -EINVAL;
828 return 0;
829 case V4L2_CID_PRIVATE_FLICKERLESS:
830 ret = pwc_get_flicker(pdev, &c->value);
831 if (ret < 0)
832 return -EINVAL;
833 c->value=(c->value?1:0);
834 return 0;
835 case V4L2_CID_PRIVATE_NOISE_REDUCTION:
836 ret = pwc_get_dynamic_noise(pdev, &c->value);
837 if (ret < 0)
838 return -EINVAL;
839 return 0;
840
841 case V4L2_CID_PRIVATE_SAVE_USER:
842 case V4L2_CID_PRIVATE_RESTORE_USER:
843 case V4L2_CID_PRIVATE_RESTORE_FACTORY:
844 return -EINVAL;
845 }
846 return -EINVAL;
847 }
848 case VIDIOC_S_CTRL:
849 {
850 struct v4l2_control *c = arg;
851 int ret;
852
853 switch (c->id)
854 {
855 case V4L2_CID_BRIGHTNESS:
856 c->value <<= 9;
857 ret = pwc_set_brightness(pdev, c->value);
858 if (ret<0)
859 return -EINVAL;
860 return 0;
861 case V4L2_CID_CONTRAST:
862 c->value <<= 10;
863 ret = pwc_set_contrast(pdev, c->value);
864 if (ret<0)
865 return -EINVAL;
866 return 0;
867 case V4L2_CID_SATURATION:
868 ret = pwc_set_saturation(pdev, c->value);
869 if (ret<0)
870 return -EINVAL;
871 return 0;
872 case V4L2_CID_GAMMA:
873 c->value <<= 11;
874 ret = pwc_set_gamma(pdev, c->value);
875 if (ret<0)
876 return -EINVAL;
877 return 0;
878 case V4L2_CID_RED_BALANCE:
879 c->value <<= 8;
880 ret = pwc_set_red_gain(pdev, c->value);
881 if (ret<0)
882 return -EINVAL;
883 return 0;
884 case V4L2_CID_BLUE_BALANCE:
885 c->value <<= 8;
886 ret = pwc_set_blue_gain(pdev, c->value);
887 if (ret<0)
888 return -EINVAL;
889 return 0;
890 case V4L2_CID_AUTO_WHITE_BALANCE:
891 c->value = (c->value == 0)?PWC_WB_MANUAL:PWC_WB_AUTO;
892 ret = pwc_set_awb(pdev, c->value);
893 if (ret<0)
894 return -EINVAL;
895 return 0;
896 case V4L2_CID_EXPOSURE:
897 c->value <<= 8;
898 ret = pwc_set_shutter_speed(pdev, c->value?0:1, c->value);
899 if (ret<0)
900 return -EINVAL;
901 return 0;
902 case V4L2_CID_AUTOGAIN:
903 /* autogain off means nothing without a gain */
904 if (c->value == 0)
905 return 0;
906 ret = pwc_set_agc(pdev, c->value, 0);
907 if (ret<0)
908 return -EINVAL;
909 return 0;
910 case V4L2_CID_GAIN:
911 c->value <<= 8;
912 ret = pwc_set_agc(pdev, 0, c->value);
913 if (ret<0)
914 return -EINVAL;
915 return 0;
916 case V4L2_CID_PRIVATE_SAVE_USER:
917 if (pwc_save_user(pdev))
918 return -EINVAL;
919 return 0;
920 case V4L2_CID_PRIVATE_RESTORE_USER:
921 if (pwc_restore_user(pdev))
922 return -EINVAL;
923 return 0;
924 case V4L2_CID_PRIVATE_RESTORE_FACTORY:
925 if (pwc_restore_factory(pdev))
926 return -EINVAL;
927 return 0;
928 case V4L2_CID_PRIVATE_COLOUR_MODE:
929 ret = pwc_set_colour_mode(pdev, c->value);
930 if (ret < 0)
931 return -EINVAL;
932 return 0;
933 case V4L2_CID_PRIVATE_AUTOCONTOUR:
934 c->value=(c->value == 1)?-1:0;
935 ret = pwc_set_contour(pdev, c->value);
936 if (ret < 0)
937 return -EINVAL;
938 return 0;
939 case V4L2_CID_PRIVATE_CONTOUR:
940 c->value <<= 10;
941 ret = pwc_set_contour(pdev, c->value);
942 if (ret < 0)
943 return -EINVAL;
944 return 0;
945 case V4L2_CID_PRIVATE_BACKLIGHT:
946 ret = pwc_set_backlight(pdev, c->value);
947 if (ret < 0)
948 return -EINVAL;
949 return 0;
950 case V4L2_CID_PRIVATE_FLICKERLESS:
951 ret = pwc_set_flicker(pdev, c->value);
952 if (ret < 0)
953 return -EINVAL;
954 case V4L2_CID_PRIVATE_NOISE_REDUCTION:
955 ret = pwc_set_dynamic_noise(pdev, c->value);
956 if (ret < 0)
957 return -EINVAL;
958 return 0;
959
960 }
961 return -EINVAL;
962 }
963
964 case VIDIOC_ENUM_FMT:
965 {
966 struct v4l2_fmtdesc *f = arg;
967 int index;
968
969 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
970 return -EINVAL;
971
972 /* We only support two format: the raw format, and YUV */
973 index = f->index;
974 memset(f,0,sizeof(struct v4l2_fmtdesc));
975 f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
976 f->index = index;
977 switch(index)
978 {
979 case 0:
980 /* RAW format */
981 f->pixelformat = pdev->type<=646?V4L2_PIX_FMT_PWC1:V4L2_PIX_FMT_PWC2;
982 f->flags = V4L2_FMT_FLAG_COMPRESSED;
983 strlcpy(f->description,"Raw Philips Webcam",sizeof(f->description));
984 break;
985 case 1:
986 f->pixelformat = V4L2_PIX_FMT_YUV420;
987 strlcpy(f->description,"4:2:0, planar, Y-Cb-Cr",sizeof(f->description));
988 break;
989 default:
990 return -EINVAL;
991 }
992 return 0;
993 }
994
995 case VIDIOC_G_FMT:
996 {
997 struct v4l2_format *f = arg;
998
999 PWC_DEBUG_IOCTL("ioctl(VIDIOC_G_FMT) return size %dx%d\n",pdev->image.x,pdev->image.y);
1000 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1001 return -EINVAL;
1002
1003 pwc_vidioc_fill_fmt(pdev, f);
1004
1005 return 0;
1006 }
1007
1008 case VIDIOC_TRY_FMT:
1009 return pwc_vidioc_try_fmt(pdev, arg);
1010
1011 case VIDIOC_S_FMT:
1012 return pwc_vidioc_set_fmt(pdev, arg);
1013
1014 case VIDIOC_G_STD:
1015 {
1016 v4l2_std_id *std = arg;
1017 *std = V4L2_STD_UNKNOWN;
1018 return 0;
1019 }
1020
1021 case VIDIOC_S_STD:
1022 {
1023 v4l2_std_id *std = arg;
1024 if (*std != V4L2_STD_UNKNOWN)
1025 return -EINVAL;
1026 return 0;
1027 }
1028
1029 case VIDIOC_ENUMSTD:
1030 {
1031 struct v4l2_standard *std = arg;
1032 if (std->index != 0)
1033 return -EINVAL;
1034 std->id = V4L2_STD_UNKNOWN;
1035 strncpy(std->name, "webcam", sizeof(std->name));
1036 return 0;
1037 }
1038
1039 case VIDIOC_REQBUFS:
1040 {
1041 struct v4l2_requestbuffers *rb = arg;
1042 int nbuffers;
1043
1044 PWC_DEBUG_IOCTL("ioctl(VIDIOC_REQBUFS) count=%d\n",rb->count);
1045 if (rb->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1046 return -EINVAL;
1047 if (rb->memory != V4L2_MEMORY_MMAP)
1048 return -EINVAL;
1049
1050 nbuffers = rb->count;
1051 if (nbuffers < 2)
1052 nbuffers = 2;
1053 else if (nbuffers > pwc_mbufs)
1054 nbuffers = pwc_mbufs;
1055 /* Force to use our # of buffers */
1056 rb->count = pwc_mbufs;
1057 return 0;
1058 }
1059
1060 case VIDIOC_QUERYBUF:
1061 {
1062 struct v4l2_buffer *buf = arg;
1063 int index;
1064
1065 PWC_DEBUG_IOCTL("ioctl(VIDIOC_QUERYBUF) index=%d\n",buf->index);
1066 if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1067 PWC_DEBUG_IOCTL("ioctl(VIDIOC_QUERYBUF) Bad type\n");
1068 return -EINVAL;
1069 }
1070 if (buf->memory != V4L2_MEMORY_MMAP) {
1071 PWC_DEBUG_IOCTL("ioctl(VIDIOC_QUERYBUF) Bad memory type\n");
1072 return -EINVAL;
1073 }
1074 index = buf->index;
1075 if (index < 0 || index >= pwc_mbufs) {
1076 PWC_DEBUG_IOCTL("ioctl(VIDIOC_QUERYBUF) Bad index %d\n", buf->index);
1077 return -EINVAL;
1078 }
1079
1080 memset(buf, 0, sizeof(struct v4l2_buffer));
1081 buf->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1082 buf->index = index;
1083 buf->m.offset = index * pdev->len_per_image;
1084 if (pdev->vpalette == VIDEO_PALETTE_RAW)
1085 buf->bytesused = pdev->frame_size + sizeof(struct pwc_raw_frame);
1086 else
1087 buf->bytesused = pdev->view.size;
1088 buf->field = V4L2_FIELD_NONE;
1089 buf->memory = V4L2_MEMORY_MMAP;
1090 //buf->flags = V4L2_BUF_FLAG_MAPPED;
1091 buf->length = pdev->len_per_image;
1092
1093 PWC_DEBUG_READ("VIDIOC_QUERYBUF: index=%d\n",buf->index);
1094 PWC_DEBUG_READ("VIDIOC_QUERYBUF: m.offset=%d\n",buf->m.offset);
1095 PWC_DEBUG_READ("VIDIOC_QUERYBUF: bytesused=%d\n",buf->bytesused);
1096
1097 return 0;
1098 }
1099
1100 case VIDIOC_QBUF:
1101 {
1102 struct v4l2_buffer *buf = arg;
1103
1104 PWC_DEBUG_IOCTL("ioctl(VIDIOC_QBUF) index=%d\n",buf->index);
1105 if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1106 return -EINVAL;
1107 if (buf->memory != V4L2_MEMORY_MMAP)
1108 return -EINVAL;
1109 if (buf->index < 0 || buf->index >= pwc_mbufs)
1110 return -EINVAL;
1111
1112 buf->flags |= V4L2_BUF_FLAG_QUEUED;
1113 buf->flags &= ~V4L2_BUF_FLAG_DONE;
1114
1115 return 0;
1116 }
1117
1118 case VIDIOC_DQBUF:
1119 {
1120 struct v4l2_buffer *buf = arg;
1121 int ret;
1122
1123 PWC_DEBUG_IOCTL("ioctl(VIDIOC_DQBUF)\n");
1124
1125 if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1126 return -EINVAL;
1127
1128 /* Add ourselves to the frame wait-queue.
1129
1130 FIXME: needs auditing for safety.
1131 QUESTION: In what respect? I think that using the
1132 frameq is safe now.
1133 */
1134 add_wait_queue(&pdev->frameq, &wait);
1135 while (pdev->full_frames == NULL) {
1136 if (pdev->error_status) {
1137 remove_wait_queue(&pdev->frameq, &wait);
1138 set_current_state(TASK_RUNNING);
1139 return -pdev->error_status;
1140 }
1141
1142 if (signal_pending(current)) {
1143 remove_wait_queue(&pdev->frameq, &wait);
1144 set_current_state(TASK_RUNNING);
1145 return -ERESTARTSYS;
1146 }
1147 schedule();
1148 set_current_state(TASK_INTERRUPTIBLE);
1149 }
1150 remove_wait_queue(&pdev->frameq, &wait);
1151 set_current_state(TASK_RUNNING);
1152
1153 PWC_DEBUG_IOCTL("VIDIOC_DQBUF: frame ready.\n");
1154 /* Decompress data in pdev->images[pdev->fill_image] */
1155 ret = pwc_handle_frame(pdev);
1156 if (ret)
1157 return -EFAULT;
1158 PWC_DEBUG_IOCTL("VIDIOC_DQBUF: after pwc_handle_frame\n");
1159
1160 buf->index = pdev->fill_image;
1161 if (pdev->vpalette == VIDEO_PALETTE_RAW)
1162 buf->bytesused = pdev->frame_size + sizeof(struct pwc_raw_frame);
1163 else
1164 buf->bytesused = pdev->view.size;
1165 buf->flags = V4L2_BUF_FLAG_MAPPED;
1166 buf->field = V4L2_FIELD_NONE;
1167 do_gettimeofday(&buf->timestamp);
1168 buf->sequence = 0;
1169 buf->memory = V4L2_MEMORY_MMAP;
1170 buf->m.offset = pdev->fill_image * pdev->len_per_image;
1171 buf->length = buf->bytesused;
1172 pwc_next_image(pdev);
1173
1174 PWC_DEBUG_IOCTL("VIDIOC_DQBUF: buf->index=%d\n",buf->index);
1175 PWC_DEBUG_IOCTL("VIDIOC_DQBUF: buf->length=%d\n",buf->length);
1176 PWC_DEBUG_IOCTL("VIDIOC_DQBUF: m.offset=%d\n",buf->m.offset);
1177 PWC_DEBUG_IOCTL("VIDIOC_DQBUF: bytesused=%d\n",buf->bytesused);
1178 PWC_DEBUG_IOCTL("VIDIOC_DQBUF: leaving\n");
1179 return 0;
1180
1181 }
1182
1183 case VIDIOC_STREAMON:
1184 {
1185 /* WARNING: pwc_try_video_mode() called pwc_isoc_init */
1186 pwc_isoc_init(pdev);
1187 return 0;
1188 }
1189
1190 case VIDIOC_STREAMOFF:
1191 {
1192 pwc_isoc_cleanup(pdev);
1193 return 0;
1194 }
1195
1196 default:
1197 return pwc_ioctl(pdev, cmd, arg);
1198 } /* ..switch */
1199 return 0;
1200}
1201
1202/* vim: set cino= formatoptions=croql cindent shiftwidth=8 tabstop=8: */
diff --git a/drivers/media/video/pwc/pwc.h b/drivers/media/video/pwc/pwc.h
index 1b0ee0ced0e..629f79e44fb 100644
--- a/drivers/media/video/pwc/pwc.h
+++ b/drivers/media/video/pwc/pwc.h
@@ -1,5 +1,5 @@
1/* (C) 1999-2003 Nemosoft Unv. 1/* (C) 1999-2003 Nemosoft Unv.
2 (C) 2004 Luc Saillard (luc@saillard.org) 2 (C) 2004-2006 Luc Saillard (luc@saillard.org)
3 3
4 NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx 4 NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx
5 driver and thus may have bugs that are not present in the original version. 5 driver and thus may have bugs that are not present in the original version.
@@ -29,51 +29,87 @@
29#include <linux/module.h> 29#include <linux/module.h>
30#include <linux/usb.h> 30#include <linux/usb.h>
31#include <linux/spinlock.h> 31#include <linux/spinlock.h>
32#include <linux/videodev.h>
33#include <linux/wait.h> 32#include <linux/wait.h>
34#include <linux/smp_lock.h> 33#include <linux/smp_lock.h>
34#include <linux/version.h>
35#include <asm/semaphore.h> 35#include <asm/semaphore.h>
36#include <asm/errno.h> 36#include <asm/errno.h>
37#include <linux/videodev.h>
38#include <media/v4l2-common.h>
37 39
38#include "pwc-uncompress.h" 40#include "pwc-uncompress.h"
39#include "pwc-ioctl.h" 41#include <media/pwc-ioctl.h>
40
41/* Defines and structures for the Philips webcam */
42/* Used for checking memory corruption/pointer validation */
43#define PWC_MAGIC 0x89DC10ABUL
44#undef PWC_MAGIC
45 42
46/* Turn some debugging options on/off */ 43/* Turn some debugging options on/off */
47#define PWC_DEBUG 0 44#ifndef CONFIG_PWC_DEBUG
45#define CONFIG_PWC_DEBUG 1
46#endif
47
48/* Version block */
49#define PWC_MAJOR 10
50#define PWC_MINOR 0
51#define PWC_EXTRAMINOR 12
52#define PWC_VERSION_CODE KERNEL_VERSION(PWC_MAJOR,PWC_MINOR,PWC_EXTRAMINOR)
53#define PWC_VERSION "10.0.12"
54#define PWC_NAME "pwc"
55#define PFX PWC_NAME ": "
56
48 57
49/* Trace certain actions in the driver */ 58/* Trace certain actions in the driver */
50#define TRACE_MODULE 0x0001 59#define PWC_DEBUG_LEVEL_MODULE (1<<0)
51#define TRACE_PROBE 0x0002 60#define PWC_DEBUG_LEVEL_PROBE (1<<1)
52#define TRACE_OPEN 0x0004 61#define PWC_DEBUG_LEVEL_OPEN (1<<2)
53#define TRACE_READ 0x0008 62#define PWC_DEBUG_LEVEL_READ (1<<3)
54#define TRACE_MEMORY 0x0010 63#define PWC_DEBUG_LEVEL_MEMORY (1<<4)
55#define TRACE_FLOW 0x0020 64#define PWC_DEBUG_LEVEL_FLOW (1<<5)
56#define TRACE_SIZE 0x0040 65#define PWC_DEBUG_LEVEL_SIZE (1<<6)
57#define TRACE_PWCX 0x0080 66#define PWC_DEBUG_LEVEL_IOCTL (1<<7)
58#define TRACE_SEQUENCE 0x1000 67#define PWC_DEBUG_LEVEL_TRACE (1<<8)
59 68
60#define Trace(R, A...) if (pwc_trace & R) printk(KERN_DEBUG PWC_NAME " " A) 69#define PWC_DEBUG_MODULE(fmt, args...) PWC_DEBUG(MODULE, fmt, ##args)
61#define Debug(A...) printk(KERN_DEBUG PWC_NAME " " A) 70#define PWC_DEBUG_PROBE(fmt, args...) PWC_DEBUG(PROBE, fmt, ##args)
62#define Info(A...) printk(KERN_INFO PWC_NAME " " A) 71#define PWC_DEBUG_OPEN(fmt, args...) PWC_DEBUG(OPEN, fmt, ##args)
63#define Err(A...) printk(KERN_ERR PWC_NAME " " A) 72#define PWC_DEBUG_READ(fmt, args...) PWC_DEBUG(READ, fmt, ##args)
73#define PWC_DEBUG_MEMORY(fmt, args...) PWC_DEBUG(MEMORY, fmt, ##args)
74#define PWC_DEBUG_FLOW(fmt, args...) PWC_DEBUG(FLOW, fmt, ##args)
75#define PWC_DEBUG_SIZE(fmt, args...) PWC_DEBUG(SIZE, fmt, ##args)
76#define PWC_DEBUG_IOCTL(fmt, args...) PWC_DEBUG(IOCTL, fmt, ##args)
77#define PWC_DEBUG_TRACE(fmt, args...) PWC_DEBUG(TRACE, fmt, ##args)
78
79
80#if CONFIG_PWC_DEBUG
81
82#define PWC_DEBUG_LEVEL (PWC_DEBUG_LEVEL_MODULE)
83
84#define PWC_DEBUG(level, fmt, args...) do {\
85 if ((PWC_DEBUG_LEVEL_ ##level) & pwc_trace) \
86 printk(KERN_DEBUG PFX fmt, ##args); \
87 } while(0)
88
89#define PWC_ERROR(fmt, args...) printk(KERN_ERR PFX fmt, ##args)
90#define PWC_WARNING(fmt, args...) printk(KERN_WARNING PFX fmt, ##args)
91#define PWC_INFO(fmt, args...) printk(KERN_INFO PFX fmt, ##args)
92#define PWC_TRACE(fmt, args...) PWC_DEBUG(TRACE, fmt, ##args)
93
94#else /* if ! CONFIG_PWC_DEBUG */
95
96#define PWC_ERROR(fmt, args...) printk(KERN_ERR PFX fmt, ##args)
97#define PWC_WARNING(fmt, args...) printk(KERN_WARNING PFX fmt, ##args)
98#define PWC_INFO(fmt, args...) printk(KERN_INFO PFX fmt, ##args)
99#define PWC_TRACE(fmt, args...) do { } while(0)
100#define PWC_DEBUG(level, fmt, args...) do { } while(0)
101
102#define pwc_trace 0
64 103
104#endif
65 105
66/* Defines for ToUCam cameras */ 106/* Defines for ToUCam cameras */
67#define TOUCAM_HEADER_SIZE 8 107#define TOUCAM_HEADER_SIZE 8
68#define TOUCAM_TRAILER_SIZE 4 108#define TOUCAM_TRAILER_SIZE 4
69 109
70#define FEATURE_MOTOR_PANTILT 0x0001 110#define FEATURE_MOTOR_PANTILT 0x0001
71 111#define FEATURE_CODEC1 0x0002
72/* Version block */ 112#define FEATURE_CODEC2 0x0004
73#define PWC_MAJOR 9
74#define PWC_MINOR 0
75#define PWC_VERSION "9.0.2-unofficial"
76#define PWC_NAME "pwc"
77 113
78/* Turn certain features on/off */ 114/* Turn certain features on/off */
79#define PWC_INT_PIPE 0 115#define PWC_INT_PIPE 0
@@ -95,6 +131,18 @@
95/* Absolute maximum number of buffers available for mmap() */ 131/* Absolute maximum number of buffers available for mmap() */
96#define MAX_IMAGES 10 132#define MAX_IMAGES 10
97 133
134/* Some macros to quickly find the type of a webcam */
135#define DEVICE_USE_CODEC1(x) ((x)<675)
136#define DEVICE_USE_CODEC2(x) ((x)>=675 && (x)<700)
137#define DEVICE_USE_CODEC3(x) ((x)>=700)
138#define DEVICE_USE_CODEC23(x) ((x)>=675)
139
140
141#ifndef V4L2_PIX_FMT_PWC1
142#define V4L2_PIX_FMT_PWC1 v4l2_fourcc('P','W','C','1')
143#define V4L2_PIX_FMT_PWC2 v4l2_fourcc('P','W','C','2')
144#endif
145
98/* The following structures were based on cpia.h. Why reinvent the wheel? :-) */ 146/* The following structures were based on cpia.h. Why reinvent the wheel? :-) */
99struct pwc_iso_buf 147struct pwc_iso_buf
100{ 148{
@@ -110,17 +158,19 @@ struct pwc_frame_buf
110 void *data; 158 void *data;
111 volatile int filled; /* number of bytes filled */ 159 volatile int filled; /* number of bytes filled */
112 struct pwc_frame_buf *next; /* list */ 160 struct pwc_frame_buf *next; /* list */
113#if PWC_DEBUG 161};
114 int sequence; /* Sequence number */ 162
115#endif 163/* additionnal informations used when dealing image between kernel and userland */
164struct pwc_imgbuf
165{
166 unsigned long offset; /* offset of this buffer in the big array of image_data */
167 int vma_use_count; /* count the number of time this memory is mapped */
116}; 168};
117 169
118struct pwc_device 170struct pwc_device
119{ 171{
120 struct video_device *vdev; 172 struct video_device *vdev;
121#ifdef PWC_MAGIC 173
122 int magic;
123#endif
124 /* Pointer to our usb_device */ 174 /* Pointer to our usb_device */
125 struct usb_device *udev; 175 struct usb_device *udev;
126 176
@@ -177,12 +227,8 @@ struct pwc_device
177 int frame_size; 227 int frame_size;
178 int frame_total_size; /* including header & trailer */ 228 int frame_total_size; /* including header & trailer */
179 int drop_frames; 229 int drop_frames;
180#if PWC_DEBUG
181 int sequence; /* Debugging aid */
182#endif
183 230
184 /* 3: decompression */ 231 /* 3: decompression */
185 struct pwc_decompressor *decompressor; /* function block with decompression routines */
186 void *decompress_data; /* private data for decompression engine */ 232 void *decompress_data; /* private data for decompression engine */
187 233
188 /* 4: image */ 234 /* 4: image */
@@ -198,7 +244,7 @@ struct pwc_device
198 struct pwc_coord offset; /* offset within the viewport */ 244 struct pwc_coord offset; /* offset within the viewport */
199 245
200 void *image_data; /* total buffer, which is subdivided into ... */ 246 void *image_data; /* total buffer, which is subdivided into ... */
201 void *image_ptr[MAX_IMAGES]; /* ...several images... */ 247 struct pwc_imgbuf images[MAX_IMAGES];/* ...several images... */
202 int fill_image; /* ...which are rotated. */ 248 int fill_image; /* ...which are rotated. */
203 int len_per_image; /* length per image */ 249 int len_per_image; /* length per image */
204 int image_read_pos; /* In case we read data in pieces, keep track of were we are in the imagebuffer */ 250 int image_read_pos; /* In case we read data in pieces, keep track of were we are in the imagebuffer */
@@ -211,6 +257,7 @@ struct pwc_device
211 struct pwc_mpt_range angle_range; 257 struct pwc_mpt_range angle_range;
212 int pan_angle; /* in degrees * 100 */ 258 int pan_angle; /* in degrees * 100 */
213 int tilt_angle; /* absolute angle; 0,0 is home position */ 259 int tilt_angle; /* absolute angle; 0,0 is home position */
260 int snapshot_button_status; /* set to 1 when the user push the button, reset to 0 when this value is read */
214 261
215 /*** Misc. data ***/ 262 /*** Misc. data ***/
216 wait_queue_head_t frameq; /* When waiting for a frame to finish... */ 263 wait_queue_head_t frameq; /* When waiting for a frame to finish... */
@@ -219,20 +266,26 @@ struct pwc_device
219#endif 266#endif
220}; 267};
221 268
222
223#ifdef __cplusplus 269#ifdef __cplusplus
224extern "C" { 270extern "C" {
225#endif 271#endif
226 272
227/* Global variable */ 273/* Global variables */
274#if CONFIG_PWC_DEBUG
228extern int pwc_trace; 275extern int pwc_trace;
276#endif
277extern int pwc_mbufs;
229 278
230/** functions in pwc-if.c */ 279/** functions in pwc-if.c */
231int pwc_try_video_mode(struct pwc_device *pdev, int width, int height, int new_fps, int new_compression, int new_snapshot); 280int pwc_try_video_mode(struct pwc_device *pdev, int width, int height, int new_fps, int new_compression, int new_snapshot);
281int pwc_handle_frame(struct pwc_device *pdev);
282void pwc_next_image(struct pwc_device *pdev);
283int pwc_isoc_init(struct pwc_device *pdev);
284void pwc_isoc_cleanup(struct pwc_device *pdev);
232 285
233/** Functions in pwc-misc.c */ 286/** Functions in pwc-misc.c */
234/* sizes in pixels */ 287/* sizes in pixels */
235extern struct pwc_coord pwc_image_sizes[PSZ_MAX]; 288extern const struct pwc_coord pwc_image_sizes[PSZ_MAX];
236 289
237int pwc_decode_size(struct pwc_device *pdev, int width, int height); 290int pwc_decode_size(struct pwc_device *pdev, int width, int height);
238void pwc_construct(struct pwc_device *pdev); 291void pwc_construct(struct pwc_device *pdev);
@@ -240,6 +293,9 @@ void pwc_construct(struct pwc_device *pdev);
240/** Functions in pwc-ctrl.c */ 293/** Functions in pwc-ctrl.c */
241/* Request a certain video mode. Returns < 0 if not possible */ 294/* Request a certain video mode. Returns < 0 if not possible */
242extern int pwc_set_video_mode(struct pwc_device *pdev, int width, int height, int frames, int compression, int snapshot); 295extern int pwc_set_video_mode(struct pwc_device *pdev, int width, int height, int frames, int compression, int snapshot);
296/* Calculate the number of bytes per image (not frame) */
297extern int pwc_mpt_reset(struct pwc_device *pdev, int flags);
298extern int pwc_mpt_set_angle(struct pwc_device *pdev, int pan, int tilt);
243 299
244/* Various controls; should be obvious. Value 0..65535, or < 0 on error */ 300/* Various controls; should be obvious. Value 0..65535, or < 0 on error */
245extern int pwc_get_brightness(struct pwc_device *pdev); 301extern int pwc_get_brightness(struct pwc_device *pdev);
@@ -248,10 +304,36 @@ extern int pwc_get_contrast(struct pwc_device *pdev);
248extern int pwc_set_contrast(struct pwc_device *pdev, int value); 304extern int pwc_set_contrast(struct pwc_device *pdev, int value);
249extern int pwc_get_gamma(struct pwc_device *pdev); 305extern int pwc_get_gamma(struct pwc_device *pdev);
250extern int pwc_set_gamma(struct pwc_device *pdev, int value); 306extern int pwc_set_gamma(struct pwc_device *pdev, int value);
251extern int pwc_get_saturation(struct pwc_device *pdev); 307extern int pwc_get_saturation(struct pwc_device *pdev, int *value);
252extern int pwc_set_saturation(struct pwc_device *pdev, int value); 308extern int pwc_set_saturation(struct pwc_device *pdev, int value);
253extern int pwc_set_leds(struct pwc_device *pdev, int on_value, int off_value); 309extern int pwc_set_leds(struct pwc_device *pdev, int on_value, int off_value);
254extern int pwc_get_cmos_sensor(struct pwc_device *pdev, int *sensor); 310extern int pwc_get_cmos_sensor(struct pwc_device *pdev, int *sensor);
311extern int pwc_restore_user(struct pwc_device *pdev);
312extern int pwc_save_user(struct pwc_device *pdev);
313extern int pwc_restore_factory(struct pwc_device *pdev);
314
315/* exported for use by v4l2 controls */
316extern int pwc_get_red_gain(struct pwc_device *pdev, int *value);
317extern int pwc_set_red_gain(struct pwc_device *pdev, int value);
318extern int pwc_get_blue_gain(struct pwc_device *pdev, int *value);
319extern int pwc_set_blue_gain(struct pwc_device *pdev, int value);
320extern int pwc_get_awb(struct pwc_device *pdev);
321extern int pwc_set_awb(struct pwc_device *pdev, int mode);
322extern int pwc_set_agc(struct pwc_device *pdev, int mode, int value);
323extern int pwc_get_agc(struct pwc_device *pdev, int *value);
324extern int pwc_set_shutter_speed(struct pwc_device *pdev, int mode, int value);
325extern int pwc_get_shutter_speed(struct pwc_device *pdev, int *value);
326
327extern int pwc_set_colour_mode(struct pwc_device *pdev, int colour);
328extern int pwc_get_colour_mode(struct pwc_device *pdev, int *colour);
329extern int pwc_set_contour(struct pwc_device *pdev, int contour);
330extern int pwc_get_contour(struct pwc_device *pdev, int *contour);
331extern int pwc_set_backlight(struct pwc_device *pdev, int backlight);
332extern int pwc_get_backlight(struct pwc_device *pdev, int *backlight);
333extern int pwc_set_flicker(struct pwc_device *pdev, int flicker);
334extern int pwc_get_flicker(struct pwc_device *pdev, int *flicker);
335extern int pwc_set_dynamic_noise(struct pwc_device *pdev, int noise);
336extern int pwc_get_dynamic_noise(struct pwc_device *pdev, int *noise);
255 337
256/* Power down or up the camera; not supported by all models */ 338/* Power down or up the camera; not supported by all models */
257extern int pwc_camera_power(struct pwc_device *pdev, int power); 339extern int pwc_camera_power(struct pwc_device *pdev, int power);
@@ -259,6 +341,9 @@ extern int pwc_camera_power(struct pwc_device *pdev, int power);
259/* Private ioctl()s; see pwc-ioctl.h */ 341/* Private ioctl()s; see pwc-ioctl.h */
260extern int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg); 342extern int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg);
261 343
344/** Functions in pwc-v4l.c */
345extern int pwc_video_do_ioctl(struct inode *inode, struct file *file,
346 unsigned int cmd, void *arg);
262 347
263/** pwc-uncompress.c */ 348/** pwc-uncompress.c */
264/* Expand frame to image, possibly including decompression. Uses read_frame and fill_image */ 349/* Expand frame to image, possibly including decompression. Uses read_frame and fill_image */
@@ -270,3 +355,4 @@ extern int pwc_decompress(struct pwc_device *pdev);
270 355
271 356
272#endif 357#endif
358/* vim: set cino= formatoptions=croql cindent shiftwidth=8 tabstop=8: */
diff --git a/drivers/media/video/saa5246a.c b/drivers/media/video/saa5246a.c
index dd830e0e5e9..59a187272c8 100644
--- a/drivers/media/video/saa5246a.c
+++ b/drivers/media/video/saa5246a.c
@@ -46,6 +46,7 @@
46#include <linux/i2c.h> 46#include <linux/i2c.h>
47#include <linux/videotext.h> 47#include <linux/videotext.h>
48#include <linux/videodev.h> 48#include <linux/videodev.h>
49#include <media/v4l2-common.h>
49#include <linux/mutex.h> 50#include <linux/mutex.h>
50 51
51#include "saa5246a.h" 52#include "saa5246a.h"
diff --git a/drivers/media/video/saa5249.c b/drivers/media/video/saa5249.c
index 531e9461cb6..19a8d65699f 100644
--- a/drivers/media/video/saa5249.c
+++ b/drivers/media/video/saa5249.c
@@ -56,6 +56,7 @@
56#include <linux/i2c.h> 56#include <linux/i2c.h>
57#include <linux/videotext.h> 57#include <linux/videotext.h>
58#include <linux/videodev.h> 58#include <linux/videodev.h>
59#include <media/v4l2-common.h>
59#include <linux/mutex.h> 60#include <linux/mutex.h>
60 61
61 62
diff --git a/drivers/media/video/saa7110.c b/drivers/media/video/saa7110.c
index 41d951db6ec..676b9970eb2 100644
--- a/drivers/media/video/saa7110.c
+++ b/drivers/media/video/saa7110.c
@@ -43,6 +43,7 @@ MODULE_LICENSE("GPL");
43#define I2C_NAME(s) (s)->name 43#define I2C_NAME(s) (s)->name
44 44
45#include <linux/videodev.h> 45#include <linux/videodev.h>
46#include <media/v4l2-common.h>
46#include <linux/video_decoder.h> 47#include <linux/video_decoder.h>
47 48
48static int debug = 0; 49static int debug = 0;
diff --git a/drivers/media/video/saa7115.c b/drivers/media/video/saa7115.c
index dceebc0b125..b59c1171727 100644
--- a/drivers/media/video/saa7115.c
+++ b/drivers/media/video/saa7115.c
@@ -72,6 +72,10 @@ struct saa7115_state {
72 int sat; 72 int sat;
73 enum v4l2_chip_ident ident; 73 enum v4l2_chip_ident ident;
74 u32 audclk_freq; 74 u32 audclk_freq;
75 u32 crystal_freq;
76 u8 ucgc;
77 u8 cgcdiv;
78 u8 apll;
75}; 79};
76 80
77/* ----------------------------------------------------------------------- */ 81/* ----------------------------------------------------------------------- */
@@ -375,10 +379,6 @@ static const unsigned char saa7113_init_auto_input[] = {
375}; 379};
376 380
377static const unsigned char saa7115_init_misc[] = { 381static const unsigned char saa7115_init_misc[] = {
378 0x38, 0x03, /* audio stuff */
379 0x39, 0x10,
380 0x3a, 0x08,
381
382 0x81, 0x01, /* reg 0x15,0x16 define blanking window */ 382 0x81, 0x01, /* reg 0x15,0x16 define blanking window */
383 0x82, 0x00, 383 0x82, 0x00,
384 0x83, 0x01, /* I port settings */ 384 0x83, 0x01, /* I port settings */
@@ -584,6 +584,7 @@ static int saa7115_set_audio_clock_freq(struct i2c_client *client, u32 freq)
584 u32 acni; 584 u32 acni;
585 u32 hz; 585 u32 hz;
586 u64 f; 586 u64 f;
587 u8 acc = 0; /* reg 0x3a, audio clock control */
587 588
588 v4l_dbg(1, debug, client, "set audio clock freq: %d\n", freq); 589 v4l_dbg(1, debug, client, "set audio clock freq: %d\n", freq);
589 590
@@ -591,18 +592,34 @@ static int saa7115_set_audio_clock_freq(struct i2c_client *client, u32 freq)
591 if (freq < 32000 || freq > 48000) 592 if (freq < 32000 || freq > 48000)
592 return -EINVAL; 593 return -EINVAL;
593 594
595 /* The saa7113 has no audio clock */
596 if (state->ident == V4L2_IDENT_SAA7113)
597 return 0;
598
594 /* hz is the refresh rate times 100 */ 599 /* hz is the refresh rate times 100 */
595 hz = (state->std & V4L2_STD_525_60) ? 5994 : 5000; 600 hz = (state->std & V4L2_STD_525_60) ? 5994 : 5000;
596 /* acpf = (256 * freq) / field_frequency == (256 * 100 * freq) / hz */ 601 /* acpf = (256 * freq) / field_frequency == (256 * 100 * freq) / hz */
597 acpf = (25600 * freq) / hz; 602 acpf = (25600 * freq) / hz;
598 /* acni = (256 * freq * 2^23) / crystal_frequency = 603 /* acni = (256 * freq * 2^23) / crystal_frequency =
599 (freq * 2^(8+23)) / crystal_frequency = 604 (freq * 2^(8+23)) / crystal_frequency =
600 (freq << 31) / 32.11 MHz */ 605 (freq << 31) / crystal_frequency */
601 f = freq; 606 f = freq;
602 f = f << 31; 607 f = f << 31;
603 do_div(f, 32110000); 608 do_div(f, state->crystal_freq);
604 acni = f; 609 acni = f;
610 if (state->ucgc) {
611 acpf = acpf * state->cgcdiv / 16;
612 acni = acni * state->cgcdiv / 16;
613 acc = 0x80;
614 if (state->cgcdiv == 3)
615 acc |= 0x40;
616 }
617 if (state->apll)
618 acc |= 0x08;
605 619
620 saa7115_write(client, 0x38, 0x03);
621 saa7115_write(client, 0x39, 0x10);
622 saa7115_write(client, 0x3a, acc);
606 saa7115_write(client, 0x30, acpf & 0xff); 623 saa7115_write(client, 0x30, acpf & 0xff);
607 saa7115_write(client, 0x31, (acpf >> 8) & 0xff); 624 saa7115_write(client, 0x31, (acpf >> 8) & 0xff);
608 saa7115_write(client, 0x32, (acpf >> 16) & 0x03); 625 saa7115_write(client, 0x32, (acpf >> 16) & 0x03);
@@ -1073,48 +1090,6 @@ static void saa7115_decode_vbi_line(struct i2c_client *client,
1073 1090
1074/* ============ SAA7115 AUDIO settings (end) ============= */ 1091/* ============ SAA7115 AUDIO settings (end) ============= */
1075 1092
1076static struct v4l2_queryctrl saa7115_qctrl[] = {
1077 {
1078 .id = V4L2_CID_BRIGHTNESS,
1079 .type = V4L2_CTRL_TYPE_INTEGER,
1080 .name = "Brightness",
1081 .minimum = 0,
1082 .maximum = 255,
1083 .step = 1,
1084 .default_value = 128,
1085 .flags = 0,
1086 }, {
1087 .id = V4L2_CID_CONTRAST,
1088 .type = V4L2_CTRL_TYPE_INTEGER,
1089 .name = "Contrast",
1090 .minimum = 0,
1091 .maximum = 127,
1092 .step = 1,
1093 .default_value = 64,
1094 .flags = 0,
1095 }, {
1096 .id = V4L2_CID_SATURATION,
1097 .type = V4L2_CTRL_TYPE_INTEGER,
1098 .name = "Saturation",
1099 .minimum = 0,
1100 .maximum = 127,
1101 .step = 1,
1102 .default_value = 64,
1103 .flags = 0,
1104 }, {
1105 .id = V4L2_CID_HUE,
1106 .type = V4L2_CTRL_TYPE_INTEGER,
1107 .name = "Hue",
1108 .minimum = -128,
1109 .maximum = 127,
1110 .step = 1,
1111 .default_value = 0,
1112 .flags = 0,
1113 },
1114};
1115
1116/* ----------------------------------------------------------------------- */
1117
1118static int saa7115_command(struct i2c_client *client, unsigned int cmd, void *arg) 1093static int saa7115_command(struct i2c_client *client, unsigned int cmd, void *arg)
1119{ 1094{
1120 struct saa7115_state *state = i2c_get_clientdata(client); 1095 struct saa7115_state *state = i2c_get_clientdata(client);
@@ -1158,14 +1133,16 @@ static int saa7115_command(struct i2c_client *client, unsigned int cmd, void *ar
1158 case VIDIOC_QUERYCTRL: 1133 case VIDIOC_QUERYCTRL:
1159 { 1134 {
1160 struct v4l2_queryctrl *qc = arg; 1135 struct v4l2_queryctrl *qc = arg;
1161 int i;
1162 1136
1163 for (i = 0; i < ARRAY_SIZE(saa7115_qctrl); i++) 1137 switch (qc->id) {
1164 if (qc->id && qc->id == saa7115_qctrl[i].id) { 1138 case V4L2_CID_BRIGHTNESS:
1165 memcpy(qc, &saa7115_qctrl[i], sizeof(*qc)); 1139 case V4L2_CID_CONTRAST:
1166 return 0; 1140 case V4L2_CID_SATURATION:
1167 } 1141 case V4L2_CID_HUE:
1168 return -EINVAL; 1142 return v4l2_ctrl_query_fill_std(qc);
1143 default:
1144 return -EINVAL;
1145 }
1169 } 1146 }
1170 1147
1171 case VIDIOC_G_STD: 1148 case VIDIOC_G_STD:
@@ -1221,34 +1198,6 @@ static int saa7115_command(struct i2c_client *client, unsigned int cmd, void *ar
1221 break; 1198 break;
1222 } 1199 }
1223 1200
1224 case VIDIOC_G_INPUT:
1225 *(int *)arg = state->input;
1226 break;
1227
1228 case VIDIOC_S_INPUT:
1229 v4l_dbg(1, debug, client, "decoder set input %d\n", *iarg);
1230 /* inputs from 0-9 are available */
1231 if (*iarg < 0 || *iarg > 9) {
1232 return -EINVAL;
1233 }
1234
1235 if (state->input == *iarg)
1236 break;
1237 v4l_dbg(1, debug, client, "now setting %s input\n",
1238 *iarg >= 6 ? "S-Video" : "Composite");
1239 state->input = *iarg;
1240
1241 /* select mode */
1242 saa7115_write(client, 0x02,
1243 (saa7115_read(client, 0x02) & 0xf0) |
1244 state->input);
1245
1246 /* bypass chrominance trap for modes 6..9 */
1247 saa7115_write(client, 0x09,
1248 (saa7115_read(client, 0x09) & 0x7f) |
1249 (state->input < 6 ? 0x0 : 0x80));
1250 break;
1251
1252 case VIDIOC_STREAMON: 1201 case VIDIOC_STREAMON:
1253 case VIDIOC_STREAMOFF: 1202 case VIDIOC_STREAMOFF:
1254 v4l_dbg(1, debug, client, "%s output\n", 1203 v4l_dbg(1, debug, client, "%s output\n",
@@ -1260,6 +1209,21 @@ static int saa7115_command(struct i2c_client *client, unsigned int cmd, void *ar
1260 } 1209 }
1261 break; 1210 break;
1262 1211
1212 case VIDIOC_INT_S_CRYSTAL_FREQ:
1213 {
1214 struct v4l2_crystal_freq *freq = arg;
1215
1216 if (freq->freq != SAA7115_FREQ_32_11_MHZ &&
1217 freq->freq != SAA7115_FREQ_24_576_MHZ)
1218 return -EINVAL;
1219 state->crystal_freq = freq->freq;
1220 state->cgcdiv = (freq->flags & SAA7115_FREQ_FL_CGCDIV) ? 3 : 4;
1221 state->ucgc = (freq->flags & SAA7115_FREQ_FL_UCGC) ? 1 : 0;
1222 state->apll = (freq->flags & SAA7115_FREQ_FL_APLL) ? 1 : 0;
1223 saa7115_set_audio_clock_freq(client, state->audclk_freq);
1224 break;
1225 }
1226
1263 case VIDIOC_INT_DECODE_VBI_LINE: 1227 case VIDIOC_INT_DECODE_VBI_LINE:
1264 saa7115_decode_vbi_line(client, arg); 1228 saa7115_decode_vbi_line(client, arg);
1265 break; 1229 break;
@@ -1401,10 +1365,13 @@ static int saa7115_attach(struct i2c_adapter *adapter, int address, int kind)
1401 v4l_dbg(1, debug, client, "writing init values\n"); 1365 v4l_dbg(1, debug, client, "writing init values\n");
1402 1366
1403 /* init to 60hz/48khz */ 1367 /* init to 60hz/48khz */
1404 if (state->ident == V4L2_IDENT_SAA7113) 1368 if (state->ident == V4L2_IDENT_SAA7113) {
1369 state->crystal_freq = SAA7115_FREQ_24_576_MHZ;
1405 saa7115_writeregs(client, saa7113_init_auto_input); 1370 saa7115_writeregs(client, saa7113_init_auto_input);
1406 else 1371 } else {
1372 state->crystal_freq = SAA7115_FREQ_32_11_MHZ;
1407 saa7115_writeregs(client, saa7115_init_auto_input); 1373 saa7115_writeregs(client, saa7115_init_auto_input);
1374 }
1408 saa7115_writeregs(client, saa7115_init_misc); 1375 saa7115_writeregs(client, saa7115_init_misc);
1409 saa7115_writeregs(client, saa7115_cfg_60hz_fullres_x); 1376 saa7115_writeregs(client, saa7115_cfg_60hz_fullres_x);
1410 saa7115_writeregs(client, saa7115_cfg_60hz_fullres_y); 1377 saa7115_writeregs(client, saa7115_cfg_60hz_fullres_y);
diff --git a/drivers/media/video/saa7127.c b/drivers/media/video/saa7127.c
index c271e2e1410..ad401bdefea 100644
--- a/drivers/media/video/saa7127.c
+++ b/drivers/media/video/saa7127.c
@@ -270,7 +270,7 @@ static const char * const wss_strs[] = {
270 "letterbox 16:9 top", 270 "letterbox 16:9 top",
271 "invalid", 271 "invalid",
272 "invalid", 272 "invalid",
273 "16:9 full format anamorphic" 273 "16:9 full format anamorphic",
274 "4:3 full format", 274 "4:3 full format",
275 "invalid", 275 "invalid",
276 "invalid", 276 "invalid",
diff --git a/drivers/media/video/saa7134/saa6752hs.c b/drivers/media/video/saa7134/saa6752hs.c
index 0e0ba50946e..de7b9e6e932 100644
--- a/drivers/media/video/saa7134/saa6752hs.c
+++ b/drivers/media/video/saa7134/saa6752hs.c
@@ -39,6 +39,23 @@ enum saa6752hs_videoformat {
39 SAA6752HS_VF_UNKNOWN, 39 SAA6752HS_VF_UNKNOWN,
40}; 40};
41 41
42struct saa6752hs_mpeg_params {
43 /* transport streams */
44 __u16 ts_pid_pmt;
45 __u16 ts_pid_audio;
46 __u16 ts_pid_video;
47 __u16 ts_pid_pcr;
48
49 /* audio */
50 enum v4l2_mpeg_audio_l2_bitrate au_l2_bitrate;
51
52 /* video */
53 enum v4l2_mpeg_video_aspect vi_aspect;
54 enum v4l2_mpeg_video_bitrate_mode vi_bitrate_mode;
55 __u32 vi_bitrate;
56 __u32 vi_bitrate_peak;
57};
58
42static const struct v4l2_format v4l2_format_table[] = 59static const struct v4l2_format v4l2_format_table[] =
43{ 60{
44 [SAA6752HS_VF_D1] = 61 [SAA6752HS_VF_D1] =
@@ -55,18 +72,19 @@ static const struct v4l2_format v4l2_format_table[] =
55 72
56struct saa6752hs_state { 73struct saa6752hs_state {
57 struct i2c_client client; 74 struct i2c_client client;
58 struct v4l2_mpeg_compression params; 75 struct v4l2_mpeg_compression old_params;
76 struct saa6752hs_mpeg_params params;
59 enum saa6752hs_videoformat video_format; 77 enum saa6752hs_videoformat video_format;
60 v4l2_std_id standard; 78 v4l2_std_id standard;
61}; 79};
62 80
63enum saa6752hs_command { 81enum saa6752hs_command {
64 SAA6752HS_COMMAND_RESET = 0, 82 SAA6752HS_COMMAND_RESET = 0,
65 SAA6752HS_COMMAND_STOP = 1, 83 SAA6752HS_COMMAND_STOP = 1,
66 SAA6752HS_COMMAND_START = 2, 84 SAA6752HS_COMMAND_START = 2,
67 SAA6752HS_COMMAND_PAUSE = 3, 85 SAA6752HS_COMMAND_PAUSE = 3,
68 SAA6752HS_COMMAND_RECONFIGURE = 4, 86 SAA6752HS_COMMAND_RECONFIGURE = 4,
69 SAA6752HS_COMMAND_SLEEP = 5, 87 SAA6752HS_COMMAND_SLEEP = 5,
70 SAA6752HS_COMMAND_RECONFIGURE_FORCE = 6, 88 SAA6752HS_COMMAND_RECONFIGURE_FORCE = 6,
71 89
72 SAA6752HS_COMMAND_MAX 90 SAA6752HS_COMMAND_MAX
@@ -129,7 +147,22 @@ static u8 PMT[] = {
129 0x00, 0x00, 0x00, 0x00 /* CRC32 */ 147 0x00, 0x00, 0x00, 0x00 /* CRC32 */
130}; 148};
131 149
132static struct v4l2_mpeg_compression param_defaults = 150static struct saa6752hs_mpeg_params param_defaults =
151{
152 .ts_pid_pmt = 16,
153 .ts_pid_video = 260,
154 .ts_pid_audio = 256,
155 .ts_pid_pcr = 259,
156
157 .vi_aspect = V4L2_MPEG_VIDEO_ASPECT_4x3,
158 .vi_bitrate = 4000,
159 .vi_bitrate_peak = 6000,
160 .vi_bitrate_mode = V4L2_MPEG_VIDEO_BITRATE_MODE_VBR,
161
162 .au_l2_bitrate = V4L2_MPEG_AUDIO_L2_BITRATE_256K,
163};
164
165static struct v4l2_mpeg_compression old_param_defaults =
133{ 166{
134 .st_type = V4L2_MPEG_TS_2, 167 .st_type = V4L2_MPEG_TS_2,
135 .st_bitrate = { 168 .st_bitrate = {
@@ -228,45 +261,57 @@ static int saa6752hs_chip_command(struct i2c_client* client,
228 261
229 262
230static int saa6752hs_set_bitrate(struct i2c_client* client, 263static int saa6752hs_set_bitrate(struct i2c_client* client,
231 struct v4l2_mpeg_compression* params) 264 struct saa6752hs_mpeg_params* params)
232{ 265{
233 u8 buf[3]; 266 u8 buf[3];
267 int tot_bitrate;
234 268
235 /* set the bitrate mode */ 269 /* set the bitrate mode */
236 buf[0] = 0x71; 270 buf[0] = 0x71;
237 buf[1] = (params->vi_bitrate.mode == V4L2_BITRATE_VBR) ? 0 : 1; 271 buf[1] = (params->vi_bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR) ? 0 : 1;
238 i2c_master_send(client, buf, 2); 272 i2c_master_send(client, buf, 2);
239 273
240 /* set the video bitrate */ 274 /* set the video bitrate */
241 if (params->vi_bitrate.mode == V4L2_BITRATE_VBR) { 275 if (params->vi_bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR) {
242 /* set the target bitrate */ 276 /* set the target bitrate */
243 buf[0] = 0x80; 277 buf[0] = 0x80;
244 buf[1] = params->vi_bitrate.target >> 8; 278 buf[1] = params->vi_bitrate >> 8;
245 buf[2] = params->vi_bitrate.target & 0xff; 279 buf[2] = params->vi_bitrate & 0xff;
246 i2c_master_send(client, buf, 3); 280 i2c_master_send(client, buf, 3);
247 281
248 /* set the max bitrate */ 282 /* set the max bitrate */
249 buf[0] = 0x81; 283 buf[0] = 0x81;
250 buf[1] = params->vi_bitrate.max >> 8; 284 buf[1] = params->vi_bitrate_peak >> 8;
251 buf[2] = params->vi_bitrate.max & 0xff; 285 buf[2] = params->vi_bitrate_peak & 0xff;
252 i2c_master_send(client, buf, 3); 286 i2c_master_send(client, buf, 3);
287 tot_bitrate = params->vi_bitrate_peak;
253 } else { 288 } else {
254 /* set the target bitrate (no max bitrate for CBR) */ 289 /* set the target bitrate (no max bitrate for CBR) */
255 buf[0] = 0x81; 290 buf[0] = 0x81;
256 buf[1] = params->vi_bitrate.target >> 8; 291 buf[1] = params->vi_bitrate >> 8;
257 buf[2] = params->vi_bitrate.target & 0xff; 292 buf[2] = params->vi_bitrate & 0xff;
258 i2c_master_send(client, buf, 3); 293 i2c_master_send(client, buf, 3);
294 tot_bitrate = params->vi_bitrate;
259 } 295 }
260 296
261 /* set the audio bitrate */ 297 /* set the audio bitrate */
262 buf[0] = 0x94; 298 buf[0] = 0x94;
263 buf[1] = (256 == params->au_bitrate.target) ? 0 : 1; 299 buf[1] = (V4L2_MPEG_AUDIO_L2_BITRATE_256K == params->au_l2_bitrate) ? 0 : 1;
264 i2c_master_send(client, buf, 2); 300 i2c_master_send(client, buf, 2);
301 tot_bitrate += (V4L2_MPEG_AUDIO_L2_BITRATE_256K == params->au_l2_bitrate) ? 256 : 384;
302
303 /* Note: the total max bitrate is determined by adding the video and audio
304 bitrates together and also adding an extra 768kbit/s to stay on the
305 safe side. If more control should be required, then an extra MPEG control
306 should be added. */
307 tot_bitrate += 768;
308 if (tot_bitrate > MPEG_TOTAL_TARGET_BITRATE_MAX)
309 tot_bitrate = MPEG_TOTAL_TARGET_BITRATE_MAX;
265 310
266 /* set the total bitrate */ 311 /* set the total bitrate */
267 buf[0] = 0xb1; 312 buf[0] = 0xb1;
268 buf[1] = params->st_bitrate.target >> 8; 313 buf[1] = tot_bitrate >> 8;
269 buf[2] = params->st_bitrate.target & 0xff; 314 buf[2] = tot_bitrate & 0xff;
270 i2c_master_send(client, buf, 3); 315 i2c_master_send(client, buf, 3);
271 316
272 return 0; 317 return 0;
@@ -318,50 +363,188 @@ static void saa6752hs_set_subsampling(struct i2c_client* client,
318} 363}
319 364
320 365
321static void saa6752hs_set_params(struct i2c_client* client, 366static void saa6752hs_old_set_params(struct i2c_client* client,
322 struct v4l2_mpeg_compression* params) 367 struct v4l2_mpeg_compression* params)
323{ 368{
324 struct saa6752hs_state *h = i2c_get_clientdata(client); 369 struct saa6752hs_state *h = i2c_get_clientdata(client);
325 370
326 /* check PIDs */ 371 /* check PIDs */
327 if (params->ts_pid_pmt <= MPEG_PID_MAX) 372 if (params->ts_pid_pmt <= MPEG_PID_MAX) {
373 h->old_params.ts_pid_pmt = params->ts_pid_pmt;
328 h->params.ts_pid_pmt = params->ts_pid_pmt; 374 h->params.ts_pid_pmt = params->ts_pid_pmt;
329 if (params->ts_pid_pcr <= MPEG_PID_MAX) 375 }
376 if (params->ts_pid_pcr <= MPEG_PID_MAX) {
377 h->old_params.ts_pid_pcr = params->ts_pid_pcr;
330 h->params.ts_pid_pcr = params->ts_pid_pcr; 378 h->params.ts_pid_pcr = params->ts_pid_pcr;
331 if (params->ts_pid_video <= MPEG_PID_MAX) 379 }
380 if (params->ts_pid_video <= MPEG_PID_MAX) {
381 h->old_params.ts_pid_video = params->ts_pid_video;
332 h->params.ts_pid_video = params->ts_pid_video; 382 h->params.ts_pid_video = params->ts_pid_video;
333 if (params->ts_pid_audio <= MPEG_PID_MAX) 383 }
384 if (params->ts_pid_audio <= MPEG_PID_MAX) {
385 h->old_params.ts_pid_audio = params->ts_pid_audio;
334 h->params.ts_pid_audio = params->ts_pid_audio; 386 h->params.ts_pid_audio = params->ts_pid_audio;
387 }
335 388
336 /* check bitrate parameters */ 389 /* check bitrate parameters */
337 if ((params->vi_bitrate.mode == V4L2_BITRATE_CBR) || 390 if ((params->vi_bitrate.mode == V4L2_BITRATE_CBR) ||
338 (params->vi_bitrate.mode == V4L2_BITRATE_VBR)) 391 (params->vi_bitrate.mode == V4L2_BITRATE_VBR)) {
339 h->params.vi_bitrate.mode = params->vi_bitrate.mode; 392 h->old_params.vi_bitrate.mode = params->vi_bitrate.mode;
393 h->params.vi_bitrate_mode = (params->vi_bitrate.mode == V4L2_BITRATE_VBR) ?
394 V4L2_MPEG_VIDEO_BITRATE_MODE_VBR : V4L2_MPEG_VIDEO_BITRATE_MODE_CBR;
395 }
340 if (params->vi_bitrate.mode != V4L2_BITRATE_NONE) 396 if (params->vi_bitrate.mode != V4L2_BITRATE_NONE)
341 h->params.st_bitrate.target = params->st_bitrate.target; 397 h->old_params.st_bitrate.target = params->st_bitrate.target;
342 if (params->vi_bitrate.mode != V4L2_BITRATE_NONE) 398 if (params->vi_bitrate.mode != V4L2_BITRATE_NONE)
343 h->params.vi_bitrate.target = params->vi_bitrate.target; 399 h->old_params.vi_bitrate.target = params->vi_bitrate.target;
344 if (params->vi_bitrate.mode == V4L2_BITRATE_VBR) 400 if (params->vi_bitrate.mode == V4L2_BITRATE_VBR)
345 h->params.vi_bitrate.max = params->vi_bitrate.max; 401 h->old_params.vi_bitrate.max = params->vi_bitrate.max;
346 if (params->au_bitrate.mode != V4L2_BITRATE_NONE) 402 if (params->au_bitrate.mode != V4L2_BITRATE_NONE)
347 h->params.au_bitrate.target = params->au_bitrate.target; 403 h->old_params.au_bitrate.target = params->au_bitrate.target;
348 404
349 /* aspect ratio */ 405 /* aspect ratio */
350 if (params->vi_aspect_ratio == V4L2_MPEG_ASPECT_4_3 || 406 if (params->vi_aspect_ratio == V4L2_MPEG_ASPECT_4_3 ||
351 params->vi_aspect_ratio == V4L2_MPEG_ASPECT_16_9) 407 params->vi_aspect_ratio == V4L2_MPEG_ASPECT_16_9) {
352 h->params.vi_aspect_ratio = params->vi_aspect_ratio; 408 h->old_params.vi_aspect_ratio = params->vi_aspect_ratio;
409 if (params->vi_aspect_ratio == V4L2_MPEG_ASPECT_4_3)
410 h->params.vi_aspect = V4L2_MPEG_VIDEO_ASPECT_4x3;
411 else
412 h->params.vi_aspect = V4L2_MPEG_VIDEO_ASPECT_16x9;
413 }
353 414
354 /* range checks */ 415 /* range checks */
355 if (h->params.st_bitrate.target > MPEG_TOTAL_TARGET_BITRATE_MAX) 416 if (h->old_params.st_bitrate.target > MPEG_TOTAL_TARGET_BITRATE_MAX)
356 h->params.st_bitrate.target = MPEG_TOTAL_TARGET_BITRATE_MAX; 417 h->old_params.st_bitrate.target = MPEG_TOTAL_TARGET_BITRATE_MAX;
357 if (h->params.vi_bitrate.target > MPEG_VIDEO_TARGET_BITRATE_MAX) 418 if (h->old_params.vi_bitrate.target > MPEG_VIDEO_TARGET_BITRATE_MAX)
358 h->params.vi_bitrate.target = MPEG_VIDEO_TARGET_BITRATE_MAX; 419 h->old_params.vi_bitrate.target = MPEG_VIDEO_TARGET_BITRATE_MAX;
359 if (h->params.vi_bitrate.max > MPEG_VIDEO_MAX_BITRATE_MAX) 420 if (h->old_params.vi_bitrate.max > MPEG_VIDEO_MAX_BITRATE_MAX)
360 h->params.vi_bitrate.max = MPEG_VIDEO_MAX_BITRATE_MAX; 421 h->old_params.vi_bitrate.max = MPEG_VIDEO_MAX_BITRATE_MAX;
361 if (h->params.au_bitrate.target <= 256) 422 h->params.vi_bitrate = params->vi_bitrate.target;
362 h->params.au_bitrate.target = 256; 423 h->params.vi_bitrate_peak = params->vi_bitrate.max;
424 if (h->old_params.au_bitrate.target <= 256) {
425 h->old_params.au_bitrate.target = 256;
426 h->params.au_l2_bitrate = V4L2_MPEG_AUDIO_L2_BITRATE_256K;
427 }
428 else {
429 h->old_params.au_bitrate.target = 384;
430 h->params.au_l2_bitrate = V4L2_MPEG_AUDIO_L2_BITRATE_384K;
431 }
432}
433
434static int handle_ctrl(struct saa6752hs_mpeg_params *params,
435 struct v4l2_ext_control *ctrl, int cmd)
436{
437 int old = 0, new;
438 int set = cmd == VIDIOC_S_EXT_CTRLS;
439
440 new = ctrl->value;
441 switch (ctrl->id) {
442 case V4L2_CID_MPEG_STREAM_TYPE:
443 old = V4L2_MPEG_STREAM_TYPE_MPEG2_TS;
444 if (set && new != old)
445 return -ERANGE;
446 new = old;
447 break;
448 case V4L2_CID_MPEG_STREAM_PID_PMT:
449 old = params->ts_pid_pmt;
450 if (set && new > MPEG_PID_MAX)
451 return -ERANGE;
452 if (new > MPEG_PID_MAX)
453 new = MPEG_PID_MAX;
454 params->ts_pid_pmt = new;
455 break;
456 case V4L2_CID_MPEG_STREAM_PID_AUDIO:
457 old = params->ts_pid_audio;
458 if (set && new > MPEG_PID_MAX)
459 return -ERANGE;
460 if (new > MPEG_PID_MAX)
461 new = MPEG_PID_MAX;
462 params->ts_pid_audio = new;
463 break;
464 case V4L2_CID_MPEG_STREAM_PID_VIDEO:
465 old = params->ts_pid_video;
466 if (set && new > MPEG_PID_MAX)
467 return -ERANGE;
468 if (new > MPEG_PID_MAX)
469 new = MPEG_PID_MAX;
470 params->ts_pid_video = new;
471 break;
472 case V4L2_CID_MPEG_STREAM_PID_PCR:
473 old = params->ts_pid_pcr;
474 if (set && new > MPEG_PID_MAX)
475 return -ERANGE;
476 if (new > MPEG_PID_MAX)
477 new = MPEG_PID_MAX;
478 params->ts_pid_pcr = new;
479 break;
480 case V4L2_CID_MPEG_AUDIO_ENCODING:
481 old = V4L2_MPEG_AUDIO_ENCODING_LAYER_2;
482 if (set && new != old)
483 return -ERANGE;
484 new = old;
485 break;
486 case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
487 old = params->au_l2_bitrate;
488 if (set && new != V4L2_MPEG_AUDIO_L2_BITRATE_256K &&
489 new != V4L2_MPEG_AUDIO_L2_BITRATE_384K)
490 return -ERANGE;
491 if (new <= V4L2_MPEG_AUDIO_L2_BITRATE_256K)
492 new = V4L2_MPEG_AUDIO_L2_BITRATE_256K;
493 else
494 new = V4L2_MPEG_AUDIO_L2_BITRATE_384K;
495 params->au_l2_bitrate = new;
496 break;
497 case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ:
498 old = V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000;
499 if (set && new != old)
500 return -ERANGE;
501 new = old;
502 break;
503 case V4L2_CID_MPEG_VIDEO_ENCODING:
504 old = V4L2_MPEG_VIDEO_ENCODING_MPEG_2;
505 if (set && new != old)
506 return -ERANGE;
507 new = old;
508 break;
509 case V4L2_CID_MPEG_VIDEO_ASPECT:
510 old = params->vi_aspect;
511 if (set && new != V4L2_MPEG_VIDEO_ASPECT_16x9 &&
512 new != V4L2_MPEG_VIDEO_ASPECT_4x3)
513 return -ERANGE;
514 if (new != V4L2_MPEG_VIDEO_ASPECT_16x9)
515 new = V4L2_MPEG_VIDEO_ASPECT_4x3;
516 params->vi_aspect = new;
517 break;
518 case V4L2_CID_MPEG_VIDEO_BITRATE:
519 old = params->vi_bitrate * 1000;
520 new = 1000 * (new / 1000);
521 if (set && new > MPEG_VIDEO_TARGET_BITRATE_MAX * 1000)
522 return -ERANGE;
523 if (new > MPEG_VIDEO_TARGET_BITRATE_MAX * 1000)
524 new = MPEG_VIDEO_TARGET_BITRATE_MAX * 1000;
525 params->vi_bitrate = new / 1000;
526 break;
527 case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
528 old = params->vi_bitrate_peak * 1000;
529 new = 1000 * (new / 1000);
530 if (set && new > MPEG_VIDEO_TARGET_BITRATE_MAX * 1000)
531 return -ERANGE;
532 if (new > MPEG_VIDEO_TARGET_BITRATE_MAX * 1000)
533 new = MPEG_VIDEO_TARGET_BITRATE_MAX * 1000;
534 params->vi_bitrate_peak = new / 1000;
535 break;
536 case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
537 old = params->vi_bitrate_mode;
538 params->vi_bitrate_mode = new;
539 break;
540 default:
541 return -EINVAL;
542 }
543 if (cmd == VIDIOC_G_EXT_CTRLS)
544 ctrl->value = old;
363 else 545 else
364 h->params.au_bitrate.target = 384; 546 ctrl->value = new;
547 return 0;
365} 548}
366 549
367static int saa6752hs_init(struct i2c_client* client) 550static int saa6752hs_init(struct i2c_client* client)
@@ -395,22 +578,22 @@ static int saa6752hs_init(struct i2c_client* client)
395 buf[2] = 0x0D; 578 buf[2] = 0x0D;
396 i2c_master_send(client,buf,3); 579 i2c_master_send(client,buf,3);
397 580
398 /* Set minimum Q-scale {4} */ 581 /* Set minimum Q-scale {4} */
399 buf[0] = 0x82; 582 buf[0] = 0x82;
400 buf[1] = 0x04; 583 buf[1] = 0x04;
401 i2c_master_send(client,buf,2); 584 i2c_master_send(client,buf,2);
402 585
403 /* Set maximum Q-scale {12} */ 586 /* Set maximum Q-scale {12} */
404 buf[0] = 0x83; 587 buf[0] = 0x83;
405 buf[1] = 0x0C; 588 buf[1] = 0x0C;
406 i2c_master_send(client,buf,2); 589 i2c_master_send(client,buf,2);
407 590
408 /* Set Output Protocol */ 591 /* Set Output Protocol */
409 buf[0] = 0xD0; 592 buf[0] = 0xD0;
410 buf[1] = 0x81; 593 buf[1] = 0x81;
411 i2c_master_send(client,buf,2); 594 i2c_master_send(client,buf,2);
412 595
413 /* Set video output stream format {TS} */ 596 /* Set video output stream format {TS} */
414 buf[0] = 0xB0; 597 buf[0] = 0xB0;
415 buf[1] = 0x05; 598 buf[1] = 0x05;
416 i2c_master_send(client,buf,2); 599 i2c_master_send(client,buf,2);
@@ -441,7 +624,7 @@ static int saa6752hs_init(struct i2c_client* client)
441 localPMT[sizeof(PMT) - 2] = (crc >> 8) & 0xFF; 624 localPMT[sizeof(PMT) - 2] = (crc >> 8) & 0xFF;
442 localPMT[sizeof(PMT) - 1] = crc & 0xFF; 625 localPMT[sizeof(PMT) - 1] = crc & 0xFF;
443 626
444 /* Set Audio PID */ 627 /* Set Audio PID */
445 buf[0] = 0xC1; 628 buf[0] = 0xC1;
446 buf[1] = (h->params.ts_pid_audio >> 8) & 0xFF; 629 buf[1] = (h->params.ts_pid_audio >> 8) & 0xFF;
447 buf[2] = h->params.ts_pid_audio & 0xFF; 630 buf[2] = h->params.ts_pid_audio & 0xFF;
@@ -489,11 +672,11 @@ static int saa6752hs_init(struct i2c_client* client)
489 buf[3] = 0x82; 672 buf[3] = 0x82;
490 buf[4] = 0xB0; 673 buf[4] = 0xB0;
491 buf[5] = buf2[0]; 674 buf[5] = buf2[0];
492 switch(h->params.vi_aspect_ratio) { 675 switch(h->params.vi_aspect) {
493 case V4L2_MPEG_ASPECT_16_9: 676 case V4L2_MPEG_VIDEO_ASPECT_16x9:
494 buf[6] = buf2[1] | 0x40; 677 buf[6] = buf2[1] | 0x40;
495 break; 678 break;
496 case V4L2_MPEG_ASPECT_4_3: 679 case V4L2_MPEG_VIDEO_ASPECT_4x3:
497 default: 680 default:
498 buf[6] = buf2[1] & 0xBF; 681 buf[6] = buf2[1] & 0xBF;
499 break; 682 break;
@@ -515,6 +698,7 @@ static int saa6752hs_attach(struct i2c_adapter *adap, int addr, int kind)
515 return -ENOMEM; 698 return -ENOMEM;
516 h->client = client_template; 699 h->client = client_template;
517 h->params = param_defaults; 700 h->params = param_defaults;
701 h->old_params = old_param_defaults;
518 h->client.adapter = adap; 702 h->client.adapter = adap;
519 h->client.addr = addr; 703 h->client.addr = addr;
520 704
@@ -550,20 +734,45 @@ static int
550saa6752hs_command(struct i2c_client *client, unsigned int cmd, void *arg) 734saa6752hs_command(struct i2c_client *client, unsigned int cmd, void *arg)
551{ 735{
552 struct saa6752hs_state *h = i2c_get_clientdata(client); 736 struct saa6752hs_state *h = i2c_get_clientdata(client);
553 struct v4l2_mpeg_compression *params = arg; 737 struct v4l2_ext_controls *ctrls = arg;
738 struct v4l2_mpeg_compression *old_params = arg;
739 struct saa6752hs_mpeg_params params;
554 int err = 0; 740 int err = 0;
741 int i;
555 742
556 switch (cmd) { 743 switch (cmd) {
557 case VIDIOC_S_MPEGCOMP: 744 case VIDIOC_S_MPEGCOMP:
558 if (NULL == params) { 745 if (NULL == old_params) {
559 /* apply settings and start encoder */ 746 /* apply settings and start encoder */
560 saa6752hs_init(client); 747 saa6752hs_init(client);
561 break; 748 break;
562 } 749 }
563 saa6752hs_set_params(client, params); 750 saa6752hs_old_set_params(client, old_params);
564 /* fall through */ 751 /* fall through */
565 case VIDIOC_G_MPEGCOMP: 752 case VIDIOC_G_MPEGCOMP:
566 *params = h->params; 753 *old_params = h->old_params;
754 break;
755 case VIDIOC_S_EXT_CTRLS:
756 if (ctrls->ctrl_class != V4L2_CTRL_CLASS_MPEG)
757 return -EINVAL;
758 if (ctrls->count == 0) {
759 /* apply settings and start encoder */
760 saa6752hs_init(client);
761 break;
762 }
763 /* fall through */
764 case VIDIOC_TRY_EXT_CTRLS:
765 case VIDIOC_G_EXT_CTRLS:
766 if (ctrls->ctrl_class != V4L2_CTRL_CLASS_MPEG)
767 return -EINVAL;
768 params = h->params;
769 for (i = 0; i < ctrls->count; i++) {
770 if ((err = handle_ctrl(&params, ctrls->controls + i, cmd))) {
771 ctrls->error_idx = i;
772 return err;
773 }
774 }
775 h->params = params;
567 break; 776 break;
568 case VIDIOC_G_FMT: 777 case VIDIOC_G_FMT:
569 { 778 {
diff --git a/drivers/media/video/saa7134/saa7134-alsa.c b/drivers/media/video/saa7134/saa7134-alsa.c
index bb3e0ba946d..d77e6a8d943 100644
--- a/drivers/media/video/saa7134/saa7134-alsa.c
+++ b/drivers/media/video/saa7134/saa7134-alsa.c
@@ -818,7 +818,7 @@ static int snd_saa7134_capsrc_put(struct snd_kcontrol * kcontrol,
818 break; 818 break;
819 } 819 }
820 820
821 /* output xbar always main channel */ 821 /* output xbar always main channel */
822 saa_dsp_writel(dev, SAA7133_DIGITAL_OUTPUT_SEL1, 0xbbbb10); 822 saa_dsp_writel(dev, SAA7133_DIGITAL_OUTPUT_SEL1, 0xbbbb10);
823 823
824 if (left || right) { // We've got data, turn the input on 824 if (left || right) { // We've got data, turn the input on
diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c
index 86eae352833..927413aded1 100644
--- a/drivers/media/video/saa7134/saa7134-cards.c
+++ b/drivers/media/video/saa7134/saa7134-cards.c
@@ -2160,7 +2160,7 @@ struct saa7134_board saa7134_boards[] = {
2160 .radio = { 2160 .radio = {
2161 .name = name_radio, 2161 .name = name_radio,
2162 .amux = LINE2, 2162 .amux = LINE2,
2163 }, 2163 },
2164 }, 2164 },
2165 [SAA7134_BOARD_GOTVIEW_7135] = { 2165 [SAA7134_BOARD_GOTVIEW_7135] = {
2166 /* Mike Baikov <mike@baikov.com> */ 2166 /* Mike Baikov <mike@baikov.com> */
@@ -2842,6 +2842,55 @@ struct saa7134_board saa7134_boards[] = {
2842 .gpio = 0x000000, /* GPIO21=Low for FM radio antenna */ 2842 .gpio = 0x000000, /* GPIO21=Low for FM radio antenna */
2843 }, 2843 },
2844 }, 2844 },
2845 [SAA7134_BOARD_FLYVIDEO3000_NTSC] = {
2846 /* "Zac Bowling" <zac@zacbowling.com> */
2847 .name = "LifeView FlyVIDEO3000 (NTSC)",
2848 .audio_clock = 0x00200000,
2849 .tuner_type = TUNER_PHILIPS_NTSC,
2850 .radio_type = UNSET,
2851 .tuner_addr = ADDR_UNSET,
2852 .radio_addr = ADDR_UNSET,
2853
2854 .gpiomask = 0xe000,
2855 .inputs = {{
2856 .name = name_tv,
2857 .vmux = 1,
2858 .amux = TV,
2859 .gpio = 0x8000,
2860 .tv = 1,
2861 },{
2862 .name = name_tv_mono,
2863 .vmux = 1,
2864 .amux = LINE2,
2865 .gpio = 0x0000,
2866 .tv = 1,
2867 },{
2868 .name = name_comp1,
2869 .vmux = 0,
2870 .amux = LINE2,
2871 .gpio = 0x4000,
2872 },{
2873 .name = name_comp2,
2874 .vmux = 3,
2875 .amux = LINE2,
2876 .gpio = 0x4000,
2877 },{
2878 .name = name_svideo,
2879 .vmux = 8,
2880 .amux = LINE2,
2881 .gpio = 0x4000,
2882 }},
2883 .radio = {
2884 .name = name_radio,
2885 .amux = LINE2,
2886 .gpio = 0x2000,
2887 },
2888 .mute = {
2889 .name = name_mute,
2890 .amux = TV,
2891 .gpio = 0x8000,
2892 },
2893 },
2845}; 2894};
2846 2895
2847const unsigned int saa7134_bcount = ARRAY_SIZE(saa7134_boards); 2896const unsigned int saa7134_bcount = ARRAY_SIZE(saa7134_boards);
@@ -2901,6 +2950,12 @@ struct pci_device_id saa7134_pci_tbl[] = {
2901 },{ 2950 },{
2902 .vendor = PCI_VENDOR_ID_PHILIPS, 2951 .vendor = PCI_VENDOR_ID_PHILIPS,
2903 .device = PCI_DEVICE_ID_PHILIPS_SAA7134, 2952 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
2953 .subvendor = 0x5169,
2954 .subdevice = 0x0138,
2955 .driver_data = SAA7134_BOARD_FLYVIDEO3000_NTSC,
2956 },{
2957 .vendor = PCI_VENDOR_ID_PHILIPS,
2958 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
2904 .subvendor = 0x5168, 2959 .subvendor = 0x5168,
2905 .subdevice = 0x0138, 2960 .subdevice = 0x0138,
2906 .driver_data = SAA7134_BOARD_FLYVIDEO3000, 2961 .driver_data = SAA7134_BOARD_FLYVIDEO3000,
@@ -3459,6 +3514,7 @@ int saa7134_board_init1(struct saa7134_dev *dev)
3459 switch (dev->board) { 3514 switch (dev->board) {
3460 case SAA7134_BOARD_FLYVIDEO2000: 3515 case SAA7134_BOARD_FLYVIDEO2000:
3461 case SAA7134_BOARD_FLYVIDEO3000: 3516 case SAA7134_BOARD_FLYVIDEO3000:
3517 case SAA7134_BOARD_FLYVIDEO3000_NTSC:
3462 dev->has_remote = SAA7134_REMOTE_GPIO; 3518 dev->has_remote = SAA7134_REMOTE_GPIO;
3463 board_flyvideo(dev); 3519 board_flyvideo(dev);
3464 break; 3520 break;
diff --git a/drivers/media/video/saa7134/saa7134-dvb.c b/drivers/media/video/saa7134/saa7134-dvb.c
index 222a36c3891..279828b8f29 100644
--- a/drivers/media/video/saa7134/saa7134-dvb.c
+++ b/drivers/media/video/saa7134/saa7134-dvb.c
@@ -132,9 +132,8 @@ static int mt352_aver777_init(struct dvb_frontend* fe)
132 return 0; 132 return 0;
133} 133}
134 134
135static int mt352_pinnacle_pll_set(struct dvb_frontend* fe, 135static int mt352_pinnacle_tuner_set_params(struct dvb_frontend* fe,
136 struct dvb_frontend_parameters* params, 136 struct dvb_frontend_parameters* params)
137 u8* pllbuf)
138{ 137{
139 u8 off[] = { 0x00, 0xf1}; 138 u8 off[] = { 0x00, 0xf1};
140 u8 on[] = { 0x00, 0x71}; 139 u8 on[] = { 0x00, 0x71};
@@ -147,30 +146,31 @@ static int mt352_pinnacle_pll_set(struct dvb_frontend* fe,
147 f.tuner = 0; 146 f.tuner = 0;
148 f.type = V4L2_TUNER_DIGITAL_TV; 147 f.type = V4L2_TUNER_DIGITAL_TV;
149 f.frequency = params->frequency / 1000 * 16 / 1000; 148 f.frequency = params->frequency / 1000 * 16 / 1000;
149 if (fe->ops.i2c_gate_ctrl)
150 fe->ops.i2c_gate_ctrl(fe, 1);
150 i2c_transfer(&dev->i2c_adap, &msg, 1); 151 i2c_transfer(&dev->i2c_adap, &msg, 1);
151 saa7134_i2c_call_clients(dev,VIDIOC_S_FREQUENCY,&f); 152 saa7134_i2c_call_clients(dev,VIDIOC_S_FREQUENCY,&f);
152 msg.buf = on; 153 msg.buf = on;
154 if (fe->ops.i2c_gate_ctrl)
155 fe->ops.i2c_gate_ctrl(fe, 1);
153 i2c_transfer(&dev->i2c_adap, &msg, 1); 156 i2c_transfer(&dev->i2c_adap, &msg, 1);
154 157
155 pinnacle_antenna_pwr(dev, antenna_pwr); 158 pinnacle_antenna_pwr(dev, antenna_pwr);
156 159
157 /* mt352 setup */ 160 /* mt352 setup */
158 mt352_pinnacle_init(fe); 161 return mt352_pinnacle_init(fe);
159 pllbuf[0] = 0xc2;
160 pllbuf[1] = 0x00;
161 pllbuf[2] = 0x00;
162 pllbuf[3] = 0x80;
163 pllbuf[4] = 0x00;
164 return 0;
165} 162}
166 163
167static int mt352_aver777_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params, u8* pllbuf) 164static int mt352_aver777_tuner_calc_regs(struct dvb_frontend *fe, struct dvb_frontend_parameters *params, u8* pllbuf, int buf_len)
168{ 165{
169 pllbuf[0] = 0xc2; 166 if (buf_len < 5)
167 return -EINVAL;
168
169 pllbuf[0] = 0x61;
170 dvb_pll_configure(&dvb_pll_philips_td1316, pllbuf+1, 170 dvb_pll_configure(&dvb_pll_philips_td1316, pllbuf+1,
171 params->frequency, 171 params->frequency,
172 params->u.ofdm.bandwidth); 172 params->u.ofdm.bandwidth);
173 return 0; 173 return 5;
174} 174}
175 175
176static struct mt352_config pinnacle_300i = { 176static struct mt352_config pinnacle_300i = {
@@ -179,13 +179,11 @@ static struct mt352_config pinnacle_300i = {
179 .if2 = 36150, 179 .if2 = 36150,
180 .no_tuner = 1, 180 .no_tuner = 1,
181 .demod_init = mt352_pinnacle_init, 181 .demod_init = mt352_pinnacle_init,
182 .pll_set = mt352_pinnacle_pll_set,
183}; 182};
184 183
185static struct mt352_config avermedia_777 = { 184static struct mt352_config avermedia_777 = {
186 .demod_address = 0xf, 185 .demod_address = 0xf,
187 .demod_init = mt352_aver777_init, 186 .demod_init = mt352_aver777_init,
188 .pll_set = mt352_aver777_pll_set,
189}; 187};
190#endif 188#endif
191 189
@@ -268,6 +266,8 @@ static int philips_tda6651_pll_set(u8 addr, struct dvb_frontend *fe, struct dvb_
268 tuner_buf[2] = 0xca; 266 tuner_buf[2] = 0xca;
269 tuner_buf[3] = (cp << 5) | (filter << 3) | band; 267 tuner_buf[3] = (cp << 5) | (filter << 3) | band;
270 268
269 if (fe->ops.i2c_gate_ctrl)
270 fe->ops.i2c_gate_ctrl(fe, 1);
271 if (i2c_transfer(&dev->i2c_adap, &tuner_msg, 1) != 1) 271 if (i2c_transfer(&dev->i2c_adap, &tuner_msg, 1) != 1)
272 return -EIO; 272 return -EIO;
273 msleep(1); 273 msleep(1);
@@ -281,6 +281,8 @@ static int philips_tda6651_pll_init(u8 addr, struct dvb_frontend *fe)
281 struct i2c_msg tuner_msg = {.addr = addr,.flags = 0,.buf = tu1216_init,.len = sizeof(tu1216_init) }; 281 struct i2c_msg tuner_msg = {.addr = addr,.flags = 0,.buf = tu1216_init,.len = sizeof(tu1216_init) };
282 282
283 /* setup PLL configuration */ 283 /* setup PLL configuration */
284 if (fe->ops.i2c_gate_ctrl)
285 fe->ops.i2c_gate_ctrl(fe, 1);
284 if (i2c_transfer(&dev->i2c_adap, &tuner_msg, 1) != 1) 286 if (i2c_transfer(&dev->i2c_adap, &tuner_msg, 1) != 1)
285 return -EIO; 287 return -EIO;
286 msleep(1); 288 msleep(1);
@@ -290,12 +292,12 @@ static int philips_tda6651_pll_init(u8 addr, struct dvb_frontend *fe)
290 292
291/* ------------------------------------------------------------------ */ 293/* ------------------------------------------------------------------ */
292 294
293static int philips_tu1216_pll_60_init(struct dvb_frontend *fe) 295static int philips_tu1216_tuner_60_init(struct dvb_frontend *fe)
294{ 296{
295 return philips_tda6651_pll_init(0x60, fe); 297 return philips_tda6651_pll_init(0x60, fe);
296} 298}
297 299
298static int philips_tu1216_pll_60_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) 300static int philips_tu1216_tuner_60_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
299{ 301{
300 return philips_tda6651_pll_set(0x60, fe, params); 302 return philips_tda6651_pll_set(0x60, fe, params);
301} 303}
@@ -315,20 +317,17 @@ static struct tda1004x_config philips_tu1216_60_config = {
315 .xtal_freq = TDA10046_XTAL_4M, 317 .xtal_freq = TDA10046_XTAL_4M,
316 .agc_config = TDA10046_AGC_DEFAULT, 318 .agc_config = TDA10046_AGC_DEFAULT,
317 .if_freq = TDA10046_FREQ_3617, 319 .if_freq = TDA10046_FREQ_3617,
318 .pll_init = philips_tu1216_pll_60_init,
319 .pll_set = philips_tu1216_pll_60_set,
320 .pll_sleep = NULL,
321 .request_firmware = philips_tu1216_request_firmware, 320 .request_firmware = philips_tu1216_request_firmware,
322}; 321};
323 322
324/* ------------------------------------------------------------------ */ 323/* ------------------------------------------------------------------ */
325 324
326static int philips_tu1216_pll_61_init(struct dvb_frontend *fe) 325static int philips_tu1216_tuner_61_init(struct dvb_frontend *fe)
327{ 326{
328 return philips_tda6651_pll_init(0x61, fe); 327 return philips_tda6651_pll_init(0x61, fe);
329} 328}
330 329
331static int philips_tu1216_pll_61_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) 330static int philips_tu1216_tuner_61_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
332{ 331{
333 return philips_tda6651_pll_set(0x61, fe, params); 332 return philips_tda6651_pll_set(0x61, fe, params);
334} 333}
@@ -341,21 +340,20 @@ static struct tda1004x_config philips_tu1216_61_config = {
341 .xtal_freq = TDA10046_XTAL_4M, 340 .xtal_freq = TDA10046_XTAL_4M,
342 .agc_config = TDA10046_AGC_DEFAULT, 341 .agc_config = TDA10046_AGC_DEFAULT,
343 .if_freq = TDA10046_FREQ_3617, 342 .if_freq = TDA10046_FREQ_3617,
344 .pll_init = philips_tu1216_pll_61_init,
345 .pll_set = philips_tu1216_pll_61_set,
346 .pll_sleep = NULL,
347 .request_firmware = philips_tu1216_request_firmware, 343 .request_firmware = philips_tu1216_request_firmware,
348}; 344};
349 345
350/* ------------------------------------------------------------------ */ 346/* ------------------------------------------------------------------ */
351 347
352static int philips_europa_pll_init(struct dvb_frontend *fe) 348static int philips_europa_tuner_init(struct dvb_frontend *fe)
353{ 349{
354 struct saa7134_dev *dev = fe->dvb->priv; 350 struct saa7134_dev *dev = fe->dvb->priv;
355 static u8 msg[] = { 0x0b, 0xf5, 0x86, 0xab }; 351 static u8 msg[] = { 0x0b, 0xf5, 0x86, 0xab };
356 struct i2c_msg init_msg = {.addr = 0x61,.flags = 0,.buf = msg,.len = sizeof(msg) }; 352 struct i2c_msg init_msg = {.addr = 0x61,.flags = 0,.buf = msg,.len = sizeof(msg) };
357 353
358 /* setup PLL configuration */ 354 /* setup PLL configuration */
355 if (fe->ops.i2c_gate_ctrl)
356 fe->ops.i2c_gate_ctrl(fe, 1);
359 if (i2c_transfer(&dev->i2c_adap, &init_msg, 1) != 1) 357 if (i2c_transfer(&dev->i2c_adap, &init_msg, 1) != 1)
360 return -EIO; 358 return -EIO;
361 msleep(1); 359 msleep(1);
@@ -365,18 +363,20 @@ static int philips_europa_pll_init(struct dvb_frontend *fe)
365 init_msg.len = 0x02; 363 init_msg.len = 0x02;
366 msg[0] = 0x00; 364 msg[0] = 0x00;
367 msg[1] = 0x40; 365 msg[1] = 0x40;
366 if (fe->ops.i2c_gate_ctrl)
367 fe->ops.i2c_gate_ctrl(fe, 1);
368 if (i2c_transfer(&dev->i2c_adap, &init_msg, 1) != 1) 368 if (i2c_transfer(&dev->i2c_adap, &init_msg, 1) != 1)
369 return -EIO; 369 return -EIO;
370 370
371 return 0; 371 return 0;
372} 372}
373 373
374static int philips_td1316_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) 374static int philips_td1316_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
375{ 375{
376 return philips_tda6651_pll_set(0x61, fe, params); 376 return philips_tda6651_pll_set(0x61, fe, params);
377} 377}
378 378
379static void philips_europa_analog(struct dvb_frontend *fe) 379static int philips_europa_tuner_sleep(struct dvb_frontend *fe)
380{ 380{
381 struct saa7134_dev *dev = fe->dvb->priv; 381 struct saa7134_dev *dev = fe->dvb->priv;
382 /* this message actually turns the tuner back to analog mode */ 382 /* this message actually turns the tuner back to analog mode */
@@ -391,7 +391,20 @@ static void philips_europa_analog(struct dvb_frontend *fe)
391 analog_msg.len = 0x02; 391 analog_msg.len = 0x02;
392 msg[0] = 0x00; 392 msg[0] = 0x00;
393 msg[1] = 0x14; 393 msg[1] = 0x14;
394 if (fe->ops.i2c_gate_ctrl)
395 fe->ops.i2c_gate_ctrl(fe, 1);
394 i2c_transfer(&dev->i2c_adap, &analog_msg, 1); 396 i2c_transfer(&dev->i2c_adap, &analog_msg, 1);
397 return 0;
398}
399
400static int philips_europa_demod_sleep(struct dvb_frontend *fe)
401{
402 struct saa7134_dev *dev = fe->dvb->priv;
403
404 if (dev->original_demod_sleep)
405 dev->original_demod_sleep(fe);
406 fe->ops.i2c_gate_ctrl(fe, 1);
407 return 0;
395} 408}
396 409
397static struct tda1004x_config philips_europa_config = { 410static struct tda1004x_config philips_europa_config = {
@@ -402,21 +415,20 @@ static struct tda1004x_config philips_europa_config = {
402 .xtal_freq = TDA10046_XTAL_4M, 415 .xtal_freq = TDA10046_XTAL_4M,
403 .agc_config = TDA10046_AGC_IFO_AUTO_POS, 416 .agc_config = TDA10046_AGC_IFO_AUTO_POS,
404 .if_freq = TDA10046_FREQ_052, 417 .if_freq = TDA10046_FREQ_052,
405 .pll_init = philips_europa_pll_init,
406 .pll_set = philips_td1316_pll_set,
407 .pll_sleep = philips_europa_analog,
408 .request_firmware = NULL, 418 .request_firmware = NULL,
409}; 419};
410 420
411/* ------------------------------------------------------------------ */ 421/* ------------------------------------------------------------------ */
412 422
413static int philips_fmd1216_pll_init(struct dvb_frontend *fe) 423static int philips_fmd1216_tuner_init(struct dvb_frontend *fe)
414{ 424{
415 struct saa7134_dev *dev = fe->dvb->priv; 425 struct saa7134_dev *dev = fe->dvb->priv;
416 /* this message is to set up ATC and ALC */ 426 /* this message is to set up ATC and ALC */
417 static u8 fmd1216_init[] = { 0x0b, 0xdc, 0x9c, 0xa0 }; 427 static u8 fmd1216_init[] = { 0x0b, 0xdc, 0x9c, 0xa0 };
418 struct i2c_msg tuner_msg = {.addr = 0x61,.flags = 0,.buf = fmd1216_init,.len = sizeof(fmd1216_init) }; 428 struct i2c_msg tuner_msg = {.addr = 0x61,.flags = 0,.buf = fmd1216_init,.len = sizeof(fmd1216_init) };
419 429
430 if (fe->ops.i2c_gate_ctrl)
431 fe->ops.i2c_gate_ctrl(fe, 1);
420 if (i2c_transfer(&dev->i2c_adap, &tuner_msg, 1) != 1) 432 if (i2c_transfer(&dev->i2c_adap, &tuner_msg, 1) != 1)
421 return -EIO; 433 return -EIO;
422 msleep(1); 434 msleep(1);
@@ -424,22 +436,27 @@ static int philips_fmd1216_pll_init(struct dvb_frontend *fe)
424 return 0; 436 return 0;
425} 437}
426 438
427static void philips_fmd1216_analog(struct dvb_frontend *fe) 439static int philips_fmd1216_tuner_sleep(struct dvb_frontend *fe)
428{ 440{
429 struct saa7134_dev *dev = fe->dvb->priv; 441 struct saa7134_dev *dev = fe->dvb->priv;
430 /* this message actually turns the tuner back to analog mode */ 442 /* this message actually turns the tuner back to analog mode */
431 static u8 fmd1216_init[] = { 0x0b, 0xdc, 0x9c, 0x60 }; 443 static u8 fmd1216_init[] = { 0x0b, 0xdc, 0x9c, 0x60 };
432 struct i2c_msg tuner_msg = {.addr = 0x61,.flags = 0,.buf = fmd1216_init,.len = sizeof(fmd1216_init) }; 444 struct i2c_msg tuner_msg = {.addr = 0x61,.flags = 0,.buf = fmd1216_init,.len = sizeof(fmd1216_init) };
433 445
446 if (fe->ops.i2c_gate_ctrl)
447 fe->ops.i2c_gate_ctrl(fe, 1);
434 i2c_transfer(&dev->i2c_adap, &tuner_msg, 1); 448 i2c_transfer(&dev->i2c_adap, &tuner_msg, 1);
435 msleep(1); 449 msleep(1);
436 fmd1216_init[2] = 0x86; 450 fmd1216_init[2] = 0x86;
437 fmd1216_init[3] = 0x54; 451 fmd1216_init[3] = 0x54;
452 if (fe->ops.i2c_gate_ctrl)
453 fe->ops.i2c_gate_ctrl(fe, 1);
438 i2c_transfer(&dev->i2c_adap, &tuner_msg, 1); 454 i2c_transfer(&dev->i2c_adap, &tuner_msg, 1);
439 msleep(1); 455 msleep(1);
456 return 0;
440} 457}
441 458
442static int philips_fmd1216_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) 459static int philips_fmd1216_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
443{ 460{
444 struct saa7134_dev *dev = fe->dvb->priv; 461 struct saa7134_dev *dev = fe->dvb->priv;
445 u8 tuner_buf[4]; 462 u8 tuner_buf[4];
@@ -516,6 +533,8 @@ static int philips_fmd1216_pll_set(struct dvb_frontend *fe, struct dvb_frontend_
516 tuner_buf[2] = 0x80 | (cp << 6) | (mode << 3) | 4; 533 tuner_buf[2] = 0x80 | (cp << 6) | (mode << 3) | 4;
517 tuner_buf[3] = 0x40 | band; 534 tuner_buf[3] = 0x40 | band;
518 535
536 if (fe->ops.i2c_gate_ctrl)
537 fe->ops.i2c_gate_ctrl(fe, 1);
519 if (i2c_transfer(&dev->i2c_adap, &tuner_msg, 1) != 1) 538 if (i2c_transfer(&dev->i2c_adap, &tuner_msg, 1) != 1)
520 return -EIO; 539 return -EIO;
521 return 0; 540 return 0;
@@ -528,9 +547,6 @@ static struct tda1004x_config medion_cardbus = {
528 .xtal_freq = TDA10046_XTAL_16M, 547 .xtal_freq = TDA10046_XTAL_16M,
529 .agc_config = TDA10046_AGC_IFO_AUTO_NEG, 548 .agc_config = TDA10046_AGC_IFO_AUTO_NEG,
530 .if_freq = TDA10046_FREQ_3613, 549 .if_freq = TDA10046_FREQ_3613,
531 .pll_init = philips_fmd1216_pll_init,
532 .pll_set = philips_fmd1216_pll_set,
533 .pll_sleep = philips_fmd1216_analog,
534 .request_firmware = NULL, 550 .request_firmware = NULL,
535}; 551};
536 552
@@ -578,12 +594,12 @@ static struct tda827x_data tda827x_dvbt[] = {
578 { .lomax = 0, .spd = 0, .bs = 0, .bp = 0, .cp = 0, .gc3 = 0, .div1p5 = 0} 594 { .lomax = 0, .spd = 0, .bs = 0, .bp = 0, .cp = 0, .gc3 = 0, .div1p5 = 0}
579}; 595};
580 596
581static int philips_tda827x_pll_init(struct dvb_frontend *fe) 597static int philips_tda827x_tuner_init(struct dvb_frontend *fe)
582{ 598{
583 return 0; 599 return 0;
584} 600}
585 601
586static int philips_tda827x_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) 602static int philips_tda827x_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
587{ 603{
588 struct saa7134_dev *dev = fe->dvb->priv; 604 struct saa7134_dev *dev = fe->dvb->priv;
589 u8 tuner_buf[14]; 605 u8 tuner_buf[14];
@@ -630,6 +646,8 @@ static int philips_tda827x_pll_set(struct dvb_frontend *fe, struct dvb_frontend_
630 tuner_buf[13] = 0x40; 646 tuner_buf[13] = 0x40;
631 647
632 tuner_msg.len = 14; 648 tuner_msg.len = 14;
649 if (fe->ops.i2c_gate_ctrl)
650 fe->ops.i2c_gate_ctrl(fe, 1);
633 if (i2c_transfer(&dev->i2c_adap, &tuner_msg, 1) != 1) 651 if (i2c_transfer(&dev->i2c_adap, &tuner_msg, 1) != 1)
634 return -EIO; 652 return -EIO;
635 653
@@ -638,18 +656,23 @@ static int philips_tda827x_pll_set(struct dvb_frontend *fe, struct dvb_frontend_
638 tuner_buf[0] = 0x30; 656 tuner_buf[0] = 0x30;
639 tuner_buf[1] = 0x50 + tda827x_dvbt[i].cp; 657 tuner_buf[1] = 0x50 + tda827x_dvbt[i].cp;
640 tuner_msg.len = 2; 658 tuner_msg.len = 2;
659 if (fe->ops.i2c_gate_ctrl)
660 fe->ops.i2c_gate_ctrl(fe, 1);
641 i2c_transfer(&dev->i2c_adap, &tuner_msg, 1); 661 i2c_transfer(&dev->i2c_adap, &tuner_msg, 1);
642 662
643 return 0; 663 return 0;
644} 664}
645 665
646static void philips_tda827x_pll_sleep(struct dvb_frontend *fe) 666static int philips_tda827x_tuner_sleep(struct dvb_frontend *fe)
647{ 667{
648 struct saa7134_dev *dev = fe->dvb->priv; 668 struct saa7134_dev *dev = fe->dvb->priv;
649 static u8 tda827x_sleep[] = { 0x30, 0xd0}; 669 static u8 tda827x_sleep[] = { 0x30, 0xd0};
650 struct i2c_msg tuner_msg = {.addr = 0x60,.flags = 0,.buf = tda827x_sleep, 670 struct i2c_msg tuner_msg = {.addr = 0x60,.flags = 0,.buf = tda827x_sleep,
651 .len = sizeof(tda827x_sleep) }; 671 .len = sizeof(tda827x_sleep) };
672 if (fe->ops.i2c_gate_ctrl)
673 fe->ops.i2c_gate_ctrl(fe, 1);
652 i2c_transfer(&dev->i2c_adap, &tuner_msg, 1); 674 i2c_transfer(&dev->i2c_adap, &tuner_msg, 1);
675 return 0;
653} 676}
654 677
655static struct tda1004x_config tda827x_lifeview_config = { 678static struct tda1004x_config tda827x_lifeview_config = {
@@ -659,9 +682,6 @@ static struct tda1004x_config tda827x_lifeview_config = {
659 .xtal_freq = TDA10046_XTAL_16M, 682 .xtal_freq = TDA10046_XTAL_16M,
660 .agc_config = TDA10046_AGC_TDA827X, 683 .agc_config = TDA10046_AGC_TDA827X,
661 .if_freq = TDA10046_FREQ_045, 684 .if_freq = TDA10046_FREQ_045,
662 .pll_init = philips_tda827x_pll_init,
663 .pll_set = philips_tda827x_pll_set,
664 .pll_sleep = philips_tda827x_pll_sleep,
665 .request_firmware = NULL, 685 .request_firmware = NULL,
666}; 686};
667 687
@@ -753,6 +773,8 @@ static int philips_tda827xa_pll_set(u8 addr, struct dvb_frontend *fe, struct dvb
753 tuner_buf[12] = 0x00; 773 tuner_buf[12] = 0x00;
754 tuner_buf[13] = 0x39; // lpsel 774 tuner_buf[13] = 0x39; // lpsel
755 msg.len = 14; 775 msg.len = 14;
776 if (fe->ops.i2c_gate_ctrl)
777 fe->ops.i2c_gate_ctrl(fe, 1);
756 if (i2c_transfer(&dev->i2c_adap, &msg, 1) != 1) 778 if (i2c_transfer(&dev->i2c_adap, &msg, 1) != 1)
757 return -EIO; 779 return -EIO;
758 780
@@ -760,10 +782,14 @@ static int philips_tda827xa_pll_set(u8 addr, struct dvb_frontend *fe, struct dvb
760 msg.len = 2; 782 msg.len = 2;
761 reg2[0] = 0x60; 783 reg2[0] = 0x60;
762 reg2[1] = 0x3c; 784 reg2[1] = 0x3c;
785 if (fe->ops.i2c_gate_ctrl)
786 fe->ops.i2c_gate_ctrl(fe, 1);
763 i2c_transfer(&dev->i2c_adap, &msg, 1); 787 i2c_transfer(&dev->i2c_adap, &msg, 1);
764 788
765 reg2[0] = 0xa0; 789 reg2[0] = 0xa0;
766 reg2[1] = 0x40; 790 reg2[1] = 0x40;
791 if (fe->ops.i2c_gate_ctrl)
792 fe->ops.i2c_gate_ctrl(fe, 1);
767 i2c_transfer(&dev->i2c_adap, &msg, 1); 793 i2c_transfer(&dev->i2c_adap, &msg, 1);
768 794
769 msleep(2); 795 msleep(2);
@@ -771,36 +797,43 @@ static int philips_tda827xa_pll_set(u8 addr, struct dvb_frontend *fe, struct dvb
771 reg2[0] = 0x30; 797 reg2[0] = 0x30;
772 reg2[1] = 0x10 + tda827xa_dvbt[i].scr; 798 reg2[1] = 0x10 + tda827xa_dvbt[i].scr;
773 msg.len = 2; 799 msg.len = 2;
800 if (fe->ops.i2c_gate_ctrl)
801 fe->ops.i2c_gate_ctrl(fe, 1);
774 i2c_transfer(&dev->i2c_adap, &msg, 1); 802 i2c_transfer(&dev->i2c_adap, &msg, 1);
775 803
776 msleep(550); 804 msleep(550);
777 reg2[0] = 0x50; 805 reg2[0] = 0x50;
778 reg2[1] = 0x4f + (tda827xa_dvbt[i].gc3 << 4); 806 reg2[1] = 0x4f + (tda827xa_dvbt[i].gc3 << 4);
807 if (fe->ops.i2c_gate_ctrl)
808 fe->ops.i2c_gate_ctrl(fe, 1);
779 i2c_transfer(&dev->i2c_adap, &msg, 1); 809 i2c_transfer(&dev->i2c_adap, &msg, 1);
780 810
781 return 0; 811 return 0;
782 812
783} 813}
784 814
785static void philips_tda827xa_pll_sleep(u8 addr, struct dvb_frontend *fe) 815static int philips_tda827xa_tuner_sleep(u8 addr, struct dvb_frontend *fe)
786{ 816{
787 struct saa7134_dev *dev = fe->dvb->priv; 817 struct saa7134_dev *dev = fe->dvb->priv;
788 static u8 tda827xa_sleep[] = { 0x30, 0x90}; 818 static u8 tda827xa_sleep[] = { 0x30, 0x90};
789 struct i2c_msg tuner_msg = {.addr = addr,.flags = 0,.buf = tda827xa_sleep, 819 struct i2c_msg tuner_msg = {.addr = addr,.flags = 0,.buf = tda827xa_sleep,
790 .len = sizeof(tda827xa_sleep) }; 820 .len = sizeof(tda827xa_sleep) };
821 if (fe->ops.i2c_gate_ctrl)
822 fe->ops.i2c_gate_ctrl(fe, 1);
791 i2c_transfer(&dev->i2c_adap, &tuner_msg, 1); 823 i2c_transfer(&dev->i2c_adap, &tuner_msg, 1);
792 824 return 0;
793} 825}
794 826
795/* ------------------------------------------------------------------ */ 827/* ------------------------------------------------------------------ */
796 828
797static int philips_tiger_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) 829static int philips_tiger_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
798{ 830{
799 int ret; 831 int ret;
800 struct saa7134_dev *dev = fe->dvb->priv; 832 struct saa7134_dev *dev = fe->dvb->priv;
801 static u8 tda8290_close[] = { 0x21, 0xc0}; 833 static u8 tda8290_close[] = { 0x21, 0xc0};
802 static u8 tda8290_open[] = { 0x21, 0x80}; 834 static u8 tda8290_open[] = { 0x21, 0x80};
803 struct i2c_msg tda8290_msg = {.addr = 0x4b,.flags = 0, .len = 2}; 835 struct i2c_msg tda8290_msg = {.addr = 0x4b,.flags = 0, .len = 2};
836
804 /* close tda8290 i2c bridge */ 837 /* close tda8290 i2c bridge */
805 tda8290_msg.buf = tda8290_close; 838 tda8290_msg.buf = tda8290_close;
806 ret = i2c_transfer(&dev->i2c_adap, &tda8290_msg, 1); 839 ret = i2c_transfer(&dev->i2c_adap, &tda8290_msg, 1);
@@ -816,7 +849,7 @@ static int philips_tiger_pll_set(struct dvb_frontend *fe, struct dvb_frontend_pa
816 return ret; 849 return ret;
817} 850}
818 851
819static int philips_tiger_dvb_mode(struct dvb_frontend *fe) 852static int philips_tiger_tuner_init(struct dvb_frontend *fe)
820{ 853{
821 struct saa7134_dev *dev = fe->dvb->priv; 854 struct saa7134_dev *dev = fe->dvb->priv;
822 static u8 data[] = { 0x3c, 0x33, 0x6a}; 855 static u8 data[] = { 0x3c, 0x33, 0x6a};
@@ -827,14 +860,15 @@ static int philips_tiger_dvb_mode(struct dvb_frontend *fe)
827 return 0; 860 return 0;
828} 861}
829 862
830static void philips_tiger_analog_mode(struct dvb_frontend *fe) 863static int philips_tiger_tuner_sleep(struct dvb_frontend *fe)
831{ 864{
832 struct saa7134_dev *dev = fe->dvb->priv; 865 struct saa7134_dev *dev = fe->dvb->priv;
833 static u8 data[] = { 0x3c, 0x33, 0x68}; 866 static u8 data[] = { 0x3c, 0x33, 0x68};
834 struct i2c_msg msg = {.addr=0x08, .flags=0, .buf=data, .len = sizeof(data)}; 867 struct i2c_msg msg = {.addr=0x08, .flags=0, .buf=data, .len = sizeof(data)};
835 868
836 i2c_transfer(&dev->i2c_adap, &msg, 1); 869 i2c_transfer(&dev->i2c_adap, &msg, 1);
837 philips_tda827xa_pll_sleep( 0x61, fe); 870 philips_tda827xa_tuner_sleep( 0x61, fe);
871 return 0;
838} 872}
839 873
840static struct tda1004x_config philips_tiger_config = { 874static struct tda1004x_config philips_tiger_config = {
@@ -844,15 +878,12 @@ static struct tda1004x_config philips_tiger_config = {
844 .xtal_freq = TDA10046_XTAL_16M, 878 .xtal_freq = TDA10046_XTAL_16M,
845 .agc_config = TDA10046_AGC_TDA827X, 879 .agc_config = TDA10046_AGC_TDA827X,
846 .if_freq = TDA10046_FREQ_045, 880 .if_freq = TDA10046_FREQ_045,
847 .pll_init = philips_tiger_dvb_mode,
848 .pll_set = philips_tiger_pll_set,
849 .pll_sleep = philips_tiger_analog_mode,
850 .request_firmware = NULL, 881 .request_firmware = NULL,
851}; 882};
852 883
853/* ------------------------------------------------------------------ */ 884/* ------------------------------------------------------------------ */
854 885
855static int lifeview_trio_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) 886static int lifeview_trio_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
856{ 887{
857 int ret; 888 int ret;
858 889
@@ -860,16 +891,12 @@ static int lifeview_trio_pll_set(struct dvb_frontend *fe, struct dvb_frontend_pa
860 return ret; 891 return ret;
861} 892}
862 893
863static int lifeview_trio_dvb_mode(struct dvb_frontend *fe) 894static int lifeview_trio_tuner_sleep(struct dvb_frontend *fe)
864{ 895{
896 philips_tda827xa_tuner_sleep(0x60, fe);
865 return 0; 897 return 0;
866} 898}
867 899
868static void lifeview_trio_analog_mode(struct dvb_frontend *fe)
869{
870 philips_tda827xa_pll_sleep(0x60, fe);
871}
872
873static struct tda1004x_config lifeview_trio_config = { 900static struct tda1004x_config lifeview_trio_config = {
874 .demod_address = 0x09, 901 .demod_address = 0x09,
875 .invert = 1, 902 .invert = 1,
@@ -877,15 +904,12 @@ static struct tda1004x_config lifeview_trio_config = {
877 .xtal_freq = TDA10046_XTAL_16M, 904 .xtal_freq = TDA10046_XTAL_16M,
878 .agc_config = TDA10046_AGC_TDA827X_GPL, 905 .agc_config = TDA10046_AGC_TDA827X_GPL,
879 .if_freq = TDA10046_FREQ_045, 906 .if_freq = TDA10046_FREQ_045,
880 .pll_init = lifeview_trio_dvb_mode,
881 .pll_set = lifeview_trio_pll_set,
882 .pll_sleep = lifeview_trio_analog_mode,
883 .request_firmware = NULL, 907 .request_firmware = NULL,
884}; 908};
885 909
886/* ------------------------------------------------------------------ */ 910/* ------------------------------------------------------------------ */
887 911
888static int ads_duo_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) 912static int ads_duo_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
889{ 913{
890 int ret; 914 int ret;
891 915
@@ -893,7 +917,7 @@ static int ads_duo_pll_set(struct dvb_frontend *fe, struct dvb_frontend_paramete
893 return ret; 917 return ret;
894} 918}
895 919
896static int ads_duo_dvb_mode(struct dvb_frontend *fe) 920static int ads_duo_tuner_init(struct dvb_frontend *fe)
897{ 921{
898 struct saa7134_dev *dev = fe->dvb->priv; 922 struct saa7134_dev *dev = fe->dvb->priv;
899 /* route TDA8275a AGC input to the channel decoder */ 923 /* route TDA8275a AGC input to the channel decoder */
@@ -901,12 +925,13 @@ static int ads_duo_dvb_mode(struct dvb_frontend *fe)
901 return 0; 925 return 0;
902} 926}
903 927
904static void ads_duo_analog_mode(struct dvb_frontend *fe) 928static int ads_duo_tuner_sleep(struct dvb_frontend *fe)
905{ 929{
906 struct saa7134_dev *dev = fe->dvb->priv; 930 struct saa7134_dev *dev = fe->dvb->priv;
907 /* route TDA8275a AGC input to the analog IF chip*/ 931 /* route TDA8275a AGC input to the analog IF chip*/
908 saa_writeb(SAA7134_GPIO_GPSTATUS2, 0x20); 932 saa_writeb(SAA7134_GPIO_GPSTATUS2, 0x20);
909 philips_tda827xa_pll_sleep( 0x61, fe); 933 philips_tda827xa_tuner_sleep( 0x61, fe);
934 return 0;
910} 935}
911 936
912static struct tda1004x_config ads_tech_duo_config = { 937static struct tda1004x_config ads_tech_duo_config = {
@@ -916,31 +941,24 @@ static struct tda1004x_config ads_tech_duo_config = {
916 .xtal_freq = TDA10046_XTAL_16M, 941 .xtal_freq = TDA10046_XTAL_16M,
917 .agc_config = TDA10046_AGC_TDA827X_GPL, 942 .agc_config = TDA10046_AGC_TDA827X_GPL,
918 .if_freq = TDA10046_FREQ_045, 943 .if_freq = TDA10046_FREQ_045,
919 .pll_init = ads_duo_dvb_mode,
920 .pll_set = ads_duo_pll_set,
921 .pll_sleep = ads_duo_analog_mode,
922 .request_firmware = NULL, 944 .request_firmware = NULL,
923}; 945};
924 946
925/* ------------------------------------------------------------------ */ 947/* ------------------------------------------------------------------ */
926 948
927static int tevion_dvb220rf_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) 949static int tevion_dvb220rf_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
928{ 950{
929 int ret; 951 int ret;
930 ret = philips_tda827xa_pll_set(0x60, fe, params); 952 ret = philips_tda827xa_pll_set(0x60, fe, params);
931 return ret; 953 return ret;
932} 954}
933 955
934static int tevion_dvb220rf_pll_init(struct dvb_frontend *fe) 956static int tevion_dvb220rf_tuner_sleep(struct dvb_frontend *fe)
935{ 957{
958 philips_tda827xa_tuner_sleep( 0x61, fe);
936 return 0; 959 return 0;
937} 960}
938 961
939static void tevion_dvb220rf_pll_sleep(struct dvb_frontend *fe)
940{
941 philips_tda827xa_pll_sleep( 0x61, fe);
942}
943
944static struct tda1004x_config tevion_dvbt220rf_config = { 962static struct tda1004x_config tevion_dvbt220rf_config = {
945 .demod_address = 0x08, 963 .demod_address = 0x08,
946 .invert = 1, 964 .invert = 1,
@@ -948,9 +966,6 @@ static struct tda1004x_config tevion_dvbt220rf_config = {
948 .xtal_freq = TDA10046_XTAL_16M, 966 .xtal_freq = TDA10046_XTAL_16M,
949 .agc_config = TDA10046_AGC_TDA827X, 967 .agc_config = TDA10046_AGC_TDA827X,
950 .if_freq = TDA10046_FREQ_045, 968 .if_freq = TDA10046_FREQ_045,
951 .pll_init = tevion_dvb220rf_pll_init,
952 .pll_set = tevion_dvb220rf_pll_set,
953 .pll_sleep = tevion_dvb220rf_pll_sleep,
954 .request_firmware = NULL, 969 .request_firmware = NULL,
955}; 970};
956 971
@@ -961,8 +976,6 @@ static struct tda1004x_config tevion_dvbt220rf_config = {
961#ifdef HAVE_NXT200X 976#ifdef HAVE_NXT200X
962static struct nxt200x_config avertvhda180 = { 977static struct nxt200x_config avertvhda180 = {
963 .demod_address = 0x0a, 978 .demod_address = 0x0a,
964 .pll_address = 0x61,
965 .pll_desc = &dvb_pll_tdhu2,
966}; 979};
967 980
968static int nxt200x_set_pll_input(u8 *buf, int input) 981static int nxt200x_set_pll_input(u8 *buf, int input)
@@ -976,8 +989,6 @@ static int nxt200x_set_pll_input(u8 *buf, int input)
976 989
977static struct nxt200x_config kworldatsc110 = { 990static struct nxt200x_config kworldatsc110 = {
978 .demod_address = 0x0a, 991 .demod_address = 0x0a,
979 .pll_address = 0x61,
980 .pll_desc = &dvb_pll_tuv1236d,
981 .set_pll_input = nxt200x_set_pll_input, 992 .set_pll_input = nxt200x_set_pll_input,
982}; 993};
983#endif 994#endif
@@ -1003,78 +1014,158 @@ static int dvb_init(struct saa7134_dev *dev)
1003 printk("%s: pinnacle 300i dvb setup\n",dev->name); 1014 printk("%s: pinnacle 300i dvb setup\n",dev->name);
1004 dev->dvb.frontend = mt352_attach(&pinnacle_300i, 1015 dev->dvb.frontend = mt352_attach(&pinnacle_300i,
1005 &dev->i2c_adap); 1016 &dev->i2c_adap);
1017 if (dev->dvb.frontend) {
1018 dev->dvb.frontend->ops.tuner_ops.set_params = mt352_pinnacle_tuner_set_params;
1019 }
1006 break; 1020 break;
1007 1021
1008 case SAA7134_BOARD_AVERMEDIA_777: 1022 case SAA7134_BOARD_AVERMEDIA_777:
1009 printk("%s: avertv 777 dvb setup\n",dev->name); 1023 printk("%s: avertv 777 dvb setup\n",dev->name);
1010 dev->dvb.frontend = mt352_attach(&avermedia_777, 1024 dev->dvb.frontend = mt352_attach(&avermedia_777,
1011 &dev->i2c_adap); 1025 &dev->i2c_adap);
1026 if (dev->dvb.frontend) {
1027 dev->dvb.frontend->ops.tuner_ops.calc_regs = mt352_aver777_tuner_calc_regs;
1028 }
1012 break; 1029 break;
1013#endif 1030#endif
1014#ifdef HAVE_TDA1004X 1031#ifdef HAVE_TDA1004X
1015 case SAA7134_BOARD_MD7134: 1032 case SAA7134_BOARD_MD7134:
1016 dev->dvb.frontend = tda10046_attach(&medion_cardbus, 1033 dev->dvb.frontend = tda10046_attach(&medion_cardbus,
1017 &dev->i2c_adap); 1034 &dev->i2c_adap);
1035 if (dev->dvb.frontend) {
1036 dev->dvb.frontend->ops.tuner_ops.init = philips_fmd1216_tuner_init;
1037 dev->dvb.frontend->ops.tuner_ops.sleep = philips_fmd1216_tuner_sleep;
1038 dev->dvb.frontend->ops.tuner_ops.set_params = philips_fmd1216_tuner_set_params;
1039 }
1018 break; 1040 break;
1019 case SAA7134_BOARD_PHILIPS_TOUGH: 1041 case SAA7134_BOARD_PHILIPS_TOUGH:
1020 dev->dvb.frontend = tda10046_attach(&philips_tu1216_60_config, 1042 dev->dvb.frontend = tda10046_attach(&philips_tu1216_60_config,
1021 &dev->i2c_adap); 1043 &dev->i2c_adap);
1044 if (dev->dvb.frontend) {
1045 dev->dvb.frontend->ops.tuner_ops.init = philips_tu1216_tuner_60_init;
1046 dev->dvb.frontend->ops.tuner_ops.set_params = philips_tu1216_tuner_60_set_params;
1047 }
1022 break; 1048 break;
1023 case SAA7134_BOARD_FLYDVBTDUO: 1049 case SAA7134_BOARD_FLYDVBTDUO:
1024 dev->dvb.frontend = tda10046_attach(&tda827x_lifeview_config, 1050 dev->dvb.frontend = tda10046_attach(&tda827x_lifeview_config,
1025 &dev->i2c_adap); 1051 &dev->i2c_adap);
1052 if (dev->dvb.frontend) {
1053 dev->dvb.frontend->ops.tuner_ops.init = philips_tda827x_tuner_init;
1054 dev->dvb.frontend->ops.tuner_ops.sleep = philips_tda827x_tuner_sleep;
1055 dev->dvb.frontend->ops.tuner_ops.set_params = philips_tda827x_tuner_set_params;
1056 }
1026 break; 1057 break;
1027 case SAA7134_BOARD_FLYDVBT_DUO_CARDBUS: 1058 case SAA7134_BOARD_FLYDVBT_DUO_CARDBUS:
1028 dev->dvb.frontend = tda10046_attach(&tda827x_lifeview_config, 1059 dev->dvb.frontend = tda10046_attach(&tda827x_lifeview_config,
1029 &dev->i2c_adap); 1060 &dev->i2c_adap);
1061 if (dev->dvb.frontend) {
1062 dev->dvb.frontend->ops.tuner_ops.init = philips_tda827x_tuner_init;
1063 dev->dvb.frontend->ops.tuner_ops.sleep = philips_tda827x_tuner_sleep;
1064 dev->dvb.frontend->ops.tuner_ops.set_params = philips_tda827x_tuner_set_params;
1065 }
1030 break; 1066 break;
1031 case SAA7134_BOARD_PHILIPS_EUROPA: 1067 case SAA7134_BOARD_PHILIPS_EUROPA:
1032 dev->dvb.frontend = tda10046_attach(&philips_europa_config, 1068 dev->dvb.frontend = tda10046_attach(&philips_europa_config,
1033 &dev->i2c_adap); 1069 &dev->i2c_adap);
1070 if (dev->dvb.frontend) {
1071 dev->original_demod_sleep = dev->dvb.frontend->ops.sleep;
1072 dev->dvb.frontend->ops.sleep = philips_europa_demod_sleep;
1073 dev->dvb.frontend->ops.tuner_ops.init = philips_europa_tuner_init;
1074 dev->dvb.frontend->ops.tuner_ops.sleep = philips_europa_tuner_sleep;
1075 dev->dvb.frontend->ops.tuner_ops.set_params = philips_td1316_tuner_set_params;
1076 }
1034 break; 1077 break;
1035 case SAA7134_BOARD_VIDEOMATE_DVBT_300: 1078 case SAA7134_BOARD_VIDEOMATE_DVBT_300:
1036 dev->dvb.frontend = tda10046_attach(&philips_europa_config, 1079 dev->dvb.frontend = tda10046_attach(&philips_europa_config,
1037 &dev->i2c_adap); 1080 &dev->i2c_adap);
1081 if (dev->dvb.frontend) {
1082 dev->dvb.frontend->ops.tuner_ops.init = philips_europa_tuner_init;
1083 dev->dvb.frontend->ops.tuner_ops.sleep = philips_europa_tuner_sleep;
1084 dev->dvb.frontend->ops.tuner_ops.set_params = philips_td1316_tuner_set_params;
1085 }
1038 break; 1086 break;
1039 case SAA7134_BOARD_VIDEOMATE_DVBT_200: 1087 case SAA7134_BOARD_VIDEOMATE_DVBT_200:
1040 dev->dvb.frontend = tda10046_attach(&philips_tu1216_61_config, 1088 dev->dvb.frontend = tda10046_attach(&philips_tu1216_61_config,
1041 &dev->i2c_adap); 1089 &dev->i2c_adap);
1090 if (dev->dvb.frontend) {
1091 dev->dvb.frontend->ops.tuner_ops.init = philips_tu1216_tuner_61_init;
1092 dev->dvb.frontend->ops.tuner_ops.set_params = philips_tu1216_tuner_61_set_params;
1093 }
1042 break; 1094 break;
1043 case SAA7134_BOARD_PHILIPS_TIGER: 1095 case SAA7134_BOARD_PHILIPS_TIGER:
1044 dev->dvb.frontend = tda10046_attach(&philips_tiger_config, 1096 dev->dvb.frontend = tda10046_attach(&philips_tiger_config,
1045 &dev->i2c_adap); 1097 &dev->i2c_adap);
1098 if (dev->dvb.frontend) {
1099 dev->dvb.frontend->ops.tuner_ops.init = philips_tiger_tuner_init;
1100 dev->dvb.frontend->ops.tuner_ops.sleep = philips_tiger_tuner_sleep;
1101 dev->dvb.frontend->ops.tuner_ops.set_params = philips_tiger_tuner_set_params;
1102 }
1046 break; 1103 break;
1047 case SAA7134_BOARD_ASUSTeK_P7131_DUAL: 1104 case SAA7134_BOARD_ASUSTeK_P7131_DUAL:
1048 dev->dvb.frontend = tda10046_attach(&philips_tiger_config, 1105 dev->dvb.frontend = tda10046_attach(&philips_tiger_config,
1049 &dev->i2c_adap); 1106 &dev->i2c_adap);
1107 if (dev->dvb.frontend) {
1108 dev->dvb.frontend->ops.tuner_ops.init = philips_tiger_tuner_init;
1109 dev->dvb.frontend->ops.tuner_ops.sleep = philips_tiger_tuner_sleep;
1110 dev->dvb.frontend->ops.tuner_ops.set_params = philips_tiger_tuner_set_params;
1111 }
1050 break; 1112 break;
1051 case SAA7134_BOARD_FLYDVBT_LR301: 1113 case SAA7134_BOARD_FLYDVBT_LR301:
1052 dev->dvb.frontend = tda10046_attach(&tda827x_lifeview_config, 1114 dev->dvb.frontend = tda10046_attach(&tda827x_lifeview_config,
1053 &dev->i2c_adap); 1115 &dev->i2c_adap);
1116 if (dev->dvb.frontend) {
1117 dev->dvb.frontend->ops.tuner_ops.init = philips_tda827x_tuner_init;
1118 dev->dvb.frontend->ops.tuner_ops.sleep = philips_tda827x_tuner_sleep;
1119 dev->dvb.frontend->ops.tuner_ops.set_params = philips_tda827x_tuner_set_params;
1120 }
1054 break; 1121 break;
1055 case SAA7134_BOARD_FLYDVB_TRIO: 1122 case SAA7134_BOARD_FLYDVB_TRIO:
1056 dev->dvb.frontend = tda10046_attach(&lifeview_trio_config, 1123 dev->dvb.frontend = tda10046_attach(&lifeview_trio_config,
1057 &dev->i2c_adap); 1124 &dev->i2c_adap);
1125 if (dev->dvb.frontend) {
1126 dev->dvb.frontend->ops.tuner_ops.sleep = lifeview_trio_tuner_sleep;
1127 dev->dvb.frontend->ops.tuner_ops.set_params = lifeview_trio_tuner_set_params;
1128 }
1058 break; 1129 break;
1059 case SAA7134_BOARD_ADS_DUO_CARDBUS_PTV331: 1130 case SAA7134_BOARD_ADS_DUO_CARDBUS_PTV331:
1060 dev->dvb.frontend = tda10046_attach(&ads_tech_duo_config, 1131 dev->dvb.frontend = tda10046_attach(&ads_tech_duo_config,
1061 &dev->i2c_adap); 1132 &dev->i2c_adap);
1133 if (dev->dvb.frontend) {
1134 dev->dvb.frontend->ops.tuner_ops.init = ads_duo_tuner_init;
1135 dev->dvb.frontend->ops.tuner_ops.sleep = ads_duo_tuner_sleep;
1136 dev->dvb.frontend->ops.tuner_ops.set_params = ads_duo_tuner_set_params;
1137 }
1062 break; 1138 break;
1063 case SAA7134_BOARD_TEVION_DVBT_220RF: 1139 case SAA7134_BOARD_TEVION_DVBT_220RF:
1064 dev->dvb.frontend = tda10046_attach(&tevion_dvbt220rf_config, 1140 dev->dvb.frontend = tda10046_attach(&tevion_dvbt220rf_config,
1065 &dev->i2c_adap); 1141 &dev->i2c_adap);
1142 if (dev->dvb.frontend) {
1143 dev->dvb.frontend->ops.tuner_ops.sleep = tevion_dvb220rf_tuner_sleep;
1144 dev->dvb.frontend->ops.tuner_ops.set_params = tevion_dvb220rf_tuner_set_params;
1145 }
1066 break; 1146 break;
1067 case SAA7134_BOARD_FLYDVBT_HYBRID_CARDBUS: 1147 case SAA7134_BOARD_FLYDVBT_HYBRID_CARDBUS:
1068 dev->dvb.frontend = tda10046_attach(&ads_tech_duo_config, 1148 dev->dvb.frontend = tda10046_attach(&ads_tech_duo_config,
1069 &dev->i2c_adap); 1149 &dev->i2c_adap);
1150 if (dev->dvb.frontend) {
1151 dev->dvb.frontend->ops.tuner_ops.init = ads_duo_tuner_init;
1152 dev->dvb.frontend->ops.tuner_ops.sleep = ads_duo_tuner_sleep;
1153 dev->dvb.frontend->ops.tuner_ops.set_params = ads_duo_tuner_set_params;
1154 }
1070 break; 1155 break;
1071#endif 1156#endif
1072#ifdef HAVE_NXT200X 1157#ifdef HAVE_NXT200X
1073 case SAA7134_BOARD_AVERMEDIA_AVERTVHD_A180: 1158 case SAA7134_BOARD_AVERMEDIA_AVERTVHD_A180:
1074 dev->dvb.frontend = nxt200x_attach(&avertvhda180, &dev->i2c_adap); 1159 dev->dvb.frontend = nxt200x_attach(&avertvhda180, &dev->i2c_adap);
1160 if (dev->dvb.frontend) {
1161 dvb_pll_attach(dev->dvb.frontend, 0x61, &dev->i2c_adap, &dvb_pll_tdhu2);
1162 }
1075 break; 1163 break;
1076 case SAA7134_BOARD_KWORLD_ATSC110: 1164 case SAA7134_BOARD_KWORLD_ATSC110:
1077 dev->dvb.frontend = nxt200x_attach(&kworldatsc110, &dev->i2c_adap); 1165 dev->dvb.frontend = nxt200x_attach(&kworldatsc110, &dev->i2c_adap);
1166 if (dev->dvb.frontend) {
1167 dvb_pll_attach(dev->dvb.frontend, 0x61, &dev->i2c_adap, &dvb_pll_tuv1236d);
1168 }
1078 break; 1169 break;
1079#endif 1170#endif
1080 default: 1171 default:
@@ -1088,7 +1179,7 @@ static int dvb_init(struct saa7134_dev *dev)
1088 } 1179 }
1089 1180
1090 /* register everything else */ 1181 /* register everything else */
1091 return videobuf_dvb_register(&dev->dvb, THIS_MODULE, dev); 1182 return videobuf_dvb_register(&dev->dvb, THIS_MODULE, dev, &dev->pci->dev);
1092} 1183}
1093 1184
1094static int dvb_fini(struct saa7134_dev *dev) 1185static int dvb_fini(struct saa7134_dev *dev)
diff --git a/drivers/media/video/saa7134/saa7134-empress.c b/drivers/media/video/saa7134/saa7134-empress.c
index 1d972edb3be..65d044086ce 100644
--- a/drivers/media/video/saa7134/saa7134-empress.c
+++ b/drivers/media/video/saa7134/saa7134-empress.c
@@ -64,8 +64,10 @@ static void ts_reset_encoder(struct saa7134_dev* dev)
64 64
65static int ts_init_encoder(struct saa7134_dev* dev) 65static int ts_init_encoder(struct saa7134_dev* dev)
66{ 66{
67 struct v4l2_ext_controls ctrls = { V4L2_CTRL_CLASS_MPEG, 0 };
68
67 ts_reset_encoder(dev); 69 ts_reset_encoder(dev);
68 saa7134_i2c_call_clients(dev, VIDIOC_S_MPEGCOMP, NULL); 70 saa7134_i2c_call_clients(dev, VIDIOC_S_EXT_CTRLS, &ctrls);
69 dev->empress_started = 1; 71 dev->empress_started = 1;
70 return 0; 72 return 0;
71} 73}
@@ -162,6 +164,7 @@ static int ts_do_ioctl(struct inode *inode, struct file *file,
162 unsigned int cmd, void *arg) 164 unsigned int cmd, void *arg)
163{ 165{
164 struct saa7134_dev *dev = file->private_data; 166 struct saa7134_dev *dev = file->private_data;
167 struct v4l2_ext_controls *ctrls = arg;
165 168
166 if (debug > 1) 169 if (debug > 1)
167 v4l_print_ioctl(dev->name,cmd); 170 v4l_print_ioctl(dev->name,cmd);
@@ -278,12 +281,31 @@ static int ts_do_ioctl(struct inode *inode, struct file *file,
278 return saa7134_common_ioctl(dev, cmd, arg); 281 return saa7134_common_ioctl(dev, cmd, arg);
279 282
280 case VIDIOC_S_MPEGCOMP: 283 case VIDIOC_S_MPEGCOMP:
284 printk(KERN_WARNING "VIDIOC_S_MPEGCOMP is obsolete. "
285 "Replace with VIDIOC_S_EXT_CTRLS!");
281 saa7134_i2c_call_clients(dev, VIDIOC_S_MPEGCOMP, arg); 286 saa7134_i2c_call_clients(dev, VIDIOC_S_MPEGCOMP, arg);
282 ts_init_encoder(dev); 287 ts_init_encoder(dev);
283 return 0; 288 return 0;
284 case VIDIOC_G_MPEGCOMP: 289 case VIDIOC_G_MPEGCOMP:
290 printk(KERN_WARNING "VIDIOC_G_MPEGCOMP is obsolete. "
291 "Replace with VIDIOC_G_EXT_CTRLS!");
285 saa7134_i2c_call_clients(dev, VIDIOC_G_MPEGCOMP, arg); 292 saa7134_i2c_call_clients(dev, VIDIOC_G_MPEGCOMP, arg);
286 return 0; 293 return 0;
294 case VIDIOC_S_EXT_CTRLS:
295 /* count == 0 is abused in saa6752hs.c, so that special
296 case is handled here explicitly. */
297 if (ctrls->count == 0)
298 return 0;
299 if (ctrls->ctrl_class != V4L2_CTRL_CLASS_MPEG)
300 return -EINVAL;
301 saa7134_i2c_call_clients(dev, VIDIOC_S_EXT_CTRLS, arg);
302 ts_init_encoder(dev);
303 return 0;
304 case VIDIOC_G_EXT_CTRLS:
305 if (ctrls->ctrl_class != V4L2_CTRL_CLASS_MPEG)
306 return -EINVAL;
307 saa7134_i2c_call_clients(dev, VIDIOC_G_EXT_CTRLS, arg);
308 return 0;
287 309
288 default: 310 default:
289 return -ENOIOCTLCMD; 311 return -ENOIOCTLCMD;
diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c
index 1426e4c8602..7c595492c56 100644
--- a/drivers/media/video/saa7134/saa7134-input.c
+++ b/drivers/media/video/saa7134/saa7134-input.c
@@ -37,6 +37,10 @@ static unsigned int ir_debug = 0;
37module_param(ir_debug, int, 0644); 37module_param(ir_debug, int, 0644);
38MODULE_PARM_DESC(ir_debug,"enable debug messages [IR]"); 38MODULE_PARM_DESC(ir_debug,"enable debug messages [IR]");
39 39
40static int pinnacle_remote = 0;
41module_param(pinnacle_remote, int, 0644); /* Choose Pinnacle PCTV remote */
42MODULE_PARM_DESC(pinnacle_remote, "Specify Pinnacle PCTV remote: 0=coloured, 1=grey (defaults to 0)");
43
40#define dprintk(fmt, arg...) if (ir_debug) \ 44#define dprintk(fmt, arg...) if (ir_debug) \
41 printk(KERN_DEBUG "%s/ir: " fmt, dev->name , ## arg) 45 printk(KERN_DEBUG "%s/ir: " fmt, dev->name , ## arg)
42#define i2cdprintk(fmt, arg...) if (ir_debug) \ 46#define i2cdprintk(fmt, arg...) if (ir_debug) \
@@ -316,8 +320,13 @@ void saa7134_set_i2c_ir(struct saa7134_dev *dev, struct IR_i2c *ir)
316 switch (dev->board) { 320 switch (dev->board) {
317 case SAA7134_BOARD_PINNACLE_PCTV_110i: 321 case SAA7134_BOARD_PINNACLE_PCTV_110i:
318 snprintf(ir->c.name, sizeof(ir->c.name), "Pinnacle PCTV"); 322 snprintf(ir->c.name, sizeof(ir->c.name), "Pinnacle PCTV");
319 ir->get_key = get_key_pinnacle; 323 if (pinnacle_remote == 0) {
320 ir->ir_codes = ir_codes_pinnacle; 324 ir->get_key = get_key_pinnacle_color;
325 ir->ir_codes = ir_codes_pinnacle_color;
326 } else {
327 ir->get_key = get_key_pinnacle_grey;
328 ir->ir_codes = ir_codes_pinnacle_grey;
329 }
321 break; 330 break;
322 case SAA7134_BOARD_UPMOST_PURPLE_TV: 331 case SAA7134_BOARD_UPMOST_PURPLE_TV:
323 snprintf(ir->c.name, sizeof(ir->c.name), "Purple TV"); 332 snprintf(ir->c.name, sizeof(ir->c.name), "Purple TV");
diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h
index 353af3a8b76..d5ee99c574c 100644
--- a/drivers/media/video/saa7134/saa7134.h
+++ b/drivers/media/video/saa7134/saa7134.h
@@ -33,6 +33,7 @@
33 33
34#include <asm/io.h> 34#include <asm/io.h>
35 35
36#include <media/v4l2-common.h>
36#include <media/tuner.h> 37#include <media/tuner.h>
37#include <media/ir-common.h> 38#include <media/ir-common.h>
38#include <media/ir-kbd-i2c.h> 39#include <media/ir-kbd-i2c.h>
@@ -221,6 +222,7 @@ struct saa7134_format {
221#define SAA7134_BOARD_AVERMEDIA_A169_B1 92 222#define SAA7134_BOARD_AVERMEDIA_A169_B1 92
222#define SAA7134_BOARD_MD7134_BRIDGE_2 93 223#define SAA7134_BOARD_MD7134_BRIDGE_2 93
223#define SAA7134_BOARD_FLYDVBT_HYBRID_CARDBUS 94 224#define SAA7134_BOARD_FLYDVBT_HYBRID_CARDBUS 94
225#define SAA7134_BOARD_FLYVIDEO3000_NTSC 95
224 226
225#define SAA7134_MAXBOARDS 8 227#define SAA7134_MAXBOARDS 8
226#define SAA7134_INPUT_MAX 8 228#define SAA7134_INPUT_MAX 8
@@ -531,6 +533,7 @@ struct saa7134_dev {
531 533
532 /* SAA7134_MPEG_DVB only */ 534 /* SAA7134_MPEG_DVB only */
533 struct videobuf_dvb dvb; 535 struct videobuf_dvb dvb;
536 int (*original_demod_sleep)(struct dvb_frontend* fe);
534}; 537};
535 538
536/* ----------------------------------------------------------- */ 539/* ----------------------------------------------------------- */
diff --git a/drivers/media/video/se401.h b/drivers/media/video/se401.h
index a7a216bd441..c0891b3e001 100644
--- a/drivers/media/video/se401.h
+++ b/drivers/media/video/se401.h
@@ -4,6 +4,7 @@
4 4
5#include <asm/uaccess.h> 5#include <asm/uaccess.h>
6#include <linux/videodev.h> 6#include <linux/videodev.h>
7#include <media/v4l2-common.h>
7#include <linux/smp_lock.h> 8#include <linux/smp_lock.h>
8#include <linux/mutex.h> 9#include <linux/mutex.h>
9 10
diff --git a/drivers/media/video/sn9c102/sn9c102_core.c b/drivers/media/video/sn9c102/sn9c102_core.c
index ea4394dc941..48d138a7c72 100644
--- a/drivers/media/video/sn9c102/sn9c102_core.c
+++ b/drivers/media/video/sn9c102/sn9c102_core.c
@@ -2608,11 +2608,9 @@ static int sn9c102_ioctl_v4l2(struct inode* inode, struct file* filp,
2608 case VIDIOC_G_CTRL: 2608 case VIDIOC_G_CTRL:
2609 return sn9c102_vidioc_g_ctrl(cam, arg); 2609 return sn9c102_vidioc_g_ctrl(cam, arg);
2610 2610
2611 case VIDIOC_S_CTRL_OLD:
2612 case VIDIOC_S_CTRL: 2611 case VIDIOC_S_CTRL:
2613 return sn9c102_vidioc_s_ctrl(cam, arg); 2612 return sn9c102_vidioc_s_ctrl(cam, arg);
2614 2613
2615 case VIDIOC_CROPCAP_OLD:
2616 case VIDIOC_CROPCAP: 2614 case VIDIOC_CROPCAP:
2617 return sn9c102_vidioc_cropcap(cam, arg); 2615 return sn9c102_vidioc_cropcap(cam, arg);
2618 2616
@@ -2659,7 +2657,6 @@ static int sn9c102_ioctl_v4l2(struct inode* inode, struct file* filp,
2659 case VIDIOC_G_PARM: 2657 case VIDIOC_G_PARM:
2660 return sn9c102_vidioc_g_parm(cam, arg); 2658 return sn9c102_vidioc_g_parm(cam, arg);
2661 2659
2662 case VIDIOC_S_PARM_OLD:
2663 case VIDIOC_S_PARM: 2660 case VIDIOC_S_PARM:
2664 return sn9c102_vidioc_s_parm(cam, arg); 2661 return sn9c102_vidioc_s_parm(cam, arg);
2665 2662
diff --git a/drivers/media/video/stradis.c b/drivers/media/video/stradis.c
index 07476c71174..6be9c1131e1 100644
--- a/drivers/media/video/stradis.c
+++ b/drivers/media/video/stradis.c
@@ -42,6 +42,7 @@
42#include <asm/uaccess.h> 42#include <asm/uaccess.h>
43#include <linux/vmalloc.h> 43#include <linux/vmalloc.h>
44#include <linux/videodev.h> 44#include <linux/videodev.h>
45#include <media/v4l2-common.h>
45 46
46#include "saa7146.h" 47#include "saa7146.h"
47#include "saa7146reg.h" 48#include "saa7146reg.h"
diff --git a/drivers/media/video/stv680.c b/drivers/media/video/stv680.c
index b38bda83a7c..351b182d921 100644
--- a/drivers/media/video/stv680.c
+++ b/drivers/media/video/stv680.c
@@ -66,6 +66,7 @@
66#include <linux/pagemap.h> 66#include <linux/pagemap.h>
67#include <linux/errno.h> 67#include <linux/errno.h>
68#include <linux/videodev.h> 68#include <linux/videodev.h>
69#include <media/v4l2-common.h>
69#include <linux/usb.h> 70#include <linux/usb.h>
70#include <linux/mutex.h> 71#include <linux/mutex.h>
71 72
diff --git a/drivers/media/video/tda9875.c b/drivers/media/video/tda9875.c
index 103ccb91929..827633b3bb4 100644
--- a/drivers/media/video/tda9875.c
+++ b/drivers/media/video/tda9875.c
@@ -26,6 +26,7 @@
26#include <linux/errno.h> 26#include <linux/errno.h>
27#include <linux/slab.h> 27#include <linux/slab.h>
28#include <linux/videodev.h> 28#include <linux/videodev.h>
29#include <media/v4l2-common.h>
29#include <linux/i2c.h> 30#include <linux/i2c.h>
30#include <linux/i2c-algo-bit.h> 31#include <linux/i2c-algo-bit.h>
31#include <linux/init.h> 32#include <linux/init.h>
@@ -163,7 +164,7 @@ static void do_tda9875_init(struct i2c_client *client)
163 struct tda9875 *t = i2c_get_clientdata(client); 164 struct tda9875 *t = i2c_get_clientdata(client);
164 dprintk("In tda9875_init\n"); 165 dprintk("In tda9875_init\n");
165 tda9875_write(client, TDA9875_CFG, 0xd0 ); /*reg de config 0 (reset)*/ 166 tda9875_write(client, TDA9875_CFG, 0xd0 ); /*reg de config 0 (reset)*/
166 tda9875_write(client, TDA9875_MSR, 0x03 ); /* Monitor 0b00000XXX*/ 167 tda9875_write(client, TDA9875_MSR, 0x03 ); /* Monitor 0b00000XXX*/
167 tda9875_write(client, TDA9875_C1MSB, 0x00 ); /*Car1(FM) MSB XMHz*/ 168 tda9875_write(client, TDA9875_C1MSB, 0x00 ); /*Car1(FM) MSB XMHz*/
168 tda9875_write(client, TDA9875_C1MIB, 0x00 ); /*Car1(FM) MIB XMHz*/ 169 tda9875_write(client, TDA9875_C1MIB, 0x00 ); /*Car1(FM) MIB XMHz*/
169 tda9875_write(client, TDA9875_C1LSB, 0x00 ); /*Car1(FM) LSB XMHz*/ 170 tda9875_write(client, TDA9875_C1LSB, 0x00 ); /*Car1(FM) LSB XMHz*/
diff --git a/drivers/media/video/tda9887.c b/drivers/media/video/tda9887.c
index 0d54f6c1982..b6ae969563b 100644
--- a/drivers/media/video/tda9887.c
+++ b/drivers/media/video/tda9887.c
@@ -18,49 +18,21 @@
18 TDA9886 (PAL, SECAM, NTSC) 18 TDA9886 (PAL, SECAM, NTSC)
19 TDA9887 (PAL, SECAM, NTSC, FM Radio) 19 TDA9887 (PAL, SECAM, NTSC, FM Radio)
20 20
21 found on: 21 Used as part of several tuners
22 - Pinnacle PCTV (Jul.2002 Version with MT2032, bttv)
23 TDA9887 (world), TDA9885 (USA)
24 Note: OP2 of tda988x must be set to 1, else MT2032 is disabled!
25 - KNC One TV-Station RDS (saa7134)
26 - Hauppauge PVR-150/500 (possibly more)
27*/ 22*/
28 23
24#define tda9887_info(fmt, arg...) do {\
25 printk(KERN_INFO "%s %d-%04x (tda9887): " fmt, t->i2c.name, \
26 i2c_adapter_id(t->i2c.adapter), t->i2c.addr , ##arg); } while (0)
27#define tda9887_dbg(fmt, arg...) do {\
28 if (tuner_debug) \
29 printk(KERN_INFO "%s %d-%04x (tda9887): " fmt, t->i2c.name, \
30 i2c_adapter_id(t->i2c.adapter), t->i2c.addr , ##arg); } while (0)
29 31
30/* Addresses to scan */
31static unsigned short normal_i2c[] = {
32 0x84 >>1,
33 0x86 >>1,
34 0x96 >>1,
35 I2C_CLIENT_END,
36};
37I2C_CLIENT_INSMOD;
38
39/* insmod options */
40static unsigned int debug = 0;
41module_param(debug, int, 0644);
42MODULE_LICENSE("GPL");
43 32
44/* ---------------------------------------------------------------------- */ 33/* ---------------------------------------------------------------------- */
45 34
46#define UNSET (-1U) 35#define UNSET (-1U)
47#define tda9887_info(fmt, arg...) do {\
48 printk(KERN_INFO "%s %d-%04x: " fmt, t->client.name, \
49 i2c_adapter_id(t->client.adapter), t->client.addr , ##arg); } while (0)
50#define tda9887_dbg(fmt, arg...) do {\
51 if (debug) \
52 printk(KERN_INFO "%s %d-%04x: " fmt, t->client.name, \
53 i2c_adapter_id(t->client.adapter), t->client.addr , ##arg); } while (0)
54
55struct tda9887 {
56 struct i2c_client client;
57 v4l2_std_id std;
58 enum tuner_mode mode;
59 unsigned int config;
60 unsigned int using_v4l2;
61 unsigned int radio_mode;
62 unsigned char data[4];
63};
64 36
65struct tvnorm { 37struct tvnorm {
66 v4l2_std_id std; 38 v4l2_std_id std;
@@ -70,9 +42,6 @@ struct tvnorm {
70 unsigned char e; 42 unsigned char e;
71}; 43};
72 44
73static struct i2c_driver driver;
74static struct i2c_client client_template;
75
76/* ---------------------------------------------------------------------- */ 45/* ---------------------------------------------------------------------- */
77 46
78// 47//
@@ -281,7 +250,7 @@ static struct tvnorm radio_mono = {
281 250
282/* ---------------------------------------------------------------------- */ 251/* ---------------------------------------------------------------------- */
283 252
284static void dump_read_message(struct tda9887 *t, unsigned char *buf) 253static void dump_read_message(struct tuner *t, unsigned char *buf)
285{ 254{
286 static char *afc[16] = { 255 static char *afc[16] = {
287 "- 12.5 kHz", 256 "- 12.5 kHz",
@@ -309,7 +278,7 @@ static void dump_read_message(struct tda9887 *t, unsigned char *buf)
309 tda9887_info(" vfi level : %s\n", (buf[0] & 0x80) ? "high" : "low"); 278 tda9887_info(" vfi level : %s\n", (buf[0] & 0x80) ? "high" : "low");
310} 279}
311 280
312static void dump_write_message(struct tda9887 *t, unsigned char *buf) 281static void dump_write_message(struct tuner *t, unsigned char *buf)
313{ 282{
314 static char *sound[4] = { 283 static char *sound[4] = {
315 "AM/TV", 284 "AM/TV",
@@ -405,13 +374,13 @@ static void dump_write_message(struct tda9887 *t, unsigned char *buf)
405 374
406/* ---------------------------------------------------------------------- */ 375/* ---------------------------------------------------------------------- */
407 376
408static int tda9887_set_tvnorm(struct tda9887 *t, char *buf) 377static int tda9887_set_tvnorm(struct tuner *t, char *buf)
409{ 378{
410 struct tvnorm *norm = NULL; 379 struct tvnorm *norm = NULL;
411 int i; 380 int i;
412 381
413 if (t->mode == T_RADIO) { 382 if (t->mode == V4L2_TUNER_RADIO) {
414 if (t->radio_mode == V4L2_TUNER_MODE_MONO) 383 if (t->audmode == V4L2_TUNER_MODE_MONO)
415 norm = &radio_mono; 384 norm = &radio_mono;
416 else 385 else
417 norm = &radio_stereo; 386 norm = &radio_stereo;
@@ -445,7 +414,7 @@ module_param(port2, int, 0644);
445module_param(qss, int, 0644); 414module_param(qss, int, 0644);
446module_param(adjust, int, 0644); 415module_param(adjust, int, 0644);
447 416
448static int tda9887_set_insmod(struct tda9887 *t, char *buf) 417static int tda9887_set_insmod(struct tuner *t, char *buf)
449{ 418{
450 if (UNSET != port1) { 419 if (UNSET != port1) {
451 if (port1) 420 if (port1)
@@ -474,27 +443,27 @@ static int tda9887_set_insmod(struct tda9887 *t, char *buf)
474 return 0; 443 return 0;
475} 444}
476 445
477static int tda9887_set_config(struct tda9887 *t, char *buf) 446static int tda9887_set_config(struct tuner *t, char *buf)
478{ 447{
479 if (t->config & TDA9887_PORT1_ACTIVE) 448 if (t->tda9887_config & TDA9887_PORT1_ACTIVE)
480 buf[1] &= ~cOutputPort1Inactive; 449 buf[1] &= ~cOutputPort1Inactive;
481 if (t->config & TDA9887_PORT1_INACTIVE) 450 if (t->tda9887_config & TDA9887_PORT1_INACTIVE)
482 buf[1] |= cOutputPort1Inactive; 451 buf[1] |= cOutputPort1Inactive;
483 if (t->config & TDA9887_PORT2_ACTIVE) 452 if (t->tda9887_config & TDA9887_PORT2_ACTIVE)
484 buf[1] &= ~cOutputPort2Inactive; 453 buf[1] &= ~cOutputPort2Inactive;
485 if (t->config & TDA9887_PORT2_INACTIVE) 454 if (t->tda9887_config & TDA9887_PORT2_INACTIVE)
486 buf[1] |= cOutputPort2Inactive; 455 buf[1] |= cOutputPort2Inactive;
487 456
488 if (t->config & TDA9887_QSS) 457 if (t->tda9887_config & TDA9887_QSS)
489 buf[1] |= cQSS; 458 buf[1] |= cQSS;
490 if (t->config & TDA9887_INTERCARRIER) 459 if (t->tda9887_config & TDA9887_INTERCARRIER)
491 buf[1] &= ~cQSS; 460 buf[1] &= ~cQSS;
492 461
493 if (t->config & TDA9887_AUTOMUTE) 462 if (t->tda9887_config & TDA9887_AUTOMUTE)
494 buf[1] |= cAutoMuteFmActive; 463 buf[1] |= cAutoMuteFmActive;
495 if (t->config & TDA9887_DEEMPHASIS_MASK) { 464 if (t->tda9887_config & TDA9887_DEEMPHASIS_MASK) {
496 buf[2] &= ~0x60; 465 buf[2] &= ~0x60;
497 switch (t->config & TDA9887_DEEMPHASIS_MASK) { 466 switch (t->tda9887_config & TDA9887_DEEMPHASIS_MASK) {
498 case TDA9887_DEEMPHASIS_NONE: 467 case TDA9887_DEEMPHASIS_NONE:
499 buf[2] |= cDeemphasisOFF; 468 buf[2] |= cDeemphasisOFF;
500 break; 469 break;
@@ -506,153 +475,36 @@ static int tda9887_set_config(struct tda9887 *t, char *buf)
506 break; 475 break;
507 } 476 }
508 } 477 }
509 if (t->config & TDA9887_TOP_SET) { 478 if (t->tda9887_config & TDA9887_TOP_SET) {
510 buf[2] &= ~cTopMask; 479 buf[2] &= ~cTopMask;
511 buf[2] |= (t->config >> 8) & cTopMask; 480 buf[2] |= (t->tda9887_config >> 8) & cTopMask;
512 } 481 }
513 if ((t->config & TDA9887_INTERCARRIER_NTSC) && (t->std & V4L2_STD_NTSC)) 482 if ((t->tda9887_config & TDA9887_INTERCARRIER_NTSC) && (t->std & V4L2_STD_NTSC))
514 buf[1] &= ~cQSS; 483 buf[1] &= ~cQSS;
515 return 0; 484 return 0;
516} 485}
517 486
518/* ---------------------------------------------------------------------- */ 487/* ---------------------------------------------------------------------- */
519 488
520static char pal[] = "--"; 489static int tda9887_status(struct tuner *t)
521static char secam[] = "--";
522static char ntsc[] = "-";
523
524module_param_string(pal, pal, sizeof(pal), 0644);
525module_param_string(secam, secam, sizeof(secam), 0644);
526module_param_string(ntsc, ntsc, sizeof(ntsc), 0644);
527
528static int tda9887_fixup_std(struct tda9887 *t)
529{
530 /* get more precise norm info from insmod option */
531 if ((t->std & V4L2_STD_PAL) == V4L2_STD_PAL) {
532 switch (pal[0]) {
533 case 'b':
534 case 'B':
535 case 'g':
536 case 'G':
537 case 'h':
538 case 'H':
539 case 'n':
540 case 'N':
541 if (pal[1] == 'c' || pal[1] == 'C') {
542 tda9887_dbg("insmod fixup: PAL => PAL-Nc\n");
543 t->std = V4L2_STD_PAL_Nc;
544 } else {
545 tda9887_dbg("insmod fixup: PAL => PAL-BGHN\n");
546 t->std = V4L2_STD_PAL_BG | V4L2_STD_PAL_H | V4L2_STD_PAL_N;
547 }
548 break;
549 case 'i':
550 case 'I':
551 tda9887_dbg("insmod fixup: PAL => PAL-I\n");
552 t->std = V4L2_STD_PAL_I;
553 break;
554 case 'd':
555 case 'D':
556 case 'k':
557 case 'K':
558 tda9887_dbg("insmod fixup: PAL => PAL-DK\n");
559 t->std = V4L2_STD_PAL_DK;
560 break;
561 case 'm':
562 case 'M':
563 tda9887_dbg("insmod fixup: PAL => PAL-M\n");
564 t->std = V4L2_STD_PAL_M;
565 break;
566 case '-':
567 /* default parameter, do nothing */
568 break;
569 default:
570 tda9887_info("pal= argument not recognised\n");
571 break;
572 }
573 }
574 if ((t->std & V4L2_STD_SECAM) == V4L2_STD_SECAM) {
575 switch (secam[0]) {
576 case 'b':
577 case 'B':
578 case 'g':
579 case 'G':
580 case 'h':
581 case 'H':
582 tda9887_dbg("insmod fixup: SECAM => SECAM-BGH\n");
583 t->std = V4L2_STD_SECAM_B | V4L2_STD_SECAM_G | V4L2_STD_SECAM_H;
584 break;
585 case 'd':
586 case 'D':
587 case 'k':
588 case 'K':
589 tda9887_dbg("insmod fixup: SECAM => SECAM-DK\n");
590 t->std = V4L2_STD_SECAM_DK;
591 break;
592 case 'l':
593 case 'L':
594 if (secam[1] == 'c' || secam[1] == 'C') {
595 tda9887_dbg("insmod fixup: SECAM => SECAM-L'\n");
596 t->std = V4L2_STD_SECAM_LC;
597 } else {
598 tda9887_dbg("insmod fixup: SECAM => SECAM-L\n");
599 t->std = V4L2_STD_SECAM_L;
600 }
601 break;
602 case '-':
603 /* default parameter, do nothing */
604 break;
605 default:
606 tda9887_info("secam= argument not recognised\n");
607 break;
608 }
609 }
610 if ((t->std & V4L2_STD_NTSC) == V4L2_STD_NTSC) {
611 switch (ntsc[0]) {
612 case 'm':
613 case 'M':
614 tda9887_dbg("insmod fixup: NTSC => NTSC-M\n");
615 t->std = V4L2_STD_NTSC_M;
616 break;
617 case 'j':
618 case 'J':
619 tda9887_dbg("insmod fixup: NTSC => NTSC_M_JP\n");
620 t->std = V4L2_STD_NTSC_M_JP;
621 break;
622 case 'k':
623 case 'K':
624 tda9887_dbg("insmod fixup: NTSC => NTSC_M_KR\n");
625 t->std = V4L2_STD_NTSC_M_KR;
626 break;
627 case '-':
628 /* default parameter, do nothing */
629 break;
630 default:
631 tda9887_info("ntsc= argument not recognised\n");
632 break;
633 }
634 }
635 return 0;
636}
637
638static int tda9887_status(struct tda9887 *t)
639{ 490{
640 unsigned char buf[1]; 491 unsigned char buf[1];
641 int rc; 492 int rc;
642 493
643 memset(buf,0,sizeof(buf)); 494 memset(buf,0,sizeof(buf));
644 if (1 != (rc = i2c_master_recv(&t->client,buf,1))) 495 if (1 != (rc = i2c_master_recv(&t->i2c,buf,1)))
645 tda9887_info("i2c i/o error: rc == %d (should be 1)\n",rc); 496 tda9887_info("i2c i/o error: rc == %d (should be 1)\n",rc);
646 dump_read_message(t, buf); 497 dump_read_message(t, buf);
647 return 0; 498 return 0;
648} 499}
649 500
650static int tda9887_configure(struct tda9887 *t) 501static void tda9887_configure(struct i2c_client *client)
651{ 502{
503 struct tuner *t = i2c_get_clientdata(client);
652 int rc; 504 int rc;
653 505
654 memset(t->data,0,sizeof(t->data)); 506 memset(t->tda9887_data,0,sizeof(t->tda9887_data));
655 tda9887_set_tvnorm(t,t->data); 507 tda9887_set_tvnorm(t,t->tda9887_data);
656 508
657 /* A note on the port settings: 509 /* A note on the port settings:
658 These settings tend to depend on the specifics of the board. 510 These settings tend to depend on the specifics of the board.
@@ -667,249 +519,84 @@ static int tda9887_configure(struct tda9887 *t)
667 the ports should be set to active (0), but, again, that may 519 the ports should be set to active (0), but, again, that may
668 differ depending on the precise hardware configuration. 520 differ depending on the precise hardware configuration.
669 */ 521 */
670 t->data[1] |= cOutputPort1Inactive; 522 t->tda9887_data[1] |= cOutputPort1Inactive;
671 t->data[1] |= cOutputPort2Inactive; 523 t->tda9887_data[1] |= cOutputPort2Inactive;
672 524
673 tda9887_set_config(t,t->data); 525 tda9887_set_config(t,t->tda9887_data);
674 tda9887_set_insmod(t,t->data); 526 tda9887_set_insmod(t,t->tda9887_data);
675 527
676 if (t->mode == T_STANDBY) { 528 if (t->mode == T_STANDBY) {
677 t->data[1] |= cForcedMuteAudioON; 529 t->tda9887_data[1] |= cForcedMuteAudioON;
678 } 530 }
679 531
680 tda9887_dbg("writing: b=0x%02x c=0x%02x e=0x%02x\n", 532 tda9887_dbg("writing: b=0x%02x c=0x%02x e=0x%02x\n",
681 t->data[1],t->data[2],t->data[3]); 533 t->tda9887_data[1],t->tda9887_data[2],t->tda9887_data[3]);
682 if (debug > 1) 534 if (tuner_debug > 1)
683 dump_write_message(t, t->data); 535 dump_write_message(t, t->tda9887_data);
684 536
685 if (4 != (rc = i2c_master_send(&t->client,t->data,4))) 537 if (4 != (rc = i2c_master_send(&t->i2c,t->tda9887_data,4)))
686 tda9887_info("i2c i/o error: rc == %d (should be 4)\n",rc); 538 tda9887_info("i2c i/o error: rc == %d (should be 4)\n",rc);
687 539
688 if (debug > 2) { 540 if (tuner_debug > 2) {
689 msleep_interruptible(1000); 541 msleep_interruptible(1000);
690 tda9887_status(t); 542 tda9887_status(t);
691 } 543 }
692 return 0;
693} 544}
694 545
695/* ---------------------------------------------------------------------- */ 546/* ---------------------------------------------------------------------- */
696 547
697static int tda9887_attach(struct i2c_adapter *adap, int addr, int kind) 548static void tda9887_tuner_status(struct i2c_client *client)
698{ 549{
699 struct tda9887 *t; 550 struct tuner *t = i2c_get_clientdata(client);
700 551 tda9887_info("Data bytes: b=0x%02x c=0x%02x e=0x%02x\n", t->tda9887_data[1], t->tda9887_data[2], t->tda9887_data[3]);
701 client_template.adapter = adap;
702 client_template.addr = addr;
703
704 if (NULL == (t = kzalloc(sizeof(*t), GFP_KERNEL)))
705 return -ENOMEM;
706
707 t->client = client_template;
708 t->std = 0;
709 t->radio_mode = V4L2_TUNER_MODE_STEREO;
710
711 tda9887_info("chip found @ 0x%x (%s)\n", addr<<1, adap->name);
712
713 i2c_set_clientdata(&t->client, t);
714 i2c_attach_client(&t->client);
715
716 return 0;
717} 552}
718 553
719static int tda9887_probe(struct i2c_adapter *adap) 554static int tda9887_get_afc(struct i2c_client *client)
720{ 555{
721 if (adap->class & I2C_CLASS_TV_ANALOG) 556 struct tuner *t = i2c_get_clientdata(client);
722 return i2c_probe(adap, &addr_data, tda9887_attach); 557 static int AFC_BITS_2_kHz[] = {
723 return 0; 558 -12500, -37500, -62500, -97500,
724} 559 -112500, -137500, -162500, -187500,
560 187500, 162500, 137500, 112500,
561 97500 , 62500, 37500 , 12500
562 };
563 int afc=0;
564 __u8 reg = 0;
725 565
726static int tda9887_detach(struct i2c_client *client) 566 if (1 == i2c_master_recv(&t->i2c,&reg,1))
727{ 567 afc = AFC_BITS_2_kHz[(reg>>1)&0x0f];
728 struct tda9887 *t = i2c_get_clientdata(client);
729 568
730 i2c_detach_client(client); 569 return afc;
731 kfree(t);
732 return 0;
733} 570}
734 571
735#define SWITCH_V4L2 if (!t->using_v4l2 && debug) \ 572static void tda9887_standby(struct i2c_client *client)
736 tda9887_info("switching to v4l2\n"); \
737 t->using_v4l2 = 1;
738#define CHECK_V4L2 if (t->using_v4l2) { if (debug) \
739 tda9887_info("ignore v4l1 call\n"); \
740 return 0; }
741
742static int
743tda9887_command(struct i2c_client *client, unsigned int cmd, void *arg)
744{ 573{
745 struct tda9887 *t = i2c_get_clientdata(client); 574 tda9887_configure(client);
746
747 switch (cmd) {
748
749 /* --- configuration --- */
750 case AUDC_SET_RADIO:
751 {
752 t->mode = T_RADIO;
753 tda9887_configure(t);
754 break;
755 }
756 case TUNER_SET_STANDBY:
757 {
758 t->mode = T_STANDBY;
759 tda9887_configure(t);
760 break;
761 }
762 case TDA9887_SET_CONFIG:
763 {
764 int *i = arg;
765
766 t->config = *i;
767 tda9887_configure(t);
768 break;
769 }
770 /* --- v4l ioctls --- */
771 /* take care: bttv does userspace copying, we'll get a
772 kernel pointer here... */
773 case VIDIOCSCHAN:
774 {
775 static const v4l2_std_id map[] = {
776 [ VIDEO_MODE_PAL ] = V4L2_STD_PAL,
777 [ VIDEO_MODE_NTSC ] = V4L2_STD_NTSC_M,
778 [ VIDEO_MODE_SECAM ] = V4L2_STD_SECAM,
779 [ 4 /* bttv */ ] = V4L2_STD_PAL_M,
780 [ 5 /* bttv */ ] = V4L2_STD_PAL_N,
781 [ 6 /* bttv */ ] = V4L2_STD_NTSC_M_JP,
782 };
783 struct video_channel *vc = arg;
784
785 CHECK_V4L2;
786 t->mode = T_ANALOG_TV;
787 if (vc->norm < ARRAY_SIZE(map))
788 t->std = map[vc->norm];
789 tda9887_fixup_std(t);
790 tda9887_configure(t);
791 break;
792 }
793 case VIDIOC_S_STD:
794 {
795 v4l2_std_id *id = arg;
796
797 SWITCH_V4L2;
798 t->mode = T_ANALOG_TV;
799 t->std = *id;
800 tda9887_fixup_std(t);
801 tda9887_configure(t);
802 break;
803 }
804 case VIDIOC_S_FREQUENCY:
805 {
806 struct v4l2_frequency *f = arg;
807
808 SWITCH_V4L2;
809 if (V4L2_TUNER_ANALOG_TV == f->type) {
810 if (t->mode == T_ANALOG_TV)
811 return 0;
812 t->mode = T_ANALOG_TV;
813 }
814 if (V4L2_TUNER_RADIO == f->type) {
815 if (t->mode == T_RADIO)
816 return 0;
817 t->mode = T_RADIO;
818 }
819 tda9887_configure(t);
820 break;
821 }
822 case VIDIOC_G_TUNER:
823 {
824 static int AFC_BITS_2_kHz[] = {
825 -12500, -37500, -62500, -97500,
826 -112500, -137500, -162500, -187500,
827 187500, 162500, 137500, 112500,
828 97500 , 62500, 37500 , 12500
829 };
830 struct v4l2_tuner* tuner = arg;
831
832 if (t->mode == T_RADIO) {
833 __u8 reg = 0;
834 tuner->afc=0;
835 if (1 == i2c_master_recv(&t->client,&reg,1))
836 tuner->afc = AFC_BITS_2_kHz[(reg>>1)&0x0f];
837 }
838 break;
839 }
840 case VIDIOC_S_TUNER:
841 {
842 struct v4l2_tuner* tuner = arg;
843
844 if (t->mode == T_RADIO) {
845 t->radio_mode = tuner->audmode;
846 tda9887_configure (t);
847 }
848 break;
849 }
850 case VIDIOC_LOG_STATUS:
851 {
852 tda9887_info("Data bytes: b=0x%02x c=0x%02x e=0x%02x\n", t->data[1], t->data[2], t->data[3]);
853 break;
854 }
855 default:
856 /* nothing */
857 break;
858 }
859 return 0;
860} 575}
861 576
862static int tda9887_suspend(struct device * dev, pm_message_t state) 577static void tda9887_set_freq(struct i2c_client *client, unsigned int freq)
863{ 578{
864 struct i2c_client *c = container_of(dev, struct i2c_client, dev); 579 tda9887_configure(client);
865 struct tda9887 *t = i2c_get_clientdata(c);
866
867 tda9887_dbg("suspend\n");
868 return 0;
869} 580}
870 581
871static int tda9887_resume(struct device * dev) 582int tda9887_tuner_init(struct i2c_client *c)
872{ 583{
873 struct i2c_client *c = container_of(dev, struct i2c_client, dev); 584 struct tuner *t = i2c_get_clientdata(c);
874 struct tda9887 *t = i2c_get_clientdata(c);
875 585
876 tda9887_dbg("resume\n"); 586 strlcpy(c->name, "tda9887", sizeof(c->name));
877 tda9887_configure(t);
878 return 0;
879}
880 587
881/* ----------------------------------------------------------------------- */ 588 tda9887_info("tda988[5/6/7] found @ 0x%x (%s)\n", t->i2c.addr,
882 589 t->i2c.driver->driver.name);
883static struct i2c_driver driver = {
884 .id = I2C_DRIVERID_TDA9887,
885 .attach_adapter = tda9887_probe,
886 .detach_client = tda9887_detach,
887 .command = tda9887_command,
888 .driver = {
889 .name = "tda9887",
890 .suspend = tda9887_suspend,
891 .resume = tda9887_resume,
892 },
893};
894static struct i2c_client client_template =
895{
896 .name = "tda9887",
897 .driver = &driver,
898};
899 590
900static int __init tda9887_init_module(void) 591 t->set_tv_freq = tda9887_set_freq;
901{ 592 t->set_radio_freq = tda9887_set_freq;
902 return i2c_add_driver(&driver); 593 t->standby = tda9887_standby;
903} 594 t->tuner_status=tda9887_tuner_status;
595 t->get_afc=tda9887_get_afc;
904 596
905static void __exit tda9887_cleanup_module(void) 597 return 0;
906{
907 i2c_del_driver(&driver);
908} 598}
909 599
910module_init(tda9887_init_module);
911module_exit(tda9887_cleanup_module);
912
913/* 600/*
914 * Overrides for Emacs so that we follow Linus's tabbing style. 601 * Overrides for Emacs so that we follow Linus's tabbing style.
915 * --------------------------------------------------------------------------- 602 * ---------------------------------------------------------------------------
diff --git a/drivers/media/video/tea5767.c b/drivers/media/video/tea5767.c
index c2b98f81c19..d1c41781ccc 100644
--- a/drivers/media/video/tea5767.c
+++ b/drivers/media/video/tea5767.c
@@ -3,7 +3,7 @@
3 * I2C address is allways 0xC0. 3 * I2C address is allways 0xC0.
4 * 4 *
5 * 5 *
6 * Copyright (c) 2005 Mauro Carvalho Chehab (mchehab@brturbo.com.br) 6 * Copyright (c) 2005 Mauro Carvalho Chehab (mchehab@infradead.org)
7 * This code is placed under the terms of the GNU General Public License 7 * This code is placed under the terms of the GNU General Public License
8 * 8 *
9 * tea5767 autodetection thanks to Torsten Seeboth and Atsushi Nakagawa 9 * tea5767 autodetection thanks to Torsten Seeboth and Atsushi Nakagawa
diff --git a/drivers/media/video/tlv320aic23b.c b/drivers/media/video/tlv320aic23b.c
new file mode 100644
index 00000000000..76b2e96429d
--- /dev/null
+++ b/drivers/media/video/tlv320aic23b.c
@@ -0,0 +1,217 @@
1/*
2 * tlv320aic23b - driver version 0.0.1
3 *
4 * Copyright (C) 2006 Scott Alfter <salfter@ssai.us>
5 *
6 * Based on wm8775 driver
7 *
8 * Copyright (C) 2004 Ulf Eklund <ivtv at eklund.to>
9 * Copyright (C) 2005 Hans Verkuil <hverkuil@xs4all.nl>
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 */
25
26#include <linux/module.h>
27#include <linux/types.h>
28#include <linux/ioctl.h>
29#include <asm/uaccess.h>
30#include <linux/i2c.h>
31#include <linux/i2c-id.h>
32#include <linux/videodev.h>
33#include <media/v4l2-common.h>
34
35MODULE_DESCRIPTION("tlv320aic23b driver");
36MODULE_AUTHOR("Scott Alfter, Ulf Eklund, Hans Verkuil");
37MODULE_LICENSE("GPL");
38
39static unsigned short normal_i2c[] = { 0x34 >> 1, I2C_CLIENT_END };
40
41
42I2C_CLIENT_INSMOD;
43
44/* ----------------------------------------------------------------------- */
45
46struct tlv320aic23b_state {
47 u8 muted;
48};
49
50static int tlv320aic23b_write(struct i2c_client *client, int reg, u16 val)
51{
52 int i;
53
54 if ((reg < 0 || reg > 9) && (reg != 15)) {
55 v4l_err(client, "Invalid register R%d\n", reg);
56 return -1;
57 }
58
59 for (i = 0; i < 3; i++) {
60 if (i2c_smbus_write_byte_data(client, (reg << 1) |
61 (val >> 8), val & 0xff) == 0) {
62 return 0;
63 }
64 }
65 v4l_err(client, "I2C: cannot write %03x to register R%d\n", val, reg);
66 return -1;
67}
68
69static int tlv320aic23b_command(struct i2c_client *client, unsigned int cmd,
70 void *arg)
71{
72 struct tlv320aic23b_state *state = i2c_get_clientdata(client);
73 struct v4l2_control *ctrl = arg;
74 u32* freq = arg;
75
76 switch (cmd) {
77 case VIDIOC_INT_AUDIO_CLOCK_FREQ:
78 switch (*freq) {
79 case 32000: /* set sample rate to 32 kHz */
80 tlv320aic23b_write(client, 8, 0x018);
81 break;
82 case 44100: /* set sample rate to 44.1 kHz */
83 tlv320aic23b_write(client, 8, 0x022);
84 break;
85 case 48000: /* set sample rate to 48 kHz */
86 tlv320aic23b_write(client, 8, 0x000);
87 break;
88 default:
89 return -EINVAL;
90 }
91 break;
92
93 case VIDIOC_G_CTRL:
94 if (ctrl->id != V4L2_CID_AUDIO_MUTE)
95 return -EINVAL;
96 ctrl->value = state->muted;
97 break;
98
99 case VIDIOC_S_CTRL:
100 if (ctrl->id != V4L2_CID_AUDIO_MUTE)
101 return -EINVAL;
102 state->muted = ctrl->value;
103 tlv320aic23b_write(client, 0, 0x180); /* mute both channels */
104 /* set gain on both channels to +3.0 dB */
105 if (!state->muted)
106 tlv320aic23b_write(client, 0, 0x119);
107 break;
108
109 case VIDIOC_LOG_STATUS:
110 v4l_info(client, "Input: %s\n",
111 state->muted ? "muted" : "active");
112 break;
113
114 default:
115 return -EINVAL;
116 }
117 return 0;
118}
119
120/* ----------------------------------------------------------------------- */
121
122/* i2c implementation */
123
124/*
125 * Generic i2c probe
126 * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
127 */
128
129static struct i2c_driver i2c_driver;
130
131static int tlv320aic23b_attach(struct i2c_adapter *adapter, int address, int kind)
132{
133 struct i2c_client *client;
134 struct tlv320aic23b_state *state;
135
136 /* Check if the adapter supports the needed features */
137 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
138 return 0;
139
140 client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
141 if (client == 0)
142 return -ENOMEM;
143
144 client->addr = address;
145 client->adapter = adapter;
146 client->driver = &i2c_driver;
147 snprintf(client->name, sizeof(client->name) - 1, "tlv320aic23b");
148
149 v4l_info(client, "chip found @ 0x%x (%s)\n", address << 1, adapter->name);
150
151 state = kmalloc(sizeof(struct tlv320aic23b_state), GFP_KERNEL);
152 if (state == NULL) {
153 kfree(client);
154 return -ENOMEM;
155 }
156 state->muted = 0;
157 i2c_set_clientdata(client, state);
158
159 /* initialize tlv320aic23b */
160 tlv320aic23b_write(client, 15, 0x000); /* RESET */
161 tlv320aic23b_write(client, 6, 0x00A); /* turn off DAC & mic input */
162 tlv320aic23b_write(client, 7, 0x049); /* left-justified, 24-bit, master mode */
163 tlv320aic23b_write(client, 0, 0x119); /* set gain on both channels to +3.0 dB */
164 tlv320aic23b_write(client, 8, 0x000); /* set sample rate to 48 kHz */
165 tlv320aic23b_write(client, 9, 0x001); /* activate digital interface */
166
167 i2c_attach_client(client);
168
169 return 0;
170}
171
172static int tlv320aic23b_probe(struct i2c_adapter *adapter)
173{
174 if (adapter->class & I2C_CLASS_TV_ANALOG)
175 return i2c_probe(adapter, &addr_data, tlv320aic23b_attach);
176 return 0;
177}
178
179static int tlv320aic23b_detach(struct i2c_client *client)
180{
181 int err;
182
183 err = i2c_detach_client(client);
184 if (err) {
185 return err;
186 }
187 kfree(client);
188
189 return 0;
190}
191
192/* ----------------------------------------------------------------------- */
193
194/* i2c implementation */
195static struct i2c_driver i2c_driver = {
196 .driver = {
197 .name = "tlv320aic23b",
198 },
199 .id = I2C_DRIVERID_TLV320AIC23B,
200 .attach_adapter = tlv320aic23b_probe,
201 .detach_client = tlv320aic23b_detach,
202 .command = tlv320aic23b_command,
203};
204
205
206static int __init tlv320aic23b_init_module(void)
207{
208 return i2c_add_driver(&i2c_driver);
209}
210
211static void __exit tlv320aic23b_cleanup_module(void)
212{
213 i2c_del_driver(&i2c_driver);
214}
215
216module_init(tlv320aic23b_init_module);
217module_exit(tlv320aic23b_cleanup_module);
diff --git a/drivers/media/video/tuner-3036.c b/drivers/media/video/tuner-3036.c
index 74ab48c09c6..bdf506e6ae2 100644
--- a/drivers/media/video/tuner-3036.c
+++ b/drivers/media/video/tuner-3036.c
@@ -25,6 +25,7 @@
25 25
26#include <linux/i2c.h> 26#include <linux/i2c.h>
27#include <linux/videodev.h> 27#include <linux/videodev.h>
28#include <media/v4l2-common.h>
28 29
29#include <media/tuner.h> 30#include <media/tuner.h>
30 31
diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c
index 1013b4de89a..e95792fd70f 100644
--- a/drivers/media/video/tuner-core.c
+++ b/drivers/media/video/tuner-core.c
@@ -199,7 +199,7 @@ static void set_type(struct i2c_client *c, unsigned int type,
199 i2c_master_send(c, buffer, 4); 199 i2c_master_send(c, buffer, 4);
200 default_tuner_init(c); 200 default_tuner_init(c);
201 break; 201 break;
202 case TUNER_LG_TDVS_H062F: 202 case TUNER_LG_TDVS_H06XF:
203 /* Set the Auxiliary Byte. */ 203 /* Set the Auxiliary Byte. */
204 buffer[2] &= ~0x20; 204 buffer[2] &= ~0x20;
205 buffer[2] |= 0x18; 205 buffer[2] |= 0x18;
@@ -215,6 +215,9 @@ static void set_type(struct i2c_client *c, unsigned int type,
215 i2c_master_send(c,buffer,4); 215 i2c_master_send(c,buffer,4);
216 default_tuner_init(c); 216 default_tuner_init(c);
217 break; 217 break;
218 case TUNER_TDA9887:
219 tda9887_tuner_init(c);
220 break;
218 default: 221 default:
219 default_tuner_init(c); 222 default_tuner_init(c);
220 break; 223 break;
@@ -241,6 +244,8 @@ static void set_addr(struct i2c_client *c, struct tuner_setup *tun_setup)
241{ 244{
242 struct tuner *t = i2c_get_clientdata(c); 245 struct tuner *t = i2c_get_clientdata(c);
243 246
247 tuner_dbg("set addr for type %i\n", t->type);
248
244 if ( t->type == UNSET && ((tun_setup->addr == ADDR_UNSET && 249 if ( t->type == UNSET && ((tun_setup->addr == ADDR_UNSET &&
245 (t->mode_mask & tun_setup->mode_mask)) || 250 (t->mode_mask & tun_setup->mode_mask)) ||
246 tun_setup->addr == c->addr)) { 251 tun_setup->addr == c->addr)) {
@@ -436,6 +441,7 @@ static int tuner_attach(struct i2c_adapter *adap, int addr, int kind)
436 t->radio_if2 = 10700 * 1000; /* 10.7MHz - FM radio */ 441 t->radio_if2 = 10700 * 1000; /* 10.7MHz - FM radio */
437 t->audmode = V4L2_TUNER_MODE_STEREO; 442 t->audmode = V4L2_TUNER_MODE_STEREO;
438 t->mode_mask = T_UNINITIALIZED; 443 t->mode_mask = T_UNINITIALIZED;
444 t->tuner_status = tuner_status;
439 if (tuner_debug_old) { 445 if (tuner_debug_old) {
440 tuner_debug = tuner_debug_old; 446 tuner_debug = tuner_debug_old;
441 printk(KERN_ERR "tuner: tuner_debug is deprecated and will be removed in 2.6.17.\n"); 447 printk(KERN_ERR "tuner: tuner_debug is deprecated and will be removed in 2.6.17.\n");
@@ -462,10 +468,14 @@ static int tuner_attach(struct i2c_adapter *adap, int addr, int kind)
462 case 0x4b: 468 case 0x4b:
463 /* If chip is not tda8290, don't register. 469 /* If chip is not tda8290, don't register.
464 since it can be tda9887*/ 470 since it can be tda9887*/
465 if (tda8290_probe(&t->i2c) != 0) { 471 if (tda8290_probe(&t->i2c) == 0) {
466 tuner_dbg("chip at addr %x is not a tda8290\n", addr); 472 tuner_dbg("chip at addr %x is a tda8290\n", addr);
467 kfree(t); 473 } else {
468 return 0; 474 /* Default is being tda9887 */
475 t->type = TUNER_TDA9887;
476 t->mode_mask = T_RADIO | T_ANALOG_TV | T_DIGITAL_TV;
477 t->mode = T_STANDBY;
478 goto register_client;
469 } 479 }
470 break; 480 break;
471 case 0x60: 481 case 0x60:
@@ -592,6 +602,7 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
592 case TUNER_SET_STANDBY: 602 case TUNER_SET_STANDBY:
593 if (check_mode(t, "TUNER_SET_STANDBY") == EINVAL) 603 if (check_mode(t, "TUNER_SET_STANDBY") == EINVAL)
594 return 0; 604 return 0;
605 t->mode = T_STANDBY;
595 if (t->standby) 606 if (t->standby)
596 t->standby (client); 607 t->standby (client);
597 break; 608 break;
@@ -604,6 +615,14 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
604 /* Should be implemented, since bttv calls it */ 615 /* Should be implemented, since bttv calls it */
605 tuner_dbg("VIDIOCSAUDIO not implemented.\n"); 616 tuner_dbg("VIDIOCSAUDIO not implemented.\n");
606 break; 617 break;
618 case TDA9887_SET_CONFIG:
619 {
620 int *i = arg;
621
622 t->tda9887_config = *i;
623 set_freq(client, t->tv_freq);
624 break;
625 }
607 /* --- v4l ioctls --- */ 626 /* --- v4l ioctls --- */
608 /* take care: bttv does userspace copying, we'll get a 627 /* take care: bttv does userspace copying, we'll get a
609 kernel pointer here... */ 628 kernel pointer here... */
@@ -744,6 +763,8 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
744 switch_v4l2(); 763 switch_v4l2();
745 764
746 tuner->type = t->mode; 765 tuner->type = t->mode;
766 if (t->get_afc)
767 tuner->afc=t->get_afc(client);
747 if (t->mode == V4L2_TUNER_ANALOG_TV) 768 if (t->mode == V4L2_TUNER_ANALOG_TV)
748 tuner->capability |= V4L2_TUNER_CAP_NORM; 769 tuner->capability |= V4L2_TUNER_CAP_NORM;
749 if (t->mode != V4L2_TUNER_RADIO) { 770 if (t->mode != V4L2_TUNER_RADIO) {
@@ -787,7 +808,8 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
787 break; 808 break;
788 } 809 }
789 case VIDIOC_LOG_STATUS: 810 case VIDIOC_LOG_STATUS:
790 tuner_status(client); 811 if (t->tuner_status)
812 t->tuner_status(client);
791 break; 813 break;
792 } 814 }
793 815
diff --git a/drivers/media/video/tuner-simple.c b/drivers/media/video/tuner-simple.c
index 5d7abed7167..6da6f82b8c8 100644
--- a/drivers/media/video/tuner-simple.c
+++ b/drivers/media/video/tuner-simple.c
@@ -105,7 +105,7 @@ static int tuner_stereo(struct i2c_client *c)
105 105
106 switch (t->type) { 106 switch (t->type) {
107 case TUNER_PHILIPS_FM1216ME_MK3: 107 case TUNER_PHILIPS_FM1216ME_MK3:
108 case TUNER_PHILIPS_FM1236_MK3: 108 case TUNER_PHILIPS_FM1236_MK3:
109 case TUNER_PHILIPS_FM1256_IH3: 109 case TUNER_PHILIPS_FM1256_IH3:
110 stereo = ((status & TUNER_SIGNAL) == TUNER_STEREO_MK3); 110 stereo = ((status & TUNER_SIGNAL) == TUNER_STEREO_MK3);
111 break; 111 break;
diff --git a/drivers/media/video/tuner-types.c b/drivers/media/video/tuner-types.c
index a1ae036b44e..9d9226cb639 100644
--- a/drivers/media/video/tuner-types.c
+++ b/drivers/media/video/tuner-types.c
@@ -874,7 +874,7 @@ static struct tuner_params tuner_philips_fmd1216me_mk3_params[] = {
874}; 874};
875 875
876 876
877/* ------------ TUNER_LG_TDVS_H062F - INFINEON ATSC ------------ */ 877/* ------ TUNER_LG_TDVS_H06XF - LG INNOTEK / INFINEON ATSC ----- */
878 878
879static struct tuner_range tuner_tua6034_ntsc_ranges[] = { 879static struct tuner_range tuner_tua6034_ntsc_ranges[] = {
880 { 16 * 165.00 /*MHz*/, 0x8e, 0x01 }, 880 { 16 * 165.00 /*MHz*/, 0x8e, 0x01 },
@@ -883,7 +883,7 @@ static struct tuner_range tuner_tua6034_ntsc_ranges[] = {
883}; 883};
884 884
885 885
886static struct tuner_params tuner_tua6034_params[] = { 886static struct tuner_params tuner_lg_tdvs_h06xf_params[] = {
887 { 887 {
888 .type = TUNER_PARAM_TYPE_NTSC, 888 .type = TUNER_PARAM_TYPE_NTSC,
889 .ranges = tuner_tua6034_ntsc_ranges, 889 .ranges = tuner_tua6034_ntsc_ranges,
@@ -1024,6 +1024,22 @@ static struct tuner_params tuner_thomson_fe6600_params[] = {
1024 }, 1024 },
1025}; 1025};
1026 1026
1027/* ------------ TUNER_SAMSUNG_TCPG_6121P30A - Samsung PAL ------------ */
1028
1029static struct tuner_range tuner_samsung_tcpg_6121p30a_pal_ranges[] = {
1030 { 16 * 146.25 /*MHz*/, 0xce, 0x01, },
1031 { 16 * 428.50 /*MHz*/, 0xce, 0x02, },
1032 { 16 * 999.99 , 0xce, 0x08, },
1033};
1034
1035static struct tuner_params tuner_samsung_tcpg_6121p30a_params[] = {
1036 {
1037 .type = TUNER_PARAM_TYPE_PAL,
1038 .ranges = tuner_samsung_tcpg_6121p30a_pal_ranges,
1039 .count = ARRAY_SIZE(tuner_samsung_tcpg_6121p30a_pal_ranges),
1040 },
1041};
1042
1027/* --------------------------------------------------------------------- */ 1043/* --------------------------------------------------------------------- */
1028 1044
1029struct tunertype tuners[] = { 1045struct tunertype tuners[] = {
@@ -1354,10 +1370,10 @@ struct tunertype tuners[] = {
1354 .params = tuner_philips_fmd1216me_mk3_params, 1370 .params = tuner_philips_fmd1216me_mk3_params,
1355 .count = ARRAY_SIZE(tuner_philips_fmd1216me_mk3_params), 1371 .count = ARRAY_SIZE(tuner_philips_fmd1216me_mk3_params),
1356 }, 1372 },
1357 [TUNER_LG_TDVS_H062F] = { /* LGINNOTEK ATSC */ 1373 [TUNER_LG_TDVS_H06XF] = { /* LGINNOTEK ATSC */
1358 .name = "LG TDVS-H062F/TUA6034", 1374 .name = "LG TDVS-H06xF", /* H061F, H062F & H064F */
1359 .params = tuner_tua6034_params, 1375 .params = tuner_lg_tdvs_h06xf_params,
1360 .count = ARRAY_SIZE(tuner_tua6034_params), 1376 .count = ARRAY_SIZE(tuner_lg_tdvs_h06xf_params),
1361 }, 1377 },
1362 [TUNER_YMEC_TVF66T5_B_DFF] = { /* Philips PAL */ 1378 [TUNER_YMEC_TVF66T5_B_DFF] = { /* Philips PAL */
1363 .name = "Ymec TVF66T5-B/DFF", 1379 .name = "Ymec TVF66T5-B/DFF",
@@ -1400,6 +1416,16 @@ struct tunertype tuners[] = {
1400 .params = tuner_thomson_fe6600_params, 1416 .params = tuner_thomson_fe6600_params,
1401 .count = ARRAY_SIZE(tuner_thomson_fe6600_params), 1417 .count = ARRAY_SIZE(tuner_thomson_fe6600_params),
1402 }, 1418 },
1419 [TUNER_SAMSUNG_TCPG_6121P30A] = { /* Samsung PAL */
1420 .name = "Samsung TCPG 6121P30A",
1421 .params = tuner_samsung_tcpg_6121p30a_params,
1422 .count = ARRAY_SIZE(tuner_samsung_tcpg_6121p30a_params),
1423 },
1424 [TUNER_TDA9887] = { /* Philips TDA 9887 IF PLL Demodulator.
1425 This chip is part of some modern tuners */
1426 .name = "Philips TDA988[5,6,7] IF PLL Demodulator",
1427 /* see tda9887.c for details */
1428 },
1403}; 1429};
1404 1430
1405unsigned const int tuner_count = ARRAY_SIZE(tuners); 1431unsigned const int tuner_count = ARRAY_SIZE(tuners);
diff --git a/drivers/media/video/tveeprom.c b/drivers/media/video/tveeprom.c
index b463e996961..30f8d80ddca 100644
--- a/drivers/media/video/tveeprom.c
+++ b/drivers/media/video/tveeprom.c
@@ -200,7 +200,7 @@ hauppauge_tuner[] =
200 { TUNER_ABSENT, "Philips FQ1286A MK4"}, 200 { TUNER_ABSENT, "Philips FQ1286A MK4"},
201 { TUNER_ABSENT, "Philips FQ1216ME MK5"}, 201 { TUNER_ABSENT, "Philips FQ1216ME MK5"},
202 { TUNER_ABSENT, "Philips FQ1236 MK5"}, 202 { TUNER_ABSENT, "Philips FQ1236 MK5"},
203 { TUNER_ABSENT, "Samsung TCPG_6121P30A"}, 203 { TUNER_SAMSUNG_TCPG_6121P30A, "Samsung TCPG 6121P30A"},
204 { TUNER_TCL_2002MB, "TCL 2002MB_3H"}, 204 { TUNER_TCL_2002MB, "TCL 2002MB_3H"},
205 { TUNER_ABSENT, "TCL 2002MI_3H"}, 205 { TUNER_ABSENT, "TCL 2002MI_3H"},
206 { TUNER_TCL_2002N, "TCL 2002N 5H"}, 206 { TUNER_TCL_2002N, "TCL 2002N 5H"},
diff --git a/drivers/media/video/tvmixer.c b/drivers/media/video/tvmixer.c
index 9e86caeb96a..1654576de10 100644
--- a/drivers/media/video/tvmixer.c
+++ b/drivers/media/video/tvmixer.c
@@ -198,10 +198,6 @@ static int tvmixer_open(struct inode *inode, struct file *file)
198 198
199 /* lock bttv in memory while the mixer is in use */ 199 /* lock bttv in memory while the mixer is in use */
200 file->private_data = mix; 200 file->private_data = mix;
201#ifndef I2C_PEC
202 if (client->adapter->inc_use)
203 client->adapter->inc_use(client->adapter);
204#endif
205 if (client->adapter->owner) 201 if (client->adapter->owner)
206 try_module_get(client->adapter->owner); 202 try_module_get(client->adapter->owner);
207 return 0; 203 return 0;
@@ -217,10 +213,6 @@ static int tvmixer_release(struct inode *inode, struct file *file)
217 return -ENODEV; 213 return -ENODEV;
218 } 214 }
219 215
220#ifndef I2C_PEC
221 if (client->adapter->dec_use)
222 client->adapter->dec_use(client->adapter);
223#endif
224 if (client->adapter->owner) 216 if (client->adapter->owner)
225 module_put(client->adapter->owner); 217 module_put(client->adapter->owner);
226 return 0; 218 return 0;
diff --git a/drivers/media/video/tvp5150.c b/drivers/media/video/tvp5150.c
index dab4973bcf8..b167ffab252 100644
--- a/drivers/media/video/tvp5150.c
+++ b/drivers/media/video/tvp5150.c
@@ -10,6 +10,7 @@
10#include <linux/delay.h> 10#include <linux/delay.h>
11#include <linux/video_decoder.h> 11#include <linux/video_decoder.h>
12#include <media/v4l2-common.h> 12#include <media/v4l2-common.h>
13#include <media/tvp5150.h>
13 14
14#include "tvp5150_reg.h" 15#include "tvp5150_reg.h"
15 16
@@ -89,7 +90,7 @@ struct tvp5150 {
89 struct i2c_client *client; 90 struct i2c_client *client;
90 91
91 v4l2_std_id norm; /* Current set standard */ 92 v4l2_std_id norm; /* Current set standard */
92 int input; 93 struct v4l2_routing route;
93 int enable; 94 int enable;
94 int bright; 95 int bright;
95 int contrast; 96 int contrast;
@@ -283,29 +284,26 @@ static void dump_reg(struct i2c_client *c)
283/**************************************************************************** 284/****************************************************************************
284 Basic functions 285 Basic functions
285 ****************************************************************************/ 286 ****************************************************************************/
286enum tvp5150_input {
287 TVP5150_ANALOG_CH0 = 0,
288 TVP5150_SVIDEO = 1,
289 TVP5150_ANALOG_CH1 = 2,
290 TVP5150_BLACK_SCREEN = 8
291};
292 287
293static inline void tvp5150_selmux(struct i2c_client *c, 288static inline void tvp5150_selmux(struct i2c_client *c)
294 enum tvp5150_input input)
295{ 289{
296 int opmode=0; 290 int opmode=0;
297
298 struct tvp5150 *decoder = i2c_get_clientdata(c); 291 struct tvp5150 *decoder = i2c_get_clientdata(c);
292 int input = 0;
299 293
300 if (!decoder->enable) 294 if ((decoder->route.output & TVP5150_BLACK_SCREEN) || !decoder->enable)
301 input |= TVP5150_BLACK_SCREEN; 295 input = 8;
302 296
303 switch (input) { 297 switch (input) {
304 case TVP5150_ANALOG_CH0: 298 case TVP5150_COMPOSITE1:
305 case TVP5150_ANALOG_CH1: 299 input |= 2;
300 /* fall through */
301 case TVP5150_COMPOSITE0:
306 opmode=0x30; /* TV Mode */ 302 opmode=0x30; /* TV Mode */
307 break; 303 break;
304 case TVP5150_SVIDEO:
308 default: 305 default:
306 input |= 1;
309 opmode=0; /* Auto Mode */ 307 opmode=0; /* Auto Mode */
310 break; 308 break;
311 } 309 }
@@ -790,7 +788,7 @@ static inline void tvp5150_reset(struct i2c_client *c)
790 tvp5150_vdp_init(c, vbi_ram_default); 788 tvp5150_vdp_init(c, vbi_ram_default);
791 789
792 /* Selects decoder input */ 790 /* Selects decoder input */
793 tvp5150_selmux(c, decoder->input); 791 tvp5150_selmux(c);
794 792
795 /* Initializes TVP5150 to stream enabled values */ 793 /* Initializes TVP5150 to stream enabled values */
796 tvp5150_write_inittab(c, tvp5150_init_enable); 794 tvp5150_write_inittab(c, tvp5150_init_enable);
@@ -860,6 +858,21 @@ static int tvp5150_command(struct i2c_client *c,
860 case VIDIOC_INT_RESET: 858 case VIDIOC_INT_RESET:
861 tvp5150_reset(c); 859 tvp5150_reset(c);
862 break; 860 break;
861 case VIDIOC_INT_G_VIDEO_ROUTING:
862 {
863 struct v4l2_routing *route = arg;
864
865 *route = decoder->route;
866 break;
867 }
868 case VIDIOC_INT_S_VIDEO_ROUTING:
869 {
870 struct v4l2_routing *route = arg;
871
872 decoder->route = *route;
873 tvp5150_selmux(c);
874 break;
875 }
863 case VIDIOC_S_STD: 876 case VIDIOC_S_STD:
864 if (decoder->norm == *(v4l2_std_id *)arg) 877 if (decoder->norm == *(v4l2_std_id *)arg)
865 break; 878 break;
@@ -1063,7 +1076,7 @@ static int tvp5150_detect_client(struct i2c_adapter *adapter,
1063 rv = i2c_attach_client(c); 1076 rv = i2c_attach_client(c);
1064 1077
1065 core->norm = V4L2_STD_ALL; /* Default is autodetect */ 1078 core->norm = V4L2_STD_ALL; /* Default is autodetect */
1066 core->input = 2; 1079 core->route.input = TVP5150_COMPOSITE1;
1067 core->enable = 1; 1080 core->enable = 1;
1068 core->bright = 32768; 1081 core->bright = 32768;
1069 core->contrast = 32768; 1082 core->contrast = 32768;
diff --git a/drivers/media/video/usbvideo/Kconfig b/drivers/media/video/usbvideo/Kconfig
index 39269a2c563..59fb899f31f 100644
--- a/drivers/media/video/usbvideo/Kconfig
+++ b/drivers/media/video/usbvideo/Kconfig
@@ -36,3 +36,15 @@ config USB_KONICAWC
36 36
37 To compile this driver as a module, choose M here: the 37 To compile this driver as a module, choose M here: the
38 module will be called konicawc. 38 module will be called konicawc.
39
40config USB_QUICKCAM_MESSENGER
41 tristate "USB Logitech Quickcam Messenger"
42 depends on USB && VIDEO_DEV
43 select VIDEO_USBVIDEO
44 ---help---
45 Say Y or M here to enable support for the USB Logitech Quickcam
46 Messenger webcam.
47
48 To compile this driver as a module, choose M here: the
49 module will be called quickcam_messenger.
50
diff --git a/drivers/media/video/usbvideo/Makefile b/drivers/media/video/usbvideo/Makefile
index bb52eb8dc2f..4a1b144bee4 100644
--- a/drivers/media/video/usbvideo/Makefile
+++ b/drivers/media/video/usbvideo/Makefile
@@ -2,3 +2,4 @@ obj-$(CONFIG_VIDEO_USBVIDEO) += usbvideo.o
2obj-$(CONFIG_USB_IBMCAM) += ibmcam.o ultracam.o 2obj-$(CONFIG_USB_IBMCAM) += ibmcam.o ultracam.o
3obj-$(CONFIG_USB_KONICAWC) += konicawc.o 3obj-$(CONFIG_USB_KONICAWC) += konicawc.o
4obj-$(CONFIG_USB_VICAM) += vicam.o 4obj-$(CONFIG_USB_VICAM) += vicam.o
5obj-$(CONFIG_USB_QUICKCAM_MESSENGER) += quickcam_messenger.o
diff --git a/drivers/media/video/usbvideo/quickcam_messenger.c b/drivers/media/video/usbvideo/quickcam_messenger.c
new file mode 100644
index 00000000000..3f3182a24da
--- /dev/null
+++ b/drivers/media/video/usbvideo/quickcam_messenger.c
@@ -0,0 +1,1120 @@
1/*
2 * Driver for Logitech Quickcam Messenger usb video camera
3 * Copyright (C) Jaya Kumar
4 *
5 * This work was sponsored by CIS(M) Sdn Bhd.
6 * History:
7 * 05/08/2006 - Jaya Kumar
8 * I wrote this based on the konicawc by Simon Evans.
9 * -
10 * Full credit for reverse engineering and creating an initial
11 * working linux driver for the VV6422 goes to the qce-ga project by
12 * Tuukka Toivonen, Jochen Hoenicke, Peter McConnell,
13 * Cristiano De Michele, Georg Acher, Jean-Frederic Clere as well as
14 * others.
15 * ---
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, write to the Free Software
28 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
29 *
30 */
31
32#include <linux/kernel.h>
33#include <linux/module.h>
34#include <linux/init.h>
35#include <linux/input.h>
36#include <linux/usb_input.h>
37
38#include "usbvideo.h"
39#include "quickcam_messenger.h"
40
41/*
42 * Version Information
43 */
44
45#ifdef CONFIG_USB_DEBUG
46static int debug;
47#define DEBUG(n, format, arg...) \
48 if (n <= debug) { \
49 printk(KERN_DEBUG __FILE__ ":%s(): " format "\n", __FUNCTION__ , ## arg); \
50 }
51#else
52#define DEBUG(n, arg...)
53static const int debug = 0;
54#endif
55
56#define DRIVER_VERSION "v0.01"
57#define DRIVER_DESC "Logitech Quickcam Messenger USB"
58
59#define USB_LOGITECH_VENDOR_ID 0x046D
60#define USB_QCM_PRODUCT_ID 0x08F0
61
62#define MAX_CAMERAS 1
63
64#define MAX_COLOUR 32768
65#define MAX_HUE 32768
66#define MAX_BRIGHTNESS 32768
67#define MAX_CONTRAST 32768
68#define MAX_WHITENESS 32768
69
70static int size = SIZE_320X240;
71static int colour = MAX_COLOUR;
72static int hue = MAX_HUE;
73static int brightness = MAX_BRIGHTNESS;
74static int contrast = MAX_CONTRAST;
75static int whiteness = MAX_WHITENESS;
76
77static struct usbvideo *cams;
78
79static struct usb_device_id qcm_table [] = {
80 { USB_DEVICE(USB_LOGITECH_VENDOR_ID, USB_QCM_PRODUCT_ID) },
81 { }
82};
83MODULE_DEVICE_TABLE(usb, qcm_table);
84
85#ifdef CONFIG_INPUT
86static void qcm_register_input(struct qcm *cam, struct usb_device *dev)
87{
88 struct input_dev *input_dev;
89
90 usb_make_path(dev, cam->input_physname, sizeof(cam->input_physname));
91 strncat(cam->input_physname, "/input0", sizeof(cam->input_physname));
92
93 cam->input = input_dev = input_allocate_device();
94 if (!input_dev) {
95 warn("insufficient mem for cam input device");
96 return;
97 }
98
99 input_dev->name = "QCM button";
100 input_dev->phys = cam->input_physname;
101 usb_to_input_id(dev, &input_dev->id);
102 input_dev->cdev.dev = &dev->dev;
103
104 input_dev->evbit[0] = BIT(EV_KEY);
105 input_dev->keybit[LONG(BTN_0)] = BIT(BTN_0);
106
107 input_dev->private = cam;
108
109 input_register_device(cam->input);
110}
111
112static void qcm_unregister_input(struct qcm *cam)
113{
114 if (cam->input) {
115 input_unregister_device(cam->input);
116 cam->input = NULL;
117 }
118}
119
120static void qcm_report_buttonstat(struct qcm *cam)
121{
122 if (cam->input) {
123 input_report_key(cam->input, BTN_0, cam->button_sts);
124 input_sync(cam->input);
125 }
126}
127
128static void qcm_int_irq(struct urb *urb, struct pt_regs *regs)
129{
130 int ret;
131 struct uvd *uvd = urb->context;
132 struct qcm *cam;
133
134 if (!CAMERA_IS_OPERATIONAL(uvd))
135 return;
136
137 if (!uvd->streaming)
138 return;
139
140 uvd->stats.urb_count++;
141
142 if (urb->status < 0)
143 uvd->stats.iso_err_count++;
144 else {
145 if (urb->actual_length > 0 ) {
146 cam = (struct qcm *) uvd->user_data;
147 if (cam->button_sts_buf == 0x88)
148 cam->button_sts = 0x0;
149 else if (cam->button_sts_buf == 0x80)
150 cam->button_sts = 0x1;
151 qcm_report_buttonstat(cam);
152 }
153 }
154
155 ret = usb_submit_urb(urb, GFP_ATOMIC);
156 if (ret < 0)
157 err("usb_submit_urb error (%d)", ret);
158}
159
160static int qcm_setup_input_int(struct qcm *cam, struct uvd *uvd)
161{
162 int errflag;
163 usb_fill_int_urb(cam->button_urb, uvd->dev,
164 usb_rcvintpipe(uvd->dev, uvd->video_endp + 1),
165 &cam->button_sts_buf,
166 1,
167 qcm_int_irq,
168 uvd, 16);
169
170 errflag = usb_submit_urb(cam->button_urb, GFP_KERNEL);
171 if (errflag)
172 err ("usb_submit_int ret %d", errflag);
173 return errflag;
174}
175
176static void qcm_stop_int_data(struct qcm *cam)
177{
178 usb_kill_urb(cam->button_urb);
179}
180
181static int qcm_alloc_int_urb(struct qcm *cam)
182{
183 cam->button_urb = usb_alloc_urb(0, GFP_KERNEL);
184
185 if (!cam->button_urb)
186 return -ENOMEM;
187
188 return 0;
189}
190
191static void qcm_free_int(struct qcm *cam)
192{
193 if (cam->button_urb)
194 usb_free_urb(cam->button_urb);
195}
196#endif /* CONFIG_INPUT */
197
198static int qcm_stv_setb(struct usb_device *dev, u16 reg, u8 val)
199{
200 int ret;
201
202 /* we'll wait up to 3 slices but no more */
203 ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
204 0x04, USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE,
205 reg, 0, &val, 1, 3*HZ);
206 return ret;
207}
208
209static int qcm_stv_setw(struct usb_device *dev, u16 reg, u16 val)
210{
211 int ret;
212
213 /* we'll wait up to 3 slices but no more */
214 ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
215 0x04, USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE,
216 reg, 0, &val, 2, 3*HZ);
217 return ret;
218}
219
220static int qcm_stv_getw(struct usb_device *dev, unsigned short reg,
221 __le16 *val)
222{
223 int ret;
224
225 /* we'll wait up to 3 slices but no more */
226 ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
227 0x04, USB_TYPE_VENDOR | USB_DIR_IN | USB_RECIP_DEVICE,
228 reg, 0, val, 2, 3*HZ);
229 return ret;
230}
231
232static int qcm_camera_on(struct uvd *uvd)
233{
234 int ret;
235 CHECK_RET(ret, qcm_stv_setb(uvd->dev, STV_ISO_ENABLE, 0x01));
236 return 0;
237}
238
239static int qcm_camera_off(struct uvd *uvd)
240{
241 int ret;
242 CHECK_RET(ret, qcm_stv_setb(uvd->dev, STV_ISO_ENABLE, 0x00));
243 return 0;
244}
245
246static void qcm_hsv2rgb(u16 hue, u16 sat, u16 val, u16 *r, u16 *g, u16 *b)
247{
248 unsigned int segment, valsat;
249 signed int h = (signed int) hue;
250 unsigned int s = (sat - 32768) * 2; /* rescale */
251 unsigned int v = val;
252 unsigned int p;
253
254 /*
255 the registers controling gain are 8 bit of which
256 we affect only the last 4 bits with our gain.
257 we know that if saturation is 0, (unsaturated) then
258 we're grayscale (center axis of the colour cone) so
259 we set rgb=value. we use a formula obtained from
260 wikipedia to map the cone to the RGB plane. it's
261 as follows for the human value case of h=0..360,
262 s=0..1, v=0..1
263 h_i = h/60 % 6 , f = h/60 - h_i , p = v(1-s)
264 q = v(1 - f*s) , t = v(1 - (1-f)s)
265 h_i==0 => r=v , g=t, b=p
266 h_i==1 => r=q , g=v, b=p
267 h_i==2 => r=p , g=v, b=t
268 h_i==3 => r=p , g=q, b=v
269 h_i==4 => r=t , g=p, b=v
270 h_i==5 => r=v , g=p, b=q
271 the bottom side (the point) and the stuff just up
272 of that is black so we simplify those two cases.
273 */
274 if (sat < 32768) {
275 /* anything less than this is unsaturated */
276 *r = val;
277 *g = val;
278 *b = val;
279 return;
280 }
281 if (val <= (0xFFFF/8)) {
282 /* anything less than this is black */
283 *r = 0;
284 *g = 0;
285 *b = 0;
286 return;
287 }
288
289 /* the rest of this code is copying tukkat's
290 implementation of the hsv2rgb conversion as taken
291 from qc-usb-messenger code. the 10923 is 0xFFFF/6
292 to divide the cone into 6 sectors. */
293
294 segment = (h + 10923) & 0xFFFF;
295 segment = segment*3 >> 16; /* 0..2: 0=R, 1=G, 2=B */
296 hue -= segment * 21845; /* -10923..10923 */
297 h = hue;
298 h *= 3;
299 valsat = v*s >> 16; /* 0..65534 */
300 p = v - valsat;
301 if (h >= 0) {
302 unsigned int t = v - (valsat * (32769 - h) >> 15);
303 switch (segment) {
304 case 0: /* R-> */
305 *r = v;
306 *g = t;
307 *b = p;
308 break;
309 case 1: /* G-> */
310 *r = p;
311 *g = v;
312 *b = t;
313 break;
314 case 2: /* B-> */
315 *r = t;
316 *g = p;
317 *b = v;
318 break;
319 }
320 } else {
321 unsigned int q = v - (valsat * (32769 + h) >> 15);
322 switch (segment) {
323 case 0: /* ->R */
324 *r = v;
325 *g = p;
326 *b = q;
327 break;
328 case 1: /* ->G */
329 *r = q;
330 *g = v;
331 *b = p;
332 break;
333 case 2: /* ->B */
334 *r = p;
335 *g = q;
336 *b = v;
337 break;
338 }
339 }
340}
341
342static int qcm_sensor_set_gains(struct uvd *uvd, u16 hue,
343 u16 saturation, u16 value)
344{
345 int ret;
346 u16 r=0,g=0,b=0;
347
348 /* this code is based on qc-usb-messenger */
349 qcm_hsv2rgb(hue, saturation, value, &r, &g, &b);
350
351 r >>= 12;
352 g >>= 12;
353 b >>= 12;
354
355 /* min val is 8 */
356 r = max((u16) 8, r);
357 g = max((u16) 8, g);
358 b = max((u16) 8, b);
359
360 r |= 0x30;
361 g |= 0x30;
362 b |= 0x30;
363
364 /* set the r,g,b gain registers */
365 CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x0509, r));
366 CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x050A, g));
367 CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x050B, b));
368
369 /* doing as qc-usb did */
370 CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x050C, 0x2A));
371 CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x050D, 0x01));
372 CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x143F, 0x01));
373
374 return 0;
375}
376
377static int qcm_sensor_set_exposure(struct uvd *uvd, int exposure)
378{
379 int ret;
380 int formedval;
381
382 /* calculation was from qc-usb-messenger driver */
383 formedval = ( exposure >> 12 );
384
385 /* max value for formedval is 14 */
386 formedval = min(formedval, 14);
387
388 CHECK_RET(ret, qcm_stv_setb(uvd->dev,
389 0x143A, 0xF0 | formedval));
390 CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x143F, 0x01));
391 return 0;
392}
393
394static int qcm_sensor_setlevels(struct uvd *uvd, int brightness, int contrast,
395 int hue, int colour)
396{
397 int ret;
398 /* brightness is exposure, contrast is gain, colour is saturation */
399 CHECK_RET(ret,
400 qcm_sensor_set_exposure(uvd, brightness));
401 CHECK_RET(ret, qcm_sensor_set_gains(uvd, hue, colour, contrast));
402
403 return 0;
404}
405
406static int qcm_sensor_setsize(struct uvd *uvd, u8 size)
407{
408 int ret;
409
410 CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x1505, size));
411 return 0;
412}
413
414static int qcm_sensor_set_shutter(struct uvd *uvd, int whiteness)
415{
416 int ret;
417 /* some rescaling as done by the qc-usb-messenger code */
418 if (whiteness > 0xC000)
419 whiteness = 0xC000 + (whiteness & 0x3FFF)*8;
420
421 CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x143D,
422 (whiteness >> 8) & 0xFF));
423 CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x143E,
424 (whiteness >> 16) & 0x03));
425 CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x143F, 0x01));
426
427 return 0;
428}
429
430static int qcm_sensor_init(struct uvd *uvd)
431{
432 struct qcm *cam = (struct qcm *) uvd->user_data;
433 int ret;
434 int i;
435
436 for (i=0; i < sizeof(regval_table)/sizeof(regval_table[0]) ; i++) {
437 CHECK_RET(ret, qcm_stv_setb(uvd->dev,
438 regval_table[i].reg,
439 regval_table[i].val));
440 }
441
442 CHECK_RET(ret, qcm_stv_setw(uvd->dev, 0x15c1,
443 cpu_to_le16(ISOC_PACKET_SIZE)));
444 CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x15c3, 0x08));
445 CHECK_RET(ret, ret = qcm_stv_setb(uvd->dev, 0x143f, 0x01));
446
447 CHECK_RET(ret, qcm_stv_setb(uvd->dev, STV_ISO_ENABLE, 0x00));
448
449 CHECK_RET(ret, qcm_sensor_setsize(uvd, camera_sizes[cam->size].cmd));
450
451 CHECK_RET(ret, qcm_sensor_setlevels(uvd, uvd->vpic.brightness,
452 uvd->vpic.contrast, uvd->vpic.hue, uvd->vpic.colour));
453
454 CHECK_RET(ret, qcm_sensor_set_shutter(uvd, uvd->vpic.whiteness));
455 CHECK_RET(ret, qcm_sensor_setsize(uvd, camera_sizes[cam->size].cmd));
456
457 return 0;
458}
459
460static int qcm_set_camera_size(struct uvd *uvd)
461{
462 int ret;
463 struct qcm *cam = (struct qcm *) uvd->user_data;
464
465 CHECK_RET(ret, qcm_sensor_setsize(uvd, camera_sizes[cam->size].cmd));
466 cam->width = camera_sizes[cam->size].width;
467 cam->height = camera_sizes[cam->size].height;
468 uvd->videosize = VIDEOSIZE(cam->width, cam->height);
469
470 return 0;
471}
472
473static int qcm_setup_on_open(struct uvd *uvd)
474{
475 int ret;
476
477 CHECK_RET(ret, qcm_sensor_set_gains(uvd, uvd->vpic.hue,
478 uvd->vpic.colour, uvd->vpic.contrast));
479 CHECK_RET(ret, qcm_sensor_set_exposure(uvd, uvd->vpic.brightness));
480 CHECK_RET(ret, qcm_sensor_set_shutter(uvd, uvd->vpic.whiteness));
481 CHECK_RET(ret, qcm_set_camera_size(uvd));
482 CHECK_RET(ret, qcm_camera_on(uvd));
483 return 0;
484}
485
486static void qcm_adjust_picture(struct uvd *uvd)
487{
488 int ret;
489 struct qcm *cam = (struct qcm *) uvd->user_data;
490
491 ret = qcm_camera_off(uvd);
492 if (ret) {
493 err("can't turn camera off. abandoning pic adjustment");
494 return;
495 }
496
497 /* if there's been a change in contrast, hue, or
498 colour then we need to recalculate hsv in order
499 to update gains */
500 if ((cam->contrast != uvd->vpic.contrast) ||
501 (cam->hue != uvd->vpic.hue) ||
502 (cam->colour != uvd->vpic.colour)) {
503 cam->contrast = uvd->vpic.contrast;
504 cam->hue = uvd->vpic.hue;
505 cam->colour = uvd->vpic.colour;
506 ret = qcm_sensor_set_gains(uvd, cam->hue, cam->colour,
507 cam->contrast);
508 if (ret) {
509 err("can't set gains. abandoning pic adjustment");
510 return;
511 }
512 }
513
514 if (cam->brightness != uvd->vpic.brightness) {
515 cam->brightness = uvd->vpic.brightness;
516 ret = qcm_sensor_set_exposure(uvd, cam->brightness);
517 if (ret) {
518 err("can't set exposure. abandoning pic adjustment");
519 return;
520 }
521 }
522
523 if (cam->whiteness != uvd->vpic.whiteness) {
524 cam->whiteness = uvd->vpic.whiteness;
525 qcm_sensor_set_shutter(uvd, cam->whiteness);
526 if (ret) {
527 err("can't set shutter. abandoning pic adjustment");
528 return;
529 }
530 }
531
532 ret = qcm_camera_on(uvd);
533 if (ret) {
534 err("can't reenable camera. pic adjustment failed");
535 return;
536 }
537}
538
539static int qcm_process_frame(struct uvd *uvd, u8 *cdata, int framelen)
540{
541 int datalen;
542 int totaldata;
543 struct framehdr {
544 __be16 id;
545 __be16 len;
546 };
547 struct framehdr *fhdr;
548
549 totaldata = 0;
550 while (framelen) {
551 fhdr = (struct framehdr *) cdata;
552 datalen = be16_to_cpu(fhdr->len);
553 framelen -= 4;
554 cdata += 4;
555
556 if ((fhdr->id) == cpu_to_be16(0x8001)) {
557 RingQueue_Enqueue(&uvd->dp, marker, 4);
558 totaldata += 4;
559 continue;
560 }
561 if ((fhdr->id & cpu_to_be16(0xFF00)) == cpu_to_be16(0x0200)) {
562 RingQueue_Enqueue(&uvd->dp, cdata, datalen);
563 totaldata += datalen;
564 }
565 framelen -= datalen;
566 cdata += datalen;
567 }
568 return totaldata;
569}
570
571static int qcm_compress_iso(struct uvd *uvd, struct urb *dataurb)
572{
573 int totlen;
574 int i;
575 unsigned char *cdata;
576
577 totlen=0;
578 for (i = 0; i < dataurb->number_of_packets; i++) {
579 int n = dataurb->iso_frame_desc[i].actual_length;
580 int st = dataurb->iso_frame_desc[i].status;
581
582 cdata = dataurb->transfer_buffer +
583 dataurb->iso_frame_desc[i].offset;
584
585 if (st < 0) {
586 warn("Data error: packet=%d. len=%d. status=%d.",
587 i, n, st);
588 uvd->stats.iso_err_count++;
589 continue;
590 }
591 if (!n)
592 continue;
593
594 totlen += qcm_process_frame(uvd, cdata, n);
595 }
596 return totlen;
597}
598
599static void resubmit_urb(struct uvd *uvd, struct urb *urb)
600{
601 int ret;
602
603 urb->dev = uvd->dev;
604 ret = usb_submit_urb(urb, GFP_ATOMIC);
605 if (ret)
606 err("usb_submit_urb error (%d)", ret);
607}
608
609static void qcm_isoc_irq(struct urb *urb, struct pt_regs *regs)
610{
611 int len;
612 struct uvd *uvd = urb->context;
613
614 if (!CAMERA_IS_OPERATIONAL(uvd))
615 return;
616
617 if (!uvd->streaming)
618 return;
619
620 uvd->stats.urb_count++;
621
622 if (!urb->actual_length) {
623 resubmit_urb(uvd, urb);
624 return;
625 }
626
627 len = qcm_compress_iso(uvd, urb);
628 resubmit_urb(uvd, urb);
629 uvd->stats.urb_length = len;
630 uvd->stats.data_count += len;
631 if (len)
632 RingQueue_WakeUpInterruptible(&uvd->dp);
633}
634
635static int qcm_start_data(struct uvd *uvd)
636{
637 struct qcm *cam = (struct qcm *) uvd->user_data;
638 int i;
639 int errflag;
640 int pktsz;
641 int err;
642
643 pktsz = uvd->iso_packet_len;
644 if (!CAMERA_IS_OPERATIONAL(uvd)) {
645 err("Camera is not operational");
646 return -EFAULT;
647 }
648
649 err = usb_set_interface(uvd->dev, uvd->iface, uvd->ifaceAltActive);
650 if (err < 0) {
651 err("usb_set_interface error");
652 uvd->last_error = err;
653 return -EBUSY;
654 }
655
656 for (i=0; i < USBVIDEO_NUMSBUF; i++) {
657 int j, k;
658 struct urb *urb = uvd->sbuf[i].urb;
659 urb->dev = uvd->dev;
660 urb->context = uvd;
661 urb->pipe = usb_rcvisocpipe(uvd->dev, uvd->video_endp);
662 urb->interval = 1;
663 urb->transfer_flags = URB_ISO_ASAP;
664 urb->transfer_buffer = uvd->sbuf[i].data;
665 urb->complete = qcm_isoc_irq;
666 urb->number_of_packets = FRAMES_PER_DESC;
667 urb->transfer_buffer_length = pktsz * FRAMES_PER_DESC;
668 for (j=k=0; j < FRAMES_PER_DESC; j++, k += pktsz) {
669 urb->iso_frame_desc[j].offset = k;
670 urb->iso_frame_desc[j].length = pktsz;
671 }
672 }
673
674 uvd->streaming = 1;
675 uvd->curframe = -1;
676 for (i=0; i < USBVIDEO_NUMSBUF; i++) {
677 errflag = usb_submit_urb(uvd->sbuf[i].urb, GFP_KERNEL);
678 if (errflag)
679 err ("usb_submit_isoc(%d) ret %d", i, errflag);
680 }
681
682 CHECK_RET(err, qcm_setup_input_int(cam, uvd));
683 CHECK_RET(err, qcm_camera_on(uvd));
684 return 0;
685}
686
687static void qcm_stop_data(struct uvd *uvd)
688{
689 struct qcm *cam = (struct qcm *) uvd->user_data;
690 int i, j;
691 int ret;
692
693 if ((uvd == NULL) || (!uvd->streaming) || (uvd->dev == NULL))
694 return;
695
696 ret = qcm_camera_off(uvd);
697 if (ret)
698 warn("couldn't turn the cam off.");
699
700 uvd->streaming = 0;
701
702 /* Unschedule all of the iso td's */
703 for (i=0; i < USBVIDEO_NUMSBUF; i++)
704 usb_kill_urb(uvd->sbuf[i].urb);
705
706 qcm_stop_int_data(cam);
707
708 if (!uvd->remove_pending) {
709 /* Set packet size to 0 */
710 j = usb_set_interface(uvd->dev, uvd->iface,
711 uvd->ifaceAltInactive);
712 if (j < 0) {
713 err("usb_set_interface() error %d.", j);
714 uvd->last_error = j;
715 }
716 }
717}
718
719static void qcm_process_isoc(struct uvd *uvd, struct usbvideo_frame *frame)
720{
721 struct qcm *cam = (struct qcm *) uvd->user_data;
722 int x;
723 struct rgb *rgbL0;
724 struct rgb *rgbL1;
725 struct bayL0 *bayL0;
726 struct bayL1 *bayL1;
727 int hor,ver,hordel,verdel;
728 assert(frame != NULL);
729
730 switch (cam->size) {
731 case SIZE_160X120:
732 hor = 162; ver = 124; hordel = 1; verdel = 2;
733 break;
734 case SIZE_320X240:
735 default:
736 hor = 324; ver = 248; hordel = 2; verdel = 4;
737 break;
738 }
739
740 if (frame->scanstate == ScanState_Scanning) {
741 while (RingQueue_GetLength(&uvd->dp) >=
742 4 + (hor*verdel + hordel)) {
743 if ((RING_QUEUE_PEEK(&uvd->dp, 0) == 0x00) &&
744 (RING_QUEUE_PEEK(&uvd->dp, 1) == 0xff) &&
745 (RING_QUEUE_PEEK(&uvd->dp, 2) == 0x00) &&
746 (RING_QUEUE_PEEK(&uvd->dp, 3) == 0xff)) {
747 frame->curline = 0;
748 frame->scanstate = ScanState_Lines;
749 frame->frameState = FrameState_Grabbing;
750 RING_QUEUE_DEQUEUE_BYTES(&uvd->dp, 4);
751 /*
752 * if we're starting, we need to discard the first
753 * 4 lines of y bayer data
754 * and the first 2 gr elements of x bayer data
755 */
756 RING_QUEUE_DEQUEUE_BYTES(&uvd->dp,
757 (hor*verdel + hordel));
758 break;
759 }
760 RING_QUEUE_DEQUEUE_BYTES(&uvd->dp, 1);
761 }
762 }
763
764 if (frame->scanstate == ScanState_Scanning)
765 return;
766
767 /* now we can start processing bayer data so long as we have at least
768 * 2 lines worth of data. this is the simplest demosaicing method that
769 * I could think of. I use each 2x2 bayer element without interpolation
770 * to generate 4 rgb pixels.
771 */
772 while ( frame->curline < cam->height &&
773 (RingQueue_GetLength(&uvd->dp) >= hor*2)) {
774 /* get 2 lines of bayer for demosaicing
775 * into 2 lines of RGB */
776 RingQueue_Dequeue(&uvd->dp, cam->scratch, hor*2);
777 bayL0 = (struct bayL0 *) cam->scratch;
778 bayL1 = (struct bayL1 *) (cam->scratch + hor);
779 /* frame->curline is the rgb y line */
780 rgbL0 = (struct rgb *)
781 ( frame->data + (cam->width*3*frame->curline));
782 /* w/2 because we're already doing 2 pixels */
783 rgbL1 = rgbL0 + (cam->width/2);
784
785 for (x=0; x < cam->width; x+=2) {
786 rgbL0->r = bayL0->r;
787 rgbL0->g = bayL0->g;
788 rgbL0->b = bayL1->b;
789
790 rgbL0->r2 = bayL0->r;
791 rgbL0->g2 = bayL1->g;
792 rgbL0->b2 = bayL1->b;
793
794 rgbL1->r = bayL0->r;
795 rgbL1->g = bayL1->g;
796 rgbL1->b = bayL1->b;
797
798 rgbL1->r2 = bayL0->r;
799 rgbL1->g2 = bayL1->g;
800 rgbL1->b2 = bayL1->b;
801
802 rgbL0++;
803 rgbL1++;
804
805 bayL0++;
806 bayL1++;
807 }
808
809 frame->seqRead_Length += cam->width*3*2;
810 frame->curline += 2;
811 }
812 /* See if we filled the frame */
813 if (frame->curline == cam->height) {
814 frame->frameState = FrameState_Done_Hold;
815 frame->curline = 0;
816 uvd->curframe = -1;
817 uvd->stats.frame_num++;
818 }
819}
820
821/* taken from konicawc */
822static int qcm_set_video_mode(struct uvd *uvd, struct video_window *vw)
823{
824 int ret;
825 int newsize;
826 int oldsize;
827 int x = vw->width;
828 int y = vw->height;
829 struct qcm *cam = (struct qcm *) uvd->user_data;
830
831 if (x > 0 && y > 0) {
832 DEBUG(2, "trying to find size %d,%d", x, y);
833 for (newsize = 0; newsize <= MAX_FRAME_SIZE; newsize++) {
834 if ((camera_sizes[newsize].width == x) &&
835 (camera_sizes[newsize].height == y))
836 break;
837 }
838 } else
839 newsize = cam->size;
840
841 if (newsize > MAX_FRAME_SIZE) {
842 DEBUG(1, "couldn't find size %d,%d", x, y);
843 return -EINVAL;
844 }
845
846 if (newsize == cam->size) {
847 DEBUG(1, "Nothing to do");
848 return 0;
849 }
850
851 qcm_stop_data(uvd);
852
853 if (cam->size != newsize) {
854 oldsize = cam->size;
855 cam->size = newsize;
856 ret = qcm_set_camera_size(uvd);
857 if (ret) {
858 err("Couldn't set camera size, err=%d",ret);
859 /* restore the original size */
860 cam->size = oldsize;
861 return ret;
862 }
863 }
864
865 /* Flush the input queue and clear any current frame in progress */
866
867 RingQueue_Flush(&uvd->dp);
868 if (uvd->curframe != -1) {
869 uvd->frame[uvd->curframe].curline = 0;
870 uvd->frame[uvd->curframe].seqRead_Length = 0;
871 uvd->frame[uvd->curframe].seqRead_Index = 0;
872 }
873
874 CHECK_RET(ret, qcm_start_data(uvd));
875 return 0;
876}
877
878static int qcm_configure_video(struct uvd *uvd)
879{
880 int ret;
881 memset(&uvd->vpic, 0, sizeof(uvd->vpic));
882 memset(&uvd->vpic_old, 0x55, sizeof(uvd->vpic_old));
883
884 uvd->vpic.colour = colour;
885 uvd->vpic.hue = hue;
886 uvd->vpic.brightness = brightness;
887 uvd->vpic.contrast = contrast;
888 uvd->vpic.whiteness = whiteness;
889 uvd->vpic.depth = 24;
890 uvd->vpic.palette = VIDEO_PALETTE_RGB24;
891
892 memset(&uvd->vcap, 0, sizeof(uvd->vcap));
893 strcpy(uvd->vcap.name, "QCM USB Camera");
894 uvd->vcap.type = VID_TYPE_CAPTURE;
895 uvd->vcap.channels = 1;
896 uvd->vcap.audios = 0;
897
898 uvd->vcap.minwidth = camera_sizes[SIZE_160X120].width;
899 uvd->vcap.minheight = camera_sizes[SIZE_160X120].height;
900 uvd->vcap.maxwidth = camera_sizes[SIZE_320X240].width;
901 uvd->vcap.maxheight = camera_sizes[SIZE_320X240].height;
902
903 memset(&uvd->vchan, 0, sizeof(uvd->vchan));
904 uvd->vchan.flags = 0 ;
905 uvd->vchan.tuners = 0;
906 uvd->vchan.channel = 0;
907 uvd->vchan.type = VIDEO_TYPE_CAMERA;
908 strcpy(uvd->vchan.name, "Camera");
909
910 CHECK_RET(ret, qcm_sensor_init(uvd));
911 return 0;
912}
913
914static int qcm_probe(struct usb_interface *intf,
915 const struct usb_device_id *devid)
916{
917 int err;
918 struct uvd *uvd;
919 struct usb_device *dev = interface_to_usbdev(intf);
920 struct qcm *cam;
921 size_t buffer_size;
922 unsigned char video_ep;
923 struct usb_host_interface *interface;
924 struct usb_endpoint_descriptor *endpoint;
925 int i,j;
926 unsigned int ifacenum, ifacenum_inact=0;
927 __le16 sensor_id;
928
929 /* we don't support multiconfig cams */
930 if (dev->descriptor.bNumConfigurations != 1)
931 return -ENODEV;
932
933 /* first check for the video interface and not
934 * the audio interface */
935 interface = &intf->cur_altsetting[0];
936 if ((interface->desc.bInterfaceClass != USB_CLASS_VENDOR_SPEC)
937 || (interface->desc.bInterfaceSubClass !=
938 USB_CLASS_VENDOR_SPEC))
939 return -ENODEV;
940
941 /*
942 walk through each endpoint in each setting in the interface
943 stop when we find the one that's an isochronous IN endpoint.
944 */
945 for (i=0; i < intf->num_altsetting; i++) {
946 interface = &intf->cur_altsetting[i];
947 ifacenum = interface->desc.bAlternateSetting;
948 /* walk the end points */
949 for (j=0; j < interface->desc.bNumEndpoints; j++) {
950 endpoint = &interface->endpoint[j].desc;
951
952 if ((endpoint->bEndpointAddress &
953 USB_ENDPOINT_DIR_MASK) != USB_DIR_IN)
954 continue; /* not input then not good */
955
956 buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);
957 if (!buffer_size) {
958 ifacenum_inact = ifacenum;
959 continue; /* 0 pkt size is not what we want */
960 }
961
962 if ((endpoint->bmAttributes &
963 USB_ENDPOINT_XFERTYPE_MASK) ==
964 USB_ENDPOINT_XFER_ISOC) {
965 video_ep = endpoint->bEndpointAddress;
966 /* break out of the search */
967 goto good_videoep;
968 }
969 }
970 }
971 /* failed out since nothing useful was found */
972 err("No suitable endpoint was found\n");
973 return -ENODEV;
974
975good_videoep:
976 /* disable isochronous stream before doing anything else */
977 err = qcm_stv_setb(dev, STV_ISO_ENABLE, 0);
978 if (err < 0) {
979 err("Failed to disable sensor stream");
980 return -EIO;
981 }
982
983 /*
984 Check that this is the same unknown sensor that is known to work. This
985 sensor is suspected to be the ST VV6422C001. I'll check the same value
986 that the qc-usb driver checks. This value is probably not even the
987 sensor ID since it matches the USB dev ID. Oh well. If it doesn't
988 match, it's probably a diff sensor so exit and apologize.
989 */
990 err = qcm_stv_getw(dev, CMOS_SENSOR_IDREV, &sensor_id);
991 if (err < 0) {
992 err("Couldn't read sensor values. Err %d\n",err);
993 return err;
994 }
995 if (sensor_id != cpu_to_le16(0x08F0)) {
996 err("Sensor ID %x != %x. Unsupported. Sorry\n",
997 le16_to_cpu(sensor_id), (0x08F0));
998 return -ENODEV;
999 }
1000
1001 uvd = usbvideo_AllocateDevice(cams);
1002 if (!uvd)
1003 return -ENOMEM;
1004
1005 cam = (struct qcm *) uvd->user_data;
1006
1007 /* buf for doing demosaicing */
1008 cam->scratch = kmalloc(324*2, GFP_KERNEL);
1009 if (!cam->scratch) /* uvd freed in dereg */
1010 return -ENOMEM;
1011
1012 /* yes, if we fail after here, cam->scratch gets freed
1013 by qcm_free_uvd */
1014
1015 err = qcm_alloc_int_urb(cam);
1016 if (err < 0)
1017 return err;
1018
1019 /* yes, if we fail after here, int urb gets freed
1020 by qcm_free_uvd */
1021
1022 RESTRICT_TO_RANGE(size, SIZE_160X120, SIZE_320X240);
1023 cam->width = camera_sizes[size].width;
1024 cam->height = camera_sizes[size].height;
1025 cam->size = size;
1026
1027 uvd->debug = debug;
1028 uvd->flags = 0;
1029 uvd->dev = dev;
1030 uvd->iface = intf->altsetting->desc.bInterfaceNumber;
1031 uvd->ifaceAltActive = ifacenum;
1032 uvd->ifaceAltInactive = ifacenum_inact;
1033 uvd->video_endp = video_ep;
1034 uvd->iso_packet_len = buffer_size;
1035 uvd->paletteBits = 1L << VIDEO_PALETTE_RGB24;
1036 uvd->defaultPalette = VIDEO_PALETTE_RGB24;
1037 uvd->canvas = VIDEOSIZE(320, 240);
1038 uvd->videosize = VIDEOSIZE(cam->width, cam->height);
1039 err = qcm_configure_video(uvd);
1040 if (err) {
1041 err("failed to configure video settings");
1042 return err;
1043 }
1044
1045 err = usbvideo_RegisterVideoDevice(uvd);
1046 if (err) { /* the uvd gets freed in Deregister */
1047 err("usbvideo_RegisterVideoDevice() failed.");
1048 return err;
1049 }
1050
1051 uvd->max_frame_size = (320 * 240 * 3);
1052 qcm_register_input(cam, dev);
1053 usb_set_intfdata(intf, uvd);
1054 return 0;
1055}
1056
1057static void qcm_free_uvd(struct uvd *uvd)
1058{
1059 struct qcm *cam = (struct qcm *) uvd->user_data;
1060
1061 kfree(cam->scratch);
1062 qcm_unregister_input(cam);
1063 qcm_free_int(cam);
1064}
1065
1066static struct usbvideo_cb qcm_driver = {
1067 .probe = qcm_probe,
1068 .setupOnOpen = qcm_setup_on_open,
1069 .processData = qcm_process_isoc,
1070 .setVideoMode = qcm_set_video_mode,
1071 .startDataPump = qcm_start_data,
1072 .stopDataPump = qcm_stop_data,
1073 .adjustPicture = qcm_adjust_picture,
1074 .userFree = qcm_free_uvd
1075};
1076
1077static int __init qcm_init(void)
1078{
1079 info(DRIVER_DESC " " DRIVER_VERSION);
1080
1081 return usbvideo_register(
1082 &cams,
1083 MAX_CAMERAS,
1084 sizeof(struct qcm),
1085 "QCM",
1086 &qcm_driver,
1087 THIS_MODULE,
1088 qcm_table);
1089}
1090
1091static void __exit qcm_exit(void)
1092{
1093 usbvideo_Deregister(&cams);
1094}
1095
1096module_param(size, int, 0);
1097MODULE_PARM_DESC(size, "Initial Size 0: 160x120 1: 320x240");
1098module_param(colour, int, 0);
1099MODULE_PARM_DESC(colour, "Initial colour");
1100module_param(hue, int, 0);
1101MODULE_PARM_DESC(hue, "Initial hue");
1102module_param(brightness, int, 0);
1103MODULE_PARM_DESC(brightness, "Initial brightness");
1104module_param(contrast, int, 0);
1105MODULE_PARM_DESC(contrast, "Initial contrast");
1106module_param(whiteness, int, 0);
1107MODULE_PARM_DESC(whiteness, "Initial whiteness");
1108
1109#ifdef CONFIG_USB_DEBUG
1110module_param(debug, int, S_IRUGO | S_IWUSR);
1111MODULE_PARM_DESC(debug, "Debug level: 0-9 (default=0)");
1112#endif
1113
1114module_init(qcm_init);
1115module_exit(qcm_exit);
1116
1117MODULE_LICENSE("GPL");
1118MODULE_AUTHOR("Jaya Kumar");
1119MODULE_DESCRIPTION("QCM USB Camera");
1120MODULE_SUPPORTED_DEVICE("QCM USB Camera");
diff --git a/drivers/media/video/usbvideo/quickcam_messenger.h b/drivers/media/video/usbvideo/quickcam_messenger.h
new file mode 100644
index 00000000000..baab9c081b5
--- /dev/null
+++ b/drivers/media/video/usbvideo/quickcam_messenger.h
@@ -0,0 +1,126 @@
1#ifndef quickcam_messenger_h
2#define quickcam_messenger_h
3
4#ifndef CONFIG_INPUT
5/* if we're not using input we dummy out these functions */
6#define qcm_register_input(...)
7#define qcm_unregister_input(...)
8#define qcm_report_buttonstat(...)
9#define qcm_setup_input_int(...) 0
10#define qcm_stop_int_data(...)
11#define qcm_alloc_int_urb(...) 0
12#define qcm_free_int(...)
13#endif
14
15
16#define CHECK_RET(ret, expr) \
17 if ((ret = expr) < 0) return ret
18
19/* Control Registers for the STVV6422 ASIC
20 * - this define is taken from the qc-usb-messenger code
21 */
22#define STV_ISO_ENABLE 0x1440
23#define ISOC_PACKET_SIZE 1023
24
25/* Chip identification number including revision indicator */
26#define CMOS_SENSOR_IDREV 0xE00A
27
28struct rgb {
29 u8 b;
30 u8 g;
31 u8 r;
32 u8 b2;
33 u8 g2;
34 u8 r2;
35};
36
37struct bayL0 {
38#ifdef __BIG_ENDIAN
39 u8 r;
40 u8 g;
41#elif __LITTLE_ENDIAN
42 u8 g;
43 u8 r;
44#else
45#error not byte order defined
46#endif
47};
48
49struct bayL1 {
50#ifdef __BIG_ENDIAN
51 u8 g;
52 u8 b;
53#elif __LITTLE_ENDIAN
54 u8 b;
55 u8 g;
56#else
57#error not byte order defined
58#endif
59};
60
61struct cam_size {
62 u16 width;
63 u16 height;
64 u8 cmd;
65};
66
67static const struct cam_size camera_sizes[] = {
68 { 160, 120, 0xf },
69 { 320, 240, 0x2 },
70};
71
72enum frame_sizes {
73 SIZE_160X120 = 0,
74 SIZE_320X240 = 1,
75};
76
77#define MAX_FRAME_SIZE SIZE_320X240
78
79struct qcm {
80 u16 colour;
81 u16 hue;
82 u16 brightness;
83 u16 contrast;
84 u16 whiteness;
85
86 u8 size;
87 int height;
88 int width;
89 u8 *scratch;
90 struct urb *button_urb;
91 u8 button_sts;
92 u8 button_sts_buf;
93
94#ifdef CONFIG_INPUT
95 struct input_dev *input;
96 char input_physname[64];
97#endif
98};
99
100struct regval {
101 u16 reg;
102 u8 val;
103};
104/* this table is derived from the
105qc-usb-messenger code */
106static const struct regval regval_table[] = {
107 { STV_ISO_ENABLE, 0x00 },
108 { 0x1436, 0x00 }, { 0x1432, 0x03 },
109 { 0x143a, 0xF9 }, { 0x0509, 0x38 },
110 { 0x050a, 0x38 }, { 0x050b, 0x38 },
111 { 0x050c, 0x2A }, { 0x050d, 0x01 },
112 { 0x1431, 0x00 }, { 0x1433, 0x34 },
113 { 0x1438, 0x18 }, { 0x1439, 0x00 },
114 { 0x143b, 0x05 }, { 0x143c, 0x00 },
115 { 0x143e, 0x01 }, { 0x143d, 0x00 },
116 { 0x1442, 0xe2 }, { 0x1500, 0xd0 },
117 { 0x1500, 0xd0 }, { 0x1500, 0x50 },
118 { 0x1501, 0xaf }, { 0x1502, 0xc2 },
119 { 0x1503, 0x45 }, { 0x1505, 0x02 },
120 { 0x150e, 0x8e }, { 0x150f, 0x37 },
121 { 0x15c0, 0x00 },
122};
123
124static const unsigned char marker[] = { 0x00, 0xff, 0x00, 0xFF };
125
126#endif /* quickcam_messenger_h */
diff --git a/drivers/media/video/usbvideo/usbvideo.h b/drivers/media/video/usbvideo/usbvideo.h
index 3cbf4fc499a..49dbee5f562 100644
--- a/drivers/media/video/usbvideo/usbvideo.h
+++ b/drivers/media/video/usbvideo/usbvideo.h
@@ -18,6 +18,7 @@
18 18
19#include <linux/config.h> 19#include <linux/config.h>
20#include <linux/videodev.h> 20#include <linux/videodev.h>
21#include <media/v4l2-common.h>
21#include <linux/usb.h> 22#include <linux/usb.h>
22#include <linux/mutex.h> 23#include <linux/mutex.h>
23 24
diff --git a/drivers/media/video/v4l1-compat.c b/drivers/media/video/v4l1-compat.c
index 474a29bc176..19d3c20dc7e 100644
--- a/drivers/media/video/v4l1-compat.c
+++ b/drivers/media/video/v4l1-compat.c
@@ -32,6 +32,7 @@
32#include <linux/errno.h> 32#include <linux/errno.h>
33#include <linux/slab.h> 33#include <linux/slab.h>
34#include <linux/videodev.h> 34#include <linux/videodev.h>
35#include <media/v4l2-common.h>
35 36
36#include <asm/uaccess.h> 37#include <asm/uaccess.h>
37#include <asm/system.h> 38#include <asm/system.h>
diff --git a/drivers/media/video/v4l2-common.c b/drivers/media/video/v4l2-common.c
index d330fa985bc..14e52347135 100644
--- a/drivers/media/video/v4l2-common.c
+++ b/drivers/media/video/v4l2-common.c
@@ -59,6 +59,7 @@
59#include <asm/io.h> 59#include <asm/io.h>
60#include <asm/div64.h> 60#include <asm/div64.h>
61#include <linux/video_decoder.h> 61#include <linux/video_decoder.h>
62#define __OLD_VIDIOC_ /* To allow fixing old calls*/
62#include <media/v4l2-common.h> 63#include <media/v4l2-common.h>
63 64
64#ifdef CONFIG_KMOD 65#ifdef CONFIG_KMOD
@@ -293,7 +294,10 @@ static const char *v4l2_ioctls[] = {
293#if 1 294#if 1
294 [_IOC_NR(VIDIOC_G_SLICED_VBI_CAP)] = "VIDIOC_G_SLICED_VBI_CAP", 295 [_IOC_NR(VIDIOC_G_SLICED_VBI_CAP)] = "VIDIOC_G_SLICED_VBI_CAP",
295#endif 296#endif
296 [_IOC_NR(VIDIOC_LOG_STATUS)] = "VIDIOC_LOG_STATUS" 297 [_IOC_NR(VIDIOC_LOG_STATUS)] = "VIDIOC_LOG_STATUS",
298 [_IOC_NR(VIDIOC_G_EXT_CTRLS)] = "VIDIOC_G_EXT_CTRLS",
299 [_IOC_NR(VIDIOC_S_EXT_CTRLS)] = "VIDIOC_S_EXT_CTRLS",
300 [_IOC_NR(VIDIOC_TRY_EXT_CTRLS)] = "VIDIOC_TRY_EXT_CTRLS"
297}; 301};
298#define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls) 302#define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls)
299 303
@@ -331,7 +335,8 @@ static const char *v4l2_int_ioctls[] = {
331 [_IOC_NR(VIDIOC_INT_S_AUDIO_ROUTING)] = "VIDIOC_INT_S_AUDIO_ROUTING", 335 [_IOC_NR(VIDIOC_INT_S_AUDIO_ROUTING)] = "VIDIOC_INT_S_AUDIO_ROUTING",
332 [_IOC_NR(VIDIOC_INT_G_AUDIO_ROUTING)] = "VIDIOC_INT_G_AUDIO_ROUTING", 336 [_IOC_NR(VIDIOC_INT_G_AUDIO_ROUTING)] = "VIDIOC_INT_G_AUDIO_ROUTING",
333 [_IOC_NR(VIDIOC_INT_S_VIDEO_ROUTING)] = "VIDIOC_INT_S_VIDEO_ROUTING", 337 [_IOC_NR(VIDIOC_INT_S_VIDEO_ROUTING)] = "VIDIOC_INT_S_VIDEO_ROUTING",
334 [_IOC_NR(VIDIOC_INT_G_VIDEO_ROUTING)] = "VIDIOC_INT_G_VIDEO_ROUTING" 338 [_IOC_NR(VIDIOC_INT_G_VIDEO_ROUTING)] = "VIDIOC_INT_G_VIDEO_ROUTING",
339 [_IOC_NR(VIDIOC_INT_S_CRYSTAL_FREQ)] = "VIDIOC_INT_S_CRYSTAL_FREQ"
335}; 340};
336#define V4L2_INT_IOCTLS ARRAY_SIZE(v4l2_int_ioctls) 341#define V4L2_INT_IOCTLS ARRAY_SIZE(v4l2_int_ioctls)
337 342
@@ -423,7 +428,9 @@ void v4l_printk_ioctl_arg(char *s,unsigned int cmd, void *arg)
423 case TUNER_SET_TYPE_ADDR: 428 case TUNER_SET_TYPE_ADDR:
424 case TUNER_SET_STANDBY: 429 case TUNER_SET_STANDBY:
425 case TDA9887_SET_CONFIG: 430 case TDA9887_SET_CONFIG:
431#ifdef __OLD_VIDIOC_
426 case VIDIOC_OVERLAY_OLD: 432 case VIDIOC_OVERLAY_OLD:
433#endif
427 case VIDIOC_STREAMOFF: 434 case VIDIOC_STREAMOFF:
428 case VIDIOC_G_OUTPUT: 435 case VIDIOC_G_OUTPUT:
429 case VIDIOC_S_OUTPUT: 436 case VIDIOC_S_OUTPUT:
@@ -439,7 +446,9 @@ void v4l_printk_ioctl_arg(char *s,unsigned int cmd, void *arg)
439 case VIDIOC_G_AUDIO: 446 case VIDIOC_G_AUDIO:
440 case VIDIOC_S_AUDIO: 447 case VIDIOC_S_AUDIO:
441 case VIDIOC_ENUMAUDIO: 448 case VIDIOC_ENUMAUDIO:
449#ifdef __OLD_VIDIOC_
442 case VIDIOC_G_AUDIO_OLD: 450 case VIDIOC_G_AUDIO_OLD:
451#endif
443 { 452 {
444 struct v4l2_audio *p=arg; 453 struct v4l2_audio *p=arg;
445 454
@@ -450,7 +459,9 @@ void v4l_printk_ioctl_arg(char *s,unsigned int cmd, void *arg)
450 case VIDIOC_G_AUDOUT: 459 case VIDIOC_G_AUDOUT:
451 case VIDIOC_S_AUDOUT: 460 case VIDIOC_S_AUDOUT:
452 case VIDIOC_ENUMAUDOUT: 461 case VIDIOC_ENUMAUDOUT:
462#ifdef __OLD_VIDIOC_
453 case VIDIOC_G_AUDOUT_OLD: 463 case VIDIOC_G_AUDOUT_OLD:
464#endif
454 { 465 {
455 struct v4l2_audioout *p=arg; 466 struct v4l2_audioout *p=arg;
456 printk ("%s: index=%d, name=%s, capability=%d, mode=%d\n", s, 467 printk ("%s: index=%d, name=%s, capability=%d, mode=%d\n", s,
@@ -478,9 +489,9 @@ void v4l_printk_ioctl_arg(char *s,unsigned int cmd, void *arg)
478 prt_names(p->memory,v4l2_memory_names), 489 prt_names(p->memory,v4l2_memory_names),
479 p->m.userptr); 490 p->m.userptr);
480 printk ("%s: timecode= %02d:%02d:%02d type=%d, " 491 printk ("%s: timecode= %02d:%02d:%02d type=%d, "
481 "flags=0x%08x, frames=%d, userbits=0x%p\n", 492 "flags=0x%08x, frames=%d, userbits=0x%08x\n",
482 s,tc->hours,tc->minutes,tc->seconds, 493 s,tc->hours,tc->minutes,tc->seconds,
483 tc->type, tc->flags, tc->frames, tc->userbits); 494 tc->type, tc->flags, tc->frames, *(__u32 *) tc->userbits);
484 break; 495 break;
485 } 496 }
486 case VIDIOC_QUERYCAP: 497 case VIDIOC_QUERYCAP:
@@ -495,12 +506,31 @@ void v4l_printk_ioctl_arg(char *s,unsigned int cmd, void *arg)
495 } 506 }
496 case VIDIOC_G_CTRL: 507 case VIDIOC_G_CTRL:
497 case VIDIOC_S_CTRL: 508 case VIDIOC_S_CTRL:
509#ifdef __OLD_VIDIOC_
498 case VIDIOC_S_CTRL_OLD: 510 case VIDIOC_S_CTRL_OLD:
511#endif
499 { 512 {
500 struct v4l2_control *p=arg; 513 struct v4l2_control *p=arg;
501 printk ("%s: id=%d, value=%d\n", s, p->id, p->value); 514 printk ("%s: id=%d, value=%d\n", s, p->id, p->value);
502 break; 515 break;
503 } 516 }
517 case VIDIOC_G_EXT_CTRLS:
518 case VIDIOC_S_EXT_CTRLS:
519 case VIDIOC_TRY_EXT_CTRLS:
520 {
521 struct v4l2_ext_controls *p = arg;
522 int i;
523
524 printk("%s: ctrl_class=%d, count=%d\n", s, p->ctrl_class, p->count);
525 for (i = 0; i < p->count; i++) {
526 struct v4l2_ext_control *c = &p->controls[i];
527 if (cmd == VIDIOC_G_EXT_CTRLS)
528 printk("%s: id=%d\n", s, c->id);
529 else
530 printk("%s: id=%d, value=%d\n", s, c->id, c->value);
531 }
532 break;
533 }
504 case VIDIOC_G_CROP: 534 case VIDIOC_G_CROP:
505 case VIDIOC_S_CROP: 535 case VIDIOC_S_CROP:
506 { 536 {
@@ -510,7 +540,9 @@ void v4l_printk_ioctl_arg(char *s,unsigned int cmd, void *arg)
510 break; 540 break;
511 } 541 }
512 case VIDIOC_CROPCAP: 542 case VIDIOC_CROPCAP:
543#ifdef __OLD_VIDIOC_
513 case VIDIOC_CROPCAP_OLD: 544 case VIDIOC_CROPCAP_OLD:
545#endif
514 { 546 {
515 struct v4l2_cropcap *p=arg; 547 struct v4l2_cropcap *p=arg;
516 /*FIXME: Should also show rect structs */ 548 /*FIXME: Should also show rect structs */
@@ -667,6 +699,12 @@ void v4l_printk_ioctl_arg(char *s,unsigned int cmd, void *arg)
667 printk ("%s: input=0x%x, output=0x%x\n", s, p->input, p->output); 699 printk ("%s: input=0x%x, output=0x%x\n", s, p->input, p->output);
668 break; 700 break;
669 } 701 }
702 case VIDIOC_INT_S_CRYSTAL_FREQ:
703 {
704 struct v4l2_crystal_freq *p=arg;
705 printk ("%s: freq=%u, flags=0x%x\n", s, p->freq, p->flags);
706 break;
707 }
670 case VIDIOC_G_SLICED_VBI_CAP: 708 case VIDIOC_G_SLICED_VBI_CAP:
671 { 709 {
672 struct v4l2_sliced_vbi_cap *p=arg; 710 struct v4l2_sliced_vbi_cap *p=arg;
@@ -696,7 +734,9 @@ void v4l_printk_ioctl_arg(char *s,unsigned int cmd, void *arg)
696 } 734 }
697 case VIDIOC_G_PARM: 735 case VIDIOC_G_PARM:
698 case VIDIOC_S_PARM: 736 case VIDIOC_S_PARM:
737#ifdef __OLD_VIDIOC_
699 case VIDIOC_S_PARM_OLD: 738 case VIDIOC_S_PARM_OLD:
739#endif
700 { 740 {
701 struct v4l2_streamparm *p=arg; 741 struct v4l2_streamparm *p=arg;
702 printk ("%s: type=%d\n", s, p->type); 742 printk ("%s: type=%d\n", s, p->type);
@@ -915,6 +955,484 @@ void v4l_printk_ioctl_arg(char *s,unsigned int cmd, void *arg)
915 955
916/* ----------------------------------------------------------------- */ 956/* ----------------------------------------------------------------- */
917 957
958/* Helper functions for control handling */
959
960/* Check for correctness of the ctrl's value based on the data from
961 struct v4l2_queryctrl and the available menu items. Note that
962 menu_items may be NULL, in that case it is ignored. */
963int v4l2_ctrl_check(struct v4l2_ext_control *ctrl, struct v4l2_queryctrl *qctrl,
964 const char **menu_items)
965{
966 if (qctrl->flags & V4L2_CTRL_FLAG_DISABLED)
967 return -EINVAL;
968 if (qctrl->flags & V4L2_CTRL_FLAG_GRABBED)
969 return -EBUSY;
970 if (qctrl->type == V4L2_CTRL_TYPE_BUTTON ||
971 qctrl->type == V4L2_CTRL_TYPE_INTEGER64 ||
972 qctrl->type == V4L2_CTRL_TYPE_CTRL_CLASS)
973 return 0;
974 if (ctrl->value < qctrl->minimum || ctrl->value > qctrl->maximum)
975 return -ERANGE;
976 if (qctrl->type == V4L2_CTRL_TYPE_MENU && menu_items != NULL) {
977 if (menu_items[ctrl->value] == NULL ||
978 menu_items[ctrl->value][0] == '\0')
979 return -EINVAL;
980 }
981 return 0;
982}
983
984/* Returns NULL or a character pointer array containing the menu for
985 the given control ID. The pointer array ends with a NULL pointer.
986 An empty string signifies a menu entry that is invalid. This allows
987 drivers to disable certain options if it is not supported. */
988const char **v4l2_ctrl_get_menu(u32 id)
989{
990 static const char *mpeg_audio_sampling_freq[] = {
991 "44.1 kHz",
992 "48 kHz",
993 "32 kHz",
994 NULL
995 };
996 static const char *mpeg_audio_encoding[] = {
997 "Layer I",
998 "Layer II",
999 "Layer III",
1000 NULL
1001 };
1002 static const char *mpeg_audio_l1_bitrate[] = {
1003 "32 kbps",
1004 "64 kbps",
1005 "96 kbps",
1006 "128 kbps",
1007 "160 kbps",
1008 "192 kbps",
1009 "224 kbps",
1010 "256 kbps",
1011 "288 kbps",
1012 "320 kbps",
1013 "352 kbps",
1014 "384 kbps",
1015 "416 kbps",
1016 "448 kbps",
1017 NULL
1018 };
1019 static const char *mpeg_audio_l2_bitrate[] = {
1020 "32 kbps",
1021 "48 kbps",
1022 "56 kbps",
1023 "64 kbps",
1024 "80 kbps",
1025 "96 kbps",
1026 "112 kbps",
1027 "128 kbps",
1028 "160 kbps",
1029 "192 kbps",
1030 "224 kbps",
1031 "256 kbps",
1032 "320 kbps",
1033 "384 kbps",
1034 NULL
1035 };
1036 static const char *mpeg_audio_l3_bitrate[] = {
1037 "32 kbps",
1038 "40 kbps",
1039 "48 kbps",
1040 "56 kbps",
1041 "64 kbps",
1042 "80 kbps",
1043 "96 kbps",
1044 "112 kbps",
1045 "128 kbps",
1046 "160 kbps",
1047 "192 kbps",
1048 "224 kbps",
1049 "256 kbps",
1050 "320 kbps",
1051 NULL
1052 };
1053 static const char *mpeg_audio_mode[] = {
1054 "Stereo",
1055 "Joint Stereo",
1056 "Dual",
1057 "Mono",
1058 NULL
1059 };
1060 static const char *mpeg_audio_mode_extension[] = {
1061 "Bound 4",
1062 "Bound 8",
1063 "Bound 12",
1064 "Bound 16",
1065 NULL
1066 };
1067 static const char *mpeg_audio_emphasis[] = {
1068 "No Emphasis",
1069 "50/15 us",
1070 "CCITT J17",
1071 NULL
1072 };
1073 static const char *mpeg_audio_crc[] = {
1074 "No CRC",
1075 "16-bit CRC",
1076 NULL
1077 };
1078 static const char *mpeg_video_encoding[] = {
1079 "MPEG-1",
1080 "MPEG-2",
1081 NULL
1082 };
1083 static const char *mpeg_video_aspect[] = {
1084 "1x1",
1085 "4x3",
1086 "16x9",
1087 "2.21x1",
1088 NULL
1089 };
1090 static const char *mpeg_video_bitrate_mode[] = {
1091 "Variable Bitrate",
1092 "Constant Bitrate",
1093 NULL
1094 };
1095 static const char *mpeg_stream_type[] = {
1096 "MPEG-2 Program Stream",
1097 "MPEG-2 Transport Stream",
1098 "MPEG-1 System Stream",
1099 "MPEG-2 DVD-compatible Stream",
1100 "MPEG-1 VCD-compatible Stream",
1101 "MPEG-2 SVCD-compatible Stream",
1102 NULL
1103 };
1104
1105 switch (id) {
1106 case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ:
1107 return mpeg_audio_sampling_freq;
1108 case V4L2_CID_MPEG_AUDIO_ENCODING:
1109 return mpeg_audio_encoding;
1110 case V4L2_CID_MPEG_AUDIO_L1_BITRATE:
1111 return mpeg_audio_l1_bitrate;
1112 case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
1113 return mpeg_audio_l2_bitrate;
1114 case V4L2_CID_MPEG_AUDIO_L3_BITRATE:
1115 return mpeg_audio_l3_bitrate;
1116 case V4L2_CID_MPEG_AUDIO_MODE:
1117 return mpeg_audio_mode;
1118 case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION:
1119 return mpeg_audio_mode_extension;
1120 case V4L2_CID_MPEG_AUDIO_EMPHASIS:
1121 return mpeg_audio_emphasis;
1122 case V4L2_CID_MPEG_AUDIO_CRC:
1123 return mpeg_audio_crc;
1124 case V4L2_CID_MPEG_VIDEO_ENCODING:
1125 return mpeg_video_encoding;
1126 case V4L2_CID_MPEG_VIDEO_ASPECT:
1127 return mpeg_video_aspect;
1128 case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
1129 return mpeg_video_bitrate_mode;
1130 case V4L2_CID_MPEG_STREAM_TYPE:
1131 return mpeg_stream_type;
1132 default:
1133 return NULL;
1134 }
1135}
1136
1137/* Fill in a struct v4l2_queryctrl */
1138int v4l2_ctrl_query_fill(struct v4l2_queryctrl *qctrl, s32 min, s32 max, s32 step, s32 def)
1139{
1140 const char *name;
1141
1142 qctrl->flags = 0;
1143 switch (qctrl->id) {
1144 /* USER controls */
1145 case V4L2_CID_USER_CLASS: name = "User Controls"; break;
1146 case V4L2_CID_AUDIO_VOLUME: name = "Volume"; break;
1147 case V4L2_CID_AUDIO_MUTE: name = "Mute"; break;
1148 case V4L2_CID_AUDIO_BALANCE: name = "Balance"; break;
1149 case V4L2_CID_AUDIO_BASS: name = "Bass"; break;
1150 case V4L2_CID_AUDIO_TREBLE: name = "Treble"; break;
1151 case V4L2_CID_AUDIO_LOUDNESS: name = "Loudness"; break;
1152 case V4L2_CID_BRIGHTNESS: name = "Brightness"; break;
1153 case V4L2_CID_CONTRAST: name = "Contrast"; break;
1154 case V4L2_CID_SATURATION: name = "Saturation"; break;
1155 case V4L2_CID_HUE: name = "Hue"; break;
1156
1157 /* MPEG controls */
1158 case V4L2_CID_MPEG_CLASS: name = "MPEG Encoder Controls"; break;
1159 case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ: name = "Audio Sampling Frequency"; break;
1160 case V4L2_CID_MPEG_AUDIO_ENCODING: name = "Audio Encoding Layer"; break;
1161 case V4L2_CID_MPEG_AUDIO_L1_BITRATE: name = "Audio Layer I Bitrate"; break;
1162 case V4L2_CID_MPEG_AUDIO_L2_BITRATE: name = "Audio Layer II Bitrate"; break;
1163 case V4L2_CID_MPEG_AUDIO_L3_BITRATE: name = "Audio Layer III Bitrate"; break;
1164 case V4L2_CID_MPEG_AUDIO_MODE: name = "Audio Stereo Mode"; break;
1165 case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION: name = "Audio Stereo Mode Extension"; break;
1166 case V4L2_CID_MPEG_AUDIO_EMPHASIS: name = "Audio Emphasis"; break;
1167 case V4L2_CID_MPEG_AUDIO_CRC: name = "Audio CRC"; break;
1168 case V4L2_CID_MPEG_VIDEO_ENCODING: name = "Video Encoding"; break;
1169 case V4L2_CID_MPEG_VIDEO_ASPECT: name = "Video Aspect"; break;
1170 case V4L2_CID_MPEG_VIDEO_B_FRAMES: name = "Video B Frames"; break;
1171 case V4L2_CID_MPEG_VIDEO_GOP_SIZE: name = "Video GOP Size"; break;
1172 case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE: name = "Video GOP Closure"; break;
1173 case V4L2_CID_MPEG_VIDEO_PULLDOWN: name = "Video Pulldown"; break;
1174 case V4L2_CID_MPEG_VIDEO_BITRATE_MODE: name = "Video Bitrate Mode"; break;
1175 case V4L2_CID_MPEG_VIDEO_BITRATE: name = "Video Bitrate"; break;
1176 case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK: name = "Video Peak Bitrate"; break;
1177 case V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION: name = "Video Temporal Decimation"; break;
1178 case V4L2_CID_MPEG_STREAM_TYPE: name = "Stream Type"; break;
1179 case V4L2_CID_MPEG_STREAM_PID_PMT: name = "Stream PMT Program ID"; break;
1180 case V4L2_CID_MPEG_STREAM_PID_AUDIO: name = "Stream Audio Program ID"; break;
1181 case V4L2_CID_MPEG_STREAM_PID_VIDEO: name = "Stream Video Program ID"; break;
1182 case V4L2_CID_MPEG_STREAM_PID_PCR: name = "Stream PCR Program ID"; break;
1183 case V4L2_CID_MPEG_STREAM_PES_ID_AUDIO: name = "Stream PES Audio ID"; break;
1184 case V4L2_CID_MPEG_STREAM_PES_ID_VIDEO: name = "Stream PES Video ID"; break;
1185
1186 default:
1187 return -EINVAL;
1188 }
1189 switch (qctrl->id) {
1190 case V4L2_CID_AUDIO_MUTE:
1191 case V4L2_CID_AUDIO_LOUDNESS:
1192 case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE:
1193 case V4L2_CID_MPEG_VIDEO_PULLDOWN:
1194 qctrl->type = V4L2_CTRL_TYPE_BOOLEAN;
1195 min = 0;
1196 max = step = 1;
1197 break;
1198 case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ:
1199 case V4L2_CID_MPEG_AUDIO_ENCODING:
1200 case V4L2_CID_MPEG_AUDIO_L1_BITRATE:
1201 case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
1202 case V4L2_CID_MPEG_AUDIO_L3_BITRATE:
1203 case V4L2_CID_MPEG_AUDIO_MODE:
1204 case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION:
1205 case V4L2_CID_MPEG_AUDIO_EMPHASIS:
1206 case V4L2_CID_MPEG_AUDIO_CRC:
1207 case V4L2_CID_MPEG_VIDEO_ENCODING:
1208 case V4L2_CID_MPEG_VIDEO_ASPECT:
1209 case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
1210 case V4L2_CID_MPEG_STREAM_TYPE:
1211 qctrl->type = V4L2_CTRL_TYPE_MENU;
1212 step = 1;
1213 break;
1214 case V4L2_CID_USER_CLASS:
1215 case V4L2_CID_MPEG_CLASS:
1216 qctrl->type = V4L2_CTRL_TYPE_CTRL_CLASS;
1217 qctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
1218 min = max = step = def = 0;
1219 break;
1220 default:
1221 qctrl->type = V4L2_CTRL_TYPE_INTEGER;
1222 break;
1223 }
1224 switch (qctrl->id) {
1225 case V4L2_CID_MPEG_AUDIO_ENCODING:
1226 case V4L2_CID_MPEG_AUDIO_MODE:
1227 case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
1228 case V4L2_CID_MPEG_VIDEO_B_FRAMES:
1229 case V4L2_CID_MPEG_STREAM_TYPE:
1230 qctrl->flags |= V4L2_CTRL_FLAG_UPDATE;
1231 break;
1232 case V4L2_CID_AUDIO_VOLUME:
1233 case V4L2_CID_AUDIO_BALANCE:
1234 case V4L2_CID_AUDIO_BASS:
1235 case V4L2_CID_AUDIO_TREBLE:
1236 case V4L2_CID_BRIGHTNESS:
1237 case V4L2_CID_CONTRAST:
1238 case V4L2_CID_SATURATION:
1239 case V4L2_CID_HUE:
1240 qctrl->flags |= V4L2_CTRL_FLAG_SLIDER;
1241 break;
1242 }
1243 qctrl->minimum = min;
1244 qctrl->maximum = max;
1245 qctrl->step = step;
1246 qctrl->default_value = def;
1247 qctrl->reserved[0] = qctrl->reserved[1] = 0;
1248 snprintf(qctrl->name, sizeof(qctrl->name), name);
1249 return 0;
1250}
1251
1252/* Fill in a struct v4l2_queryctrl with standard values based on
1253 the control ID. */
1254int v4l2_ctrl_query_fill_std(struct v4l2_queryctrl *qctrl)
1255{
1256 switch (qctrl->id) {
1257 /* USER controls */
1258 case V4L2_CID_USER_CLASS:
1259 case V4L2_CID_MPEG_CLASS:
1260 return v4l2_ctrl_query_fill(qctrl, 0, 0, 0, 0);
1261 case V4L2_CID_AUDIO_VOLUME:
1262 return v4l2_ctrl_query_fill(qctrl, 0, 65535, 65535 / 100, 58880);
1263 case V4L2_CID_AUDIO_MUTE:
1264 case V4L2_CID_AUDIO_LOUDNESS:
1265 return v4l2_ctrl_query_fill(qctrl, 0, 1, 1, 0);
1266 case V4L2_CID_AUDIO_BALANCE:
1267 case V4L2_CID_AUDIO_BASS:
1268 case V4L2_CID_AUDIO_TREBLE:
1269 return v4l2_ctrl_query_fill(qctrl, 0, 65535, 65535 / 100, 32768);
1270 case V4L2_CID_BRIGHTNESS:
1271 return v4l2_ctrl_query_fill(qctrl, 0, 255, 1, 128);
1272 case V4L2_CID_CONTRAST:
1273 case V4L2_CID_SATURATION:
1274 return v4l2_ctrl_query_fill(qctrl, 0, 127, 1, 64);
1275 case V4L2_CID_HUE:
1276 return v4l2_ctrl_query_fill(qctrl, -128, 127, 1, 0);
1277
1278 /* MPEG controls */
1279 case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ:
1280 return v4l2_ctrl_query_fill(qctrl,
1281 V4L2_MPEG_AUDIO_SAMPLING_FREQ_44100,
1282 V4L2_MPEG_AUDIO_SAMPLING_FREQ_32000, 1,
1283 V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000);
1284 case V4L2_CID_MPEG_AUDIO_ENCODING:
1285 return v4l2_ctrl_query_fill(qctrl,
1286 V4L2_MPEG_AUDIO_ENCODING_LAYER_1,
1287 V4L2_MPEG_AUDIO_ENCODING_LAYER_3, 1,
1288 V4L2_MPEG_AUDIO_ENCODING_LAYER_2);
1289 case V4L2_CID_MPEG_AUDIO_L1_BITRATE:
1290 return v4l2_ctrl_query_fill(qctrl,
1291 V4L2_MPEG_AUDIO_L1_BITRATE_32K,
1292 V4L2_MPEG_AUDIO_L1_BITRATE_448K, 1,
1293 V4L2_MPEG_AUDIO_L1_BITRATE_256K);
1294 case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
1295 return v4l2_ctrl_query_fill(qctrl,
1296 V4L2_MPEG_AUDIO_L2_BITRATE_32K,
1297 V4L2_MPEG_AUDIO_L2_BITRATE_384K, 1,
1298 V4L2_MPEG_AUDIO_L2_BITRATE_224K);
1299 case V4L2_CID_MPEG_AUDIO_L3_BITRATE:
1300 return v4l2_ctrl_query_fill(qctrl,
1301 V4L2_MPEG_AUDIO_L3_BITRATE_32K,
1302 V4L2_MPEG_AUDIO_L3_BITRATE_320K, 1,
1303 V4L2_MPEG_AUDIO_L3_BITRATE_192K);
1304 case V4L2_CID_MPEG_AUDIO_MODE:
1305 return v4l2_ctrl_query_fill(qctrl,
1306 V4L2_MPEG_AUDIO_MODE_STEREO,
1307 V4L2_MPEG_AUDIO_MODE_MONO, 1,
1308 V4L2_MPEG_AUDIO_MODE_STEREO);
1309 case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION:
1310 return v4l2_ctrl_query_fill(qctrl,
1311 V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_4,
1312 V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_16, 1,
1313 V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_4);
1314 case V4L2_CID_MPEG_AUDIO_EMPHASIS:
1315 return v4l2_ctrl_query_fill(qctrl,
1316 V4L2_MPEG_AUDIO_EMPHASIS_NONE,
1317 V4L2_MPEG_AUDIO_EMPHASIS_CCITT_J17, 1,
1318 V4L2_MPEG_AUDIO_EMPHASIS_NONE);
1319 case V4L2_CID_MPEG_AUDIO_CRC:
1320 return v4l2_ctrl_query_fill(qctrl,
1321 V4L2_MPEG_AUDIO_CRC_NONE,
1322 V4L2_MPEG_AUDIO_CRC_CRC16, 1,
1323 V4L2_MPEG_AUDIO_CRC_NONE);
1324 case V4L2_CID_MPEG_VIDEO_ENCODING:
1325 return v4l2_ctrl_query_fill(qctrl,
1326 V4L2_MPEG_VIDEO_ENCODING_MPEG_1,
1327 V4L2_MPEG_VIDEO_ENCODING_MPEG_2, 1,
1328 V4L2_MPEG_VIDEO_ENCODING_MPEG_2);
1329 case V4L2_CID_MPEG_VIDEO_ASPECT:
1330 return v4l2_ctrl_query_fill(qctrl,
1331 V4L2_MPEG_VIDEO_ASPECT_1x1,
1332 V4L2_MPEG_VIDEO_ASPECT_221x100, 1,
1333 V4L2_MPEG_VIDEO_ASPECT_4x3);
1334 case V4L2_CID_MPEG_VIDEO_B_FRAMES:
1335 return v4l2_ctrl_query_fill(qctrl, 0, 33, 1, 2);
1336 case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
1337 return v4l2_ctrl_query_fill(qctrl, 1, 34, 1, 12);
1338 case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE:
1339 return v4l2_ctrl_query_fill(qctrl, 0, 1, 1, 1);
1340 case V4L2_CID_MPEG_VIDEO_PULLDOWN:
1341 return v4l2_ctrl_query_fill(qctrl, 0, 1, 1, 0);
1342 case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
1343 return v4l2_ctrl_query_fill(qctrl,
1344 V4L2_MPEG_VIDEO_BITRATE_MODE_VBR,
1345 V4L2_MPEG_VIDEO_BITRATE_MODE_CBR, 1,
1346 V4L2_MPEG_VIDEO_BITRATE_MODE_VBR);
1347 case V4L2_CID_MPEG_VIDEO_BITRATE:
1348 return v4l2_ctrl_query_fill(qctrl, 0, 27000000, 1, 6000000);
1349 case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
1350 return v4l2_ctrl_query_fill(qctrl, 0, 27000000, 1, 8000000);
1351 case V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION:
1352 return v4l2_ctrl_query_fill(qctrl, 0, 255, 1, 0);
1353 case V4L2_CID_MPEG_STREAM_TYPE:
1354 return v4l2_ctrl_query_fill(qctrl,
1355 V4L2_MPEG_STREAM_TYPE_MPEG2_PS,
1356 V4L2_MPEG_STREAM_TYPE_MPEG2_SVCD, 1,
1357 V4L2_MPEG_STREAM_TYPE_MPEG2_PS);
1358 case V4L2_CID_MPEG_STREAM_PID_PMT:
1359 return v4l2_ctrl_query_fill(qctrl, 0, (1 << 14) - 1, 1, 16);
1360 case V4L2_CID_MPEG_STREAM_PID_AUDIO:
1361 return v4l2_ctrl_query_fill(qctrl, 0, (1 << 14) - 1, 1, 260);
1362 case V4L2_CID_MPEG_STREAM_PID_VIDEO:
1363 return v4l2_ctrl_query_fill(qctrl, 0, (1 << 14) - 1, 1, 256);
1364 case V4L2_CID_MPEG_STREAM_PID_PCR:
1365 return v4l2_ctrl_query_fill(qctrl, 0, (1 << 14) - 1, 1, 259);
1366 case V4L2_CID_MPEG_STREAM_PES_ID_AUDIO:
1367 return v4l2_ctrl_query_fill(qctrl, 0, 255, 1, 0);
1368 case V4L2_CID_MPEG_STREAM_PES_ID_VIDEO:
1369 return v4l2_ctrl_query_fill(qctrl, 0, 255, 1, 0);
1370 default:
1371 return -EINVAL;
1372 }
1373}
1374
1375/* Fill in a struct v4l2_querymenu based on the struct v4l2_queryctrl and
1376 the menu. The qctrl pointer may be NULL, in which case it is ignored. */
1377int v4l2_ctrl_query_menu(struct v4l2_querymenu *qmenu, struct v4l2_queryctrl *qctrl,
1378 const char **menu_items)
1379{
1380 int i;
1381
1382 if (menu_items == NULL ||
1383 (qctrl && (qmenu->index < qctrl->minimum || qmenu->index > qctrl->maximum)))
1384 return -EINVAL;
1385 for (i = 0; i < qmenu->index && menu_items[i]; i++) ;
1386 if (menu_items[i] == NULL || menu_items[i][0] == '\0')
1387 return -EINVAL;
1388 snprintf(qmenu->name, sizeof(qmenu->name), menu_items[qmenu->index]);
1389 qmenu->reserved = 0;
1390 return 0;
1391}
1392
1393/* ctrl_classes points to an array of u32 pointers, the last element is
1394 a NULL pointer. Each u32 array is a 0-terminated array of control IDs.
1395 Each array must be sorted low to high and belong to the same control
1396 class. The array of u32 pointer must also be sorted, from low class IDs
1397 to high class IDs.
1398
1399 This function returns the first ID that follows after the given ID.
1400 When no more controls are available 0 is returned. */
1401u32 v4l2_ctrl_next(const u32 * const * ctrl_classes, u32 id)
1402{
1403 u32 ctrl_class;
1404 const u32 *pctrl;
1405
1406 /* if no query is desired, then just return the control ID */
1407 if ((id & V4L2_CTRL_FLAG_NEXT_CTRL) == 0)
1408 return id;
1409 if (ctrl_classes == NULL)
1410 return 0;
1411 id &= V4L2_CTRL_ID_MASK;
1412 ctrl_class = V4L2_CTRL_ID2CLASS(id);
1413 id++; /* select next control */
1414 /* find first class that matches (or is greater than) the class of
1415 the ID */
1416 while (*ctrl_classes && V4L2_CTRL_ID2CLASS(**ctrl_classes) < ctrl_class)
1417 ctrl_classes++;
1418 /* no more classes */
1419 if (*ctrl_classes == NULL)
1420 return 0;
1421 pctrl = *ctrl_classes;
1422 /* find first ctrl within the class that is >= ID */
1423 while (*pctrl && *pctrl < id) pctrl++;
1424 if (*pctrl)
1425 return *pctrl;
1426 /* we are at the end of the controls of the current class. */
1427 /* continue with next class if available */
1428 ctrl_classes++;
1429 if (*ctrl_classes == NULL)
1430 return 0;
1431 return **ctrl_classes;
1432}
1433
1434/* ----------------------------------------------------------------- */
1435
918EXPORT_SYMBOL(v4l2_video_std_construct); 1436EXPORT_SYMBOL(v4l2_video_std_construct);
919 1437
920EXPORT_SYMBOL(v4l2_prio_init); 1438EXPORT_SYMBOL(v4l2_prio_init);
@@ -929,6 +1447,13 @@ EXPORT_SYMBOL(v4l2_type_names);
929EXPORT_SYMBOL(v4l_printk_ioctl); 1447EXPORT_SYMBOL(v4l_printk_ioctl);
930EXPORT_SYMBOL(v4l_printk_ioctl_arg); 1448EXPORT_SYMBOL(v4l_printk_ioctl_arg);
931 1449
1450EXPORT_SYMBOL(v4l2_ctrl_next);
1451EXPORT_SYMBOL(v4l2_ctrl_check);
1452EXPORT_SYMBOL(v4l2_ctrl_get_menu);
1453EXPORT_SYMBOL(v4l2_ctrl_query_menu);
1454EXPORT_SYMBOL(v4l2_ctrl_query_fill);
1455EXPORT_SYMBOL(v4l2_ctrl_query_fill_std);
1456
932/* 1457/*
933 * Local variables: 1458 * Local variables:
934 * c-basic-offset: 8 1459 * c-basic-offset: 8
diff --git a/drivers/media/video/video-buf-dvb.c b/drivers/media/video/video-buf-dvb.c
index caf3e7e2f21..7ee8a53cd33 100644
--- a/drivers/media/video/video-buf-dvb.c
+++ b/drivers/media/video/video-buf-dvb.c
@@ -135,14 +135,15 @@ static int videobuf_dvb_stop_feed(struct dvb_demux_feed *feed)
135 135
136int videobuf_dvb_register(struct videobuf_dvb *dvb, 136int videobuf_dvb_register(struct videobuf_dvb *dvb,
137 struct module *module, 137 struct module *module,
138 void *adapter_priv) 138 void *adapter_priv,
139 struct device *device)
139{ 140{
140 int result; 141 int result;
141 142
142 mutex_init(&dvb->lock); 143 mutex_init(&dvb->lock);
143 144
144 /* register adapter */ 145 /* register adapter */
145 result = dvb_register_adapter(&dvb->adapter, dvb->name, module); 146 result = dvb_register_adapter(&dvb->adapter, dvb->name, module, device);
146 if (result < 0) { 147 if (result < 0) {
147 printk(KERN_WARNING "%s: dvb_register_adapter failed (errno = %d)\n", 148 printk(KERN_WARNING "%s: dvb_register_adapter failed (errno = %d)\n",
148 dvb->name, result); 149 dvb->name, result);
diff --git a/drivers/media/video/videodev.c b/drivers/media/video/videodev.c
index 5f87dd5f1d0..2dfa7f23d0c 100644
--- a/drivers/media/video/videodev.c
+++ b/drivers/media/video/videodev.c
@@ -1,20 +1,31 @@
1/* 1/*
2 * Video capture interface for Linux 2 * Video capture interface for Linux version 2
3 * 3 *
4 * A generic video device interface for the LINUX operating system 4 * A generic video device interface for the LINUX operating system
5 * using a set of device structures/vectors for low level operations. 5 * using a set of device structures/vectors for low level operations.
6 * 6 *
7 * This program is free software; you can redistribute it and/or 7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License 8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 9 * as published by the Free Software Foundation; either version
10 * 2 of the License, or (at your option) any later version. 10 * 2 of the License, or (at your option) any later version.
11 * 11 *
12 * Author: Alan Cox, <alan@redhat.com> 12 * Authors: Alan Cox, <alan@redhat.com> (version 1)
13 * Mauro Carvalho Chehab <mchehab@infradead.org> (version 2)
13 * 14 *
14 * Fixes: 20000516 Claudio Matsuoka <claudio@conectiva.com> 15 * Fixes: 20000516 Claudio Matsuoka <claudio@conectiva.com>
15 * - Added procfs support 16 * - Added procfs support
16 */ 17 */
17 18
19#define dbgarg(cmd, fmt, arg...) \
20 if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) \
21 printk (KERN_DEBUG "%s: ", vfd->name); \
22 v4l_printk_ioctl(cmd); \
23 printk (KERN_DEBUG "%s: " fmt, vfd->name, ## arg);
24
25#define dbgarg2(fmt, arg...) \
26 if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) \
27 printk (KERN_DEBUG "%s: " fmt, vfd->name, ## arg);
28
18#include <linux/module.h> 29#include <linux/module.h>
19#include <linux/types.h> 30#include <linux/types.h>
20#include <linux/kernel.h> 31#include <linux/kernel.h>
@@ -30,7 +41,13 @@
30#include <asm/uaccess.h> 41#include <asm/uaccess.h>
31#include <asm/system.h> 42#include <asm/system.h>
32 43
44#define __OLD_VIDIOC_ /* To allow fixing old calls*/
45#include <linux/videodev2.h>
46
47#ifdef CONFIG_VIDEO_V4L1
33#include <linux/videodev.h> 48#include <linux/videodev.h>
49#endif
50#include <media/v4l2-common.h>
34 51
35#define VIDEO_NUM_DEVICES 256 52#define VIDEO_NUM_DEVICES 256
36#define VIDEO_NAME "video4linux" 53#define VIDEO_NAME "video4linux"
@@ -41,7 +58,8 @@
41 58
42static ssize_t show_name(struct class_device *cd, char *buf) 59static ssize_t show_name(struct class_device *cd, char *buf)
43{ 60{
44 struct video_device *vfd = container_of(cd, struct video_device, class_dev); 61 struct video_device *vfd = container_of(cd, struct video_device,
62 class_dev);
45 return sprintf(buf,"%.*s\n",(int)sizeof(vfd->name),vfd->name); 63 return sprintf(buf,"%.*s\n",(int)sizeof(vfd->name),vfd->name);
46} 64}
47 65
@@ -62,7 +80,8 @@ void video_device_release(struct video_device *vfd)
62 80
63static void video_release(struct class_device *cd) 81static void video_release(struct class_device *cd)
64{ 82{
65 struct video_device *vfd = container_of(cd, struct video_device, class_dev); 83 struct video_device *vfd = container_of(cd, struct video_device,
84 class_dev);
66 85
67#if 1 86#if 1
68 /* needed until all drivers are fixed */ 87 /* needed until all drivers are fixed */
@@ -90,7 +109,7 @@ struct video_device* video_devdata(struct file *file)
90} 109}
91 110
92/* 111/*
93 * Open a video device. 112 * Open a video device - FIXME: Obsoleted
94 */ 113 */
95static int video_open(struct inode *inode, struct file *file) 114static int video_open(struct inode *inode, struct file *file)
96{ 115{
@@ -130,6 +149,7 @@ static int video_open(struct inode *inode, struct file *file)
130 * helper function -- handles userspace copying for ioctl arguments 149 * helper function -- handles userspace copying for ioctl arguments
131 */ 150 */
132 151
152#ifdef __OLD_VIDIOC_
133static unsigned int 153static unsigned int
134video_fix_command(unsigned int cmd) 154video_fix_command(unsigned int cmd)
135{ 155{
@@ -155,7 +175,11 @@ video_fix_command(unsigned int cmd)
155 } 175 }
156 return cmd; 176 return cmd;
157} 177}
178#endif
158 179
180/*
181 * Obsolete usercopy function - Should be removed soon
182 */
159int 183int
160video_usercopy(struct inode *inode, struct file *file, 184video_usercopy(struct inode *inode, struct file *file,
161 unsigned int cmd, unsigned long arg, 185 unsigned int cmd, unsigned long arg,
@@ -166,8 +190,15 @@ video_usercopy(struct inode *inode, struct file *file,
166 void *mbuf = NULL; 190 void *mbuf = NULL;
167 void *parg = NULL; 191 void *parg = NULL;
168 int err = -EINVAL; 192 int err = -EINVAL;
193 int is_ext_ctrl;
194 size_t ctrls_size = 0;
195 void __user *user_ptr = NULL;
169 196
197#ifdef __OLD_VIDIOC_
170 cmd = video_fix_command(cmd); 198 cmd = video_fix_command(cmd);
199#endif
200 is_ext_ctrl = (cmd == VIDIOC_S_EXT_CTRLS || cmd == VIDIOC_G_EXT_CTRLS ||
201 cmd == VIDIOC_TRY_EXT_CTRLS);
171 202
172 /* Copy arguments into temp kernel buffer */ 203 /* Copy arguments into temp kernel buffer */
173 switch (_IOC_DIR(cmd)) { 204 switch (_IOC_DIR(cmd)) {
@@ -193,14 +224,43 @@ video_usercopy(struct inode *inode, struct file *file,
193 goto out; 224 goto out;
194 break; 225 break;
195 } 226 }
227 if (is_ext_ctrl) {
228 struct v4l2_ext_controls *p = parg;
229
230 /* In case of an error, tell the caller that it wasn't
231 a specific control that caused it. */
232 p->error_idx = p->count;
233 user_ptr = (void __user *)p->controls;
234 if (p->count) {
235 ctrls_size = sizeof(struct v4l2_ext_control) * p->count;
236 /* Note: v4l2_ext_controls fits in sbuf[] so mbuf is still NULL. */
237 mbuf = kmalloc(ctrls_size, GFP_KERNEL);
238 err = -ENOMEM;
239 if (NULL == mbuf)
240 goto out_ext_ctrl;
241 err = -EFAULT;
242 if (copy_from_user(mbuf, user_ptr, ctrls_size))
243 goto out_ext_ctrl;
244 p->controls = mbuf;
245 }
246 }
196 247
197 /* call driver */ 248 /* call driver */
198 err = func(inode, file, cmd, parg); 249 err = func(inode, file, cmd, parg);
199 if (err == -ENOIOCTLCMD) 250 if (err == -ENOIOCTLCMD)
200 err = -EINVAL; 251 err = -EINVAL;
252 if (is_ext_ctrl) {
253 struct v4l2_ext_controls *p = parg;
254
255 p->controls = (void *)user_ptr;
256 if (p->count && err == 0 && copy_to_user(user_ptr, mbuf, ctrls_size))
257 err = -EFAULT;
258 goto out_ext_ctrl;
259 }
201 if (err < 0) 260 if (err < 0)
202 goto out; 261 goto out;
203 262
263out_ext_ctrl:
204 /* Copy results into user buffer */ 264 /* Copy results into user buffer */
205 switch (_IOC_DIR(cmd)) 265 switch (_IOC_DIR(cmd))
206 { 266 {
@@ -218,6 +278,7 @@ out:
218 278
219/* 279/*
220 * open/release helper functions -- handle exclusive opens 280 * open/release helper functions -- handle exclusive opens
281 * Should be removed soon
221 */ 282 */
222int video_exclusive_open(struct inode *inode, struct file *file) 283int video_exclusive_open(struct inode *inode, struct file *file)
223{ 284{
@@ -242,6 +303,1184 @@ int video_exclusive_release(struct inode *inode, struct file *file)
242 return 0; 303 return 0;
243} 304}
244 305
306static char *v4l2_memory_names[] = {
307 [V4L2_MEMORY_MMAP] = "mmap",
308 [V4L2_MEMORY_USERPTR] = "userptr",
309 [V4L2_MEMORY_OVERLAY] = "overlay",
310};
311
312
313/* FIXME: Those stuff are replicated also on v4l2-common.c */
314static char *v4l2_type_names_FIXME[] = {
315 [V4L2_BUF_TYPE_VIDEO_CAPTURE] = "video-cap",
316 [V4L2_BUF_TYPE_VIDEO_OVERLAY] = "video-over",
317 [V4L2_BUF_TYPE_VIDEO_OUTPUT] = "video-out",
318 [V4L2_BUF_TYPE_VBI_CAPTURE] = "vbi-cap",
319 [V4L2_BUF_TYPE_VBI_OUTPUT] = "vbi-out",
320 [V4L2_BUF_TYPE_SLICED_VBI_OUTPUT] = "sliced-vbi-out",
321 [V4L2_BUF_TYPE_SLICED_VBI_CAPTURE] = "sliced-vbi-capture",
322 [V4L2_BUF_TYPE_PRIVATE] = "private",
323};
324
325static char *v4l2_field_names_FIXME[] = {
326 [V4L2_FIELD_ANY] = "any",
327 [V4L2_FIELD_NONE] = "none",
328 [V4L2_FIELD_TOP] = "top",
329 [V4L2_FIELD_BOTTOM] = "bottom",
330 [V4L2_FIELD_INTERLACED] = "interlaced",
331 [V4L2_FIELD_SEQ_TB] = "seq-tb",
332 [V4L2_FIELD_SEQ_BT] = "seq-bt",
333 [V4L2_FIELD_ALTERNATE] = "alternate",
334};
335
336#define prt_names(a,arr) (((a)>=0)&&((a)<ARRAY_SIZE(arr)))?arr[a]:"unknown"
337
338static void dbgbuf(unsigned int cmd, struct video_device *vfd,
339 struct v4l2_buffer *p)
340{
341 struct v4l2_timecode *tc=&p->timecode;
342
343 dbgarg (cmd, "%02ld:%02d:%02d.%08ld index=%d, type=%s, "
344 "bytesused=%d, flags=0x%08d, "
345 "field=%0d, sequence=%d, memory=%s, offset/userptr=0x%08lx\n",
346 (p->timestamp.tv_sec/3600),
347 (int)(p->timestamp.tv_sec/60)%60,
348 (int)(p->timestamp.tv_sec%60),
349 p->timestamp.tv_usec,
350 p->index,
351 prt_names(p->type,v4l2_type_names_FIXME),
352 p->bytesused,p->flags,
353 p->field,p->sequence,
354 prt_names(p->memory,v4l2_memory_names),
355 p->m.userptr);
356 dbgarg2 ("timecode= %02d:%02d:%02d type=%d, "
357 "flags=0x%08d, frames=%d, userbits=0x%08x\n",
358 tc->hours,tc->minutes,tc->seconds,
359 tc->type, tc->flags, tc->frames, *(__u32 *) tc->userbits);
360}
361
362static inline void dbgrect(struct video_device *vfd, char *s,
363 struct v4l2_rect *r)
364{
365 dbgarg2 ("%sRect start at %dx%d, size= %dx%d\n", s, r->left, r->top,
366 r->width, r->height);
367};
368
369static inline void v4l_print_pix_fmt (struct video_device *vfd,
370 struct v4l2_pix_format *fmt)
371{
372 dbgarg2 ("width=%d, height=%d, format=0x%08x, field=%s, "
373 "bytesperline=%d sizeimage=%d, colorspace=%d\n",
374 fmt->width,fmt->height,fmt->pixelformat,
375 prt_names(fmt->field,v4l2_field_names_FIXME),
376 fmt->bytesperline,fmt->sizeimage,fmt->colorspace);
377};
378
379
380static int check_fmt (struct video_device *vfd, enum v4l2_buf_type type)
381{
382 switch (type) {
383 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
384 if (vfd->vidioc_try_fmt_cap)
385 return (0);
386 break;
387 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
388 if (vfd->vidioc_try_fmt_overlay)
389 return (0);
390 break;
391 case V4L2_BUF_TYPE_VBI_CAPTURE:
392 if (vfd->vidioc_try_fmt_vbi)
393 return (0);
394 break;
395 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
396 if (vfd->vidioc_try_fmt_vbi_output)
397 return (0);
398 break;
399 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
400 if (vfd->vidioc_try_fmt_vbi_capture)
401 return (0);
402 break;
403 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
404 if (vfd->vidioc_try_fmt_video_output)
405 return (0);
406 break;
407 case V4L2_BUF_TYPE_VBI_OUTPUT:
408 if (vfd->vidioc_try_fmt_vbi_output)
409 return (0);
410 break;
411 case V4L2_BUF_TYPE_PRIVATE:
412 if (vfd->vidioc_try_fmt_type_private)
413 return (0);
414 break;
415 }
416 return (-EINVAL);
417}
418
419static int __video_do_ioctl(struct inode *inode, struct file *file,
420 unsigned int cmd, void *arg)
421{
422 struct video_device *vfd = video_devdata(file);
423 void *fh = file->private_data;
424 int ret = -EINVAL;
425
426 if ( (vfd->debug & V4L2_DEBUG_IOCTL) &&
427 !(vfd->debug | V4L2_DEBUG_IOCTL_ARG)) {
428 v4l_print_ioctl(vfd->name, cmd);
429 }
430
431 switch(cmd) {
432 /* --- capabilities ------------------------------------------ */
433 case VIDIOC_QUERYCAP:
434 {
435 struct v4l2_capability *cap = (struct v4l2_capability*)arg;
436 memset(cap, 0, sizeof(*cap));
437
438 if (!vfd->vidioc_querycap)
439 break;
440
441 ret=vfd->vidioc_querycap(file, fh, cap);
442 if (!ret)
443 dbgarg (cmd, "driver=%s, card=%s, bus=%s, "
444 "version=0x%08x, "
445 "capabilities=0x%08x\n",
446 cap->driver,cap->card,cap->bus_info,
447 cap->version,
448 cap->capabilities);
449 break;
450 }
451
452 /* --- priority ------------------------------------------ */
453 case VIDIOC_G_PRIORITY:
454 {
455 enum v4l2_priority *p=arg;
456
457 if (!vfd->vidioc_g_priority)
458 break;
459 ret=vfd->vidioc_g_priority(file, fh, p);
460 if (!ret)
461 dbgarg(cmd, "priority is %d\n", *p);
462 break;
463 }
464 case VIDIOC_S_PRIORITY:
465 {
466 enum v4l2_priority *p=arg;
467
468 if (!vfd->vidioc_s_priority)
469 break;
470 dbgarg(cmd, "setting priority to %d\n", *p);
471 ret=vfd->vidioc_s_priority(file, fh, *p);
472 break;
473 }
474
475 /* --- capture ioctls ---------------------------------------- */
476 case VIDIOC_ENUM_FMT:
477 {
478 struct v4l2_fmtdesc *f = arg;
479 enum v4l2_buf_type type;
480 unsigned int index;
481
482 index = f->index;
483 type = f->type;
484 memset(f,0,sizeof(*f));
485 f->index = index;
486 f->type = type;
487
488 switch (type) {
489 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
490 if (vfd->vidioc_enum_fmt_cap)
491 ret=vfd->vidioc_enum_fmt_cap(file, fh, f);
492 break;
493 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
494 if (vfd->vidioc_enum_fmt_overlay)
495 ret=vfd->vidioc_enum_fmt_overlay(file, fh, f);
496 break;
497 case V4L2_BUF_TYPE_VBI_CAPTURE:
498 if (vfd->vidioc_enum_fmt_vbi)
499 ret=vfd->vidioc_enum_fmt_vbi(file, fh, f);
500 break;
501 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
502 if (vfd->vidioc_enum_fmt_vbi_output)
503 ret=vfd->vidioc_enum_fmt_vbi_output(file,
504 fh, f);
505 break;
506 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
507 if (vfd->vidioc_enum_fmt_vbi_capture)
508 ret=vfd->vidioc_enum_fmt_vbi_capture(file,
509 fh, f);
510 break;
511 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
512 if (vfd->vidioc_enum_fmt_video_output)
513 ret=vfd->vidioc_enum_fmt_video_output(file,
514 fh, f);
515 break;
516 case V4L2_BUF_TYPE_VBI_OUTPUT:
517 if (vfd->vidioc_enum_fmt_vbi_output)
518 ret=vfd->vidioc_enum_fmt_vbi_output(file,
519 fh, f);
520 break;
521 case V4L2_BUF_TYPE_PRIVATE:
522 if (vfd->vidioc_enum_fmt_type_private)
523 ret=vfd->vidioc_enum_fmt_type_private(file,
524 fh, f);
525 break;
526 }
527 if (!ret)
528 dbgarg (cmd, "index=%d, type=%d, flags=%d, "
529 "description=%s,"
530 " pixelformat=0x%8x\n",
531 f->index, f->type, f->flags,
532 f->description,
533 f->pixelformat);
534
535 break;
536 }
537 case VIDIOC_G_FMT:
538 {
539 struct v4l2_format *f = (struct v4l2_format *)arg;
540 enum v4l2_buf_type type=f->type;
541
542 memset(&f->fmt.pix,0,sizeof(f->fmt.pix));
543 f->type=type;
544
545 /* FIXME: Should be one dump per type */
546 dbgarg (cmd, "type=%s\n", prt_names(type,
547 v4l2_type_names_FIXME));
548
549 switch (type) {
550 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
551 if (vfd->vidioc_g_fmt_cap)
552 ret=vfd->vidioc_g_fmt_cap(file, fh, f);
553 if (!ret)
554 v4l_print_pix_fmt(vfd,&f->fmt.pix);
555 break;
556 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
557 if (vfd->vidioc_g_fmt_overlay)
558 ret=vfd->vidioc_g_fmt_overlay(file, fh, f);
559 break;
560 case V4L2_BUF_TYPE_VBI_CAPTURE:
561 if (vfd->vidioc_g_fmt_vbi)
562 ret=vfd->vidioc_g_fmt_vbi(file, fh, f);
563 break;
564 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
565 if (vfd->vidioc_g_fmt_vbi_output)
566 ret=vfd->vidioc_g_fmt_vbi_output(file, fh, f);
567 break;
568 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
569 if (vfd->vidioc_g_fmt_vbi_capture)
570 ret=vfd->vidioc_g_fmt_vbi_capture(file, fh, f);
571 break;
572 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
573 if (vfd->vidioc_g_fmt_video_output)
574 ret=vfd->vidioc_g_fmt_video_output(file,
575 fh, f);
576 break;
577 case V4L2_BUF_TYPE_VBI_OUTPUT:
578 if (vfd->vidioc_g_fmt_vbi_output)
579 ret=vfd->vidioc_g_fmt_vbi_output(file, fh, f);
580 break;
581 case V4L2_BUF_TYPE_PRIVATE:
582 if (vfd->vidioc_g_fmt_type_private)
583 ret=vfd->vidioc_g_fmt_type_private(file,
584 fh, f);
585 break;
586 }
587
588 break;
589 }
590 case VIDIOC_S_FMT:
591 {
592 struct v4l2_format *f = (struct v4l2_format *)arg;
593
594 /* FIXME: Should be one dump per type */
595 dbgarg (cmd, "type=%s\n", prt_names(f->type,
596 v4l2_type_names_FIXME));
597
598 switch (f->type) {
599 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
600 v4l_print_pix_fmt(vfd,&f->fmt.pix);
601 if (vfd->vidioc_s_fmt_cap)
602 ret=vfd->vidioc_s_fmt_cap(file, fh, f);
603 break;
604 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
605 if (vfd->vidioc_s_fmt_overlay)
606 ret=vfd->vidioc_s_fmt_overlay(file, fh, f);
607 break;
608 case V4L2_BUF_TYPE_VBI_CAPTURE:
609 if (vfd->vidioc_s_fmt_vbi)
610 ret=vfd->vidioc_s_fmt_vbi(file, fh, f);
611 break;
612 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
613 if (vfd->vidioc_s_fmt_vbi_output)
614 ret=vfd->vidioc_s_fmt_vbi_output(file, fh, f);
615 break;
616 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
617 if (vfd->vidioc_s_fmt_vbi_capture)
618 ret=vfd->vidioc_s_fmt_vbi_capture(file, fh, f);
619 break;
620 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
621 if (vfd->vidioc_s_fmt_video_output)
622 ret=vfd->vidioc_s_fmt_video_output(file,
623 fh, f);
624 break;
625 case V4L2_BUF_TYPE_VBI_OUTPUT:
626 if (vfd->vidioc_s_fmt_vbi_output)
627 ret=vfd->vidioc_s_fmt_vbi_output(file,
628 fh, f);
629 break;
630 case V4L2_BUF_TYPE_PRIVATE:
631 if (vfd->vidioc_s_fmt_type_private)
632 ret=vfd->vidioc_s_fmt_type_private(file,
633 fh, f);
634 break;
635 }
636 break;
637 }
638 case VIDIOC_TRY_FMT:
639 {
640 struct v4l2_format *f = (struct v4l2_format *)arg;
641
642 /* FIXME: Should be one dump per type */
643 dbgarg (cmd, "type=%s\n", prt_names(f->type,
644 v4l2_type_names_FIXME));
645 switch (f->type) {
646 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
647 if (vfd->vidioc_try_fmt_cap)
648 ret=vfd->vidioc_try_fmt_cap(file, fh, f);
649 if (!ret)
650 v4l_print_pix_fmt(vfd,&f->fmt.pix);
651 break;
652 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
653 if (vfd->vidioc_try_fmt_overlay)
654 ret=vfd->vidioc_try_fmt_overlay(file, fh, f);
655 break;
656 case V4L2_BUF_TYPE_VBI_CAPTURE:
657 if (vfd->vidioc_try_fmt_vbi)
658 ret=vfd->vidioc_try_fmt_vbi(file, fh, f);
659 break;
660 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
661 if (vfd->vidioc_try_fmt_vbi_output)
662 ret=vfd->vidioc_try_fmt_vbi_output(file,
663 fh, f);
664 break;
665 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
666 if (vfd->vidioc_try_fmt_vbi_capture)
667 ret=vfd->vidioc_try_fmt_vbi_capture(file,
668 fh, f);
669 break;
670 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
671 if (vfd->vidioc_try_fmt_video_output)
672 ret=vfd->vidioc_try_fmt_video_output(file,
673 fh, f);
674 break;
675 case V4L2_BUF_TYPE_VBI_OUTPUT:
676 if (vfd->vidioc_try_fmt_vbi_output)
677 ret=vfd->vidioc_try_fmt_vbi_output(file,
678 fh, f);
679 break;
680 case V4L2_BUF_TYPE_PRIVATE:
681 if (vfd->vidioc_try_fmt_type_private)
682 ret=vfd->vidioc_try_fmt_type_private(file,
683 fh, f);
684 break;
685 }
686
687 break;
688 }
689 /* FIXME: Those buf reqs could be handled here,
690 with some changes on videobuf to allow its header to be included at
691 videodev2.h or being merged at videodev2.
692 */
693 case VIDIOC_REQBUFS:
694 {
695 struct v4l2_requestbuffers *p=arg;
696
697 if (!vfd->vidioc_reqbufs)
698 break;
699 ret = check_fmt (vfd, p->type);
700 if (ret)
701 break;
702
703 ret=vfd->vidioc_reqbufs(file, fh, p);
704 dbgarg (cmd, "count=%d, type=%s, memory=%s\n",
705 p->count,
706 prt_names(p->type,v4l2_type_names_FIXME),
707 prt_names(p->memory,v4l2_memory_names));
708 break;
709 }
710 case VIDIOC_QUERYBUF:
711 {
712 struct v4l2_buffer *p=arg;
713
714 if (!vfd->vidioc_querybuf)
715 break;
716 ret = check_fmt (vfd, p->type);
717 if (ret)
718 break;
719
720 ret=vfd->vidioc_querybuf(file, fh, p);
721 if (!ret)
722 dbgbuf(cmd,vfd,p);
723 break;
724 }
725 case VIDIOC_QBUF:
726 {
727 struct v4l2_buffer *p=arg;
728
729 if (!vfd->vidioc_qbuf)
730 break;
731 ret = check_fmt (vfd, p->type);
732 if (ret)
733 break;
734
735 ret=vfd->vidioc_qbuf(file, fh, p);
736 if (!ret)
737 dbgbuf(cmd,vfd,p);
738 break;
739 }
740 case VIDIOC_DQBUF:
741 {
742 struct v4l2_buffer *p=arg;
743 if (!vfd->vidioc_qbuf)
744 break;
745 ret = check_fmt (vfd, p->type);
746 if (ret)
747 break;
748
749 ret=vfd->vidioc_qbuf(file, fh, p);
750 if (!ret)
751 dbgbuf(cmd,vfd,p);
752 break;
753 }
754 case VIDIOC_OVERLAY:
755 {
756 int *i = arg;
757
758 if (!vfd->vidioc_overlay)
759 break;
760 dbgarg (cmd, "value=%d\n",*i);
761 ret=vfd->vidioc_overlay(file, fh, *i);
762 break;
763 }
764#ifdef HAVE_V4L1
765 /* --- streaming capture ------------------------------------- */
766 case VIDIOCGMBUF:
767 {
768 struct video_mbuf *p=arg;
769
770 memset(p,0,sizeof(p));
771
772 if (!vfd->vidiocgmbuf)
773 break;
774 ret=vfd->vidiocgmbuf(file, fh, p);
775 if (!ret)
776 dbgarg (cmd, "size=%d, frames=%d, offsets=0x%08lx\n",
777 p->size, p->frames,
778 (unsigned long)p->offsets);
779 break;
780 }
781#endif
782 case VIDIOC_G_FBUF:
783 {
784 struct v4l2_framebuffer *p=arg;
785 if (!vfd->vidioc_g_fbuf)
786 break;
787 ret=vfd->vidioc_g_fbuf(file, fh, arg);
788 if (!ret) {
789 dbgarg (cmd, "capability=%d, flags=%d, base=0x%08lx\n",
790 p->capability,p->flags,
791 (unsigned long)p->base);
792 v4l_print_pix_fmt (vfd, &p->fmt);
793 }
794 break;
795 }
796 case VIDIOC_S_FBUF:
797 {
798 struct v4l2_framebuffer *p=arg;
799 if (!vfd->vidioc_s_fbuf)
800 break;
801
802 dbgarg (cmd, "capability=%d, flags=%d, base=0x%08lx\n",
803 p->capability,p->flags,(unsigned long)p->base);
804 v4l_print_pix_fmt (vfd, &p->fmt);
805 ret=vfd->vidioc_s_fbuf(file, fh, arg);
806
807 break;
808 }
809 case VIDIOC_STREAMON:
810 {
811 enum v4l2_buf_type i = *(int *)arg;
812 if (!vfd->vidioc_streamon)
813 break;
814 dbgarg (cmd, "type=%s\n", prt_names(i,v4l2_type_names_FIXME));
815 ret=vfd->vidioc_streamon(file, fh,i);
816 break;
817 }
818 case VIDIOC_STREAMOFF:
819 {
820 enum v4l2_buf_type i = *(int *)arg;
821
822 if (!vfd->vidioc_streamoff)
823 break;
824 dbgarg (cmd, "type=%s\n", prt_names(i,v4l2_type_names_FIXME));
825 ret=vfd->vidioc_streamoff(file, fh, i);
826 break;
827 }
828 /* ---------- tv norms ---------- */
829 case VIDIOC_ENUMSTD:
830 {
831 struct v4l2_standard *p = arg;
832 unsigned int index = p->index;
833
834 if (!vfd->tvnormsize) {
835 printk (KERN_WARNING "%s: no TV norms defined!\n",
836 vfd->name);
837 break;
838 }
839
840 if (index<=0 || index >= vfd->tvnormsize) {
841 ret=-EINVAL;
842 break;
843 }
844 v4l2_video_std_construct(p, vfd->tvnorms[p->index].id,
845 vfd->tvnorms[p->index].name);
846 p->index = index;
847
848 dbgarg (cmd, "index=%d, id=%Ld, name=%s, fps=%d/%d, "
849 "framelines=%d\n", p->index,
850 (unsigned long long)p->id, p->name,
851 p->frameperiod.numerator,
852 p->frameperiod.denominator,
853 p->framelines);
854
855 ret=0;
856 break;
857 }
858 case VIDIOC_G_STD:
859 {
860 v4l2_std_id *id = arg;
861
862 *id = vfd->current_norm;
863
864 dbgarg (cmd, "value=%Lu\n", (long long unsigned) *id);
865
866 ret=0;
867 break;
868 }
869 case VIDIOC_S_STD:
870 {
871 v4l2_std_id *id = arg;
872 unsigned int i;
873
874 if (!vfd->tvnormsize) {
875 printk (KERN_WARNING "%s: no TV norms defined!\n",
876 vfd->name);
877 break;
878 }
879
880 dbgarg (cmd, "value=%Lu\n", (long long unsigned) *id);
881
882 /* First search for exact match */
883 for (i = 0; i < vfd->tvnormsize; i++)
884 if (*id == vfd->tvnorms[i].id)
885 break;
886 /* Then for a generic video std that contains desired std */
887 if (i == vfd->tvnormsize)
888 for (i = 0; i < vfd->tvnormsize; i++)
889 if (*id & vfd->tvnorms[i].id)
890 break;
891 if (i == vfd->tvnormsize) {
892 break;
893 }
894
895 /* Calls the specific handler */
896 if (vfd->vidioc_s_std)
897 ret=vfd->vidioc_s_std(file, fh, i);
898 else
899 ret=-EINVAL;
900
901 /* Updates standard information */
902 if (!ret)
903 vfd->current_norm=*id;
904
905 break;
906 }
907 case VIDIOC_QUERYSTD:
908 {
909 v4l2_std_id *p=arg;
910
911 if (!vfd->vidioc_querystd)
912 break;
913 ret=vfd->vidioc_querystd(file, fh, arg);
914 if (!ret)
915 dbgarg (cmd, "detected std=%Lu\n",
916 (unsigned long long)*p);
917 break;
918 }
919 /* ------ input switching ---------- */
920 /* FIXME: Inputs can be handled inside videodev2 */
921 case VIDIOC_ENUMINPUT:
922 {
923 struct v4l2_input *p=arg;
924 int i=p->index;
925
926 if (!vfd->vidioc_enum_input)
927 break;
928 memset(p, 0, sizeof(*p));
929 p->index=i;
930
931 ret=vfd->vidioc_enum_input(file, fh, p);
932 if (!ret)
933 dbgarg (cmd, "index=%d, name=%s, type=%d, "
934 "audioset=%d, "
935 "tuner=%d, std=%Ld, status=%d\n",
936 p->index,p->name,p->type,p->audioset,
937 p->tuner,
938 (unsigned long long)p->std,
939 p->status);
940 break;
941 }
942 case VIDIOC_G_INPUT:
943 {
944 unsigned int *i = arg;
945
946 if (!vfd->vidioc_g_input)
947 break;
948 ret=vfd->vidioc_g_input(file, fh, i);
949 if (!ret)
950 dbgarg (cmd, "value=%d\n",*i);
951 break;
952 }
953 case VIDIOC_S_INPUT:
954 {
955 unsigned int *i = arg;
956
957 if (!vfd->vidioc_s_input)
958 break;
959 dbgarg (cmd, "value=%d\n",*i);
960 ret=vfd->vidioc_s_input(file, fh, *i);
961 break;
962 }
963
964 /* ------ output switching ---------- */
965 case VIDIOC_G_OUTPUT:
966 {
967 unsigned int *i = arg;
968
969 if (!vfd->vidioc_g_output)
970 break;
971 ret=vfd->vidioc_g_output(file, fh, i);
972 if (!ret)
973 dbgarg (cmd, "value=%d\n",*i);
974 break;
975 }
976 case VIDIOC_S_OUTPUT:
977 {
978 unsigned int *i = arg;
979
980 if (!vfd->vidioc_s_output)
981 break;
982 dbgarg (cmd, "value=%d\n",*i);
983 ret=vfd->vidioc_s_output(file, fh, *i);
984 break;
985 }
986
987 /* --- controls ---------------------------------------------- */
988 case VIDIOC_QUERYCTRL:
989 {
990 struct v4l2_queryctrl *p=arg;
991
992 if (!vfd->vidioc_queryctrl)
993 break;
994 ret=vfd->vidioc_queryctrl(file, fh, p);
995
996 if (!ret)
997 dbgarg (cmd, "id=%d, type=%d, name=%s, "
998 "min/max=%d/%d,"
999 " step=%d, default=%d, flags=0x%08x\n",
1000 p->id,p->type,p->name,p->minimum,
1001 p->maximum,p->step,p->default_value,
1002 p->flags);
1003 break;
1004 }
1005 case VIDIOC_G_CTRL:
1006 {
1007 struct v4l2_control *p = arg;
1008
1009 if (!vfd->vidioc_g_ctrl)
1010 break;
1011 dbgarg(cmd, "Enum for index=%d\n", p->id);
1012
1013 ret=vfd->vidioc_g_ctrl(file, fh, p);
1014 if (!ret)
1015 dbgarg2 ( "id=%d, value=%d\n", p->id, p->value);
1016 break;
1017 }
1018 case VIDIOC_S_CTRL:
1019 {
1020 struct v4l2_control *p = arg;
1021
1022 if (!vfd->vidioc_s_ctrl)
1023 break;
1024 dbgarg (cmd, "id=%d, value=%d\n", p->id, p->value);
1025
1026 ret=vfd->vidioc_s_ctrl(file, fh, p);
1027 break;
1028 }
1029 case VIDIOC_G_EXT_CTRLS:
1030 {
1031 struct v4l2_ext_controls *p = arg;
1032
1033 if (vfd->vidioc_g_ext_ctrls) {
1034 dbgarg(cmd, "count=%d\n", p->count);
1035
1036 ret=vfd->vidioc_g_ext_ctrls(file, fh, p);
1037 }
1038 break;
1039 }
1040 case VIDIOC_S_EXT_CTRLS:
1041 {
1042 struct v4l2_ext_controls *p = arg;
1043
1044 if (vfd->vidioc_s_ext_ctrls) {
1045 dbgarg(cmd, "count=%d\n", p->count);
1046
1047 ret=vfd->vidioc_s_ext_ctrls(file, fh, p);
1048 }
1049 break;
1050 }
1051 case VIDIOC_TRY_EXT_CTRLS:
1052 {
1053 struct v4l2_ext_controls *p = arg;
1054
1055 if (vfd->vidioc_try_ext_ctrls) {
1056 dbgarg(cmd, "count=%d\n", p->count);
1057
1058 ret=vfd->vidioc_try_ext_ctrls(file, fh, p);
1059 }
1060 break;
1061 }
1062 case VIDIOC_QUERYMENU:
1063 {
1064 struct v4l2_querymenu *p=arg;
1065 if (!vfd->vidioc_querymenu)
1066 break;
1067 ret=vfd->vidioc_querymenu(file, fh, p);
1068 if (!ret)
1069 dbgarg (cmd, "id=%d, index=%d, name=%s\n",
1070 p->id,p->index,p->name);
1071 break;
1072 }
1073 /* --- audio ---------------------------------------------- */
1074 case VIDIOC_ENUMAUDIO:
1075 {
1076 struct v4l2_audio *p=arg;
1077
1078 if (!vfd->vidioc_enumaudio)
1079 break;
1080 dbgarg(cmd, "Enum for index=%d\n", p->index);
1081 ret=vfd->vidioc_enumaudio(file, fh, p);
1082 if (!ret)
1083 dbgarg2("index=%d, name=%s, capability=%d, "
1084 "mode=%d\n",p->index,p->name,
1085 p->capability, p->mode);
1086 break;
1087 }
1088 case VIDIOC_G_AUDIO:
1089 {
1090 struct v4l2_audio *p=arg;
1091
1092 if (!vfd->vidioc_g_audio)
1093 break;
1094 dbgarg(cmd, "Get for index=%d\n", p->index);
1095 ret=vfd->vidioc_g_audio(file, fh, p);
1096 if (!ret)
1097 dbgarg2("index=%d, name=%s, capability=%d, "
1098 "mode=%d\n",p->index,
1099 p->name,p->capability, p->mode);
1100 break;
1101 }
1102 case VIDIOC_S_AUDIO:
1103 {
1104 struct v4l2_audio *p=arg;
1105
1106 if (!vfd->vidioc_s_audio)
1107 break;
1108 dbgarg(cmd, "index=%d, name=%s, capability=%d, "
1109 "mode=%d\n", p->index, p->name,
1110 p->capability, p->mode);
1111 ret=vfd->vidioc_s_audio(file, fh, p);
1112 break;
1113 }
1114 case VIDIOC_ENUMAUDOUT:
1115 {
1116 struct v4l2_audioout *p=arg;
1117
1118 if (!vfd->vidioc_enumaudout)
1119 break;
1120 dbgarg(cmd, "Enum for index=%d\n", p->index);
1121 ret=vfd->vidioc_enumaudout(file, fh, p);
1122 if (!ret)
1123 dbgarg2("index=%d, name=%s, capability=%d, "
1124 "mode=%d\n", p->index, p->name,
1125 p->capability,p->mode);
1126 break;
1127 }
1128 case VIDIOC_G_AUDOUT:
1129 {
1130 struct v4l2_audioout *p=arg;
1131
1132 if (!vfd->vidioc_g_audout)
1133 break;
1134 dbgarg(cmd, "Enum for index=%d\n", p->index);
1135 ret=vfd->vidioc_g_audout(file, fh, p);
1136 if (!ret)
1137 dbgarg2("index=%d, name=%s, capability=%d, "
1138 "mode=%d\n", p->index, p->name,
1139 p->capability,p->mode);
1140 break;
1141 }
1142 case VIDIOC_S_AUDOUT:
1143 {
1144 struct v4l2_audioout *p=arg;
1145
1146 if (!vfd->vidioc_s_audout)
1147 break;
1148 dbgarg(cmd, "index=%d, name=%s, capability=%d, "
1149 "mode=%d\n", p->index, p->name,
1150 p->capability,p->mode);
1151
1152 ret=vfd->vidioc_s_audout(file, fh, p);
1153 break;
1154 }
1155 case VIDIOC_G_MODULATOR:
1156 {
1157 struct v4l2_modulator *p=arg;
1158 if (!vfd->vidioc_g_modulator)
1159 break;
1160 ret=vfd->vidioc_g_modulator(file, fh, p);
1161 if (!ret)
1162 dbgarg(cmd, "index=%d, name=%s, "
1163 "capability=%d, rangelow=%d,"
1164 " rangehigh=%d, txsubchans=%d\n",
1165 p->index, p->name,p->capability,
1166 p->rangelow, p->rangehigh,
1167 p->txsubchans);
1168 break;
1169 }
1170 case VIDIOC_S_MODULATOR:
1171 {
1172 struct v4l2_modulator *p=arg;
1173 if (!vfd->vidioc_s_modulator)
1174 break;
1175 dbgarg(cmd, "index=%d, name=%s, capability=%d, "
1176 "rangelow=%d, rangehigh=%d, txsubchans=%d\n",
1177 p->index, p->name,p->capability,p->rangelow,
1178 p->rangehigh,p->txsubchans);
1179 ret=vfd->vidioc_s_modulator(file, fh, p);
1180 break;
1181 }
1182 case VIDIOC_G_CROP:
1183 {
1184 struct v4l2_crop *p=arg;
1185 if (!vfd->vidioc_g_crop)
1186 break;
1187 ret=vfd->vidioc_g_crop(file, fh, p);
1188 if (!ret) {
1189 dbgarg(cmd, "type=%d\n", p->type);
1190 dbgrect(vfd, "", &p->c);
1191 }
1192 break;
1193 }
1194 case VIDIOC_S_CROP:
1195 {
1196 struct v4l2_crop *p=arg;
1197 if (!vfd->vidioc_s_crop)
1198 break;
1199 dbgarg(cmd, "type=%d\n", p->type);
1200 dbgrect(vfd, "", &p->c);
1201 ret=vfd->vidioc_s_crop(file, fh, p);
1202 break;
1203 }
1204 case VIDIOC_CROPCAP:
1205 {
1206 struct v4l2_cropcap *p=arg;
1207 /*FIXME: Should also show v4l2_fract pixelaspect */
1208 if (!vfd->vidioc_cropcap)
1209 break;
1210 dbgarg(cmd, "type=%d\n", p->type);
1211 dbgrect(vfd, "bounds ", &p->bounds);
1212 dbgrect(vfd, "defrect ", &p->defrect);
1213 ret=vfd->vidioc_cropcap(file, fh, p);
1214 break;
1215 }
1216 case VIDIOC_G_MPEGCOMP:
1217 {
1218 struct v4l2_mpeg_compression *p=arg;
1219
1220 /*FIXME: Several fields not shown */
1221 if (!vfd->vidioc_g_mpegcomp)
1222 break;
1223 ret=vfd->vidioc_g_mpegcomp(file, fh, p);
1224 if (!ret)
1225 dbgarg (cmd, "ts_pid_pmt=%d, ts_pid_audio=%d,"
1226 " ts_pid_video=%d, ts_pid_pcr=%d, "
1227 "ps_size=%d, au_sample_rate=%d, "
1228 "au_pesid=%c, vi_frame_rate=%d, "
1229 "vi_frames_per_gop=%d, "
1230 "vi_bframes_count=%d, vi_pesid=%c\n",
1231 p->ts_pid_pmt,p->ts_pid_audio,
1232 p->ts_pid_video,p->ts_pid_pcr,
1233 p->ps_size, p->au_sample_rate,
1234 p->au_pesid, p->vi_frame_rate,
1235 p->vi_frames_per_gop,
1236 p->vi_bframes_count, p->vi_pesid);
1237 break;
1238 }
1239 case VIDIOC_S_MPEGCOMP:
1240 {
1241 struct v4l2_mpeg_compression *p=arg;
1242 /*FIXME: Several fields not shown */
1243 if (!vfd->vidioc_s_mpegcomp)
1244 break;
1245 dbgarg (cmd, "ts_pid_pmt=%d, ts_pid_audio=%d, "
1246 "ts_pid_video=%d, ts_pid_pcr=%d, ps_size=%d, "
1247 "au_sample_rate=%d, au_pesid=%c, "
1248 "vi_frame_rate=%d, vi_frames_per_gop=%d, "
1249 "vi_bframes_count=%d, vi_pesid=%c\n",
1250 p->ts_pid_pmt,p->ts_pid_audio, p->ts_pid_video,
1251 p->ts_pid_pcr, p->ps_size, p->au_sample_rate,
1252 p->au_pesid, p->vi_frame_rate,
1253 p->vi_frames_per_gop, p->vi_bframes_count,
1254 p->vi_pesid);
1255 ret=vfd->vidioc_s_mpegcomp(file, fh, p);
1256 break;
1257 }
1258 case VIDIOC_G_JPEGCOMP:
1259 {
1260 struct v4l2_jpegcompression *p=arg;
1261 if (!vfd->vidioc_g_jpegcomp)
1262 break;
1263 ret=vfd->vidioc_g_jpegcomp(file, fh, p);
1264 if (!ret)
1265 dbgarg (cmd, "quality=%d, APPn=%d, "
1266 "APP_len=%d, COM_len=%d, "
1267 "jpeg_markers=%d\n",
1268 p->quality,p->APPn,p->APP_len,
1269 p->COM_len,p->jpeg_markers);
1270 break;
1271 }
1272 case VIDIOC_S_JPEGCOMP:
1273 {
1274 struct v4l2_jpegcompression *p=arg;
1275 if (!vfd->vidioc_g_jpegcomp)
1276 break;
1277 dbgarg (cmd, "quality=%d, APPn=%d, APP_len=%d, "
1278 "COM_len=%d, jpeg_markers=%d\n",
1279 p->quality,p->APPn,p->APP_len,
1280 p->COM_len,p->jpeg_markers);
1281 ret=vfd->vidioc_s_jpegcomp(file, fh, p);
1282 break;
1283 }
1284 case VIDIOC_G_PARM:
1285 {
1286 struct v4l2_streamparm *p=arg;
1287 if (!vfd->vidioc_g_parm)
1288 break;
1289 ret=vfd->vidioc_g_parm(file, fh, p);
1290 dbgarg (cmd, "type=%d\n", p->type);
1291 break;
1292 }
1293 case VIDIOC_S_PARM:
1294 {
1295 struct v4l2_streamparm *p=arg;
1296 if (!vfd->vidioc_s_parm)
1297 break;
1298 dbgarg (cmd, "type=%d\n", p->type);
1299 ret=vfd->vidioc_s_parm(file, fh, p);
1300 break;
1301 }
1302 case VIDIOC_G_TUNER:
1303 {
1304 struct v4l2_tuner *p=arg;
1305 if (!vfd->vidioc_g_tuner)
1306 break;
1307 ret=vfd->vidioc_g_tuner(file, fh, p);
1308 if (!ret)
1309 dbgarg (cmd, "index=%d, name=%s, type=%d, "
1310 "capability=%d, rangelow=%d, "
1311 "rangehigh=%d, signal=%d, afc=%d, "
1312 "rxsubchans=%d, audmode=%d\n",
1313 p->index, p->name, p->type,
1314 p->capability, p->rangelow,
1315 p->rangehigh, p->rxsubchans,
1316 p->audmode, p->signal, p->afc);
1317 break;
1318 }
1319 case VIDIOC_S_TUNER:
1320 {
1321 struct v4l2_tuner *p=arg;
1322 if (!vfd->vidioc_s_tuner)
1323 break;
1324 dbgarg (cmd, "index=%d, name=%s, type=%d, "
1325 "capability=%d, rangelow=%d, rangehigh=%d, "
1326 "signal=%d, afc=%d, rxsubchans=%d, "
1327 "audmode=%d\n",p->index, p->name, p->type,
1328 p->capability, p->rangelow,p->rangehigh,
1329 p->rxsubchans, p->audmode, p->signal,
1330 p->afc);
1331 ret=vfd->vidioc_s_tuner(file, fh, p);
1332 break;
1333 }
1334 case VIDIOC_G_FREQUENCY:
1335 {
1336 struct v4l2_frequency *p=arg;
1337 if (!vfd->vidioc_g_frequency)
1338 break;
1339 ret=vfd->vidioc_g_frequency(file, fh, p);
1340 if (!ret)
1341 dbgarg (cmd, "tuner=%d, type=%d, frequency=%d\n",
1342 p->tuner,p->type,p->frequency);
1343 break;
1344 }
1345 case VIDIOC_S_FREQUENCY:
1346 {
1347 struct v4l2_frequency *p=arg;
1348 if (!vfd->vidioc_s_frequency)
1349 break;
1350 dbgarg (cmd, "tuner=%d, type=%d, frequency=%d\n",
1351 p->tuner,p->type,p->frequency);
1352 ret=vfd->vidioc_s_frequency(file, fh, p);
1353 break;
1354 }
1355 case VIDIOC_G_SLICED_VBI_CAP:
1356 {
1357 struct v4l2_sliced_vbi_cap *p=arg;
1358 if (!vfd->vidioc_g_sliced_vbi_cap)
1359 break;
1360 ret=vfd->vidioc_g_sliced_vbi_cap(file, fh, p);
1361 if (!ret)
1362 dbgarg (cmd, "service_set=%d\n", p->service_set);
1363 break;
1364 }
1365 case VIDIOC_LOG_STATUS:
1366 {
1367 if (!vfd->vidioc_log_status)
1368 break;
1369 ret=vfd->vidioc_log_status(file, fh);
1370 break;
1371 }
1372
1373 /* --- Others --------------------------------------------- */
1374
1375 default:
1376 ret=v4l_compat_translate_ioctl(inode,file,cmd,arg,__video_do_ioctl);
1377 }
1378
1379 if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) {
1380 if (ret<0) {
1381 printk ("%s: err:\n", vfd->name);
1382 v4l_print_ioctl(vfd->name, cmd);
1383 }
1384 }
1385
1386 return ret;
1387}
1388
1389int video_ioctl2 (struct inode *inode, struct file *file,
1390 unsigned int cmd, unsigned long arg)
1391{
1392 char sbuf[128];
1393 void *mbuf = NULL;
1394 void *parg = NULL;
1395 int err = -EINVAL;
1396 int is_ext_ctrl;
1397 size_t ctrls_size = 0;
1398 void __user *user_ptr = NULL;
1399
1400#ifdef __OLD_VIDIOC_
1401 cmd = video_fix_command(cmd);
1402#endif
1403 is_ext_ctrl = (cmd == VIDIOC_S_EXT_CTRLS || cmd == VIDIOC_G_EXT_CTRLS ||
1404 cmd == VIDIOC_TRY_EXT_CTRLS);
1405
1406 /* Copy arguments into temp kernel buffer */
1407 switch (_IOC_DIR(cmd)) {
1408 case _IOC_NONE:
1409 parg = NULL;
1410 break;
1411 case _IOC_READ:
1412 case _IOC_WRITE:
1413 case (_IOC_WRITE | _IOC_READ):
1414 if (_IOC_SIZE(cmd) <= sizeof(sbuf)) {
1415 parg = sbuf;
1416 } else {
1417 /* too big to allocate from stack */
1418 mbuf = kmalloc(_IOC_SIZE(cmd),GFP_KERNEL);
1419 if (NULL == mbuf)
1420 return -ENOMEM;
1421 parg = mbuf;
1422 }
1423
1424 err = -EFAULT;
1425 if (_IOC_DIR(cmd) & _IOC_WRITE)
1426 if (copy_from_user(parg, (void __user *)arg, _IOC_SIZE(cmd)))
1427 goto out;
1428 break;
1429 }
1430
1431 if (is_ext_ctrl) {
1432 struct v4l2_ext_controls *p = parg;
1433
1434 /* In case of an error, tell the caller that it wasn't
1435 a specific control that caused it. */
1436 p->error_idx = p->count;
1437 user_ptr = (void __user *)p->controls;
1438 if (p->count) {
1439 ctrls_size = sizeof(struct v4l2_ext_control) * p->count;
1440 /* Note: v4l2_ext_controls fits in sbuf[] so mbuf is still NULL. */
1441 mbuf = kmalloc(ctrls_size, GFP_KERNEL);
1442 err = -ENOMEM;
1443 if (NULL == mbuf)
1444 goto out_ext_ctrl;
1445 err = -EFAULT;
1446 if (copy_from_user(mbuf, user_ptr, ctrls_size))
1447 goto out_ext_ctrl;
1448 p->controls = mbuf;
1449 }
1450 }
1451
1452 /* Handles IOCTL */
1453 err = __video_do_ioctl(inode, file, cmd, parg);
1454 if (err == -ENOIOCTLCMD)
1455 err = -EINVAL;
1456 if (is_ext_ctrl) {
1457 struct v4l2_ext_controls *p = parg;
1458
1459 p->controls = (void *)user_ptr;
1460 if (p->count && err == 0 && copy_to_user(user_ptr, mbuf, ctrls_size))
1461 err = -EFAULT;
1462 goto out_ext_ctrl;
1463 }
1464 if (err < 0)
1465 goto out;
1466
1467out_ext_ctrl:
1468 /* Copy results into user buffer */
1469 switch (_IOC_DIR(cmd))
1470 {
1471 case _IOC_READ:
1472 case (_IOC_WRITE | _IOC_READ):
1473 if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd)))
1474 err = -EFAULT;
1475 break;
1476 }
1477
1478out:
1479 kfree(mbuf);
1480 return err;
1481}
1482
1483
245static struct file_operations video_fops; 1484static struct file_operations video_fops;
246 1485
247/** 1486/**
@@ -371,7 +1610,9 @@ void video_unregister_device(struct video_device *vfd)
371 mutex_unlock(&videodev_lock); 1610 mutex_unlock(&videodev_lock);
372} 1611}
373 1612
374 1613/*
1614 * Video fs operations
1615 */
375static struct file_operations video_fops= 1616static struct file_operations video_fops=
376{ 1617{
377 .owner = THIS_MODULE, 1618 .owner = THIS_MODULE,
@@ -387,7 +1628,7 @@ static int __init videodev_init(void)
387{ 1628{
388 int ret; 1629 int ret;
389 1630
390 printk(KERN_INFO "Linux video capture interface: v1.00\n"); 1631 printk(KERN_INFO "Linux video capture interface: v2.00\n");
391 if (register_chrdev(VIDEO_MAJOR, VIDEO_NAME, &video_fops)) { 1632 if (register_chrdev(VIDEO_MAJOR, VIDEO_NAME, &video_fops)) {
392 printk(KERN_WARNING "video_dev: unable to get major %d\n", VIDEO_MAJOR); 1633 printk(KERN_WARNING "video_dev: unable to get major %d\n", VIDEO_MAJOR);
393 return -EIO; 1634 return -EIO;
@@ -418,11 +1659,12 @@ EXPORT_SYMBOL(video_devdata);
418EXPORT_SYMBOL(video_usercopy); 1659EXPORT_SYMBOL(video_usercopy);
419EXPORT_SYMBOL(video_exclusive_open); 1660EXPORT_SYMBOL(video_exclusive_open);
420EXPORT_SYMBOL(video_exclusive_release); 1661EXPORT_SYMBOL(video_exclusive_release);
1662EXPORT_SYMBOL(video_ioctl2);
421EXPORT_SYMBOL(video_device_alloc); 1663EXPORT_SYMBOL(video_device_alloc);
422EXPORT_SYMBOL(video_device_release); 1664EXPORT_SYMBOL(video_device_release);
423 1665
424MODULE_AUTHOR("Alan Cox"); 1666MODULE_AUTHOR("Alan Cox, Mauro Carvalho Chehab <mchehab@infradead.org>");
425MODULE_DESCRIPTION("Device registrar for Video4Linux drivers"); 1667MODULE_DESCRIPTION("Device registrar for Video4Linux drivers v2");
426MODULE_LICENSE("GPL"); 1668MODULE_LICENSE("GPL");
427 1669
428 1670
diff --git a/drivers/media/video/vino.c b/drivers/media/video/vino.c
index a8c101494cf..268e69fdefc 100644
--- a/drivers/media/video/vino.c
+++ b/drivers/media/video/vino.c
@@ -40,7 +40,7 @@
40#include <linux/i2c-algo-sgi.h> 40#include <linux/i2c-algo-sgi.h>
41 41
42#include <linux/videodev.h> 42#include <linux/videodev.h>
43#include <linux/videodev2.h> 43#include <media/v4l2-common.h>
44#include <linux/video_decoder.h> 44#include <linux/video_decoder.h>
45#include <linux/mutex.h> 45#include <linux/mutex.h>
46 46
diff --git a/drivers/media/video/vivi.c b/drivers/media/video/vivi.c
index 779db26771c..41d23c8acbd 100644
--- a/drivers/media/video/vivi.c
+++ b/drivers/media/video/vivi.c
@@ -48,34 +48,15 @@
48 48
49#include "font.h" 49#include "font.h"
50 50
51#ifndef kzalloc
52#define kzalloc(size, flags) \
53({ \
54 void *__ret = kmalloc(size, flags); \
55 if (__ret) \
56 memset(__ret, 0, size); \
57 __ret; \
58})
59#endif
60
61MODULE_DESCRIPTION("Video Technology Magazine Virtual Video Capture Board");
62MODULE_AUTHOR("Mauro Carvalho Chehab, Ted Walther and John Sokol");
63MODULE_LICENSE("Dual BSD/GPL");
64
65#define VIVI_MAJOR_VERSION 0 51#define VIVI_MAJOR_VERSION 0
66#define VIVI_MINOR_VERSION 4 52#define VIVI_MINOR_VERSION 4
67#define VIVI_RELEASE 0 53#define VIVI_RELEASE 0
68#define VIVI_VERSION KERNEL_VERSION(VIVI_MAJOR_VERSION, VIVI_MINOR_VERSION, VIVI_RELEASE) 54#define VIVI_VERSION KERNEL_VERSION(VIVI_MAJOR_VERSION, VIVI_MINOR_VERSION, VIVI_RELEASE)
69 55
70static int video_nr = -1; /* /dev/videoN, -1 for autodetect */ 56/* Declare static vars that will be used as parameters */
71module_param(video_nr, int, 0); 57static unsigned int vid_limit = 16; /* Video memory limit, in Mb */
72 58static struct video_device vivi; /* Video device */
73static int debug = 0; 59static int video_nr = -1; /* /dev/videoN, -1 for autodetect */
74module_param(debug, int, 0);
75
76static unsigned int vid_limit = 16;
77module_param(vid_limit,int,0644);
78MODULE_PARM_DESC(vid_limit,"capture memory limit in megabytes");
79 60
80/* supported controls */ 61/* supported controls */
81static struct v4l2_queryctrl vivi_qctrl[] = { 62static struct v4l2_queryctrl vivi_qctrl[] = {
@@ -129,10 +110,10 @@ static struct v4l2_queryctrl vivi_qctrl[] = {
129 110
130static int qctl_regs[ARRAY_SIZE(vivi_qctrl)]; 111static int qctl_regs[ARRAY_SIZE(vivi_qctrl)];
131 112
132#define dprintk(level,fmt, arg...) \ 113#define dprintk(level,fmt, arg...) \
133 do { \ 114 do { \
134 if (debug >= (level)) \ 115 if (vivi.debug >= (level)) \
135 printk(KERN_DEBUG "vivi: " fmt , ## arg); \ 116 printk(KERN_DEBUG "vivi: " fmt , ## arg); \
136 } while (0) 117 } while (0)
137 118
138/* ------------------------------------------------------------------ 119/* ------------------------------------------------------------------
@@ -190,7 +171,7 @@ struct vivi_dev {
190 171
191 /* various device info */ 172 /* various device info */
192 unsigned int resources; 173 unsigned int resources;
193 struct video_device video_dev; 174 struct video_device vfd;
194 175
195 struct vivi_dmaqueue vidq; 176 struct vivi_dmaqueue vidq;
196 177
@@ -248,7 +229,8 @@ static u8 bars[8][3] = {
248#define TSTAMP_MAX_Y TSTAMP_MIN_Y+15 229#define TSTAMP_MAX_Y TSTAMP_MIN_Y+15
249#define TSTAMP_MIN_X 64 230#define TSTAMP_MIN_X 64
250 231
251void prep_to_addr(struct sg_to_addr to_addr[],struct videobuf_buffer *vb) 232static void prep_to_addr(struct sg_to_addr to_addr[],
233 struct videobuf_buffer *vb)
252{ 234{
253 int i, pos=0; 235 int i, pos=0;
254 236
@@ -259,7 +241,7 @@ void prep_to_addr(struct sg_to_addr to_addr[],struct videobuf_buffer *vb)
259 } 241 }
260} 242}
261 243
262inline int get_addr_pos(int pos, int pages, struct sg_to_addr to_addr[]) 244static int get_addr_pos(int pos, int pages, struct sg_to_addr to_addr[])
263{ 245{
264 int p1=0,p2=pages-1,p3=pages/2; 246 int p1=0,p2=pages-1,p3=pages/2;
265 247
@@ -280,8 +262,8 @@ inline int get_addr_pos(int pos, int pages, struct sg_to_addr to_addr[])
280 return (p1); 262 return (p1);
281} 263}
282 264
283void gen_line(struct sg_to_addr to_addr[],int inipos,int pages,int wmax, 265static void gen_line(struct sg_to_addr to_addr[],int inipos,int pages,int wmax,
284 int hmax, int line, char *timestr) 266 int hmax, int line, char *timestr)
285{ 267{
286 int w,i,j,pos=inipos,pgpos,oldpg,y; 268 int w,i,j,pos=inipos,pgpos,oldpg,y;
287 char *p,*s,*basep; 269 char *p,*s,*basep;
@@ -491,7 +473,7 @@ static void vivi_thread_tick(struct vivi_dmaqueue *dma_q)
491 dprintk(1,"%s: %d buffers handled (should be 1)\n",__FUNCTION__,bc); 473 dprintk(1,"%s: %d buffers handled (should be 1)\n",__FUNCTION__,bc);
492} 474}
493 475
494void vivi_sleep(struct vivi_dmaqueue *dma_q) 476static void vivi_sleep(struct vivi_dmaqueue *dma_q)
495{ 477{
496 int timeout; 478 int timeout;
497 DECLARE_WAITQUEUE(wait, current); 479 DECLARE_WAITQUEUE(wait, current);
@@ -526,7 +508,7 @@ void vivi_sleep(struct vivi_dmaqueue *dma_q)
526 try_to_freeze(); 508 try_to_freeze();
527} 509}
528 510
529int vivi_thread(void *data) 511static int vivi_thread(void *data)
530{ 512{
531 struct vivi_dmaqueue *dma_q=data; 513 struct vivi_dmaqueue *dma_q=data;
532 514
@@ -542,7 +524,7 @@ int vivi_thread(void *data)
542 return 0; 524 return 0;
543} 525}
544 526
545int vivi_start_thread(struct vivi_dmaqueue *dma_q) 527static int vivi_start_thread(struct vivi_dmaqueue *dma_q)
546{ 528{
547 dma_q->frame=0; 529 dma_q->frame=0;
548 dma_q->ini_jiffies=jiffies; 530 dma_q->ini_jiffies=jiffies;
@@ -560,7 +542,7 @@ int vivi_start_thread(struct vivi_dmaqueue *dma_q)
560 return 0; 542 return 0;
561} 543}
562 544
563void vivi_stop_thread(struct vivi_dmaqueue *dma_q) 545static void vivi_stop_thread(struct vivi_dmaqueue *dma_q)
564{ 546{
565 dprintk(1,"%s\n",__FUNCTION__); 547 dprintk(1,"%s\n",__FUNCTION__);
566 /* shutdown control thread */ 548 /* shutdown control thread */
@@ -666,8 +648,7 @@ buffer_setup(struct videobuf_queue *vq, unsigned int *count, unsigned int *size)
666 return 0; 648 return 0;
667} 649}
668 650
669void 651static void free_buffer(struct videobuf_queue *vq, struct vivi_buffer *buf)
670free_buffer(struct videobuf_queue *vq, struct vivi_buffer *buf)
671{ 652{
672 dprintk(1,"%s\n",__FUNCTION__); 653 dprintk(1,"%s\n",__FUNCTION__);
673 654
@@ -791,8 +772,8 @@ static void buffer_release(struct videobuf_queue *vq, struct videobuf_buffer *vb
791 free_buffer(vq,buf); 772 free_buffer(vq,buf);
792} 773}
793 774
794int vivi_map_sg (void *dev, struct scatterlist *sg, int nents, 775static int vivi_map_sg(void *dev, struct scatterlist *sg, int nents,
795 int direction) 776 int direction)
796{ 777{
797 int i; 778 int i;
798 779
@@ -808,15 +789,15 @@ int vivi_map_sg (void *dev, struct scatterlist *sg, int nents,
808 return nents; 789 return nents;
809} 790}
810 791
811int vivi_unmap_sg(void *dev,struct scatterlist *sglist,int nr_pages, 792static int vivi_unmap_sg(void *dev,struct scatterlist *sglist,int nr_pages,
812 int direction) 793 int direction)
813{ 794{
814 dprintk(1,"%s\n",__FUNCTION__); 795 dprintk(1,"%s\n",__FUNCTION__);
815 return 0; 796 return 0;
816} 797}
817 798
818int vivi_dma_sync_sg(void *dev,struct scatterlist *sglist,int nr_pages, 799static int vivi_dma_sync_sg(void *dev,struct scatterlist *sglist, int nr_pages,
819 int direction) 800 int direction)
820{ 801{
821// dprintk(1,"%s\n",__FUNCTION__); 802// dprintk(1,"%s\n",__FUNCTION__);
822 803
@@ -840,7 +821,80 @@ static struct videobuf_queue_ops vivi_video_qops = {
840 IOCTL handling 821 IOCTL handling
841 ------------------------------------------------------------------*/ 822 ------------------------------------------------------------------*/
842 823
843static int vivi_try_fmt(struct vivi_dev *dev, struct vivi_fh *fh, 824
825static int res_get(struct vivi_dev *dev, struct vivi_fh *fh)
826{
827 /* is it free? */
828 down(&dev->lock);
829 if (dev->resources) {
830 /* no, someone else uses it */
831 up(&dev->lock);
832 return 0;
833 }
834 /* it's free, grab it */
835 dev->resources =1;
836 dprintk(1,"res: get\n");
837 up(&dev->lock);
838 return 1;
839}
840
841static int res_locked(struct vivi_dev *dev)
842{
843 return (dev->resources);
844}
845
846static void res_free(struct vivi_dev *dev, struct vivi_fh *fh)
847{
848 down(&dev->lock);
849 dev->resources = 0;
850 dprintk(1,"res: put\n");
851 up(&dev->lock);
852}
853
854/* ------------------------------------------------------------------
855 IOCTL vidioc handling
856 ------------------------------------------------------------------*/
857static int vidioc_querycap (struct file *file, void *priv,
858 struct v4l2_capability *cap)
859{
860 strcpy(cap->driver, "vivi");
861 strcpy(cap->card, "vivi");
862 cap->version = VIVI_VERSION;
863 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE |
864 V4L2_CAP_STREAMING |
865 V4L2_CAP_READWRITE;
866 return 0;
867}
868
869static int vidioc_enum_fmt_cap (struct file *file, void *priv,
870 struct v4l2_fmtdesc *f)
871{
872 if (f->index > 0)
873 return -EINVAL;
874
875 strlcpy(f->description,format.name,sizeof(f->description));
876 f->pixelformat = format.fourcc;
877 return 0;
878}
879
880static int vidioc_g_fmt_cap (struct file *file, void *priv,
881 struct v4l2_format *f)
882{
883 struct vivi_fh *fh=priv;
884
885 f->fmt.pix.width = fh->width;
886 f->fmt.pix.height = fh->height;
887 f->fmt.pix.field = fh->vb_vidq.field;
888 f->fmt.pix.pixelformat = fh->fmt->fourcc;
889 f->fmt.pix.bytesperline =
890 (f->fmt.pix.width * fh->fmt->depth) >> 3;
891 f->fmt.pix.sizeimage =
892 f->fmt.pix.height * f->fmt.pix.bytesperline;
893
894 return (0);
895}
896
897static int vidioc_try_fmt_cap (struct file *file, void *priv,
844 struct v4l2_format *f) 898 struct v4l2_format *f)
845{ 899{
846 struct vivi_fmt *fmt; 900 struct vivi_fmt *fmt;
@@ -848,7 +902,8 @@ static int vivi_try_fmt(struct vivi_dev *dev, struct vivi_fh *fh,
848 unsigned int maxw, maxh; 902 unsigned int maxw, maxh;
849 903
850 if (format.fourcc != f->fmt.pix.pixelformat) { 904 if (format.fourcc != f->fmt.pix.pixelformat) {
851 dprintk(1,"Fourcc format invalid.\n"); 905 dprintk(1,"Fourcc format (0x%08x) invalid. Driver accepts "
906 "only 0x%08x\n",f->fmt.pix.pixelformat,format.fourcc);
852 return -EINVAL; 907 return -EINVAL;
853 } 908 }
854 fmt=&format; 909 fmt=&format;
@@ -884,356 +939,196 @@ static int vivi_try_fmt(struct vivi_dev *dev, struct vivi_fh *fh,
884 return 0; 939 return 0;
885} 940}
886 941
887static int res_get(struct vivi_dev *dev, struct vivi_fh *fh) 942/*FIXME: This seems to be generic enough to be at videodev2 */
943static int vidioc_s_fmt_cap (struct file *file, void *priv,
944 struct v4l2_format *f)
888{ 945{
889 /* is it free? */ 946 struct vivi_fh *fh=priv;
890 down(&dev->lock); 947 int ret = vidioc_try_fmt_cap(file,fh,f);
891 if (dev->resources) { 948 if (ret < 0)
892 /* no, someone else uses it */ 949 return (ret);
893 up(&dev->lock); 950
894 return 0; 951 fh->fmt = &format;
895 } 952 fh->width = f->fmt.pix.width;
896 /* it's free, grab it */ 953 fh->height = f->fmt.pix.height;
897 dev->resources =1; 954 fh->vb_vidq.field = f->fmt.pix.field;
898 dprintk(1,"res: get\n"); 955 fh->type = f->type;
899 up(&dev->lock); 956
900 return 1; 957 return (0);
901} 958}
902 959
903static inline int res_locked(struct vivi_dev *dev) 960static int vidioc_reqbufs (struct file *file, void *priv, struct v4l2_requestbuffers *p)
904{ 961{
905 return (dev->resources); 962 struct vivi_fh *fh=priv;
906}
907 963
908static void res_free(struct vivi_dev *dev, struct vivi_fh *fh) 964 return (videobuf_reqbufs(&fh->vb_vidq, p));
909{
910 down(&dev->lock);
911 dev->resources = 0;
912 dprintk(1,"res: put\n");
913 up(&dev->lock);
914} 965}
915 966
916static int vivi_do_ioctl(struct inode *inode, struct file *file, unsigned int cmd, void *arg) 967static int vidioc_querybuf (struct file *file, void *priv, struct v4l2_buffer *p)
917{ 968{
918 struct vivi_fh *fh = file->private_data; 969 struct vivi_fh *fh=priv;
919 struct vivi_dev *dev = fh->dev;
920 int ret=0;
921 970
922 if (debug) { 971 return (videobuf_querybuf(&fh->vb_vidq, p));
923 if (_IOC_DIR(cmd) & _IOC_WRITE) 972}
924 v4l_printk_ioctl_arg("vivi(w)",cmd, arg);
925 else if (!_IOC_DIR(cmd) & _IOC_READ) {
926 v4l_print_ioctl("vivi", cmd);
927 }
928 }
929 973
930 switch(cmd) { 974static int vidioc_qbuf (struct file *file, void *priv, struct v4l2_buffer *p)
931 /* --- capabilities ------------------------------------------ */ 975{
932 case VIDIOC_QUERYCAP: 976 struct vivi_fh *fh=priv;
933 {
934 struct v4l2_capability *cap = (struct v4l2_capability*)arg;
935
936 memset(cap, 0, sizeof(*cap));
937
938 strcpy(cap->driver, "vivi");
939 strcpy(cap->card, "vivi");
940 cap->version = VIVI_VERSION;
941 cap->capabilities =
942 V4L2_CAP_VIDEO_CAPTURE |
943 V4L2_CAP_STREAMING |
944 V4L2_CAP_READWRITE;
945 break;
946 }
947 /* --- capture ioctls ---------------------------------------- */
948 case VIDIOC_ENUM_FMT:
949 {
950 struct v4l2_fmtdesc *f = arg;
951 enum v4l2_buf_type type;
952 unsigned int index;
953 977
954 index = f->index; 978 return (videobuf_qbuf(&fh->vb_vidq, p));
955 type = f->type; 979}
956 980
957 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { 981static int vidioc_dqbuf (struct file *file, void *priv, struct v4l2_buffer *p)
958 ret=-EINVAL; 982{
959 break; 983 struct vivi_fh *fh=priv;
960 }
961 984
962 switch (type) { 985 return (videobuf_dqbuf(&fh->vb_vidq, p,
963 case V4L2_BUF_TYPE_VIDEO_CAPTURE: 986 file->f_flags & O_NONBLOCK));
964 if (index > 0){ 987}
965 ret=-EINVAL;
966 break;
967 }
968 memset(f,0,sizeof(*f));
969 988
970 f->index = index; 989#ifdef HAVE_V4L1
971 f->type = type; 990static int vidiocgmbuf (struct file *file, void *priv, struct video_mbuf *mbuf)
972 strlcpy(f->description,format.name,sizeof(f->description)); 991{
973 f->pixelformat = format.fourcc; 992 struct vivi_fh *fh=priv;
974 break; 993 struct videobuf_queue *q=&fh->vb_vidq;
975 default: 994 struct v4l2_requestbuffers req;
976 ret=-EINVAL; 995 unsigned int i, ret;
977 } 996
978 break; 997 req.type = q->type;
998 req.count = 8;
999 req.memory = V4L2_MEMORY_MMAP;
1000 ret = videobuf_reqbufs(q,&req);
1001 if (ret < 0)
1002 return (ret);
1003
1004 mbuf->frames = req.count;
1005 mbuf->size = 0;
1006 for (i = 0; i < mbuf->frames; i++) {
1007 mbuf->offsets[i] = q->bufs[i]->boff;
1008 mbuf->size += q->bufs[i]->bsize;
979 } 1009 }
980 case VIDIOC_G_FMT: 1010 return (0);
981 { 1011}
982 struct v4l2_format *f = (struct v4l2_format *)arg; 1012#endif
983 1013
984 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { 1014static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
985 ret=-EINVAL; 1015{
986 break; 1016 struct vivi_fh *fh=priv;
987 } 1017 struct vivi_dev *dev = fh->dev;
988 1018
989 memset(&f->fmt.pix,0,sizeof(f->fmt.pix)); 1019 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
990 f->fmt.pix.width = fh->width; 1020 return -EINVAL;
991 f->fmt.pix.height = fh->height; 1021 if (i != fh->type)
992 f->fmt.pix.field = fh->vb_vidq.field; 1022 return -EINVAL;
993 f->fmt.pix.pixelformat = fh->fmt->fourcc;
994 f->fmt.pix.bytesperline =
995 (f->fmt.pix.width * fh->fmt->depth) >> 3;
996 f->fmt.pix.sizeimage =
997 f->fmt.pix.height * f->fmt.pix.bytesperline;
998 break;
999 }
1000 case VIDIOC_S_FMT:
1001 {
1002 struct v4l2_format *f = arg;
1003 1023
1004 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { 1024 if (!res_get(dev,fh))
1005 dprintk(1,"Only capture supported.\n"); 1025 return -EBUSY;
1006 ret=-EINVAL; 1026 return (videobuf_streamon(&fh->vb_vidq));
1007 break; 1027}
1008 }
1009 1028
1010 ret = vivi_try_fmt(dev,fh,f); 1029static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
1011 if (ret < 0) 1030{
1012 break; 1031 struct vivi_fh *fh=priv;
1032 struct vivi_dev *dev = fh->dev;
1013 1033
1014 fh->fmt = &format; 1034 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1015 fh->width = f->fmt.pix.width; 1035 return -EINVAL;
1016 fh->height = f->fmt.pix.height; 1036 if (i != fh->type)
1017 fh->vb_vidq.field = f->fmt.pix.field; 1037 return -EINVAL;
1018 fh->type = f->type;
1019 1038
1020 break; 1039 videobuf_streamoff(&fh->vb_vidq);
1021 } 1040 res_free(dev,fh);
1022 case VIDIOC_TRY_FMT:
1023 {
1024 struct v4l2_format *f = arg;
1025 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1026 ret=-EINVAL;
1027 break;
1028 }
1029 1041
1030 ret=vivi_try_fmt(dev,fh,f); 1042 return (0);
1031 break; 1043}
1032 } 1044
1033 case VIDIOC_REQBUFS: 1045static struct v4l2_tvnorm tvnorms[] = {
1034 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1035 ret=-EINVAL;
1036 break;
1037 }
1038 ret=videobuf_reqbufs(&fh->vb_vidq, arg);
1039 break;
1040 case VIDIOC_QUERYBUF:
1041 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1042 ret=-EINVAL;
1043 break;
1044 }
1045 ret=videobuf_querybuf(&fh->vb_vidq, arg);
1046 break;
1047 case VIDIOC_QBUF:
1048 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1049 ret=-EINVAL;
1050 break;
1051 }
1052 ret=videobuf_qbuf(&fh->vb_vidq, arg);
1053 break;
1054 case VIDIOC_DQBUF:
1055 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1056 ret=-EINVAL;
1057 break;
1058 }
1059 ret=videobuf_dqbuf(&fh->vb_vidq, arg,
1060 file->f_flags & O_NONBLOCK);
1061 break;
1062#ifdef HAVE_V4L1
1063 /* --- streaming capture ------------------------------------- */
1064 case VIDIOCGMBUF:
1065 {
1066 struct video_mbuf *mbuf = arg;
1067 struct videobuf_queue *q=&fh->vb_vidq;
1068 struct v4l2_requestbuffers req;
1069 unsigned int i;
1070
1071 memset(&req,0,sizeof(req));
1072 req.type = q->type;
1073 req.count = 8;
1074 req.memory = V4L2_MEMORY_MMAP;
1075 ret = videobuf_reqbufs(q,&req);
1076 if (ret < 0)
1077 break;
1078 memset(mbuf,0,sizeof(*mbuf));
1079 mbuf->frames = req.count;
1080 mbuf->size = 0;
1081 for (i = 0; i < mbuf->frames; i++) {
1082 mbuf->offsets[i] = q->bufs[i]->boff;
1083 mbuf->size += q->bufs[i]->bsize;
1084 }
1085 break;
1086 }
1087#endif
1088 case VIDIOC_STREAMON:
1089 {
1090 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1091 return -EINVAL;
1092 if (!res_get(dev,fh))
1093 return -EBUSY;
1094 ret=videobuf_streamon(&fh->vb_vidq);
1095 break;
1096 }
1097 case VIDIOC_STREAMOFF:
1098 { 1046 {
1099 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { 1047 .name = "NTSC-M",
1100 ret=-EINVAL; 1048 .id = V4L2_STD_NTSC_M,
1101 break;
1102 }
1103 ret = videobuf_streamoff(&fh->vb_vidq);
1104 if (ret < 0)
1105 break;
1106 res_free(dev,fh);
1107 break;
1108 } 1049 }
1109 /* ---------- tv norms ---------- */ 1050};
1110 case VIDIOC_ENUMSTD:
1111 {
1112 struct v4l2_standard *e = arg;
1113 1051
1114 if (e->index>0) { 1052static int vidioc_s_std (struct file *file, void *priv, v4l2_std_id a)
1115 ret=-EINVAL; 1053{
1116 break;
1117 }
1118 ret = v4l2_video_std_construct(e, V4L2_STD_NTSC_M, "NTSC-M");
1119 1054
1120 /* Allows vivi to use different fps from video std */ 1055 return 0;
1121 e->frameperiod.numerator = WAKE_NUMERATOR; 1056}
1122 e->frameperiod.denominator = WAKE_DENOMINATOR;
1123 1057
1124 break; 1058/* only one input in this sample driver */
1125 } 1059static int vidioc_enum_input (struct file *file, void *priv,
1126 case VIDIOC_G_STD: 1060 struct v4l2_input *inp)
1127 { 1061{
1128 v4l2_std_id *id = arg; 1062 if (inp->index != 0)
1063 return -EINVAL;
1129 1064
1130 *id = V4L2_STD_NTSC_M; 1065 inp->type = V4L2_INPUT_TYPE_CAMERA;
1131 break; 1066 inp->std = V4L2_STD_NTSC_M;
1132 } 1067 strcpy(inp->name,"Camera");
1133 case VIDIOC_S_STD:
1134 {
1135 break;
1136 }
1137 /* ------ input switching ---------- */
1138 case VIDIOC_ENUMINPUT:
1139 { /* only one input in this sample driver */
1140 struct v4l2_input *inp = arg;
1141 1068
1142 if (inp->index != 0) { 1069 return (0);
1143 ret=-EINVAL; 1070}
1144 break;
1145 }
1146 memset(inp, 0, sizeof(*inp));
1147 1071
1148 inp->index = 0; 1072static int vidioc_g_input (struct file *file, void *priv, unsigned int *i)
1149 inp->type = V4L2_INPUT_TYPE_CAMERA; 1073{
1150 inp->std = V4L2_STD_NTSC_M; 1074 *i = 0;
1151 strcpy(inp->name,"Camera");
1152 break;
1153 }
1154 case VIDIOC_G_INPUT:
1155 {
1156 unsigned int *i = arg;
1157 1075
1158 *i = 0; 1076 return (0);
1159 break; 1077}
1160 } 1078static int vidioc_s_input (struct file *file, void *priv, unsigned int i)
1161 case VIDIOC_S_INPUT: 1079{
1162 { 1080 if (i > 0)
1163 unsigned int *i = arg; 1081 return -EINVAL;
1164 1082
1165 if (*i > 0) 1083 return (0);
1166 ret=-EINVAL; 1084}
1167 break;
1168 }
1169 1085
1170 /* --- controls ---------------------------------------------- */ 1086 /* --- controls ---------------------------------------------- */
1171 case VIDIOC_QUERYCTRL: 1087static int vidioc_queryctrl (struct file *file, void *priv,
1172 { 1088 struct v4l2_queryctrl *qc)
1173 struct v4l2_queryctrl *qc = arg; 1089{
1174 int i; 1090 int i;
1175
1176 for (i = 0; i < ARRAY_SIZE(vivi_qctrl); i++)
1177 if (qc->id && qc->id == vivi_qctrl[i].id) {
1178 memcpy(qc, &(vivi_qctrl[i]),
1179 sizeof(*qc));
1180 break;
1181 }
1182 1091
1183 ret=-EINVAL; 1092 for (i = 0; i < ARRAY_SIZE(vivi_qctrl); i++)
1184 break; 1093 if (qc->id && qc->id == vivi_qctrl[i].id) {
1185 } 1094 memcpy(qc, &(vivi_qctrl[i]),
1186 case VIDIOC_G_CTRL: 1095 sizeof(*qc));
1187 { 1096 return (0);
1188 struct v4l2_control *ctrl = arg; 1097 }
1189 int i;
1190 1098
1191 for (i = 0; i < ARRAY_SIZE(vivi_qctrl); i++) 1099 return -EINVAL;
1192 if (ctrl->id == vivi_qctrl[i].id) { 1100}
1193 ctrl->value=qctl_regs[i];
1194 break;
1195 }
1196 1101
1197 ret=-EINVAL; 1102static int vidioc_g_ctrl (struct file *file, void *priv,
1198 break; 1103 struct v4l2_control *ctrl)
1199 } 1104{
1200 case VIDIOC_S_CTRL: 1105 int i;
1201 {
1202 struct v4l2_control *ctrl = arg;
1203 int i;
1204 for (i = 0; i < ARRAY_SIZE(vivi_qctrl); i++)
1205 if (ctrl->id == vivi_qctrl[i].id) {
1206 if (ctrl->value <
1207 vivi_qctrl[i].minimum
1208 || ctrl->value >
1209 vivi_qctrl[i].maximum) {
1210 ret=-ERANGE;
1211 break;
1212 }
1213 qctl_regs[i]=ctrl->value;
1214 break;
1215 }
1216 ret=-EINVAL;
1217 break;
1218 }
1219 default:
1220 ret=v4l_compat_translate_ioctl(inode,file,cmd,arg,vivi_do_ioctl);
1221 }
1222 1106
1223 if (debug) { 1107 for (i = 0; i < ARRAY_SIZE(vivi_qctrl); i++)
1224 if (ret<0) { 1108 if (ctrl->id == vivi_qctrl[i].id) {
1225 v4l_print_ioctl("vivi(err)", cmd); 1109 ctrl->value=qctl_regs[i];
1226 dprintk(1,"errcode=%d\n",ret); 1110 return (0);
1227 } else if (_IOC_DIR(cmd) & _IOC_READ) 1111 }
1228 v4l_printk_ioctl_arg("vivi(r)",cmd, arg);
1229 }
1230 1112
1231 return ret; 1113 return -EINVAL;
1232} 1114}
1233 1115static int vidioc_s_ctrl (struct file *file, void *priv,
1234static int vivi_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) 1116 struct v4l2_control *ctrl)
1235{ 1117{
1236 return video_usercopy(inode, file, cmd, arg, vivi_do_ioctl); 1118 int i;
1119
1120 for (i = 0; i < ARRAY_SIZE(vivi_qctrl); i++)
1121 if (ctrl->id == vivi_qctrl[i].id) {
1122 if (ctrl->value <
1123 vivi_qctrl[i].minimum
1124 || ctrl->value >
1125 vivi_qctrl[i].maximum) {
1126 return (-ERANGE);
1127 }
1128 qctl_regs[i]=ctrl->value;
1129 return (0);
1130 }
1131 return -EINVAL;
1237} 1132}
1238 1133
1239/* ------------------------------------------------------------------ 1134/* ------------------------------------------------------------------
@@ -1255,7 +1150,7 @@ static int vivi_open(struct inode *inode, struct file *file)
1255 1150
1256 list_for_each(list,&vivi_devlist) { 1151 list_for_each(list,&vivi_devlist) {
1257 h = list_entry(list, struct vivi_dev, vivi_devlist); 1152 h = list_entry(list, struct vivi_dev, vivi_devlist);
1258 if (h->video_dev.minor == minor) { 1153 if (h->vfd.minor == minor) {
1259 dev = h; 1154 dev = h;
1260 type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 1155 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1261 } 1156 }
@@ -1264,6 +1159,7 @@ static int vivi_open(struct inode *inode, struct file *file)
1264 return -ENODEV; 1159 return -ENODEV;
1265 1160
1266 1161
1162
1267 /* If more than one user, mutex should be added */ 1163 /* If more than one user, mutex should be added */
1268 dev->users++; 1164 dev->users++;
1269 1165
@@ -1279,6 +1175,7 @@ static int vivi_open(struct inode *inode, struct file *file)
1279 1175
1280 file->private_data = fh; 1176 file->private_data = fh;
1281 fh->dev = dev; 1177 fh->dev = dev;
1178
1282 fh->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 1179 fh->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1283 fh->fmt = &format; 1180 fh->fmt = &format;
1284 fh->width = 640; 1181 fh->width = 640;
@@ -1314,7 +1211,7 @@ static int vivi_open(struct inode *inode, struct file *file)
1314static ssize_t 1211static ssize_t
1315vivi_read(struct file *file, char __user *data, size_t count, loff_t *ppos) 1212vivi_read(struct file *file, char __user *data, size_t count, loff_t *ppos)
1316{ 1213{
1317 struct vivi_fh *fh = file->private_data; 1214 struct vivi_fh *fh = file->private_data;
1318 1215
1319 if (fh->type==V4L2_BUF_TYPE_VIDEO_CAPTURE) { 1216 if (fh->type==V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1320 if (res_locked(fh->dev)) 1217 if (res_locked(fh->dev))
@@ -1328,8 +1225,8 @@ vivi_read(struct file *file, char __user *data, size_t count, loff_t *ppos)
1328static unsigned int 1225static unsigned int
1329vivi_poll(struct file *file, struct poll_table_struct *wait) 1226vivi_poll(struct file *file, struct poll_table_struct *wait)
1330{ 1227{
1331 struct vivi_fh *fh = file->private_data; 1228 struct vivi_fh *fh = file->private_data;
1332 struct vivi_buffer *buf; 1229 struct vivi_buffer *buf;
1333 1230
1334 dprintk(1,"%s\n",__FUNCTION__); 1231 dprintk(1,"%s\n",__FUNCTION__);
1335 1232
@@ -1358,8 +1255,8 @@ vivi_poll(struct file *file, struct poll_table_struct *wait)
1358 1255
1359static int vivi_release(struct inode *inode, struct file *file) 1256static int vivi_release(struct inode *inode, struct file *file)
1360{ 1257{
1361 struct vivi_fh *fh = file->private_data; 1258 struct vivi_fh *fh = file->private_data;
1362 struct vivi_dev *dev = fh->dev; 1259 struct vivi_dev *dev = fh->dev;
1363 struct vivi_dmaqueue *vidq = &dev->vidq; 1260 struct vivi_dmaqueue *vidq = &dev->vidq;
1364 1261
1365 int minor = iminor(inode); 1262 int minor = iminor(inode);
@@ -1379,7 +1276,7 @@ static int vivi_release(struct inode *inode, struct file *file)
1379static int 1276static int
1380vivi_mmap(struct file *file, struct vm_area_struct * vma) 1277vivi_mmap(struct file *file, struct vm_area_struct * vma)
1381{ 1278{
1382 struct vivi_fh *fh = file->private_data; 1279 struct vivi_fh *fh = file->private_data;
1383 int ret; 1280 int ret;
1384 1281
1385 dprintk (1,"mmap called, vma=0x%08lx\n",(unsigned long)vma); 1282 dprintk (1,"mmap called, vma=0x%08lx\n",(unsigned long)vma);
@@ -1400,20 +1297,44 @@ static struct file_operations vivi_fops = {
1400 .release = vivi_release, 1297 .release = vivi_release,
1401 .read = vivi_read, 1298 .read = vivi_read,
1402 .poll = vivi_poll, 1299 .poll = vivi_poll,
1403 .ioctl = vivi_ioctl, 1300 .ioctl = video_ioctl2, /* V4L2 ioctl handler */
1404 .mmap = vivi_mmap, 1301 .mmap = vivi_mmap,
1405 .llseek = no_llseek, 1302 .llseek = no_llseek,
1406}; 1303};
1407 1304
1408static struct video_device vivi = { 1305static struct video_device vivi = {
1409 .name = "VTM Virtual Video Capture Board", 1306 .name = "vivi",
1410 .type = VID_TYPE_CAPTURE, 1307 .type = VID_TYPE_CAPTURE,
1411 .hardware = 0, 1308 .hardware = 0,
1412 .fops = &vivi_fops, 1309 .fops = &vivi_fops,
1413 .minor = -1, 1310 .minor = -1,
1414// .release = video_device_release, 1311// .release = video_device_release,
1312
1313 .vidioc_querycap = vidioc_querycap,
1314 .vidioc_enum_fmt_cap = vidioc_enum_fmt_cap,
1315 .vidioc_g_fmt_cap = vidioc_g_fmt_cap,
1316 .vidioc_try_fmt_cap = vidioc_try_fmt_cap,
1317 .vidioc_s_fmt_cap = vidioc_s_fmt_cap,
1318 .vidioc_reqbufs = vidioc_reqbufs,
1319 .vidioc_querybuf = vidioc_querybuf,
1320 .vidioc_qbuf = vidioc_qbuf,
1321 .vidioc_dqbuf = vidioc_dqbuf,
1322 .vidioc_s_std = vidioc_s_std,
1323 .vidioc_enum_input = vidioc_enum_input,
1324 .vidioc_g_input = vidioc_g_input,
1325 .vidioc_s_input = vidioc_s_input,
1326 .vidioc_queryctrl = vidioc_queryctrl,
1327 .vidioc_g_ctrl = vidioc_g_ctrl,
1328 .vidioc_s_ctrl = vidioc_s_ctrl,
1329 .vidioc_streamon = vidioc_streamon,
1330 .vidioc_streamoff = vidioc_streamoff,
1331#ifdef HAVE_V4L1
1332 .vidiocgmbuf = vidiocgmbuf,
1333#endif
1334 .tvnorms = tvnorms,
1335 .tvnormsize = ARRAY_SIZE(tvnorms),
1415}; 1336};
1416/* ------------------------------------------------------------------ 1337/* -----------------------------------------------------------------
1417 Initialization and module stuff 1338 Initialization and module stuff
1418 ------------------------------------------------------------------*/ 1339 ------------------------------------------------------------------*/
1419 1340
@@ -1457,3 +1378,16 @@ static void __exit vivi_exit(void)
1457 1378
1458module_init(vivi_init); 1379module_init(vivi_init);
1459module_exit(vivi_exit); 1380module_exit(vivi_exit);
1381
1382MODULE_DESCRIPTION("Video Technology Magazine Virtual Video Capture Board");
1383MODULE_AUTHOR("Mauro Carvalho Chehab, Ted Walther and John Sokol");
1384MODULE_LICENSE("Dual BSD/GPL");
1385
1386module_param(video_nr, int, 0);
1387
1388module_param_named(debug,vivi.debug, int, 0644);
1389MODULE_PARM_DESC(debug,"activates debug info");
1390
1391module_param(vid_limit,int,0644);
1392MODULE_PARM_DESC(vid_limit,"capture memory limit in megabytes");
1393
diff --git a/drivers/media/video/vpx3220.c b/drivers/media/video/vpx3220.c
index 40b205b9148..1eca7e65d23 100644
--- a/drivers/media/video/vpx3220.c
+++ b/drivers/media/video/vpx3220.c
@@ -34,6 +34,7 @@
34#define I2C_NAME(x) (x)->name 34#define I2C_NAME(x) (x)->name
35 35
36#include <linux/videodev.h> 36#include <linux/videodev.h>
37#include <media/v4l2-common.h>
37#include <linux/video_decoder.h> 38#include <linux/video_decoder.h>
38 39
39#define I2C_VPX3220 0x86 40#define I2C_VPX3220 0x86
diff --git a/drivers/media/video/w9966.c b/drivers/media/video/w9966.c
index 80ef8a1b8f6..4bdc886abc4 100644
--- a/drivers/media/video/w9966.c
+++ b/drivers/media/video/w9966.c
@@ -58,6 +58,7 @@
58#include <linux/init.h> 58#include <linux/init.h>
59#include <linux/delay.h> 59#include <linux/delay.h>
60#include <linux/videodev.h> 60#include <linux/videodev.h>
61#include <media/v4l2-common.h>
61#include <linux/parport.h> 62#include <linux/parport.h>
62 63
63//#define DEBUG // Undef me for production 64//#define DEBUG // Undef me for production
diff --git a/drivers/media/video/zc0301/Kconfig b/drivers/media/video/zc0301/Kconfig
index 115833e4f4d..a859a692018 100644
--- a/drivers/media/video/zc0301/Kconfig
+++ b/drivers/media/video/zc0301/Kconfig
@@ -1,9 +1,9 @@
1config USB_ZC0301 1config USB_ZC0301
2 tristate "USB ZC0301 Image Processor and Control Chip support" 2 tristate "USB ZC0301[P] Image Processor and Control Chip support"
3 depends on USB && VIDEO_V4L1 3 depends on USB && VIDEO_V4L1
4 ---help--- 4 ---help---
5 Say Y here if you want support for cameras based on the ZC0301 5 Say Y here if you want support for cameras based on the ZC0301 or
6 Image Processor and Control Chip. 6 ZC0301P Image Processors and Control Chips.
7 7
8 See <file:Documentation/video4linux/zc0301.txt> for more info. 8 See <file:Documentation/video4linux/zc0301.txt> for more info.
9 9
diff --git a/drivers/media/video/zc0301/Makefile b/drivers/media/video/zc0301/Makefile
index d749199d8f0..d9e6d97fade 100644
--- a/drivers/media/video/zc0301/Makefile
+++ b/drivers/media/video/zc0301/Makefile
@@ -1,3 +1,3 @@
1zc0301-objs := zc0301_core.o zc0301_pas202bcb.o 1zc0301-objs := zc0301_core.o zc0301_pb0330.o zc0301_pas202bcb.o
2 2
3obj-$(CONFIG_USB_ZC0301) += zc0301.o 3obj-$(CONFIG_USB_ZC0301) += zc0301.o
diff --git a/drivers/media/video/zc0301/zc0301_core.c b/drivers/media/video/zc0301/zc0301_core.c
index 0fad39754f7..1b2be2d2a3e 100644
--- a/drivers/media/video/zc0301/zc0301_core.c
+++ b/drivers/media/video/zc0301/zc0301_core.c
@@ -1,5 +1,5 @@
1/*************************************************************************** 1/***************************************************************************
2 * Video4Linux2 driver for ZC0301 Image Processor and Control Chip * 2 * Video4Linux2 driver for ZC0301[P] Image Processor and Control Chip *
3 * * 3 * *
4 * Copyright (C) 2006 by Luca Risolia <luca.risolia@studio.unibo.it> * 4 * Copyright (C) 2006 by Luca Risolia <luca.risolia@studio.unibo.it> *
5 * * 5 * *
@@ -47,13 +47,13 @@
47 47
48/*****************************************************************************/ 48/*****************************************************************************/
49 49
50#define ZC0301_MODULE_NAME "V4L2 driver for ZC0301 " \ 50#define ZC0301_MODULE_NAME "V4L2 driver for ZC0301[P] " \
51 "Image Processor and Control Chip" 51 "Image Processor and Control Chip"
52#define ZC0301_MODULE_AUTHOR "(C) 2006 Luca Risolia" 52#define ZC0301_MODULE_AUTHOR "(C) 2006 Luca Risolia"
53#define ZC0301_AUTHOR_EMAIL "<luca.risolia@studio.unibo.it>" 53#define ZC0301_AUTHOR_EMAIL "<luca.risolia@studio.unibo.it>"
54#define ZC0301_MODULE_LICENSE "GPL" 54#define ZC0301_MODULE_LICENSE "GPL"
55#define ZC0301_MODULE_VERSION "1:1.03" 55#define ZC0301_MODULE_VERSION "1:1.05"
56#define ZC0301_MODULE_VERSION_CODE KERNEL_VERSION(1, 0, 3) 56#define ZC0301_MODULE_VERSION_CODE KERNEL_VERSION(1, 0, 5)
57 57
58/*****************************************************************************/ 58/*****************************************************************************/
59 59
@@ -427,10 +427,11 @@ resubmit_urb:
427static int zc0301_start_transfer(struct zc0301_device* cam) 427static int zc0301_start_transfer(struct zc0301_device* cam)
428{ 428{
429 struct usb_device *udev = cam->usbdev; 429 struct usb_device *udev = cam->usbdev;
430 struct usb_host_interface* altsetting = usb_altnum_to_altsetting(
431 usb_ifnum_to_if(udev, 0),
432 ZC0301_ALTERNATE_SETTING);
433 const unsigned int psz = altsetting->endpoint[0].desc.wMaxPacketSize;
430 struct urb* urb; 434 struct urb* urb;
431 const unsigned int wMaxPacketSize[] = {0, 128, 192, 256, 384,
432 512, 768, 1023};
433 const unsigned int psz = wMaxPacketSize[ZC0301_ALTERNATE_SETTING];
434 s8 i, j; 435 s8 i, j;
435 int err = 0; 436 int err = 0;
436 437
@@ -1772,11 +1773,9 @@ static int zc0301_ioctl_v4l2(struct inode* inode, struct file* filp,
1772 case VIDIOC_G_CTRL: 1773 case VIDIOC_G_CTRL:
1773 return zc0301_vidioc_g_ctrl(cam, arg); 1774 return zc0301_vidioc_g_ctrl(cam, arg);
1774 1775
1775 case VIDIOC_S_CTRL_OLD:
1776 case VIDIOC_S_CTRL: 1776 case VIDIOC_S_CTRL:
1777 return zc0301_vidioc_s_ctrl(cam, arg); 1777 return zc0301_vidioc_s_ctrl(cam, arg);
1778 1778
1779 case VIDIOC_CROPCAP_OLD:
1780 case VIDIOC_CROPCAP: 1779 case VIDIOC_CROPCAP:
1781 return zc0301_vidioc_cropcap(cam, arg); 1780 return zc0301_vidioc_cropcap(cam, arg);
1782 1781
@@ -1823,7 +1822,6 @@ static int zc0301_ioctl_v4l2(struct inode* inode, struct file* filp,
1823 case VIDIOC_G_PARM: 1822 case VIDIOC_G_PARM:
1824 return zc0301_vidioc_g_parm(cam, arg); 1823 return zc0301_vidioc_g_parm(cam, arg);
1825 1824
1826 case VIDIOC_S_PARM_OLD:
1827 case VIDIOC_S_PARM: 1825 case VIDIOC_S_PARM:
1828 return zc0301_vidioc_s_parm(cam, arg); 1826 return zc0301_vidioc_s_parm(cam, arg);
1829 1827
@@ -1914,7 +1912,7 @@ zc0301_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
1914 1912
1915 mutex_init(&cam->dev_mutex); 1913 mutex_init(&cam->dev_mutex);
1916 1914
1917 DBG(2, "ZC0301 Image Processor and Control Chip detected " 1915 DBG(2, "ZC0301[P] Image Processor and Control Chip detected "
1918 "(vid/pid 0x%04X/0x%04X)",id->idVendor, id->idProduct); 1916 "(vid/pid 0x%04X/0x%04X)",id->idVendor, id->idProduct);
1919 1917
1920 for (i = 0; zc0301_sensor_table[i]; i++) { 1918 for (i = 0; zc0301_sensor_table[i]; i++) {
@@ -1936,7 +1934,7 @@ zc0301_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
1936 cam->state |= DEV_MISCONFIGURED; 1934 cam->state |= DEV_MISCONFIGURED;
1937 } 1935 }
1938 1936
1939 strcpy(cam->v4ldev->name, "ZC0301 PC Camera"); 1937 strcpy(cam->v4ldev->name, "ZC0301[P] PC Camera");
1940 cam->v4ldev->owner = THIS_MODULE; 1938 cam->v4ldev->owner = THIS_MODULE;
1941 cam->v4ldev->type = VID_TYPE_CAPTURE | VID_TYPE_SCALES; 1939 cam->v4ldev->type = VID_TYPE_CAPTURE | VID_TYPE_SCALES;
1942 cam->v4ldev->hardware = 0; 1940 cam->v4ldev->hardware = 0;
diff --git a/drivers/media/video/zc0301/zc0301_pas202bcb.c b/drivers/media/video/zc0301/zc0301_pas202bcb.c
index eaadf025204..ecfd39a56df 100644
--- a/drivers/media/video/zc0301/zc0301_pas202bcb.c
+++ b/drivers/media/video/zc0301/zc0301_pas202bcb.c
@@ -1,10 +1,10 @@
1/*************************************************************************** 1/***************************************************************************
2 * Plug-in for PAS202BCB image sensor connected to the ZC030! Image * 2 * Plug-in for PAS202BCB image sensor connected to the ZC0301[P] Image *
3 * Processor and Control Chip * 3 * Processor and Control Chip *
4 * * 4 * *
5 * Copyright (C) 2006 by Luca Risolia <luca.risolia@studio.unibo.it> * 5 * Copyright (C) 2006 by Luca Risolia <luca.risolia@studio.unibo.it> *
6 * * 6 * *
7 * Initialization values of the ZC0301 have been taken from the SPCA5XX * 7 * Initialization values of the ZC0301[P] have been taken from the SPCA5XX *
8 * driver maintained by Michel Xhaard <mxhaard@magic.fr> * 8 * driver maintained by Michel Xhaard <mxhaard@magic.fr> *
9 * * 9 * *
10 * This program is free software; you can redistribute it and/or modify * 10 * This program is free software; you can redistribute it and/or modify *
diff --git a/drivers/media/video/zc0301/zc0301_pb0330.c b/drivers/media/video/zc0301/zc0301_pb0330.c
new file mode 100644
index 00000000000..ed8542e6c50
--- /dev/null
+++ b/drivers/media/video/zc0301/zc0301_pb0330.c
@@ -0,0 +1,187 @@
1/***************************************************************************
2 * Plug-in for PB-0330 image sensor connected to the ZC0301[P] Image *
3 * Processor and Control Chip *
4 * *
5 * Copyright (C) 2006 by Luca Risolia <luca.risolia@studio.unibo.it> *
6 * *
7 * Initialization values of the ZC0301[P] have been taken from the SPCA5XX *
8 * driver maintained by Michel Xhaard <mxhaard@magic.fr> *
9 * *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the Free Software *
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
23 ***************************************************************************/
24
25#include <linux/delay.h>
26#include "zc0301_sensor.h"
27
28
29static struct zc0301_sensor pb0330;
30
31
32static int pb0330_init(struct zc0301_device* cam)
33{
34 int err = 0;
35
36 err += zc0301_write_reg(cam, 0x0000, 0x01);
37 err += zc0301_write_reg(cam, 0x0008, 0x03);
38 err += zc0301_write_reg(cam, 0x0010, 0x0A);
39 err += zc0301_write_reg(cam, 0x0002, 0x00);
40 err += zc0301_write_reg(cam, 0x0003, 0x02);
41 err += zc0301_write_reg(cam, 0x0004, 0x80);
42 err += zc0301_write_reg(cam, 0x0005, 0x01);
43 err += zc0301_write_reg(cam, 0x0006, 0xE0);
44 err += zc0301_write_reg(cam, 0x0001, 0x01);
45 err += zc0301_write_reg(cam, 0x0012, 0x05);
46 err += zc0301_write_reg(cam, 0x0012, 0x07);
47 err += zc0301_write_reg(cam, 0x0098, 0x00);
48 err += zc0301_write_reg(cam, 0x009A, 0x00);
49 err += zc0301_write_reg(cam, 0x011A, 0x00);
50 err += zc0301_write_reg(cam, 0x011C, 0x00);
51 err += zc0301_write_reg(cam, 0x0012, 0x05);
52
53 err += zc0301_i2c_write(cam, 0x01, 0x0006);
54 err += zc0301_i2c_write(cam, 0x02, 0x0011);
55 err += zc0301_i2c_write(cam, 0x03, 0x01E7);
56 err += zc0301_i2c_write(cam, 0x04, 0x0287);
57 err += zc0301_i2c_write(cam, 0x06, 0x0003);
58 err += zc0301_i2c_write(cam, 0x07, 0x3002);
59 err += zc0301_i2c_write(cam, 0x20, 0x1100);
60 err += zc0301_i2c_write(cam, 0x2F, 0xF7B0);
61 err += zc0301_i2c_write(cam, 0x30, 0x0005);
62 err += zc0301_i2c_write(cam, 0x31, 0x0000);
63 err += zc0301_i2c_write(cam, 0x34, 0x0100);
64 err += zc0301_i2c_write(cam, 0x35, 0x0060);
65 err += zc0301_i2c_write(cam, 0x3D, 0x068F);
66 err += zc0301_i2c_write(cam, 0x40, 0x01E0);
67 err += zc0301_i2c_write(cam, 0x58, 0x0078);
68 err += zc0301_i2c_write(cam, 0x62, 0x0411);
69
70 err += zc0301_write_reg(cam, 0x0087, 0x10);
71 err += zc0301_write_reg(cam, 0x0101, 0x37);
72 err += zc0301_write_reg(cam, 0x0012, 0x05);
73 err += zc0301_write_reg(cam, 0x0100, 0x0D);
74 err += zc0301_write_reg(cam, 0x0189, 0x06);
75 err += zc0301_write_reg(cam, 0x01AD, 0x00);
76 err += zc0301_write_reg(cam, 0x01C5, 0x03);
77 err += zc0301_write_reg(cam, 0x01CB, 0x13);
78 err += zc0301_write_reg(cam, 0x0250, 0x08);
79 err += zc0301_write_reg(cam, 0x0301, 0x08);
80 err += zc0301_write_reg(cam, 0x01A8, 0x60);
81 err += zc0301_write_reg(cam, 0x018D, 0x6C);
82 err += zc0301_write_reg(cam, 0x01AD, 0x09);
83 err += zc0301_write_reg(cam, 0x01AE, 0x15);
84 err += zc0301_write_reg(cam, 0x010A, 0x50);
85 err += zc0301_write_reg(cam, 0x010B, 0xF8);
86 err += zc0301_write_reg(cam, 0x010C, 0xF8);
87 err += zc0301_write_reg(cam, 0x010D, 0xF8);
88 err += zc0301_write_reg(cam, 0x010E, 0x50);
89 err += zc0301_write_reg(cam, 0x010F, 0xF8);
90 err += zc0301_write_reg(cam, 0x0110, 0xF8);
91 err += zc0301_write_reg(cam, 0x0111, 0xF8);
92 err += zc0301_write_reg(cam, 0x0112, 0x50);
93 err += zc0301_write_reg(cam, 0x0008, 0x03);
94 err += zc0301_write_reg(cam, 0x01C6, 0x08);
95 err += zc0301_write_reg(cam, 0x01CB, 0x0F);
96 err += zc0301_write_reg(cam, 0x010A, 0x50);
97 err += zc0301_write_reg(cam, 0x010B, 0xF8);
98 err += zc0301_write_reg(cam, 0x010C, 0xF8);
99 err += zc0301_write_reg(cam, 0x010D, 0xF8);
100 err += zc0301_write_reg(cam, 0x010E, 0x50);
101 err += zc0301_write_reg(cam, 0x010F, 0xF8);
102 err += zc0301_write_reg(cam, 0x0110, 0xF8);
103 err += zc0301_write_reg(cam, 0x0111, 0xF8);
104 err += zc0301_write_reg(cam, 0x0112, 0x50);
105 err += zc0301_write_reg(cam, 0x0180, 0x00);
106 err += zc0301_write_reg(cam, 0x0019, 0x00);
107
108 err += zc0301_i2c_write(cam, 0x05, 0x0066);
109 err += zc0301_i2c_write(cam, 0x09, 0x02B2);
110 err += zc0301_i2c_write(cam, 0x10, 0x0002);
111
112 err += zc0301_write_reg(cam, 0x011D, 0x60);
113 err += zc0301_write_reg(cam, 0x0190, 0x00);
114 err += zc0301_write_reg(cam, 0x0191, 0x07);
115 err += zc0301_write_reg(cam, 0x0192, 0x8C);
116 err += zc0301_write_reg(cam, 0x0195, 0x00);
117 err += zc0301_write_reg(cam, 0x0196, 0x00);
118 err += zc0301_write_reg(cam, 0x0197, 0x8A);
119 err += zc0301_write_reg(cam, 0x018C, 0x10);
120 err += zc0301_write_reg(cam, 0x018F, 0x20);
121 err += zc0301_write_reg(cam, 0x01A9, 0x14);
122 err += zc0301_write_reg(cam, 0x01AA, 0x24);
123 err += zc0301_write_reg(cam, 0x001D, 0xD7);
124 err += zc0301_write_reg(cam, 0x001E, 0xF0);
125 err += zc0301_write_reg(cam, 0x001F, 0xF8);
126 err += zc0301_write_reg(cam, 0x0020, 0xFF);
127 err += zc0301_write_reg(cam, 0x01AD, 0x09);
128 err += zc0301_write_reg(cam, 0x01AE, 0x15);
129 err += zc0301_write_reg(cam, 0x0180, 0x40);
130 err += zc0301_write_reg(cam, 0x0180, 0x42);
131
132 msleep(100);
133
134 return err;
135}
136
137
138static struct zc0301_sensor pb0330 = {
139 .name = "PB-0330",
140 .init = &pb0330_init,
141 .cropcap = {
142 .bounds = {
143 .left = 0,
144 .top = 0,
145 .width = 640,
146 .height = 480,
147 },
148 .defrect = {
149 .left = 0,
150 .top = 0,
151 .width = 640,
152 .height = 480,
153 },
154 },
155 .pix_format = {
156 .width = 640,
157 .height = 480,
158 .pixelformat = V4L2_PIX_FMT_JPEG,
159 .priv = 8,
160 },
161};
162
163
164int zc0301_probe_pb0330(struct zc0301_device* cam)
165{
166 int r0, err = 0;
167
168 err += zc0301_write_reg(cam, 0x0000, 0x01);
169 err += zc0301_write_reg(cam, 0x0010, 0x0a);
170 err += zc0301_write_reg(cam, 0x0001, 0x01);
171 err += zc0301_write_reg(cam, 0x0012, 0x03);
172 err += zc0301_write_reg(cam, 0x0012, 0x01);
173
174 msleep(10);
175
176 r0 = zc0301_i2c_read(cam, 0x00, 2);
177
178 if (r0 < 0 || err)
179 return -EIO;
180
181 if (r0 != 0x8243)
182 return -ENODEV;
183
184 zc0301_attach_sensor(cam, &pb0330);
185
186 return 0;
187}
diff --git a/drivers/media/video/zc0301/zc0301_sensor.h b/drivers/media/video/zc0301/zc0301_sensor.h
index 1f95c28b101..4363a915b1f 100644
--- a/drivers/media/video/zc0301/zc0301_sensor.h
+++ b/drivers/media/video/zc0301/zc0301_sensor.h
@@ -1,5 +1,5 @@
1/*************************************************************************** 1/***************************************************************************
2 * API for image sensors connected to the ZC030! Image Processor and * 2 * API for image sensors connected to the ZC0301 Image Processor and *
3 * Control Chip * 3 * Control Chip *
4 * * 4 * *
5 * Copyright (C) 2006 by Luca Risolia <luca.risolia@studio.unibo.it> * 5 * Copyright (C) 2006 by Luca Risolia <luca.risolia@studio.unibo.it> *
@@ -35,11 +35,13 @@ struct zc0301_sensor;
35/*****************************************************************************/ 35/*****************************************************************************/
36 36
37extern int zc0301_probe_pas202bcb(struct zc0301_device* cam); 37extern int zc0301_probe_pas202bcb(struct zc0301_device* cam);
38extern int zc0301_probe_pb0330(struct zc0301_device* cam);
38 39
39#define ZC0301_SENSOR_TABLE \ 40#define ZC0301_SENSOR_TABLE \
40/* Weak detections must go at the end of the list */ \ 41/* Weak detections must go at the end of the list */ \
41static int (*zc0301_sensor_table[])(struct zc0301_device*) = { \ 42static int (*zc0301_sensor_table[])(struct zc0301_device*) = { \
42 &zc0301_probe_pas202bcb, \ 43 &zc0301_probe_pas202bcb, \
44 &zc0301_probe_pb0330, \
43 NULL, \ 45 NULL, \
44}; 46};
45 47
@@ -58,14 +60,28 @@ zc0301_attach_sensor(struct zc0301_device* cam, struct zc0301_sensor* sensor);
58 60
59#define ZC0301_ID_TABLE \ 61#define ZC0301_ID_TABLE \
60static const struct usb_device_id zc0301_id_table[] = { \ 62static const struct usb_device_id zc0301_id_table[] = { \
61 { ZC0301_USB_DEVICE(0x041e, 0x4017, 0xff), }, \ 63 { ZC0301_USB_DEVICE(0x041e, 0x4017, 0xff), }, /* ICM105 */ \
62 { ZC0301_USB_DEVICE(0x041e, 0x401c, 0xff), }, /* PAS106 */ \ 64 { ZC0301_USB_DEVICE(0x041e, 0x401c, 0xff), }, /* PAS106 */ \
63 { ZC0301_USB_DEVICE(0x041e, 0x401e, 0xff), }, /* HV7131B */ \ 65 { ZC0301_USB_DEVICE(0x041e, 0x401e, 0xff), }, /* HV7131 */ \
66 { ZC0301_USB_DEVICE(0x041e, 0x401f, 0xff), }, /* TAS5130 */ \
67 { ZC0301_USB_DEVICE(0x041e, 0x4022, 0xff), }, \
64 { ZC0301_USB_DEVICE(0x041e, 0x4034, 0xff), }, /* PAS106 */ \ 68 { ZC0301_USB_DEVICE(0x041e, 0x4034, 0xff), }, /* PAS106 */ \
65 { ZC0301_USB_DEVICE(0x041e, 0x4035, 0xff), }, /* PAS106 */ \ 69 { ZC0301_USB_DEVICE(0x041e, 0x4035, 0xff), }, /* PAS106 */ \
66 { ZC0301_USB_DEVICE(0x046d, 0x08ae, 0xff), }, /* PAS202BCB */ \ 70 { ZC0301_USB_DEVICE(0x041e, 0x4036, 0xff), }, /* HV7131 */ \
71 { ZC0301_USB_DEVICE(0x041e, 0x403a, 0xff), }, /* HV7131 */ \
72 { ZC0301_USB_DEVICE(0x0458, 0x7007, 0xff), }, /* TAS5130 */ \
73 { ZC0301_USB_DEVICE(0x0458, 0x700C, 0xff), }, /* TAS5130 */ \
74 { ZC0301_USB_DEVICE(0x0458, 0x700f, 0xff), }, /* TAS5130 */ \
75 { ZC0301_USB_DEVICE(0x046d, 0x08ae, 0xff), }, /* PAS202 */ \
76 { ZC0301_USB_DEVICE(0x055f, 0xd003, 0xff), }, /* TAS5130 */ \
77 { ZC0301_USB_DEVICE(0x055f, 0xd004, 0xff), }, /* TAS5130 */ \
78 { ZC0301_USB_DEVICE(0x046d, 0x08ae, 0xff), }, /* PAS202 */ \
67 { ZC0301_USB_DEVICE(0x0ac8, 0x0301, 0xff), }, \ 79 { ZC0301_USB_DEVICE(0x0ac8, 0x0301, 0xff), }, \
68 { ZC0301_USB_DEVICE(0x10fd, 0x8050, 0xff), }, /* TAS5130D */ \ 80 { ZC0301_USB_DEVICE(0x0ac8, 0x301b, 0xff), }, /* PB-0330/HV7131 */ \
81 { ZC0301_USB_DEVICE(0x0ac8, 0x303b, 0xff), }, /* PB-0330 */ \
82 { ZC0301_USB_DEVICE(0x10fd, 0x0128, 0xff), }, /* TAS5130 */ \
83 { ZC0301_USB_DEVICE(0x10fd, 0x8050, 0xff), }, /* TAS5130 */ \
84 { ZC0301_USB_DEVICE(0x10fd, 0x804e, 0xff), }, /* TAS5130 */ \
69 { } \ 85 { } \
70}; 86};
71 87
diff --git a/drivers/media/video/zoran.h b/drivers/media/video/zoran.h
index 0166f555a5c..ffcda95ed9d 100644
--- a/drivers/media/video/zoran.h
+++ b/drivers/media/video/zoran.h
@@ -159,7 +159,7 @@ Private IOCTL to set up for displaying MJPEG
159#define BUZ_MAX_FRAME 256 /* Must be a power of 2 */ 159#define BUZ_MAX_FRAME 256 /* Must be a power of 2 */
160#define BUZ_MASK_FRAME 255 /* Must be BUZ_MAX_FRAME-1 */ 160#define BUZ_MASK_FRAME 255 /* Must be BUZ_MAX_FRAME-1 */
161 161
162#define BUZ_MAX_INPUT 8 162#define BUZ_MAX_INPUT 16
163 163
164#if VIDEO_MAX_FRAME <= 32 164#if VIDEO_MAX_FRAME <= 32
165# define V4L_MAX_FRAME 32 165# define V4L_MAX_FRAME 32
@@ -191,6 +191,9 @@ enum card_type {
191 /* Iomega */ 191 /* Iomega */
192 BUZ, 192 BUZ,
193 193
194 /* AverMedia */
195 AVS6EYES,
196
194 /* total number of cards */ 197 /* total number of cards */
195 NUM_CARDS 198 NUM_CARDS
196}; 199};
@@ -379,6 +382,9 @@ struct card_info {
379 /* is the /GWS line conected? */ 382 /* is the /GWS line conected? */
380 u8 gws_not_connected; 383 u8 gws_not_connected;
381 384
385 /* avs6eyes mux setting */
386 u8 input_mux;
387
382 void (*init) (struct zoran * zr); 388 void (*init) (struct zoran * zr);
383}; 389};
384 390
diff --git a/drivers/media/video/zoran_card.c b/drivers/media/video/zoran_card.c
index 0a85c9e7fb4..958c1e6fc85 100644
--- a/drivers/media/video/zoran_card.c
+++ b/drivers/media/video/zoran_card.c
@@ -27,6 +27,8 @@
27 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 27 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28 */ 28 */
29 29
30#include <linux/delay.h>
31
30#include <linux/config.h> 32#include <linux/config.h>
31#include <linux/types.h> 33#include <linux/types.h>
32#include <linux/kernel.h> 34#include <linux/kernel.h>
@@ -38,6 +40,7 @@
38#include <linux/i2c.h> 40#include <linux/i2c.h>
39#include <linux/i2c-algo-bit.h> 41#include <linux/i2c-algo-bit.h>
40#include <linux/videodev.h> 42#include <linux/videodev.h>
43#include <media/v4l2-common.h>
41#include <linux/spinlock.h> 44#include <linux/spinlock.h>
42#include <linux/sem.h> 45#include <linux/sem.h>
43#include <linux/kmod.h> 46#include <linux/kmod.h>
@@ -93,6 +96,11 @@ module_param(default_input, int, 0);
93MODULE_PARM_DESC(default_input, 96MODULE_PARM_DESC(default_input,
94 "Default input (0=Composite, 1=S-Video, 2=Internal)"); 97 "Default input (0=Composite, 1=S-Video, 2=Internal)");
95 98
99static int default_mux = 1; /* 6 Eyes input selection */
100module_param(default_mux, int, 0);
101MODULE_PARM_DESC(default_mux,
102 "Default 6 Eyes mux setting (Input selection)");
103
96static int default_norm = 0; /* 0=PAL, 1=NTSC 2=SECAM */ 104static int default_norm = 0; /* 0=PAL, 1=NTSC 2=SECAM */
97module_param(default_norm, int, 0); 105module_param(default_norm, int, 0);
98MODULE_PARM_DESC(default_norm, "Default norm (0=PAL, 1=NTSC, 2=SECAM)"); 106MODULE_PARM_DESC(default_norm, "Default norm (0=PAL, 1=NTSC, 2=SECAM)");
@@ -301,6 +309,30 @@ lml33_init (struct zoran *zr)
301 GPIO(zr, 2, 1); // Set Composite input/output 309 GPIO(zr, 2, 1); // Set Composite input/output
302} 310}
303 311
312static void
313avs6eyes_init (struct zoran *zr)
314{
315 // AverMedia 6-Eyes original driver by Christer Weinigel
316
317 // Lifted straight from Christer's old driver and
318 // modified slightly by Martin Samuelsson.
319
320 int mux = default_mux; /* 1 = BT866, 7 = VID1 */
321
322 GPIO(zr, 4, 1); /* Bt866 SLEEP on */
323 udelay(2);
324
325 GPIO(zr, 0, 1); /* ZR36060 /RESET on */
326 GPIO(zr, 1, 0); /* ZR36060 /SLEEP on */
327 GPIO(zr, 2, mux & 1); /* MUX S0 */
328 GPIO(zr, 3, 0); /* /FRAME on */
329 GPIO(zr, 4, 0); /* Bt866 SLEEP off */
330 GPIO(zr, 5, mux & 2); /* MUX S1 */
331 GPIO(zr, 6, 0); /* ? */
332 GPIO(zr, 7, mux & 4); /* MUX S2 */
333
334}
335
304static char * 336static char *
305i2cid_to_modulename (u16 i2c_id) 337i2cid_to_modulename (u16 i2c_id)
306{ 338{
@@ -391,6 +423,14 @@ static struct tvnorm f60sqpixel_dc10 = { 780, 640, 0, 716, 525, 480, 12 };
391static struct tvnorm f50ccir601_lm33r10 = { 864, 720, 74+54, 804, 625, 576, 18 }; 423static struct tvnorm f50ccir601_lm33r10 = { 864, 720, 74+54, 804, 625, 576, 18 };
392static struct tvnorm f60ccir601_lm33r10 = { 858, 720, 56+54, 788, 525, 480, 16 }; 424static struct tvnorm f60ccir601_lm33r10 = { 858, 720, 56+54, 788, 525, 480, 16 };
393 425
426/* FIXME: The ks0127 seem incapable of swapping U and V, too, which is why I
427 * copy Maxim's left shift hack for the 6 Eyes.
428 *
429 * Christer's driver used the unshifted norms, though...
430 * /Sam */
431static struct tvnorm f50ccir601_avs6eyes = { 864, 720, 74, 804, 625, 576, 18 };
432static struct tvnorm f60ccir601_avs6eyes = { 858, 720, 56, 788, 525, 480, 16 };
433
394static struct card_info zoran_cards[NUM_CARDS] __devinitdata = { 434static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
395 { 435 {
396 .type = DC10_old, 436 .type = DC10_old,
@@ -419,6 +459,7 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
419 .gpcs = { -1, 0 }, 459 .gpcs = { -1, 0 },
420 .vfe_pol = { 0, 0, 0, 0, 0, 0, 0, 0 }, 460 .vfe_pol = { 0, 0, 0, 0, 0, 0, 0, 0 },
421 .gws_not_connected = 0, 461 .gws_not_connected = 0,
462 .input_mux = 0,
422 .init = &dc10_init, 463 .init = &dc10_init,
423 }, { 464 }, {
424 .type = DC10_new, 465 .type = DC10_new,
@@ -445,6 +486,7 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
445 .gpcs = { -1, 1}, 486 .gpcs = { -1, 1},
446 .vfe_pol = { 1, 1, 1, 1, 0, 0, 0, 0 }, 487 .vfe_pol = { 1, 1, 1, 1, 0, 0, 0, 0 },
447 .gws_not_connected = 0, 488 .gws_not_connected = 0,
489 .input_mux = 0,
448 .init = &dc10plus_init, 490 .init = &dc10plus_init,
449 }, { 491 }, {
450 .type = DC10plus, 492 .type = DC10plus,
@@ -474,6 +516,7 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
474 .gpcs = { -1, 1 }, 516 .gpcs = { -1, 1 },
475 .vfe_pol = { 1, 1, 1, 1, 0, 0, 0, 0 }, 517 .vfe_pol = { 1, 1, 1, 1, 0, 0, 0, 0 },
476 .gws_not_connected = 0, 518 .gws_not_connected = 0,
519 .input_mux = 0,
477 .init = &dc10plus_init, 520 .init = &dc10plus_init,
478 }, { 521 }, {
479 .type = DC30, 522 .type = DC30,
@@ -502,6 +545,7 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
502 .gpcs = { -1, 0 }, 545 .gpcs = { -1, 0 },
503 .vfe_pol = { 0, 0, 0, 0, 0, 0, 0, 0 }, 546 .vfe_pol = { 0, 0, 0, 0, 0, 0, 0, 0 },
504 .gws_not_connected = 0, 547 .gws_not_connected = 0,
548 .input_mux = 0,
505 .init = &dc10_init, 549 .init = &dc10_init,
506 }, { 550 }, {
507 .type = DC30plus, 551 .type = DC30plus,
@@ -532,6 +576,7 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
532 .gpcs = { -1, 0 }, 576 .gpcs = { -1, 0 },
533 .vfe_pol = { 0, 0, 0, 0, 0, 0, 0, 0 }, 577 .vfe_pol = { 0, 0, 0, 0, 0, 0, 0, 0 },
534 .gws_not_connected = 0, 578 .gws_not_connected = 0,
579 .input_mux = 0,
535 .init = &dc10_init, 580 .init = &dc10_init,
536 }, { 581 }, {
537 .type = LML33, 582 .type = LML33,
@@ -558,6 +603,7 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
558 .gpcs = { 3, 1 }, 603 .gpcs = { 3, 1 },
559 .vfe_pol = { 1, 1, 0, 0, 0, 1, 0, 0 }, 604 .vfe_pol = { 1, 1, 0, 0, 0, 1, 0, 0 },
560 .gws_not_connected = 1, 605 .gws_not_connected = 1,
606 .input_mux = 0,
561 .init = &lml33_init, 607 .init = &lml33_init,
562 }, { 608 }, {
563 .type = LML33R10, 609 .type = LML33R10,
@@ -586,6 +632,7 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
586 .gpcs = { 3, 1 }, 632 .gpcs = { 3, 1 },
587 .vfe_pol = { 1, 1, 0, 0, 0, 1, 0, 0 }, 633 .vfe_pol = { 1, 1, 0, 0, 0, 1, 0, 0 },
588 .gws_not_connected = 1, 634 .gws_not_connected = 1,
635 .input_mux = 0,
589 .init = &lml33_init, 636 .init = &lml33_init,
590 }, { 637 }, {
591 .type = BUZ, 638 .type = BUZ,
@@ -614,8 +661,49 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
614 .gpcs = { 3, 1 }, 661 .gpcs = { 3, 1 },
615 .vfe_pol = { 1, 1, 0, 0, 0, 1, 0, 0 }, 662 .vfe_pol = { 1, 1, 0, 0, 0, 1, 0, 0 },
616 .gws_not_connected = 1, 663 .gws_not_connected = 1,
664 .input_mux = 0,
617 .init = &buz_init, 665 .init = &buz_init,
666 }, {
667 .type = AVS6EYES,
668 .name = "6-Eyes",
669 /* AverMedia chose not to brand the 6-Eyes. Thus it
670 can't be autodetected, and requires card=x. */
671 .vendor_id = -1,
672 .device_id = -1,
673 .i2c_decoder = I2C_DRIVERID_KS0127,
674 .i2c_encoder = I2C_DRIVERID_BT866,
675 .video_codec = CODEC_TYPE_ZR36060,
676
677 .inputs = 10,
678 .input = {
679 { 0, "Composite 1" },
680 { 1, "Composite 2" },
681 { 2, "Composite 3" },
682 { 4, "Composite 4" },
683 { 5, "Composite 5" },
684 { 6, "Composite 6" },
685 { 8, "S-Video 1" },
686 { 9, "S-Video 2" },
687 {10, "S-Video 3" },
688 {15, "YCbCr" }
689 },
690 .norms = 2,
691 .tvn = {
692 &f50ccir601_avs6eyes,
693 &f60ccir601_avs6eyes,
694 NULL
695 },
696 .jpeg_int = ZR36057_ISR_GIRQ1,
697 .vsync_int = ZR36057_ISR_GIRQ0,
698 .gpio = { 1, 0, 3, -1, -1, -1, -1, -1 },// Validity unknown /Sam
699 .gpio_pol = { 0, 0, 0, 0, 0, 0, 0, 0 }, // Validity unknown /Sam
700 .gpcs = { 3, 1 }, // Validity unknown /Sam
701 .vfe_pol = { 1, 0, 0, 0, 0, 1, 0, 0 }, // Validity unknown /Sam
702 .gws_not_connected = 1,
703 .input_mux = 1,
704 .init = &avs6eyes_init,
618 } 705 }
706
619}; 707};
620 708
621/* 709/*
diff --git a/drivers/media/video/zoran_device.c b/drivers/media/video/zoran_device.c
index c690b2ee880..02168d9c218 100644
--- a/drivers/media/video/zoran_device.c
+++ b/drivers/media/video/zoran_device.c
@@ -536,7 +536,7 @@ zr36057_overlay (struct zoran *zr,
536 * All error messages are internal driver checking only! */ 536 * All error messages are internal driver checking only! */
537 537
538 /* video display top and bottom registers */ 538 /* video display top and bottom registers */
539 reg = (u32) zr->buffer.base + 539 reg = (long) zr->buffer.base +
540 zr->overlay_settings.x * 540 zr->overlay_settings.x *
541 ((zr->overlay_settings.format->depth + 7) / 8) + 541 ((zr->overlay_settings.format->depth + 7) / 8) +
542 zr->overlay_settings.y * 542 zr->overlay_settings.y *
diff --git a/drivers/media/video/zoran_driver.c b/drivers/media/video/zoran_driver.c
index b5a576a37fd..9711f6248ef 100644
--- a/drivers/media/video/zoran_driver.c
+++ b/drivers/media/video/zoran_driver.c
@@ -73,6 +73,7 @@
73 ) 73 )
74 74
75#include <linux/videodev.h> 75#include <linux/videodev.h>
76#include <media/v4l2-common.h>
76#include "videocodec.h" 77#include "videocodec.h"
77 78
78#include <asm/io.h> 79#include <asm/io.h>
@@ -2047,7 +2048,7 @@ zoran_do_ioctl (struct inode *inode,
2047 dprintk(3, KERN_DEBUG "%s: VIDIOCGCAP\n", ZR_DEVNAME(zr)); 2048 dprintk(3, KERN_DEBUG "%s: VIDIOCGCAP\n", ZR_DEVNAME(zr));
2048 2049
2049 memset(vcap, 0, sizeof(struct video_capability)); 2050 memset(vcap, 0, sizeof(struct video_capability));
2050 strncpy(vcap->name, ZR_DEVNAME(zr), sizeof(vcap->name)); 2051 strncpy(vcap->name, ZR_DEVNAME(zr), sizeof(vcap->name)-1);
2051 vcap->type = ZORAN_VID_TYPE; 2052 vcap->type = ZORAN_VID_TYPE;
2052 2053
2053 vcap->channels = zr->card.inputs; 2054 vcap->channels = zr->card.inputs;
@@ -2689,8 +2690,8 @@ zoran_do_ioctl (struct inode *inode,
2689 dprintk(3, KERN_DEBUG "%s: VIDIOC_QUERYCAP\n", ZR_DEVNAME(zr)); 2690 dprintk(3, KERN_DEBUG "%s: VIDIOC_QUERYCAP\n", ZR_DEVNAME(zr));
2690 2691
2691 memset(cap, 0, sizeof(*cap)); 2692 memset(cap, 0, sizeof(*cap));
2692 strncpy(cap->card, ZR_DEVNAME(zr), sizeof(cap->card)); 2693 strncpy(cap->card, ZR_DEVNAME(zr), sizeof(cap->card)-1);
2693 strncpy(cap->driver, "zoran", sizeof(cap->driver)); 2694 strncpy(cap->driver, "zoran", sizeof(cap->driver)-1);
2694 snprintf(cap->bus_info, sizeof(cap->bus_info), "PCI:%s", 2695 snprintf(cap->bus_info, sizeof(cap->bus_info), "PCI:%s",
2695 pci_name(zr->pci_dev)); 2696 pci_name(zr->pci_dev));
2696 cap->version = 2697 cap->version =
@@ -2742,7 +2743,7 @@ zoran_do_ioctl (struct inode *inode,
2742 memset(fmt, 0, sizeof(*fmt)); 2743 memset(fmt, 0, sizeof(*fmt));
2743 fmt->index = index; 2744 fmt->index = index;
2744 fmt->type = type; 2745 fmt->type = type;
2745 strncpy(fmt->description, zoran_formats[i].name, 31); 2746 strncpy(fmt->description, zoran_formats[i].name, sizeof(fmt->description)-1);
2746 fmt->pixelformat = zoran_formats[i].fourcc; 2747 fmt->pixelformat = zoran_formats[i].fourcc;
2747 if (zoran_formats[i].flags & ZORAN_FORMAT_COMPRESSED) 2748 if (zoran_formats[i].flags & ZORAN_FORMAT_COMPRESSED)
2748 fmt->flags |= V4L2_FMT_FLAG_COMPRESSED; 2749 fmt->flags |= V4L2_FMT_FLAG_COMPRESSED;
@@ -3566,16 +3567,16 @@ zoran_do_ioctl (struct inode *inode,
3566 3567
3567 switch (ctrl->id) { 3568 switch (ctrl->id) {
3568 case V4L2_CID_BRIGHTNESS: 3569 case V4L2_CID_BRIGHTNESS:
3569 strncpy(ctrl->name, "Brightness", 31); 3570 strncpy(ctrl->name, "Brightness", sizeof(ctrl->name)-1);
3570 break; 3571 break;
3571 case V4L2_CID_CONTRAST: 3572 case V4L2_CID_CONTRAST:
3572 strncpy(ctrl->name, "Contrast", 31); 3573 strncpy(ctrl->name, "Contrast", sizeof(ctrl->name)-1);
3573 break; 3574 break;
3574 case V4L2_CID_SATURATION: 3575 case V4L2_CID_SATURATION:
3575 strncpy(ctrl->name, "Saturation", 31); 3576 strncpy(ctrl->name, "Saturation", sizeof(ctrl->name)-1);
3576 break; 3577 break;
3577 case V4L2_CID_HUE: 3578 case V4L2_CID_HUE:
3578 strncpy(ctrl->name, "Hue", 31); 3579 strncpy(ctrl->name, "Hue", sizeof(ctrl->name)-1);
3579 break; 3580 break;
3580 } 3581 }
3581 3582
@@ -3693,7 +3694,7 @@ zoran_do_ioctl (struct inode *inode,
3693 &caps); 3694 &caps);
3694 if (caps.flags & VIDEO_DECODER_AUTO) { 3695 if (caps.flags & VIDEO_DECODER_AUTO) {
3695 std->id = V4L2_STD_ALL; 3696 std->id = V4L2_STD_ALL;
3696 strncpy(std->name, "Autodetect", 31); 3697 strncpy(std->name, "Autodetect", sizeof(std->name)-1);
3697 return 0; 3698 return 0;
3698 } else 3699 } else
3699 return -EINVAL; 3700 return -EINVAL;
@@ -3701,21 +3702,21 @@ zoran_do_ioctl (struct inode *inode,
3701 switch (std->index) { 3702 switch (std->index) {
3702 case 0: 3703 case 0:
3703 std->id = V4L2_STD_PAL; 3704 std->id = V4L2_STD_PAL;
3704 strncpy(std->name, "PAL", 31); 3705 strncpy(std->name, "PAL", sizeof(std->name)-1);
3705 std->frameperiod.numerator = 1; 3706 std->frameperiod.numerator = 1;
3706 std->frameperiod.denominator = 25; 3707 std->frameperiod.denominator = 25;
3707 std->framelines = zr->card.tvn[0]->Ht; 3708 std->framelines = zr->card.tvn[0]->Ht;
3708 break; 3709 break;
3709 case 1: 3710 case 1:
3710 std->id = V4L2_STD_NTSC; 3711 std->id = V4L2_STD_NTSC;
3711 strncpy(std->name, "NTSC", 31); 3712 strncpy(std->name, "NTSC", sizeof(std->name)-1);
3712 std->frameperiod.numerator = 1001; 3713 std->frameperiod.numerator = 1001;
3713 std->frameperiod.denominator = 30000; 3714 std->frameperiod.denominator = 30000;
3714 std->framelines = zr->card.tvn[1]->Ht; 3715 std->framelines = zr->card.tvn[1]->Ht;
3715 break; 3716 break;
3716 case 2: 3717 case 2:
3717 std->id = V4L2_STD_SECAM; 3718 std->id = V4L2_STD_SECAM;
3718 strncpy(std->name, "SECAM", 31); 3719 strncpy(std->name, "SECAM", sizeof(std->name)-1);
3719 std->frameperiod.numerator = 1; 3720 std->frameperiod.numerator = 1;
3720 std->frameperiod.denominator = 25; 3721 std->frameperiod.denominator = 25;
3721 std->framelines = zr->card.tvn[2]->Ht; 3722 std->framelines = zr->card.tvn[2]->Ht;
@@ -3871,7 +3872,7 @@ zoran_do_ioctl (struct inode *inode,
3871 memset(outp, 0, sizeof(*outp)); 3872 memset(outp, 0, sizeof(*outp));
3872 outp->index = 0; 3873 outp->index = 0;
3873 outp->type = V4L2_OUTPUT_TYPE_ANALOGVGAOVERLAY; 3874 outp->type = V4L2_OUTPUT_TYPE_ANALOGVGAOVERLAY;
3874 strncpy(outp->name, "Autodetect", 31); 3875 strncpy(outp->name, "Autodetect", sizeof(outp->name)-1);
3875 3876
3876 return 0; 3877 return 0;
3877 } 3878 }
diff --git a/drivers/media/video/zoran_procfs.c b/drivers/media/video/zoran_procfs.c
index a00fae90229..f4ffe79bdc5 100644
--- a/drivers/media/video/zoran_procfs.c
+++ b/drivers/media/video/zoran_procfs.c
@@ -43,6 +43,7 @@
43#include <linux/seq_file.h> 43#include <linux/seq_file.h>
44 44
45#include <linux/ctype.h> 45#include <linux/ctype.h>
46#include <linux/poll.h>
46#include <asm/io.h> 47#include <asm/io.h>
47 48
48#include "videocodec.h" 49#include "videocodec.h"