aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
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
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')
-rw-r--r--drivers/media/Kconfig7
-rw-r--r--drivers/media/common/Makefile2
-rw-r--r--drivers/media/common/ir-functions.c1
-rw-r--r--drivers/media/common/ir-keymaps.c82
-rw-r--r--drivers/media/common/saa7146_fops.c4
-rw-r--r--drivers/media/common/saa7146_hlp.c1
-rw-r--r--drivers/media/common/saa7146_video.c2
-rw-r--r--drivers/media/common/saa7146_vv_ksyms.c12
-rw-r--r--drivers/media/dvb/b2c2/flexcop-fe-tuner.c122
-rw-r--r--drivers/media/dvb/b2c2/flexcop-pci.c19
-rw-r--r--drivers/media/dvb/b2c2/flexcop-usb.c10
-rw-r--r--drivers/media/dvb/b2c2/flexcop.c12
-rw-r--r--drivers/media/dvb/bt8xx/bt878.c11
-rw-r--r--drivers/media/dvb/bt8xx/dst.c606
-rw-r--r--drivers/media/dvb/bt8xx/dst_ca.c116
-rw-r--r--drivers/media/dvb/bt8xx/dst_common.h33
-rw-r--r--drivers/media/dvb/bt8xx/dvb-bt8xx.c118
-rw-r--r--drivers/media/dvb/bt8xx/dvb-bt8xx.h2
-rw-r--r--drivers/media/dvb/cinergyT2/Kconfig2
-rw-r--r--drivers/media/dvb/cinergyT2/cinergyT2.c8
-rw-r--r--drivers/media/dvb/dvb-core/Makefile6
-rw-r--r--drivers/media/dvb/dvb-core/dmxdev.c3
-rw-r--r--drivers/media/dvb/dvb-core/dvb_ca_en50221.c25
-rw-r--r--drivers/media/dvb/dvb-core/dvb_demux.c4
-rw-r--r--drivers/media/dvb/dvb-core/dvb_frontend.c151
-rw-r--r--drivers/media/dvb/dvb-core/dvb_frontend.h45
-rw-r--r--drivers/media/dvb/dvb-core/dvb_math.c145
-rw-r--r--drivers/media/dvb/dvb-core/dvb_math.h58
-rw-r--r--drivers/media/dvb/dvb-core/dvb_net.c230
-rw-r--r--drivers/media/dvb/dvb-core/dvbdev.c5
-rw-r--r--drivers/media/dvb/dvb-core/dvbdev.h4
-rw-r--r--drivers/media/dvb/dvb-usb/Kconfig10
-rw-r--r--drivers/media/dvb/dvb-usb/Makefile3
-rw-r--r--drivers/media/dvb/dvb-usb/cxusb.c48
-rw-r--r--drivers/media/dvb/dvb-usb/dibusb-common.c9
-rw-r--r--drivers/media/dvb/dvb-usb/dibusb-mb.c7
-rw-r--r--drivers/media/dvb/dvb-usb/digitv.c15
-rw-r--r--drivers/media/dvb/dvb-usb/dtt200u-fe.c8
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-dvb.c17
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-i2c.c24
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-ids.h4
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb.h6
-rw-r--r--drivers/media/dvb/dvb-usb/gp8psk-fe.c272
-rw-r--r--drivers/media/dvb/dvb-usb/gp8psk.c256
-rw-r--r--drivers/media/dvb/dvb-usb/gp8psk.h79
-rw-r--r--drivers/media/dvb/dvb-usb/umt-010.c2
-rw-r--r--drivers/media/dvb/dvb-usb/vp702x-fe.c7
-rw-r--r--drivers/media/dvb/dvb-usb/vp7045-fe.c9
-rw-r--r--drivers/media/dvb/frontends/Kconfig18
-rw-r--r--drivers/media/dvb/frontends/Makefile2
-rw-r--r--drivers/media/dvb/frontends/bcm3510.c4
-rw-r--r--drivers/media/dvb/frontends/bsbe1.h6
-rw-r--r--drivers/media/dvb/frontends/bsru6.h6
-rw-r--r--drivers/media/dvb/frontends/cx22700.c31
-rw-r--r--drivers/media/dvb/frontends/cx22700.h4
-rw-r--r--drivers/media/dvb/frontends/cx22702.c29
-rw-r--r--drivers/media/dvb/frontends/cx22702.h7
-rw-r--r--drivers/media/dvb/frontends/cx24110.c26
-rw-r--r--drivers/media/dvb/frontends/cx24110.h5
-rw-r--r--drivers/media/dvb/frontends/cx24123.c195
-rw-r--r--drivers/media/dvb/frontends/cx24123.h13
-rw-r--r--drivers/media/dvb/frontends/dib3000-common.h2
-rw-r--r--drivers/media/dvb/frontends/dib3000.h4
-rw-r--r--drivers/media/dvb/frontends/dib3000mb.c11
-rw-r--r--drivers/media/dvb/frontends/dib3000mc.c14
-rw-r--r--drivers/media/dvb/frontends/dvb-pll.c181
-rw-r--r--drivers/media/dvb/frontends/dvb-pll.h18
-rw-r--r--drivers/media/dvb/frontends/dvb_dummy_fe.c21
-rw-r--r--drivers/media/dvb/frontends/isl6421.c149
-rw-r--r--drivers/media/dvb/frontends/isl6421.h46
-rw-r--r--drivers/media/dvb/frontends/l64781.c11
-rw-r--r--drivers/media/dvb/frontends/l64781.h4
-rw-r--r--drivers/media/dvb/frontends/lg_h06xf.h64
-rw-r--r--drivers/media/dvb/frontends/lgdt330x.c19
-rw-r--r--drivers/media/dvb/frontends/lgdt330x.h1
-rw-r--r--drivers/media/dvb/frontends/lnbp21.c145
-rw-r--r--drivers/media/dvb/frontends/lnbp21.h102
-rw-r--r--drivers/media/dvb/frontends/mt312.c46
-rw-r--r--drivers/media/dvb/frontends/mt312.h4
-rw-r--r--drivers/media/dvb/frontends/mt352.c23
-rw-r--r--drivers/media/dvb/frontends/mt352.h6
-rw-r--r--drivers/media/dvb/frontends/nxt200x.c20
-rw-r--r--drivers/media/dvb/frontends/nxt200x.h4
-rw-r--r--drivers/media/dvb/frontends/nxt6000.c29
-rw-r--r--drivers/media/dvb/frontends/nxt6000.h4
-rw-r--r--drivers/media/dvb/frontends/or51132.c157
-rw-r--r--drivers/media/dvb/frontends/or51132.h2
-rw-r--r--drivers/media/dvb/frontends/or51211.c4
-rw-r--r--drivers/media/dvb/frontends/s5h1420.c43
-rw-r--r--drivers/media/dvb/frontends/s5h1420.h4
-rw-r--r--drivers/media/dvb/frontends/sp8870.c31
-rw-r--r--drivers/media/dvb/frontends/sp8870.h4
-rw-r--r--drivers/media/dvb/frontends/sp887x.c38
-rw-r--r--drivers/media/dvb/frontends/sp887x.h6
-rw-r--r--drivers/media/dvb/frontends/stv0297.c73
-rw-r--r--drivers/media/dvb/frontends/stv0297.h6
-rw-r--r--drivers/media/dvb/frontends/stv0299.c41
-rw-r--r--drivers/media/dvb/frontends/stv0299.h5
-rw-r--r--drivers/media/dvb/frontends/tda10021.c39
-rw-r--r--drivers/media/dvb/frontends/tda10021.h6
-rw-r--r--drivers/media/dvb/frontends/tda1004x.c55
-rw-r--r--drivers/media/dvb/frontends/tda1004x.h5
-rw-r--r--drivers/media/dvb/frontends/tda8083.c12
-rw-r--r--drivers/media/dvb/frontends/tda8083.h4
-rw-r--r--drivers/media/dvb/frontends/ves1820.c19
-rw-r--r--drivers/media/dvb/frontends/ves1820.h4
-rw-r--r--drivers/media/dvb/frontends/ves1x93.c29
-rw-r--r--drivers/media/dvb/frontends/ves1x93.h4
-rw-r--r--drivers/media/dvb/frontends/zl10353.c30
-rw-r--r--drivers/media/dvb/frontends/zl10353.h6
-rw-r--r--drivers/media/dvb/pluto2/pluto2.c15
-rw-r--r--drivers/media/dvb/ttpci/Kconfig3
-rw-r--r--drivers/media/dvb/ttpci/Makefile6
-rw-r--r--drivers/media/dvb/ttpci/av7110.c135
-rw-r--r--drivers/media/dvb/ttpci/budget-av.c283
-rw-r--r--drivers/media/dvb/ttpci/budget-ci.c59
-rw-r--r--drivers/media/dvb/ttpci/budget-core.c4
-rw-r--r--drivers/media/dvb/ttpci/budget-patch.c43
-rw-r--r--drivers/media/dvb/ttpci/budget.c69
-rw-r--r--drivers/media/dvb/ttusb-budget/Kconfig2
-rw-r--r--drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c264
-rw-r--r--drivers/media/dvb/ttusb-dec/ttusb_dec.c6
-rw-r--r--drivers/media/dvb/ttusb-dec/ttusbdecfe.c8
-rw-r--r--drivers/media/radio/Kconfig2
-rw-r--r--drivers/media/radio/Makefile2
-rw-r--r--drivers/media/radio/miropcm20-radio.c17
-rw-r--r--drivers/media/radio/miropcm20-rds-core.c34
-rw-r--r--drivers/media/radio/miropcm20-rds.c2
-rw-r--r--drivers/media/radio/radio-aimslab.c51
-rw-r--r--drivers/media/radio/radio-aztech.c45
-rw-r--r--drivers/media/radio/radio-cadet.c317
-rw-r--r--drivers/media/radio/radio-gemtek-pci.c47
-rw-r--r--drivers/media/radio/radio-gemtek.c33
-rw-r--r--drivers/media/radio/radio-maestro.c10
-rw-r--r--drivers/media/radio/radio-maxiradio.c81
-rw-r--r--drivers/media/radio/radio-rtrack2.c35
-rw-r--r--drivers/media/radio/radio-sf16fmi.c41
-rw-r--r--drivers/media/radio/radio-sf16fmr2.c5
-rw-r--r--drivers/media/radio/radio-terratec.c63
-rw-r--r--drivers/media/radio/radio-trust.c27
-rw-r--r--drivers/media/radio/radio-typhoon.c5
-rw-r--r--drivers/media/radio/radio-zoltrix.c31
-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
-rw-r--r--drivers/video/matrox/matroxfb_base.c52
263 files changed, 17515 insertions, 5750 deletions
diff --git a/drivers/media/Kconfig b/drivers/media/Kconfig
index 344d83aae3ec..583d151b7486 100644
--- a/drivers/media/Kconfig
+++ b/drivers/media/Kconfig
@@ -25,7 +25,7 @@ config VIDEO_DEV
25 module will be called videodev. 25 module will be called videodev.
26 26
27config VIDEO_V4L1 27config VIDEO_V4L1
28 boolean "Enable Video For Linux API 1 (DEPRECATED)" 28 bool "Enable Video For Linux API 1 (DEPRECATED)"
29 depends on VIDEO_DEV 29 depends on VIDEO_DEV
30 select VIDEO_V4L1_COMPAT 30 select VIDEO_V4L1_COMPAT
31 default y 31 default y
@@ -36,7 +36,7 @@ config VIDEO_V4L1
36 If you are unsure as to whether this is required, answer Y. 36 If you are unsure as to whether this is required, answer Y.
37 37
38config VIDEO_V4L1_COMPAT 38config VIDEO_V4L1_COMPAT
39 boolean "Enable Video For Linux API 1 compatible Layer" 39 bool "Enable Video For Linux API 1 compatible Layer"
40 depends on VIDEO_DEV 40 depends on VIDEO_DEV
41 default y 41 default y
42 ---help--- 42 ---help---
@@ -82,6 +82,9 @@ config VIDEO_IR
82config VIDEO_TVEEPROM 82config VIDEO_TVEEPROM
83 tristate 83 tristate
84 84
85config VIDEO_CX2341X
86 tristate
87
85config USB_DABUSB 88config USB_DABUSB
86 tristate "DABUSB driver" 89 tristate "DABUSB driver"
87 depends on USB 90 depends on USB
diff --git a/drivers/media/common/Makefile b/drivers/media/common/Makefile
index 61b89617a967..8e7448230643 100644
--- a/drivers/media/common/Makefile
+++ b/drivers/media/common/Makefile
@@ -1,5 +1,5 @@
1saa7146-objs := saa7146_i2c.o saa7146_core.o 1saa7146-objs := saa7146_i2c.o saa7146_core.o
2saa7146_vv-objs := saa7146_vv_ksyms.o saa7146_fops.o saa7146_video.o saa7146_hlp.o saa7146_vbi.o 2saa7146_vv-objs := saa7146_fops.o saa7146_video.o saa7146_hlp.o saa7146_vbi.o
3ir-common-objs := ir-functions.o ir-keymaps.o 3ir-common-objs := ir-functions.o ir-keymaps.o
4 4
5obj-$(CONFIG_VIDEO_SAA7146) += saa7146.o 5obj-$(CONFIG_VIDEO_SAA7146) += saa7146.o
diff --git a/drivers/media/common/ir-functions.c b/drivers/media/common/ir-functions.c
index 397cff8b345b..8eaa88fd8b9b 100644
--- a/drivers/media/common/ir-functions.c
+++ b/drivers/media/common/ir-functions.c
@@ -269,4 +269,3 @@ EXPORT_SYMBOL_GPL(ir_decode_pulsedistance);
269 * c-basic-offset: 8 269 * c-basic-offset: 8
270 * End: 270 * End:
271 */ 271 */
272
diff --git a/drivers/media/common/ir-keymaps.c b/drivers/media/common/ir-keymaps.c
index a294d5c2c73f..ca98d9478947 100644
--- a/drivers/media/common/ir-keymaps.c
+++ b/drivers/media/common/ir-keymaps.c
@@ -618,7 +618,7 @@ IR_KEYTAB_TYPE ir_codes_em_terratec[IR_KEYTAB_SIZE] = {
618 618
619EXPORT_SYMBOL_GPL(ir_codes_em_terratec); 619EXPORT_SYMBOL_GPL(ir_codes_em_terratec);
620 620
621IR_KEYTAB_TYPE ir_codes_em_pinnacle_usb[IR_KEYTAB_SIZE] = { 621IR_KEYTAB_TYPE ir_codes_pinnacle_grey[IR_KEYTAB_SIZE] = {
622 [ 0x3a ] = KEY_0, 622 [ 0x3a ] = KEY_0,
623 [ 0x31 ] = KEY_1, 623 [ 0x31 ] = KEY_1,
624 [ 0x32 ] = KEY_2, 624 [ 0x32 ] = KEY_2,
@@ -670,7 +670,7 @@ IR_KEYTAB_TYPE ir_codes_em_pinnacle_usb[IR_KEYTAB_SIZE] = {
670 [ 0x27 ] = KEY_RECORD, 670 [ 0x27 ] = KEY_RECORD,
671}; 671};
672 672
673EXPORT_SYMBOL_GPL(ir_codes_em_pinnacle_usb); 673EXPORT_SYMBOL_GPL(ir_codes_pinnacle_grey);
674 674
675IR_KEYTAB_TYPE ir_codes_flyvideo[IR_KEYTAB_SIZE] = { 675IR_KEYTAB_TYPE ir_codes_flyvideo[IR_KEYTAB_SIZE] = {
676 [ 0x0f ] = KEY_0, 676 [ 0x0f ] = KEY_0,
@@ -1263,34 +1263,51 @@ IR_KEYTAB_TYPE ir_codes_winfast[IR_KEYTAB_SIZE] = {
1263 [ 0x0f ] = KEY_9, 1263 [ 0x0f ] = KEY_9,
1264 1264
1265 [ 0x00 ] = KEY_POWER, 1265 [ 0x00 ] = KEY_POWER,
1266 [ 0x02 ] = KEY_TUNER, /* TV/FM */ 1266 [ 0x1b ] = KEY_AUDIO, /* Audio Source */
1267 [ 0x1e ] = KEY_VIDEO, 1267 [ 0x02 ] = KEY_TUNER, /* TV/FM, not on Y0400052 */
1268 [ 0x1e ] = KEY_VIDEO, /* Video Source */
1269 [ 0x16 ] = KEY_INFO, /* Display information */
1268 [ 0x04 ] = KEY_VOLUMEUP, 1270 [ 0x04 ] = KEY_VOLUMEUP,
1269 [ 0x08 ] = KEY_VOLUMEDOWN, 1271 [ 0x08 ] = KEY_VOLUMEDOWN,
1270 [ 0x0c ] = KEY_CHANNELUP, 1272 [ 0x0c ] = KEY_CHANNELUP,
1271 [ 0x10 ] = KEY_CHANNELDOWN, 1273 [ 0x10 ] = KEY_CHANNELDOWN,
1272 [ 0x03 ] = KEY_ZOOM, /* fullscreen */ 1274 [ 0x03 ] = KEY_ZOOM, /* fullscreen */
1273 [ 0x1f ] = KEY_SUBTITLE, /* closed caption/teletext */ 1275 [ 0x1f ] = KEY_TEXT, /* closed caption/teletext */
1274 [ 0x20 ] = KEY_SLEEP, 1276 [ 0x20 ] = KEY_SLEEP,
1277 [ 0x29 ] = KEY_CLEAR, /* boss key */
1275 [ 0x14 ] = KEY_MUTE, 1278 [ 0x14 ] = KEY_MUTE,
1276 [ 0x2b ] = KEY_RED, 1279 [ 0x2b ] = KEY_RED,
1277 [ 0x2c ] = KEY_GREEN, 1280 [ 0x2c ] = KEY_GREEN,
1278 [ 0x2d ] = KEY_YELLOW, 1281 [ 0x2d ] = KEY_YELLOW,
1279 [ 0x2e ] = KEY_BLUE, 1282 [ 0x2e ] = KEY_BLUE,
1280 [ 0x18 ] = KEY_KPPLUS, /* fine tune + */ 1283 [ 0x18 ] = KEY_KPPLUS, /* fine tune + , not on Y040052 */
1281 [ 0x19 ] = KEY_KPMINUS, /* fine tune - */ 1284 [ 0x19 ] = KEY_KPMINUS, /* fine tune - , not on Y040052 */
1285 [ 0x2a ] = KEY_MEDIA, /* PIP (Picture in picture */
1282 [ 0x21 ] = KEY_DOT, 1286 [ 0x21 ] = KEY_DOT,
1283 [ 0x13 ] = KEY_ENTER, 1287 [ 0x13 ] = KEY_ENTER,
1284 [ 0x22 ] = KEY_BACK, 1288 [ 0x11 ] = KEY_LAST, /* Recall (last channel */
1289 [ 0x22 ] = KEY_PREVIOUS,
1285 [ 0x23 ] = KEY_PLAYPAUSE, 1290 [ 0x23 ] = KEY_PLAYPAUSE,
1286 [ 0x24 ] = KEY_NEXT, 1291 [ 0x24 ] = KEY_NEXT,
1292 [ 0x25 ] = KEY_ARCHIVE, /* Time Shifting */
1287 [ 0x26 ] = KEY_STOP, 1293 [ 0x26 ] = KEY_STOP,
1288 [ 0x27 ] = KEY_RECORD 1294 [ 0x27 ] = KEY_RECORD,
1295 [ 0x28 ] = KEY_SAVE, /* Screenshot */
1296 [ 0x2f ] = KEY_MENU,
1297 [ 0x30 ] = KEY_CANCEL,
1298 [ 0x31 ] = KEY_CHANNEL, /* Channel Surf */
1299 [ 0x32 ] = KEY_SUBTITLE,
1300 [ 0x33 ] = KEY_LANGUAGE,
1301 [ 0x34 ] = KEY_REWIND,
1302 [ 0x35 ] = KEY_FASTFORWARD,
1303 [ 0x36 ] = KEY_TV,
1304 [ 0x37 ] = KEY_RADIO, /* FM */
1305 [ 0x38 ] = KEY_DVD
1289}; 1306};
1290 1307
1291EXPORT_SYMBOL_GPL(ir_codes_winfast); 1308EXPORT_SYMBOL_GPL(ir_codes_winfast);
1292 1309
1293IR_KEYTAB_TYPE ir_codes_pinnacle[IR_KEYTAB_SIZE] = { 1310IR_KEYTAB_TYPE ir_codes_pinnacle_color[IR_KEYTAB_SIZE] = {
1294 [ 0x59 ] = KEY_MUTE, 1311 [ 0x59 ] = KEY_MUTE,
1295 [ 0x4a ] = KEY_POWER, 1312 [ 0x4a ] = KEY_POWER,
1296 1313
@@ -1348,7 +1365,7 @@ IR_KEYTAB_TYPE ir_codes_pinnacle[IR_KEYTAB_SIZE] = {
1348 [ 0x0a ] = KEY_BACKSPACE, 1365 [ 0x0a ] = KEY_BACKSPACE,
1349}; 1366};
1350 1367
1351EXPORT_SYMBOL_GPL(ir_codes_pinnacle); 1368EXPORT_SYMBOL_GPL(ir_codes_pinnacle_color);
1352 1369
1353/* Hauppauge: the newer, gray remotes (seems there are multiple 1370/* Hauppauge: the newer, gray remotes (seems there are multiple
1354 * slightly different versions), shipped with cx88+ivtv cards. 1371 * slightly different versions), shipped with cx88+ivtv cards.
@@ -1413,3 +1430,46 @@ IR_KEYTAB_TYPE ir_codes_hauppauge_new[IR_KEYTAB_SIZE] = {
1413 1430
1414EXPORT_SYMBOL_GPL(ir_codes_hauppauge_new); 1431EXPORT_SYMBOL_GPL(ir_codes_hauppauge_new);
1415 1432
1433IR_KEYTAB_TYPE ir_codes_npgtech[IR_KEYTAB_SIZE] = {
1434 [ 0x1d ] = KEY_SWITCHVIDEOMODE, /* switch inputs */
1435 [ 0x2a ] = KEY_FRONT,
1436
1437 [ 0x3e ] = KEY_1,
1438 [ 0x02 ] = KEY_2,
1439 [ 0x06 ] = KEY_3,
1440 [ 0x0a ] = KEY_4,
1441 [ 0x0e ] = KEY_5,
1442 [ 0x12 ] = KEY_6,
1443 [ 0x16 ] = KEY_7,
1444 [ 0x1a ] = KEY_8,
1445 [ 0x1e ] = KEY_9,
1446 [ 0x3a ] = KEY_0,
1447 [ 0x22 ] = KEY_NUMLOCK, /* -/-- */
1448 [ 0x20 ] = KEY_REFRESH,
1449
1450 [ 0x03 ] = KEY_BRIGHTNESSDOWN,
1451 [ 0x28 ] = KEY_AUDIO,
1452 [ 0x3c ] = KEY_UP,
1453 [ 0x3f ] = KEY_LEFT,
1454 [ 0x2e ] = KEY_MUTE,
1455 [ 0x3b ] = KEY_RIGHT,
1456 [ 0x00 ] = KEY_DOWN,
1457 [ 0x07 ] = KEY_BRIGHTNESSUP,
1458 [ 0x2c ] = KEY_TEXT,
1459
1460 [ 0x37 ] = KEY_RECORD,
1461 [ 0x17 ] = KEY_PLAY,
1462 [ 0x13 ] = KEY_PAUSE,
1463 [ 0x26 ] = KEY_STOP,
1464 [ 0x18 ] = KEY_FASTFORWARD,
1465 [ 0x14 ] = KEY_REWIND,
1466 [ 0x33 ] = KEY_ZOOM,
1467 [ 0x32 ] = KEY_KEYBOARD,
1468 [ 0x30 ] = KEY_GOTO, /* Pointing arrow */
1469 [ 0x36 ] = KEY_MACRO, /* Maximize/Minimize (yellow) */
1470 [ 0x0b ] = KEY_RADIO,
1471 [ 0x10 ] = KEY_POWER,
1472
1473};
1474
1475EXPORT_SYMBOL_GPL(ir_codes_npgtech);
diff --git a/drivers/media/common/saa7146_fops.c b/drivers/media/common/saa7146_fops.c
index 523ab3851c7b..0027acc5b8e9 100644
--- a/drivers/media/common/saa7146_fops.c
+++ b/drivers/media/common/saa7146_fops.c
@@ -501,6 +501,7 @@ int saa7146_vv_init(struct saa7146_dev* dev, struct saa7146_ext_vv *ext_vv)
501 501
502 return 0; 502 return 0;
503} 503}
504EXPORT_SYMBOL_GPL(saa7146_vv_init);
504 505
505int saa7146_vv_release(struct saa7146_dev* dev) 506int saa7146_vv_release(struct saa7146_dev* dev)
506{ 507{
@@ -515,6 +516,7 @@ int saa7146_vv_release(struct saa7146_dev* dev)
515 516
516 return 0; 517 return 0;
517} 518}
519EXPORT_SYMBOL_GPL(saa7146_vv_release);
518 520
519int saa7146_register_device(struct video_device **vid, struct saa7146_dev* dev, 521int saa7146_register_device(struct video_device **vid, struct saa7146_dev* dev,
520 char *name, int type) 522 char *name, int type)
@@ -553,6 +555,7 @@ int saa7146_register_device(struct video_device **vid, struct saa7146_dev* dev,
553 *vid = vfd; 555 *vid = vfd;
554 return 0; 556 return 0;
555} 557}
558EXPORT_SYMBOL_GPL(saa7146_register_device);
556 559
557int saa7146_unregister_device(struct video_device **vid, struct saa7146_dev* dev) 560int saa7146_unregister_device(struct video_device **vid, struct saa7146_dev* dev)
558{ 561{
@@ -571,6 +574,7 @@ int saa7146_unregister_device(struct video_device **vid, struct saa7146_dev* dev
571 574
572 return 0; 575 return 0;
573} 576}
577EXPORT_SYMBOL_GPL(saa7146_unregister_device);
574 578
575static int __init saa7146_vv_init_module(void) 579static int __init saa7146_vv_init_module(void)
576{ 580{
diff --git a/drivers/media/common/saa7146_hlp.c b/drivers/media/common/saa7146_hlp.c
index 33bec8a6843b..2092e6c33dd2 100644
--- a/drivers/media/common/saa7146_hlp.c
+++ b/drivers/media/common/saa7146_hlp.c
@@ -641,6 +641,7 @@ void saa7146_set_hps_source_and_sync(struct saa7146_dev *dev, int source, int sy
641 vv->current_hps_source = source; 641 vv->current_hps_source = source;
642 vv->current_hps_sync = sync; 642 vv->current_hps_sync = sync;
643} 643}
644EXPORT_SYMBOL_GPL(saa7146_set_hps_source_and_sync);
644 645
645int saa7146_enable_overlay(struct saa7146_fh *fh) 646int saa7146_enable_overlay(struct saa7146_fh *fh)
646{ 647{
diff --git a/drivers/media/common/saa7146_video.c b/drivers/media/common/saa7146_video.c
index e7079d1bd537..8393d472d3b8 100644
--- a/drivers/media/common/saa7146_video.c
+++ b/drivers/media/common/saa7146_video.c
@@ -318,6 +318,7 @@ int saa7146_start_preview(struct saa7146_fh *fh)
318 318
319 return 0; 319 return 0;
320} 320}
321EXPORT_SYMBOL_GPL(saa7146_start_preview);
321 322
322int saa7146_stop_preview(struct saa7146_fh *fh) 323int saa7146_stop_preview(struct saa7146_fh *fh)
323{ 324{
@@ -352,6 +353,7 @@ int saa7146_stop_preview(struct saa7146_fh *fh)
352 353
353 return 0; 354 return 0;
354} 355}
356EXPORT_SYMBOL_GPL(saa7146_stop_preview);
355 357
356static int s_fmt(struct saa7146_fh *fh, struct v4l2_format *f) 358static int s_fmt(struct saa7146_fh *fh, struct v4l2_format *f)
357{ 359{
diff --git a/drivers/media/common/saa7146_vv_ksyms.c b/drivers/media/common/saa7146_vv_ksyms.c
deleted file mode 100644
index 62226eb4753b..000000000000
--- a/drivers/media/common/saa7146_vv_ksyms.c
+++ /dev/null
@@ -1,12 +0,0 @@
1#include <linux/module.h>
2#include <media/saa7146_vv.h>
3
4EXPORT_SYMBOL_GPL(saa7146_start_preview);
5EXPORT_SYMBOL_GPL(saa7146_stop_preview);
6
7EXPORT_SYMBOL_GPL(saa7146_set_hps_source_and_sync);
8EXPORT_SYMBOL_GPL(saa7146_register_device);
9EXPORT_SYMBOL_GPL(saa7146_unregister_device);
10
11EXPORT_SYMBOL_GPL(saa7146_vv_init);
12EXPORT_SYMBOL_GPL(saa7146_vv_release);
diff --git a/drivers/media/dvb/b2c2/flexcop-fe-tuner.c b/drivers/media/dvb/b2c2/flexcop-fe-tuner.c
index 9c7f122826e0..3be87c72e37b 100644
--- a/drivers/media/dvb/b2c2/flexcop-fe-tuner.c
+++ b/drivers/media/dvb/b2c2/flexcop-fe-tuner.c
@@ -14,6 +14,7 @@
14#include "stv0297.h" 14#include "stv0297.h"
15#include "mt312.h" 15#include "mt312.h"
16#include "lgdt330x.h" 16#include "lgdt330x.h"
17#include "lg_h06xf.h"
17#include "dvb-pll.h" 18#include "dvb-pll.h"
18 19
19/* lnb control */ 20/* lnb control */
@@ -166,11 +167,12 @@ static int samsung_tbmu24112_set_symbol_rate(struct dvb_frontend* fe, u32 srate,
166 return 0; 167 return 0;
167} 168}
168 169
169static int samsung_tbmu24112_pll_set(struct dvb_frontend* fe, struct i2c_adapter *i2c, struct dvb_frontend_parameters* params) 170static int samsung_tbmu24112_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters *params)
170{ 171{
171 u8 buf[4]; 172 u8 buf[4];
172 u32 div; 173 u32 div;
173 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) }; 174 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) };
175 struct flexcop_device *fc = fe->dvb->priv;
174 176
175 div = params->frequency / 125; 177 div = params->frequency / 125;
176 178
@@ -181,8 +183,11 @@ static int samsung_tbmu24112_pll_set(struct dvb_frontend* fe, struct i2c_adapter
181 183
182 if (params->frequency < 1500000) buf[3] |= 0x10; 184 if (params->frequency < 1500000) buf[3] |= 0x10;
183 185
184 if (i2c_transfer(i2c, &msg, 1) != 1) 186 if (fe->ops.i2c_gate_ctrl)
187 fe->ops.i2c_gate_ctrl(fe, 1);
188 if (i2c_transfer(&fc->i2c_adap, &msg, 1) != 1) {
185 return -EIO; 189 return -EIO;
190 }
186 return 0; 191 return 0;
187} 192}
188 193
@@ -241,7 +246,6 @@ static struct stv0299_config samsung_tbmu24112_config = {
241 .volt13_op0_op1 = STV0299_VOLT13_OP1, 246 .volt13_op0_op1 = STV0299_VOLT13_OP1,
242 .min_delay_ms = 100, 247 .min_delay_ms = 100,
243 .set_symbol_rate = samsung_tbmu24112_set_symbol_rate, 248 .set_symbol_rate = samsung_tbmu24112_set_symbol_rate,
244 .pll_set = samsung_tbmu24112_pll_set,
245}; 249};
246 250
247/* dvb-t mt352 */ 251/* dvb-t mt352 */
@@ -264,11 +268,14 @@ static int samsung_tdtc9251dh0_demod_init(struct dvb_frontend* fe)
264 return 0; 268 return 0;
265} 269}
266 270
267static int samsung_tdtc9251dh0_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params, u8* pllbuf) 271static int samsung_tdtc9251dh0_calc_regs(struct dvb_frontend* fe, struct dvb_frontend_parameters *params, u8* pllbuf, int buf_len)
268{ 272{
269 u32 div; 273 u32 div;
270 unsigned char bs = 0; 274 unsigned char bs = 0;
271 275
276 if (buf_len < 5)
277 return -EINVAL;
278
272 #define IF_FREQUENCYx6 217 /* 6 * 36.16666666667MHz */ 279 #define IF_FREQUENCYx6 217 /* 6 * 36.16666666667MHz */
273 div = (((params->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6; 280 div = (((params->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6;
274 281
@@ -276,19 +283,18 @@ static int samsung_tdtc9251dh0_pll_set(struct dvb_frontend* fe, struct dvb_front
276 if (params->frequency >= 161000000 && params->frequency <= 439000000) bs = 0x0a; 283 if (params->frequency >= 161000000 && params->frequency <= 439000000) bs = 0x0a;
277 if (params->frequency >= 447000000 && params->frequency <= 863000000) bs = 0x08; 284 if (params->frequency >= 447000000 && params->frequency <= 863000000) bs = 0x08;
278 285
279 pllbuf[0] = 0xc2; /* Note: non-linux standard PLL i2c address */ 286 pllbuf[0] = 0x61;
280 pllbuf[1] = div >> 8; 287 pllbuf[1] = div >> 8;
281 pllbuf[2] = div & 0xff; 288 pllbuf[2] = div & 0xff;
282 pllbuf[3] = 0xcc; 289 pllbuf[3] = 0xcc;
283 pllbuf[4] = bs; 290 pllbuf[4] = bs;
284 291
285 return 0; 292 return 5;
286} 293}
287 294
288static struct mt352_config samsung_tdtc9251dh0_config = { 295static struct mt352_config samsung_tdtc9251dh0_config = {
289 .demod_address = 0x0f, 296 .demod_address = 0x0f,
290 .demod_init = samsung_tdtc9251dh0_demod_init, 297 .demod_init = samsung_tdtc9251dh0_demod_init,
291 .pll_set = samsung_tdtc9251dh0_pll_set,
292}; 298};
293 299
294static int flexcop_fe_request_firmware(struct dvb_frontend* fe, const struct firmware **fw, char* name) 300static int flexcop_fe_request_firmware(struct dvb_frontend* fe, const struct firmware **fw, char* name)
@@ -297,56 +303,21 @@ static int flexcop_fe_request_firmware(struct dvb_frontend* fe, const struct fir
297 return request_firmware(fw, name, fc->dev); 303 return request_firmware(fw, name, fc->dev);
298} 304}
299 305
300static int lgdt3303_pll_set(struct dvb_frontend* fe, 306static int lgdt3303_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters *params)
301 struct dvb_frontend_parameters* params)
302{ 307{
303 struct flexcop_device *fc = fe->dvb->priv; 308 struct flexcop_device *fc = fe->dvb->priv;
304 u8 buf[4]; 309 return lg_h06xf_pll_set(fe, &fc->i2c_adap, params);
305 struct i2c_msg msg =
306 { .addr = 0x61, .flags = 0, .buf = buf, .len = 4 };
307 int err;
308
309 dvb_pll_configure(&dvb_pll_tdvs_tua6034,buf, params->frequency, 0);
310 dprintk(1, "%s: tuner at 0x%02x bytes: 0x%02x 0x%02x 0x%02x 0x%02x\n",
311 __FUNCTION__, msg.addr, buf[0],buf[1],buf[2],buf[3]);
312 if ((err = i2c_transfer(&fc->i2c_adap, &msg, 1)) != 1) {
313 printk(KERN_WARNING "lgdt3303: %s error "
314 "(addr %02x <- %02x, err = %i)\n",
315 __FUNCTION__, buf[0], buf[1], err);
316 if (err < 0)
317 return err;
318 else
319 return -EREMOTEIO;
320 }
321
322 buf[0] = 0x86 | 0x18;
323 buf[1] = 0x50;
324 msg.len = 2;
325 if ((err = i2c_transfer(&fc->i2c_adap, &msg, 1)) != 1) {
326 printk(KERN_WARNING "lgdt3303: %s error "
327 "(addr %02x <- %02x, err = %i)\n",
328 __FUNCTION__, buf[0], buf[1], err);
329 if (err < 0)
330 return err;
331 else
332 return -EREMOTEIO;
333 }
334
335 return 0;
336} 310}
337 311
338static struct lgdt330x_config air2pc_atsc_hd5000_config = { 312static struct lgdt330x_config air2pc_atsc_hd5000_config = {
339 .demod_address = 0x59, 313 .demod_address = 0x59,
340 .demod_chip = LGDT3303, 314 .demod_chip = LGDT3303,
341 .serial_mpeg = 0x04, 315 .serial_mpeg = 0x04,
342 .pll_set = lgdt3303_pll_set,
343 .clock_polarity_flip = 1, 316 .clock_polarity_flip = 1,
344}; 317};
345 318
346static struct nxt200x_config samsung_tbmv_config = { 319static struct nxt200x_config samsung_tbmv_config = {
347 .demod_address = 0x0a, 320 .demod_address = 0x0a,
348 .pll_address = 0xc2,
349 .pll_desc = &dvb_pll_samsung_tbmv,
350}; 321};
351 322
352static struct bcm3510_config air2pc_atsc_first_gen_config = { 323static struct bcm3510_config air2pc_atsc_first_gen_config = {
@@ -354,7 +325,7 @@ static struct bcm3510_config air2pc_atsc_first_gen_config = {
354 .request_firmware = flexcop_fe_request_firmware, 325 .request_firmware = flexcop_fe_request_firmware,
355}; 326};
356 327
357static int skystar23_samsung_tbdu18132_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) 328static int skystar23_samsung_tbdu18132_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters *params)
358{ 329{
359 u8 buf[4]; 330 u8 buf[4];
360 u32 div; 331 u32 div;
@@ -371,6 +342,8 @@ static int skystar23_samsung_tbdu18132_pll_set(struct dvb_frontend* fe, struct d
371 if (params->frequency < 1550000) 342 if (params->frequency < 1550000)
372 buf[3] |= 0x02; 343 buf[3] |= 0x02;
373 344
345 if (fe->ops.i2c_gate_ctrl)
346 fe->ops.i2c_gate_ctrl(fe, 1);
374 if (i2c_transfer(&fc->i2c_adap, &msg, 1) != 1) 347 if (i2c_transfer(&fc->i2c_adap, &msg, 1) != 1)
375 return -EIO; 348 return -EIO;
376 return 0; 349 return 0;
@@ -379,9 +352,52 @@ static int skystar23_samsung_tbdu18132_pll_set(struct dvb_frontend* fe, struct d
379static struct mt312_config skystar23_samsung_tbdu18132_config = { 352static struct mt312_config skystar23_samsung_tbdu18132_config = {
380 353
381 .demod_address = 0x0e, 354 .demod_address = 0x0e,
382 .pll_set = skystar23_samsung_tbdu18132_pll_set,
383}; 355};
384 356
357static int alps_tdee4_stv0297_tuner_set_params(struct dvb_frontend* fe,
358 struct dvb_frontend_parameters *fep)
359{
360 struct flexcop_device *fc = fe->dvb->priv;
361 u8 buf[4];
362 u16 div;
363 int ret;
364
365/* 62.5 kHz * 10 */
366#define REF_FREQ 625
367#define FREQ_OFFSET 36125
368
369 div = ((fep->frequency/1000 + FREQ_OFFSET ) * 10) / REF_FREQ; // 4 MHz = 4000 KHz
370
371 buf[0] = (u8)( div >> 8) & 0x7f;
372 buf[1] = (u8) div & 0xff;
373
374/* F(osc) = N * Reference Freq. (62.5 kHz)
375 * byte 2 : 0 N14 N13 N12 N11 N10 N9 N8
376 * byte 3 : N7 N6 N5 N4 N3 N2 N1 N0
377 * byte 4 : 1 * * AGD R3 R2 R1 R0
378 * byte 5 : C1 * RE RTS BS4 BS3 BS2 BS1
379 * AGD = 1, R3 R2 R1 R0 = 0 1 0 1 => byte 4 = 1**10101 = 0x95 */
380 buf[2] = 0x95;
381
382// Range(MHz) C1 * RE RTS BS4 BS3 BS2 BS1 Byte 5
383// 47 - 153 0 * 0 0 0 0 0 1 0x01
384// 153 - 430 0 * 0 0 0 0 1 0 0x02
385// 430 - 822 0 * 0 0 1 0 0 0 0x08
386// 822 - 862 1 * 0 0 1 0 0 0 0x88
387
388 if (fep->frequency <= 153000000) buf[3] = 0x01;
389 else if (fep->frequency <= 430000000) buf[3] = 0x02;
390 else if (fep->frequency <= 822000000) buf[3] = 0x08;
391 else buf[3] = 0x88;
392
393 if (fe->ops.i2c_gate_ctrl)
394 fe->ops.i2c_gate_ctrl(fe, 1);
395 deb_tuner("tuner buffer for %d Hz: %x %x %x %x\n",fep->frequency, buf[0],buf[1],buf[2],buf[3]);
396 ret = fc->i2c_request(fc,FC_WRITE,FC_I2C_PORT_TUNER,0x61,buf[0],&buf[1],3);
397 deb_tuner("tuner write returned: %d\n",ret);
398
399 return 0;
400}
385 401
386static u8 alps_tdee4_stv0297_inittab[] = { 402static u8 alps_tdee4_stv0297_inittab[] = {
387 0x80, 0x01, 403 0x80, 0x01,
@@ -490,7 +506,9 @@ int flexcop_frontend_init(struct flexcop_device *fc)
490 506
491 /* try the sky v2.6 (stv0299/Samsung tbmu24112(sl1935)) */ 507 /* try the sky v2.6 (stv0299/Samsung tbmu24112(sl1935)) */
492 if ((fc->fe = stv0299_attach(&samsung_tbmu24112_config, &fc->i2c_adap)) != NULL) { 508 if ((fc->fe = stv0299_attach(&samsung_tbmu24112_config, &fc->i2c_adap)) != NULL) {
493 ops = fc->fe->ops; 509 ops = &fc->fe->ops;
510
511 ops->tuner_ops.set_params = samsung_tbmu24112_tuner_set_params;
494 512
495 ops->set_voltage = flexcop_set_voltage; 513 ops->set_voltage = flexcop_set_voltage;
496 514
@@ -503,16 +521,19 @@ int flexcop_frontend_init(struct flexcop_device *fc)
503 /* try the air dvb-t (mt352/Samsung tdtc9251dh0(??)) */ 521 /* try the air dvb-t (mt352/Samsung tdtc9251dh0(??)) */
504 if ((fc->fe = mt352_attach(&samsung_tdtc9251dh0_config, &fc->i2c_adap)) != NULL ) { 522 if ((fc->fe = mt352_attach(&samsung_tdtc9251dh0_config, &fc->i2c_adap)) != NULL ) {
505 fc->dev_type = FC_AIR_DVB; 523 fc->dev_type = FC_AIR_DVB;
524 fc->fe->ops.tuner_ops.calc_regs = samsung_tdtc9251dh0_calc_regs;
506 info("found the mt352 at i2c address: 0x%02x",samsung_tdtc9251dh0_config.demod_address); 525 info("found the mt352 at i2c address: 0x%02x",samsung_tdtc9251dh0_config.demod_address);
507 } else 526 } else
508 /* try the air atsc 2nd generation (nxt2002) */ 527 /* try the air atsc 2nd generation (nxt2002) */
509 if ((fc->fe = nxt200x_attach(&samsung_tbmv_config, &fc->i2c_adap)) != NULL) { 528 if ((fc->fe = nxt200x_attach(&samsung_tbmv_config, &fc->i2c_adap)) != NULL) {
510 fc->dev_type = FC_AIR_ATSC2; 529 fc->dev_type = FC_AIR_ATSC2;
530 dvb_pll_attach(fc->fe, 0x61, &fc->i2c_adap, &dvb_pll_samsung_tbmv);
511 info("found the nxt2002 at i2c address: 0x%02x",samsung_tbmv_config.demod_address); 531 info("found the nxt2002 at i2c address: 0x%02x",samsung_tbmv_config.demod_address);
512 } else 532 } else
513 /* try the air atsc 3nd generation (lgdt3303) */ 533 /* try the air atsc 3nd generation (lgdt3303) */
514 if ((fc->fe = lgdt330x_attach(&air2pc_atsc_hd5000_config, &fc->i2c_adap)) != NULL) { 534 if ((fc->fe = lgdt330x_attach(&air2pc_atsc_hd5000_config, &fc->i2c_adap)) != NULL) {
515 fc->dev_type = FC_AIR_ATSC3; 535 fc->dev_type = FC_AIR_ATSC3;
536 fc->fe->ops.tuner_ops.set_params = lgdt3303_tuner_set_params;
516 info("found the lgdt3303 at i2c address: 0x%02x",air2pc_atsc_hd5000_config.demod_address); 537 info("found the lgdt3303 at i2c address: 0x%02x",air2pc_atsc_hd5000_config.demod_address);
517 } else 538 } else
518 /* try the air atsc 1nd generation (bcm3510)/panasonic ct10s */ 539 /* try the air atsc 1nd generation (bcm3510)/panasonic ct10s */
@@ -523,11 +544,14 @@ int flexcop_frontend_init(struct flexcop_device *fc)
523 /* try the cable dvb (stv0297) */ 544 /* try the cable dvb (stv0297) */
524 if ((fc->fe = stv0297_attach(&alps_tdee4_stv0297_config, &fc->i2c_adap)) != NULL) { 545 if ((fc->fe = stv0297_attach(&alps_tdee4_stv0297_config, &fc->i2c_adap)) != NULL) {
525 fc->dev_type = FC_CABLE; 546 fc->dev_type = FC_CABLE;
547 fc->fe->ops.tuner_ops.set_params = alps_tdee4_stv0297_tuner_set_params;
526 info("found the stv0297 at i2c address: 0x%02x",alps_tdee4_stv0297_config.demod_address); 548 info("found the stv0297 at i2c address: 0x%02x",alps_tdee4_stv0297_config.demod_address);
527 } else 549 } else
528 /* try the sky v2.3 (vp310/Samsung tbdu18132(tsa5059)) */ 550 /* try the sky v2.3 (vp310/Samsung tbdu18132(tsa5059)) */
529 if ((fc->fe = vp310_mt312_attach(&skystar23_samsung_tbdu18132_config, &fc->i2c_adap)) != NULL) { 551 if ((fc->fe = vp310_mt312_attach(&skystar23_samsung_tbdu18132_config, &fc->i2c_adap)) != NULL) {
530 ops = fc->fe->ops; 552 ops = &fc->fe->ops;
553
554 ops->tuner_ops.set_params = skystar23_samsung_tbdu18132_tuner_set_params;
531 555
532 ops->diseqc_send_master_cmd = flexcop_diseqc_send_master_cmd; 556 ops->diseqc_send_master_cmd = flexcop_diseqc_send_master_cmd;
533 ops->diseqc_send_burst = flexcop_diseqc_send_burst; 557 ops->diseqc_send_burst = flexcop_diseqc_send_burst;
@@ -547,7 +571,7 @@ int flexcop_frontend_init(struct flexcop_device *fc)
547 } else { 571 } else {
548 if (dvb_register_frontend(&fc->dvb_adapter, fc->fe)) { 572 if (dvb_register_frontend(&fc->dvb_adapter, fc->fe)) {
549 err("frontend registration failed!"); 573 err("frontend registration failed!");
550 ops = fc->fe->ops; 574 ops = &fc->fe->ops;
551 if (ops->release != NULL) 575 if (ops->release != NULL)
552 ops->release(fc->fe); 576 ops->release(fc->fe);
553 fc->fe = NULL; 577 fc->fe = NULL;
diff --git a/drivers/media/dvb/b2c2/flexcop-pci.c b/drivers/media/dvb/b2c2/flexcop-pci.c
index 9bc40bdcc282..f04041702191 100644
--- a/drivers/media/dvb/b2c2/flexcop-pci.c
+++ b/drivers/media/dvb/b2c2/flexcop-pci.c
@@ -242,19 +242,16 @@ static int flexcop_pci_dma_init(struct flexcop_pci *fc_pci)
242 if ((ret = flexcop_dma_allocate(fc_pci->pdev,&fc_pci->dma[0],FC_DEFAULT_DMA1_BUFSIZE)) != 0) 242 if ((ret = flexcop_dma_allocate(fc_pci->pdev,&fc_pci->dma[0],FC_DEFAULT_DMA1_BUFSIZE)) != 0)
243 return ret; 243 return ret;
244 244
245 if ((ret = flexcop_dma_allocate(fc_pci->pdev,&fc_pci->dma[1],FC_DEFAULT_DMA2_BUFSIZE)) != 0) 245 if ((ret = flexcop_dma_allocate(fc_pci->pdev,&fc_pci->dma[1],FC_DEFAULT_DMA2_BUFSIZE)) != 0) {
246 goto dma1_free; 246 flexcop_dma_free(&fc_pci->dma[0]);
247 return ret;
248 }
247 249
248 flexcop_sram_set_dest(fc_pci->fc_dev,FC_SRAM_DEST_MEDIA | FC_SRAM_DEST_NET, FC_SRAM_DEST_TARGET_DMA1); 250 flexcop_sram_set_dest(fc_pci->fc_dev,FC_SRAM_DEST_MEDIA | FC_SRAM_DEST_NET, FC_SRAM_DEST_TARGET_DMA1);
249 flexcop_sram_set_dest(fc_pci->fc_dev,FC_SRAM_DEST_CAO | FC_SRAM_DEST_CAI, FC_SRAM_DEST_TARGET_DMA2); 251 flexcop_sram_set_dest(fc_pci->fc_dev,FC_SRAM_DEST_CAO | FC_SRAM_DEST_CAI, FC_SRAM_DEST_TARGET_DMA2);
250 252
251 fc_pci->init_state |= FC_PCI_DMA_INIT; 253 fc_pci->init_state |= FC_PCI_DMA_INIT;
252 254
253 goto success;
254dma1_free:
255 flexcop_dma_free(&fc_pci->dma[0]);
256
257success:
258 return ret; 255 return ret;
259} 256}
260 257
@@ -303,7 +300,7 @@ static int flexcop_pci_init(struct flexcop_pci *fc_pci)
303 spin_lock_init(&fc_pci->irq_lock); 300 spin_lock_init(&fc_pci->irq_lock);
304 301
305 fc_pci->init_state |= FC_PCI_INIT; 302 fc_pci->init_state |= FC_PCI_INIT;
306 goto success; 303 return ret;
307 304
308err_pci_iounmap: 305err_pci_iounmap:
309 pci_iounmap(fc_pci->pdev, fc_pci->io_mem); 306 pci_iounmap(fc_pci->pdev, fc_pci->io_mem);
@@ -312,8 +309,6 @@ err_pci_release_regions:
312 pci_release_regions(fc_pci->pdev); 309 pci_release_regions(fc_pci->pdev);
313err_pci_disable_device: 310err_pci_disable_device:
314 pci_disable_device(fc_pci->pdev); 311 pci_disable_device(fc_pci->pdev);
315
316success:
317 return ret; 312 return ret;
318} 313}
319 314
@@ -378,14 +373,14 @@ static int flexcop_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
378 373
379 INIT_WORK(&fc_pci->irq_check_work, flexcop_pci_irq_check_work, fc_pci); 374 INIT_WORK(&fc_pci->irq_check_work, flexcop_pci_irq_check_work, fc_pci);
380 375
381 goto success; 376 return ret;
377
382err_fc_exit: 378err_fc_exit:
383 flexcop_device_exit(fc); 379 flexcop_device_exit(fc);
384err_pci_exit: 380err_pci_exit:
385 flexcop_pci_exit(fc_pci); 381 flexcop_pci_exit(fc_pci);
386err_kfree: 382err_kfree:
387 flexcop_device_kfree(fc); 383 flexcop_device_kfree(fc);
388success:
389 return ret; 384 return ret;
390} 385}
391 386
diff --git a/drivers/media/dvb/b2c2/flexcop-usb.c b/drivers/media/dvb/b2c2/flexcop-usb.c
index 06ec9fff0ec1..515954f96c9a 100644
--- a/drivers/media/dvb/b2c2/flexcop-usb.c
+++ b/drivers/media/dvb/b2c2/flexcop-usb.c
@@ -433,11 +433,10 @@ static int flexcop_usb_transfer_init(struct flexcop_usb *fc_usb)
433 flexcop_wan_set_speed(fc_usb->fc_dev,FC_WAN_SPEED_8MBITS); 433 flexcop_wan_set_speed(fc_usb->fc_dev,FC_WAN_SPEED_8MBITS);
434 flexcop_sram_ctrl(fc_usb->fc_dev,1,1,1); 434 flexcop_sram_ctrl(fc_usb->fc_dev,1,1,1);
435 435
436 ret = 0; 436 return 0;
437 goto success; 437
438urb_error: 438urb_error:
439 flexcop_usb_transfer_exit(fc_usb); 439 flexcop_usb_transfer_exit(fc_usb);
440success:
441 return ret; 440 return ret;
442} 441}
443 442
@@ -515,15 +514,14 @@ static int flexcop_usb_probe(struct usb_interface *intf,
515 goto err_fc_exit; 514 goto err_fc_exit;
516 515
517 info("%s successfully initialized and connected.",DRIVER_NAME); 516 info("%s successfully initialized and connected.",DRIVER_NAME);
518 ret = 0; 517 return 0;
519 goto success; 518
520err_fc_exit: 519err_fc_exit:
521 flexcop_device_exit(fc); 520 flexcop_device_exit(fc);
522err_usb_exit: 521err_usb_exit:
523 flexcop_usb_exit(fc_usb); 522 flexcop_usb_exit(fc_usb);
524err_kfree: 523err_kfree:
525 flexcop_device_kfree(fc); 524 flexcop_device_kfree(fc);
526success:
527 return ret; 525 return ret;
528} 526}
529 527
diff --git a/drivers/media/dvb/b2c2/flexcop.c b/drivers/media/dvb/b2c2/flexcop.c
index 56ba52470676..29ec4183118e 100644
--- a/drivers/media/dvb/b2c2/flexcop.c
+++ b/drivers/media/dvb/b2c2/flexcop.c
@@ -67,7 +67,7 @@ static int flexcop_dvb_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
67static int flexcop_dvb_init(struct flexcop_device *fc) 67static int flexcop_dvb_init(struct flexcop_device *fc)
68{ 68{
69 int ret; 69 int ret;
70 if ((ret = dvb_register_adapter(&fc->dvb_adapter,"FlexCop Digital TV device",fc->owner)) < 0) { 70 if ((ret = dvb_register_adapter(&fc->dvb_adapter,"FlexCop Digital TV device",fc->owner,fc->dev)) < 0) {
71 err("error registering DVB adapter"); 71 err("error registering DVB adapter");
72 return ret; 72 return ret;
73 } 73 }
@@ -116,7 +116,7 @@ static int flexcop_dvb_init(struct flexcop_device *fc)
116 dvb_net_init(&fc->dvb_adapter, &fc->dvbnet, &fc->demux.dmx); 116 dvb_net_init(&fc->dvb_adapter, &fc->dvbnet, &fc->demux.dmx);
117 117
118 fc->init_state |= FC_STATE_DVB_INIT; 118 fc->init_state |= FC_STATE_DVB_INIT;
119 goto success; 119 return 0;
120 120
121err_connect_frontend: 121err_connect_frontend:
122 fc->demux.dmx.remove_frontend(&fc->demux.dmx,&fc->mem_frontend); 122 fc->demux.dmx.remove_frontend(&fc->demux.dmx,&fc->mem_frontend);
@@ -129,9 +129,6 @@ err_dmx_dev:
129err_dmx: 129err_dmx:
130 dvb_unregister_adapter(&fc->dvb_adapter); 130 dvb_unregister_adapter(&fc->dvb_adapter);
131 return ret; 131 return ret;
132
133success:
134 return 0;
135} 132}
136 133
137static void flexcop_dvb_exit(struct flexcop_device *fc) 134static void flexcop_dvb_exit(struct flexcop_device *fc)
@@ -279,11 +276,10 @@ int flexcop_device_initialize(struct flexcop_device *fc)
279 276
280 flexcop_device_name(fc,"initialization of","complete"); 277 flexcop_device_name(fc,"initialization of","complete");
281 278
282 ret = 0; 279 return 0;
283 goto success; 280
284error: 281error:
285 flexcop_device_exit(fc); 282 flexcop_device_exit(fc);
286success:
287 return ret; 283 return ret;
288} 284}
289EXPORT_SYMBOL(flexcop_device_initialize); 285EXPORT_SYMBOL(flexcop_device_initialize);
diff --git a/drivers/media/dvb/bt8xx/bt878.c b/drivers/media/dvb/bt8xx/bt878.c
index 5500f8a0ffe2..761fa6e7d762 100644
--- a/drivers/media/dvb/bt8xx/bt878.c
+++ b/drivers/media/dvb/bt8xx/bt878.c
@@ -63,8 +63,6 @@ MODULE_PARM_DESC(debug, "Turn on/off debugging, default is 0 (off).");
63int bt878_num; 63int bt878_num;
64struct bt878 bt878[BT878_MAX]; 64struct bt878 bt878[BT878_MAX];
65 65
66EXPORT_SYMBOL(bt878_debug);
67EXPORT_SYMBOL(bt878_verbose);
68EXPORT_SYMBOL(bt878_num); 66EXPORT_SYMBOL(bt878_num);
69EXPORT_SYMBOL(bt878); 67EXPORT_SYMBOL(bt878);
70 68
@@ -393,7 +391,9 @@ static struct cards card_list[] __devinitdata = {
393 { 0x07711461, BTTV_BOARD_AVDVBT_771, "AVermedia AverTV DVB-T 771" }, 391 { 0x07711461, BTTV_BOARD_AVDVBT_771, "AVermedia AverTV DVB-T 771" },
394 { 0xdb1018ac, BTTV_BOARD_DVICO_DVBT_LITE, "DViCO FusionHDTV DVB-T Lite" }, 392 { 0xdb1018ac, BTTV_BOARD_DVICO_DVBT_LITE, "DViCO FusionHDTV DVB-T Lite" },
395 { 0xd50018ac, BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE, "DViCO FusionHDTV 5 Lite" }, 393 { 0xd50018ac, BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE, "DViCO FusionHDTV 5 Lite" },
396 { 0x20007063, BTTV_BOARD_PC_HDTV, "pcHDTV HD-2000 TV"}, 394 { 0x20007063, BTTV_BOARD_PC_HDTV, "pcHDTV HD-2000 TV" },
395 { 0x00261822, BTTV_BOARD_TWINHAN_DST, "DNTV Live! Mini" },
396
397 { 0, -1, NULL } 397 { 0, -1, NULL }
398}; 398};
399 399
@@ -417,6 +417,11 @@ static int __devinit bt878_probe(struct pci_dev *dev,
417 417
418 printk(KERN_INFO "bt878: Bt878 AUDIO function found (%d).\n", 418 printk(KERN_INFO "bt878: Bt878 AUDIO function found (%d).\n",
419 bt878_num); 419 bt878_num);
420 if (bt878_num >= BT878_MAX) {
421 printk(KERN_ERR "bt878: Too many devices inserted\n");
422 result = -ENOMEM;
423 goto fail0;
424 }
420 if (pci_enable_device(dev)) 425 if (pci_enable_device(dev))
421 return -EIO; 426 return -EIO;
422 427
diff --git a/drivers/media/dvb/bt8xx/dst.c b/drivers/media/dvb/bt8xx/dst.c
index 1cfa5e5035d8..d687a14ec0a7 100644
--- a/drivers/media/dvb/bt8xx/dst.c
+++ b/drivers/media/dvb/bt8xx/dst.c
@@ -38,6 +38,10 @@ static unsigned int dst_addons;
38module_param(dst_addons, int, 0644); 38module_param(dst_addons, int, 0644);
39MODULE_PARM_DESC(dst_addons, "CA daughterboard, default is 0 (No addons)"); 39MODULE_PARM_DESC(dst_addons, "CA daughterboard, default is 0 (No addons)");
40 40
41static unsigned int dst_algo;
42module_param(dst_algo, int, 0644);
43MODULE_PARM_DESC(dst_algo, "tuning algo: default is 0=(SW), 1=(HW)");
44
41#define HAS_LOCK 1 45#define HAS_LOCK 1
42#define ATTEMPT_TUNE 2 46#define ATTEMPT_TUNE 2
43#define HAS_POWER 4 47#define HAS_POWER 4
@@ -47,20 +51,24 @@ MODULE_PARM_DESC(dst_addons, "CA daughterboard, default is 0 (No addons)");
47#define DST_INFO 2 51#define DST_INFO 2
48#define DST_DEBUG 3 52#define DST_DEBUG 3
49 53
50#define dprintk(x, y, z, format, arg...) do { \ 54#define dprintk(x, y, z, format, arg...) do { \
51 if (z) { \ 55 if (z) { \
52 if ((x > DST_ERROR) && (x > y)) \ 56 if ((x > DST_ERROR) && (x > y)) \
53 printk(KERN_ERR "%s: " format "\n", __FUNCTION__ , ##arg); \ 57 printk(KERN_ERR "dst(%d) %s: " format "\n", \
54 else if ((x > DST_NOTICE) && (x > y)) \ 58 state->bt->nr, __func__ , ##arg); \
55 printk(KERN_NOTICE "%s: " format "\n", __FUNCTION__ , ##arg); \ 59 else if ((x > DST_NOTICE) && (x > y)) \
56 else if ((x > DST_INFO) && (x > y)) \ 60 printk(KERN_NOTICE "dst(%d) %s: " format "\n", \
57 printk(KERN_INFO "%s: " format "\n", __FUNCTION__ , ##arg); \ 61 state->bt->nr, __func__ , ##arg); \
58 else if ((x > DST_DEBUG) && (x > y)) \ 62 else if ((x > DST_INFO) && (x > y)) \
59 printk(KERN_DEBUG "%s: " format "\n", __FUNCTION__ , ##arg); \ 63 printk(KERN_INFO "dst(%d) %s: " format "\n", \
60 } else { \ 64 state->bt->nr, __func__ , ##arg); \
61 if (x > y) \ 65 else if ((x > DST_DEBUG) && (x > y)) \
62 printk(format, ##arg); \ 66 printk(KERN_DEBUG "dst(%d) %s: " format "\n", \
63 } \ 67 state->bt->nr, __func__ , ##arg); \
68 } else { \
69 if (x > y) \
70 printk(format, ##arg); \
71 } \
64} while(0) 72} while(0)
65 73
66 74
@@ -110,7 +118,7 @@ int dst_gpio_inb(struct dst_state *state, u8 *result)
110 118
111 *result = 0; 119 *result = 0;
112 if ((err = bt878_device_control(state->bt, DST_IG_READ, &rd_packet)) < 0) { 120 if ((err = bt878_device_control(state->bt, DST_IG_READ, &rd_packet)) < 0) {
113 dprintk(verbose, DST_ERROR, 1, "dst_gpio_inb error (err == %i)\n", err); 121 dprintk(verbose, DST_ERROR, 1, "dst_gpio_inb error (err == %i)", err);
114 return -EREMOTEIO; 122 return -EREMOTEIO;
115 } 123 }
116 *result = (u8) rd_packet.rd.value; 124 *result = (u8) rd_packet.rd.value;
@@ -363,6 +371,17 @@ static int dst_set_freq(struct dst_state *state, u32 freq)
363 state->tx_tuna[2] = (freq >> 16) & 0xff; 371 state->tx_tuna[2] = (freq >> 16) & 0xff;
364 state->tx_tuna[3] = (freq >> 8) & 0xff; 372 state->tx_tuna[3] = (freq >> 8) & 0xff;
365 state->tx_tuna[4] = (u8) freq; 373 state->tx_tuna[4] = (u8) freq;
374 } else if (state->dst_type == DST_TYPE_IS_ATSC) {
375 freq = freq / 1000;
376 if (freq < 51000 || freq > 858000)
377 return -EINVAL;
378 state->tx_tuna[2] = (freq >> 16) & 0xff;
379 state->tx_tuna[3] = (freq >> 8) & 0xff;
380 state->tx_tuna[4] = (u8) freq;
381 state->tx_tuna[5] = 0x00; /* ATSC */
382 state->tx_tuna[6] = 0x00;
383 if (state->dst_hw_cap & DST_TYPE_HAS_ANALOG)
384 state->tx_tuna[7] = 0x00; /* Digital */
366 } else 385 } else
367 return -EINVAL; 386 return -EINVAL;
368 387
@@ -447,29 +466,41 @@ static int dst_set_symbolrate(struct dst_state *state, u32 srate)
447 } 466 }
448 dprintk(verbose, DST_INFO, 1, "set symrate %u", srate); 467 dprintk(verbose, DST_INFO, 1, "set symrate %u", srate);
449 srate /= 1000; 468 srate /= 1000;
450 if (state->type_flags & DST_TYPE_HAS_SYMDIV) { 469 if (state->dst_type == DST_TYPE_IS_SAT) {
451 sval = srate; 470 if (state->type_flags & DST_TYPE_HAS_SYMDIV) {
452 sval <<= 20; 471 sval = srate;
453 do_div(sval, 88000); 472 sval <<= 20;
454 symcalc = (u32) sval; 473 do_div(sval, 88000);
455 dprintk(verbose, DST_INFO, 1, "set symcalc %u", symcalc); 474 symcalc = (u32) sval;
456 state->tx_tuna[5] = (u8) (symcalc >> 12); 475 dprintk(verbose, DST_INFO, 1, "set symcalc %u", symcalc);
457 state->tx_tuna[6] = (u8) (symcalc >> 4); 476 state->tx_tuna[5] = (u8) (symcalc >> 12);
458 state->tx_tuna[7] = (u8) (symcalc << 4); 477 state->tx_tuna[6] = (u8) (symcalc >> 4);
459 } else { 478 state->tx_tuna[7] = (u8) (symcalc << 4);
460 state->tx_tuna[5] = (u8) (srate >> 16) & 0x7f; 479 } else {
461 state->tx_tuna[6] = (u8) (srate >> 8); 480 state->tx_tuna[5] = (u8) (srate >> 16) & 0x7f;
462 state->tx_tuna[7] = (u8) srate; 481 state->tx_tuna[6] = (u8) (srate >> 8);
463 } 482 state->tx_tuna[7] = (u8) srate;
464 state->tx_tuna[8] &= ~0x20; 483 }
465 if (state->type_flags & DST_TYPE_HAS_OBS_REGS) { 484 state->tx_tuna[8] &= ~0x20;
466 if (srate > 8000) 485 if (state->type_flags & DST_TYPE_HAS_OBS_REGS) {
467 state->tx_tuna[8] |= 0x20; 486 if (srate > 8000)
487 state->tx_tuna[8] |= 0x20;
488 }
489 } else if (state->dst_type == DST_TYPE_IS_CABLE) {
490 dprintk(verbose, DST_DEBUG, 1, "%s", state->fw_name);
491 if (!strncmp(state->fw_name, "DCTNEW", 6)) {
492 state->tx_tuna[5] = (u8) (srate >> 8);
493 state->tx_tuna[6] = (u8) srate;
494 state->tx_tuna[7] = 0x00;
495 } else if (!strncmp(state->fw_name, "DCT-CI", 6)) {
496 state->tx_tuna[5] = 0x00;
497 state->tx_tuna[6] = (u8) (srate >> 8);
498 state->tx_tuna[7] = (u8) srate;
499 }
468 } 500 }
469 return 0; 501 return 0;
470} 502}
471 503
472
473static int dst_set_modulation(struct dst_state *state, fe_modulation_t modulation) 504static int dst_set_modulation(struct dst_state *state, fe_modulation_t modulation)
474{ 505{
475 if (state->dst_type != DST_TYPE_IS_CABLE) 506 if (state->dst_type != DST_TYPE_IS_CABLE)
@@ -490,7 +521,10 @@ static int dst_set_modulation(struct dst_state *state, fe_modulation_t modulatio
490 state->tx_tuna[8] = 0x80; 521 state->tx_tuna[8] = 0x80;
491 break; 522 break;
492 case QAM_256: 523 case QAM_256:
493 state->tx_tuna[8] = 0x00; 524 if (!strncmp(state->fw_name, "DCTNEW", 6))
525 state->tx_tuna[8] = 0xff;
526 else if (!strncmp(state->fw_name, "DCT-CI", 6))
527 state->tx_tuna[8] = 0x00;
494 break; 528 break;
495 case QPSK: 529 case QPSK:
496 case QAM_AUTO: 530 case QAM_AUTO:
@@ -523,13 +557,19 @@ u8 dst_check_sum(u8 *buf, u32 len)
523} 557}
524EXPORT_SYMBOL(dst_check_sum); 558EXPORT_SYMBOL(dst_check_sum);
525 559
526static void dst_type_flags_print(u32 type_flags) 560static void dst_type_flags_print(struct dst_state *state)
527{ 561{
562 u32 type_flags = state->type_flags;
563
528 dprintk(verbose, DST_ERROR, 0, "DST type flags :"); 564 dprintk(verbose, DST_ERROR, 0, "DST type flags :");
529 if (type_flags & DST_TYPE_HAS_NEWTUNE) 565 if (type_flags & DST_TYPE_HAS_TS188)
530 dprintk(verbose, DST_ERROR, 0, " 0x%x newtuner", DST_TYPE_HAS_NEWTUNE); 566 dprintk(verbose, DST_ERROR, 0, " 0x%x newtuner", DST_TYPE_HAS_TS188);
567 if (type_flags & DST_TYPE_HAS_NEWTUNE_2)
568 dprintk(verbose, DST_ERROR, 0, " 0x%x newtuner 2", DST_TYPE_HAS_NEWTUNE_2);
531 if (type_flags & DST_TYPE_HAS_TS204) 569 if (type_flags & DST_TYPE_HAS_TS204)
532 dprintk(verbose, DST_ERROR, 0, " 0x%x ts204", DST_TYPE_HAS_TS204); 570 dprintk(verbose, DST_ERROR, 0, " 0x%x ts204", DST_TYPE_HAS_TS204);
571 if (type_flags & DST_TYPE_HAS_VLF)
572 dprintk(verbose, DST_ERROR, 0, " 0x%x VLF", DST_TYPE_HAS_VLF);
533 if (type_flags & DST_TYPE_HAS_SYMDIV) 573 if (type_flags & DST_TYPE_HAS_SYMDIV)
534 dprintk(verbose, DST_ERROR, 0, " 0x%x symdiv", DST_TYPE_HAS_SYMDIV); 574 dprintk(verbose, DST_ERROR, 0, " 0x%x symdiv", DST_TYPE_HAS_SYMDIV);
535 if (type_flags & DST_TYPE_HAS_FW_1) 575 if (type_flags & DST_TYPE_HAS_FW_1)
@@ -542,7 +582,7 @@ static void dst_type_flags_print(u32 type_flags)
542} 582}
543 583
544 584
545static int dst_type_print(u8 type) 585static int dst_type_print(struct dst_state *state, u8 type)
546{ 586{
547 char *otype; 587 char *otype;
548 switch (type) { 588 switch (type) {
@@ -558,6 +598,10 @@ static int dst_type_print(u8 type)
558 otype = "cable"; 598 otype = "cable";
559 break; 599 break;
560 600
601 case DST_TYPE_IS_ATSC:
602 otype = "atsc";
603 break;
604
561 default: 605 default:
562 dprintk(verbose, DST_INFO, 1, "invalid dst type %d", type); 606 dprintk(verbose, DST_INFO, 1, "invalid dst type %d", type);
563 return -EINVAL; 607 return -EINVAL;
@@ -567,6 +611,127 @@ static int dst_type_print(u8 type)
567 return 0; 611 return 0;
568} 612}
569 613
614struct tuner_types tuner_list[] = {
615 {
616 .tuner_type = TUNER_TYPE_L64724,
617 .tuner_name = "L 64724",
618 .board_name = "UNKNOWN",
619 .fw_name = "UNKNOWN"
620 },
621
622 {
623 .tuner_type = TUNER_TYPE_STV0299,
624 .tuner_name = "STV 0299",
625 .board_name = "VP1020",
626 .fw_name = "DST-MOT"
627 },
628
629 {
630 .tuner_type = TUNER_TYPE_STV0299,
631 .tuner_name = "STV 0299",
632 .board_name = "VP1020",
633 .fw_name = "DST-03T"
634 },
635
636 {
637 .tuner_type = TUNER_TYPE_MB86A15,
638 .tuner_name = "MB 86A15",
639 .board_name = "VP1022",
640 .fw_name = "DST-03T"
641 },
642
643 {
644 .tuner_type = TUNER_TYPE_MB86A15,
645 .tuner_name = "MB 86A15",
646 .board_name = "VP1025",
647 .fw_name = "DST-03T"
648 },
649
650 {
651 .tuner_type = TUNER_TYPE_STV0299,
652 .tuner_name = "STV 0299",
653 .board_name = "VP1030",
654 .fw_name = "DST-CI"
655 },
656
657 {
658 .tuner_type = TUNER_TYPE_STV0299,
659 .tuner_name = "STV 0299",
660 .board_name = "VP1030",
661 .fw_name = "DSTMCI"
662 },
663
664 {
665 .tuner_type = TUNER_TYPE_UNKNOWN,
666 .tuner_name = "UNKNOWN",
667 .board_name = "VP2021",
668 .fw_name = "DCTNEW"
669 },
670
671 {
672 .tuner_type = TUNER_TYPE_UNKNOWN,
673 .tuner_name = "UNKNOWN",
674 .board_name = "VP2030",
675 .fw_name = "DCT-CI"
676 },
677
678 {
679 .tuner_type = TUNER_TYPE_UNKNOWN,
680 .tuner_name = "UNKNOWN",
681 .board_name = "VP2031",
682 .fw_name = "DCT-CI"
683 },
684
685 {
686 .tuner_type = TUNER_TYPE_UNKNOWN,
687 .tuner_name = "UNKNOWN",
688 .board_name = "VP2040",
689 .fw_name = "DCT-CI"
690 },
691
692 {
693 .tuner_type = TUNER_TYPE_UNKNOWN,
694 .tuner_name = "UNKNOWN",
695 .board_name = "VP3020",
696 .fw_name = "DTTFTA"
697 },
698
699 {
700 .tuner_type = TUNER_TYPE_UNKNOWN,
701 .tuner_name = "UNKNOWN",
702 .board_name = "VP3021",
703 .fw_name = "DTTFTA"
704 },
705
706 {
707 .tuner_type = TUNER_TYPE_TDA10046,
708 .tuner_name = "TDA10046",
709 .board_name = "VP3040",
710 .fw_name = "DTT-CI"
711 },
712
713 {
714 .tuner_type = TUNER_TYPE_UNKNOWN,
715 .tuner_name = "UNKNOWN",
716 .board_name = "VP3051",
717 .fw_name = "DTTNXT"
718 },
719
720 {
721 .tuner_type = TUNER_TYPE_NXT200x,
722 .tuner_name = "NXT200x",
723 .board_name = "VP3220",
724 .fw_name = "ATSCDI"
725 },
726
727 {
728 .tuner_type = TUNER_TYPE_NXT200x,
729 .tuner_name = "NXT200x",
730 .board_name = "VP3250",
731 .fw_name = "ATSCAD"
732 },
733};
734
570/* 735/*
571 Known cards list 736 Known cards list
572 Satellite 737 Satellite
@@ -608,7 +773,8 @@ static struct dst_types dst_tlist[] = {
608 .offset = 0, 773 .offset = 0,
609 .dst_type = DST_TYPE_IS_SAT, 774 .dst_type = DST_TYPE_IS_SAT,
610 .type_flags = DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_FW_1 | DST_TYPE_HAS_OBS_REGS, 775 .type_flags = DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_FW_1 | DST_TYPE_HAS_OBS_REGS,
611 .dst_feature = 0 776 .dst_feature = 0,
777 .tuner_type = 0
612 }, /* obsolete */ 778 }, /* obsolete */
613 779
614 { 780 {
@@ -616,15 +782,17 @@ static struct dst_types dst_tlist[] = {
616 .offset = 0, 782 .offset = 0,
617 .dst_type = DST_TYPE_IS_SAT, 783 .dst_type = DST_TYPE_IS_SAT,
618 .type_flags = DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_FW_1, 784 .type_flags = DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_FW_1,
619 .dst_feature = 0 785 .dst_feature = 0,
786 .tuner_type = 0
620 }, /* obsolete */ 787 }, /* obsolete */
621 788
622 { 789 {
623 .device_id = "DST-030", 790 .device_id = "DST-030",
624 .offset = 0, 791 .offset = 0,
625 .dst_type = DST_TYPE_IS_SAT, 792 .dst_type = DST_TYPE_IS_SAT,
626 .type_flags = DST_TYPE_HAS_TS204 | DST_TYPE_HAS_NEWTUNE | DST_TYPE_HAS_FW_1, 793 .type_flags = DST_TYPE_HAS_TS204 | DST_TYPE_HAS_TS188 | DST_TYPE_HAS_FW_1,
627 .dst_feature = 0 794 .dst_feature = 0,
795 .tuner_type = 0
628 }, /* obsolete */ 796 }, /* obsolete */
629 797
630 { 798 {
@@ -633,7 +801,8 @@ static struct dst_types dst_tlist[] = {
633 .dst_type = DST_TYPE_IS_SAT, 801 .dst_type = DST_TYPE_IS_SAT,
634 .type_flags = DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_TS204 | DST_TYPE_HAS_FW_2, 802 .type_flags = DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_TS204 | DST_TYPE_HAS_FW_2,
635 .dst_feature = DST_TYPE_HAS_DISEQC3 | DST_TYPE_HAS_DISEQC4 | DST_TYPE_HAS_DISEQC5 803 .dst_feature = DST_TYPE_HAS_DISEQC3 | DST_TYPE_HAS_DISEQC4 | DST_TYPE_HAS_DISEQC5
636 | DST_TYPE_HAS_MAC | DST_TYPE_HAS_MOTO 804 | DST_TYPE_HAS_MAC | DST_TYPE_HAS_MOTO,
805 .tuner_type = TUNER_TYPE_MULTI
637 }, 806 },
638 807
639 { 808 {
@@ -641,57 +810,63 @@ static struct dst_types dst_tlist[] = {
641 .offset = 0, 810 .offset = 0,
642 .dst_type = DST_TYPE_IS_SAT, 811 .dst_type = DST_TYPE_IS_SAT,
643 .type_flags = DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_FW_1, 812 .type_flags = DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_FW_1,
644 .dst_feature = 0 813 .dst_feature = 0,
814 .tuner_type = 0
645 }, /* obsolete */ 815 }, /* obsolete */
646 816
647 { 817 {
648 .device_id = "DST-CI", 818 .device_id = "DST-CI",
649 .offset = 1, 819 .offset = 1,
650 .dst_type = DST_TYPE_IS_SAT, 820 .dst_type = DST_TYPE_IS_SAT,
651 .type_flags = DST_TYPE_HAS_TS204 | DST_TYPE_HAS_NEWTUNE | DST_TYPE_HAS_FW_1, 821 .type_flags = DST_TYPE_HAS_TS204 | DST_TYPE_HAS_FW_1,
652 .dst_feature = DST_TYPE_HAS_CA 822 .dst_feature = DST_TYPE_HAS_CA,
823 .tuner_type = 0
653 }, /* An OEM board */ 824 }, /* An OEM board */
654 825
655 { 826 {
656 .device_id = "DSTMCI", 827 .device_id = "DSTMCI",
657 .offset = 1, 828 .offset = 1,
658 .dst_type = DST_TYPE_IS_SAT, 829 .dst_type = DST_TYPE_IS_SAT,
659 .type_flags = DST_TYPE_HAS_NEWTUNE | DST_TYPE_HAS_FW_2 | DST_TYPE_HAS_FW_BUILD | DST_TYPE_HAS_INC_COUNT, 830 .type_flags = DST_TYPE_HAS_TS188 | DST_TYPE_HAS_FW_2 | DST_TYPE_HAS_FW_BUILD | DST_TYPE_HAS_INC_COUNT | DST_TYPE_HAS_VLF,
660 .dst_feature = DST_TYPE_HAS_CA | DST_TYPE_HAS_DISEQC3 | DST_TYPE_HAS_DISEQC4 831 .dst_feature = DST_TYPE_HAS_CA | DST_TYPE_HAS_DISEQC3 | DST_TYPE_HAS_DISEQC4
661 | DST_TYPE_HAS_MOTO | DST_TYPE_HAS_MAC 832 | DST_TYPE_HAS_MOTO | DST_TYPE_HAS_MAC,
833 .tuner_type = TUNER_TYPE_MULTI
662 }, 834 },
663 835
664 { 836 {
665 .device_id = "DSTFCI", 837 .device_id = "DSTFCI",
666 .offset = 1, 838 .offset = 1,
667 .dst_type = DST_TYPE_IS_SAT, 839 .dst_type = DST_TYPE_IS_SAT,
668 .type_flags = DST_TYPE_HAS_NEWTUNE | DST_TYPE_HAS_FW_1, 840 .type_flags = DST_TYPE_HAS_TS188 | DST_TYPE_HAS_FW_1,
669 .dst_feature = 0 841 .dst_feature = 0,
842 .tuner_type = 0
670 }, /* unknown to vendor */ 843 }, /* unknown to vendor */
671 844
672 { 845 {
673 .device_id = "DCT-CI", 846 .device_id = "DCT-CI",
674 .offset = 1, 847 .offset = 1,
675 .dst_type = DST_TYPE_IS_CABLE, 848 .dst_type = DST_TYPE_IS_CABLE,
676 .type_flags = DST_TYPE_HAS_TS204 | DST_TYPE_HAS_NEWTUNE | DST_TYPE_HAS_FW_1 849 .type_flags = DST_TYPE_HAS_MULTI_FE | DST_TYPE_HAS_FW_1 | DST_TYPE_HAS_FW_2 | DST_TYPE_HAS_VLF,
677 | DST_TYPE_HAS_FW_2, 850 .dst_feature = DST_TYPE_HAS_CA,
678 .dst_feature = DST_TYPE_HAS_CA 851 .tuner_type = 0
679 }, 852 },
680 853
681 { 854 {
682 .device_id = "DCTNEW", 855 .device_id = "DCTNEW",
683 .offset = 1, 856 .offset = 1,
684 .dst_type = DST_TYPE_IS_CABLE, 857 .dst_type = DST_TYPE_IS_CABLE,
685 .type_flags = DST_TYPE_HAS_NEWTUNE | DST_TYPE_HAS_FW_3 | DST_TYPE_HAS_FW_BUILD, 858 .type_flags = DST_TYPE_HAS_TS188 | DST_TYPE_HAS_FW_3 | DST_TYPE_HAS_FW_BUILD | DST_TYPE_HAS_MULTI_FE,
686 .dst_feature = 0 859 .dst_feature = 0,
860 .tuner_type = 0
687 }, 861 },
688 862
689 { 863 {
690 .device_id = "DTT-CI", 864 .device_id = "DTT-CI",
691 .offset = 1, 865 .offset = 1,
692 .dst_type = DST_TYPE_IS_TERR, 866 .dst_type = DST_TYPE_IS_TERR,
693 .type_flags = DST_TYPE_HAS_TS204 | DST_TYPE_HAS_NEWTUNE | DST_TYPE_HAS_FW_2 | DST_TYPE_HAS_MULTI_FE, 867 .type_flags = DST_TYPE_HAS_FW_2 | DST_TYPE_HAS_MULTI_FE | DST_TYPE_HAS_VLF,
694 .dst_feature = DST_TYPE_HAS_CA 868 .dst_feature = DST_TYPE_HAS_CA,
869 .tuner_type = 0
695 }, 870 },
696 871
697 { 872 {
@@ -699,7 +874,8 @@ static struct dst_types dst_tlist[] = {
699 .offset = 1, 874 .offset = 1,
700 .dst_type = DST_TYPE_IS_TERR, 875 .dst_type = DST_TYPE_IS_TERR,
701 .type_flags = DST_TYPE_HAS_FW_2, 876 .type_flags = DST_TYPE_HAS_FW_2,
702 .dst_feature = 0 877 .dst_feature = 0,
878 .tuner_type = 0
703 }, 879 },
704 880
705 { 881 {
@@ -707,7 +883,8 @@ static struct dst_types dst_tlist[] = {
707 .offset = 1, 883 .offset = 1,
708 .dst_type = DST_TYPE_IS_TERR, 884 .dst_type = DST_TYPE_IS_TERR,
709 .type_flags = DST_TYPE_HAS_FW_2, 885 .type_flags = DST_TYPE_HAS_FW_2,
710 .dst_feature = DST_TYPE_HAS_ANALOG 886 .dst_feature = DST_TYPE_HAS_ANALOG,
887 .tuner_type = 0
711 }, 888 },
712 889
713 { 890 {
@@ -715,15 +892,17 @@ static struct dst_types dst_tlist[] = {
715 .offset = 1, 892 .offset = 1,
716 .dst_type = DST_TYPE_IS_ATSC, 893 .dst_type = DST_TYPE_IS_ATSC,
717 .type_flags = DST_TYPE_HAS_FW_2, 894 .type_flags = DST_TYPE_HAS_FW_2,
718 .dst_feature = 0 895 .dst_feature = 0,
896 .tuner_type = 0
719 }, 897 },
720 898
721 { 899 {
722 .device_id = "ATSCAD", 900 .device_id = "ATSCAD",
723 .offset = 1, 901 .offset = 1,
724 .dst_type = DST_TYPE_IS_ATSC, 902 .dst_type = DST_TYPE_IS_ATSC,
725 .type_flags = DST_TYPE_HAS_FW_2, 903 .type_flags = DST_TYPE_HAS_MULTI_FE | DST_TYPE_HAS_FW_2 | DST_TYPE_HAS_FW_BUILD,
726 .dst_feature = 0 904 .dst_feature = DST_TYPE_HAS_MAC | DST_TYPE_HAS_ANALOG,
905 .tuner_type = 0
727 }, 906 },
728 907
729 { } 908 { }
@@ -768,6 +947,9 @@ static int dst_fw_ver(struct dst_state *state)
768 947
769static int dst_card_type(struct dst_state *state) 948static int dst_card_type(struct dst_state *state)
770{ 949{
950 int j;
951 struct tuner_types *p_tuner_list = NULL;
952
771 u8 get_type[] = { 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; 953 u8 get_type[] = { 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
772 get_type[7] = dst_check_sum(get_type, 7); 954 get_type[7] = dst_check_sum(get_type, 7);
773 if (dst_command(state, get_type, 8) < 0) { 955 if (dst_command(state, get_type, 8) < 0) {
@@ -775,9 +957,17 @@ static int dst_card_type(struct dst_state *state)
775 return -1; 957 return -1;
776 } 958 }
777 memset(&state->card_info, '\0', 8); 959 memset(&state->card_info, '\0', 8);
778 memcpy(&state->card_info, &state->rxbuffer, 8); 960 memcpy(&state->card_info, &state->rxbuffer, 7);
779 dprintk(verbose, DST_ERROR, 1, "Device Model=[%s]", &state->card_info[0]); 961 dprintk(verbose, DST_ERROR, 1, "Device Model=[%s]", &state->card_info[0]);
780 962
963 for (j = 0, p_tuner_list = tuner_list; j < ARRAY_SIZE(tuner_list); j++, p_tuner_list++) {
964 if (!strcmp(&state->card_info[0], p_tuner_list->board_name)) {
965 state->tuner_type = p_tuner_list->tuner_type;
966 dprintk(verbose, DST_ERROR, 1, "DST has [%s] tuner, tuner type=[%d]",
967 p_tuner_list->tuner_name, p_tuner_list->tuner_type);
968 }
969 }
970
781 return 0; 971 return 0;
782} 972}
783 973
@@ -790,12 +980,64 @@ static int dst_get_vendor(struct dst_state *state)
790 return -1; 980 return -1;
791 } 981 }
792 memset(&state->vendor, '\0', 8); 982 memset(&state->vendor, '\0', 8);
793 memcpy(&state->vendor, &state->rxbuffer, 8); 983 memcpy(&state->vendor, &state->rxbuffer, 7);
794 dprintk(verbose, DST_ERROR, 1, "Vendor=[%s]", &state->vendor[0]); 984 dprintk(verbose, DST_ERROR, 1, "Vendor=[%s]", &state->vendor[0]);
795 985
796 return 0; 986 return 0;
797} 987}
798 988
989static void debug_dst_buffer(struct dst_state *state)
990{
991 int i;
992
993 if (verbose > 2) {
994 printk("%s: [", __func__);
995 for (i = 0; i < 8; i++)
996 printk(" %02x", state->rxbuffer[i]);
997 printk("]\n");
998 }
999}
1000
1001static int dst_check_stv0299(struct dst_state *state)
1002{
1003 u8 check_stv0299[] = { 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
1004
1005 check_stv0299[7] = dst_check_sum(check_stv0299, 7);
1006 if (dst_command(state, check_stv0299, 8) < 0) {
1007 dprintk(verbose, DST_ERROR, 1, "Cmd=[0x04] failed");
1008 return -1;
1009 }
1010 debug_dst_buffer(state);
1011
1012 if (memcmp(&check_stv0299, &state->rxbuffer, 8)) {
1013 dprintk(verbose, DST_ERROR, 1, "Found a STV0299 NIM");
1014 state->tuner_type = TUNER_TYPE_STV0299;
1015 return 0;
1016 }
1017
1018 return -1;
1019}
1020
1021static int dst_check_mb86a15(struct dst_state *state)
1022{
1023 u8 check_mb86a15[] = { 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
1024
1025 check_mb86a15[7] = dst_check_sum(check_mb86a15, 7);
1026 if (dst_command(state, check_mb86a15, 8) < 0) {
1027 dprintk(verbose, DST_ERROR, 1, "Cmd=[0x10], failed");
1028 return -1;
1029 }
1030 debug_dst_buffer(state);
1031
1032 if (memcmp(&check_mb86a15, &state->rxbuffer, 8) < 0) {
1033 dprintk(verbose, DST_ERROR, 1, "Found a MB86A15 NIM");
1034 state->tuner_type = TUNER_TYPE_MB86A15;
1035 return 0;
1036 }
1037
1038 return -1;
1039}
1040
799static int dst_get_tuner_info(struct dst_state *state) 1041static int dst_get_tuner_info(struct dst_state *state)
800{ 1042{
801 u8 get_tuner_1[] = { 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; 1043 u8 get_tuner_1[] = { 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
@@ -803,60 +1045,59 @@ static int dst_get_tuner_info(struct dst_state *state)
803 1045
804 get_tuner_1[7] = dst_check_sum(get_tuner_1, 7); 1046 get_tuner_1[7] = dst_check_sum(get_tuner_1, 7);
805 get_tuner_2[7] = dst_check_sum(get_tuner_2, 7); 1047 get_tuner_2[7] = dst_check_sum(get_tuner_2, 7);
1048 dprintk(verbose, DST_ERROR, 1, "DST TYpe = MULTI FE");
806 if (state->type_flags & DST_TYPE_HAS_MULTI_FE) { 1049 if (state->type_flags & DST_TYPE_HAS_MULTI_FE) {
807 if (dst_command(state, get_tuner_2, 8) < 0) { 1050 if (dst_command(state, get_tuner_1, 8) < 0) {
808 dprintk(verbose, DST_INFO, 1, "Unsupported Command"); 1051 dprintk(verbose, DST_INFO, 1, "Cmd=[0x13], Unsupported");
809 return -1; 1052 goto force;
810 } 1053 }
811 } else { 1054 } else {
812 if (dst_command(state, get_tuner_1, 8) < 0) { 1055 if (dst_command(state, get_tuner_2, 8) < 0) {
813 dprintk(verbose, DST_INFO, 1, "Unsupported Command"); 1056 dprintk(verbose, DST_INFO, 1, "Cmd=[0xb], Unsupported");
814 return -1; 1057 goto force;
815 } 1058 }
816 } 1059 }
817 memset(&state->board_info, '\0', 8); 1060 memset(&state->board_info, '\0', 8);
818 memcpy(&state->board_info, &state->rxbuffer, 8); 1061 memcpy(&state->board_info, &state->rxbuffer, 8);
819 if (state->type_flags & DST_TYPE_HAS_MULTI_FE) { 1062 if (state->type_flags & DST_TYPE_HAS_MULTI_FE) {
820 if (state->board_info[1] == 0x0b) { 1063 dprintk(verbose, DST_ERROR, 1, "DST type has TS=188");
821 if (state->type_flags & DST_TYPE_HAS_TS204) 1064 }
822 state->type_flags &= ~DST_TYPE_HAS_TS204; 1065 if (state->board_info[0] == 0xbc) {
823 state->type_flags |= DST_TYPE_HAS_NEWTUNE; 1066 if (state->type_flags != DST_TYPE_IS_ATSC)
824 dprintk(verbose, DST_INFO, 1, "DST type has TS=188"); 1067 state->type_flags |= DST_TYPE_HAS_TS188;
825 } else { 1068 else
826 if (state->type_flags & DST_TYPE_HAS_NEWTUNE) 1069 state->type_flags |= DST_TYPE_HAS_NEWTUNE_2;
827 state->type_flags &= ~DST_TYPE_HAS_NEWTUNE; 1070
828 state->type_flags |= DST_TYPE_HAS_TS204; 1071 if (state->board_info[1] == 0x01) {
829 dprintk(verbose, DST_INFO, 1, "DST type has TS=204"); 1072 state->dst_hw_cap |= DST_TYPE_HAS_DBOARD;
830 } 1073 dprintk(verbose, DST_ERROR, 1, "DST has Daughterboard");
831 } else {
832 if (state->board_info[0] == 0xbc) {
833 if (state->type_flags & DST_TYPE_HAS_TS204)
834 state->type_flags &= ~DST_TYPE_HAS_TS204;
835 state->type_flags |= DST_TYPE_HAS_NEWTUNE;
836 dprintk(verbose, DST_INFO, 1, "DST type has TS=188, Daughterboard=[%d]", state->board_info[1]);
837
838 } else if (state->board_info[0] == 0xcc) {
839 if (state->type_flags & DST_TYPE_HAS_NEWTUNE)
840 state->type_flags &= ~DST_TYPE_HAS_NEWTUNE;
841 state->type_flags |= DST_TYPE_HAS_TS204;
842 dprintk(verbose, DST_INFO, 1, "DST type has TS=204 Daughterboard=[%d]", state->board_info[1]);
843 } 1074 }
844 } 1075 }
845 1076
846 return 0; 1077 return 0;
1078force:
1079 if (!strncmp(state->fw_name, "DCT-CI", 6)) {
1080 state->type_flags |= DST_TYPE_HAS_TS204;
1081 dprintk(verbose, DST_ERROR, 1, "Forcing [%s] to TS188", state->fw_name);
1082 }
1083
1084 return -1;
847} 1085}
848 1086
849static int dst_get_device_id(struct dst_state *state) 1087static int dst_get_device_id(struct dst_state *state)
850{ 1088{
851 u8 reply; 1089 u8 reply;
852 1090
853 int i; 1091 int i, j;
854 struct dst_types *p_dst_type; 1092 struct dst_types *p_dst_type = NULL;
1093 struct tuner_types *p_tuner_list = NULL;
1094
855 u8 use_dst_type = 0; 1095 u8 use_dst_type = 0;
856 u32 use_type_flags = 0; 1096 u32 use_type_flags = 0;
857 1097
858 static u8 device_type[8] = {0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff}; 1098 static u8 device_type[8] = {0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff};
859 1099
1100 state->tuner_type = 0;
860 device_type[7] = dst_check_sum(device_type, 7); 1101 device_type[7] = dst_check_sum(device_type, 7);
861 1102
862 if (write_dst(state, device_type, FIXED_COMM)) 1103 if (write_dst(state, device_type, FIXED_COMM))
@@ -888,8 +1129,34 @@ static int dst_get_device_id(struct dst_state *state)
888 1129
889 /* Card capabilities */ 1130 /* Card capabilities */
890 state->dst_hw_cap = p_dst_type->dst_feature; 1131 state->dst_hw_cap = p_dst_type->dst_feature;
891 dprintk(verbose, DST_ERROR, 1, "Recognise [%s]\n", p_dst_type->device_id); 1132 dprintk(verbose, DST_ERROR, 1, "Recognise [%s]", p_dst_type->device_id);
892 1133 strncpy(&state->fw_name[0], p_dst_type->device_id, 6);
1134 /* Multiple tuners */
1135 if (p_dst_type->tuner_type & TUNER_TYPE_MULTI) {
1136 switch (use_dst_type) {
1137 case DST_TYPE_IS_SAT:
1138 /* STV0299 check */
1139 if (dst_check_stv0299(state) < 0) {
1140 dprintk(verbose, DST_ERROR, 1, "Unsupported");
1141 state->tuner_type = TUNER_TYPE_MB86A15;
1142 }
1143 break;
1144 default:
1145 break;
1146 }
1147 if (dst_check_mb86a15(state) < 0)
1148 dprintk(verbose, DST_ERROR, 1, "Unsupported");
1149 /* Single tuner */
1150 } else {
1151 state->tuner_type = p_dst_type->tuner_type;
1152 }
1153 for (j = 0, p_tuner_list = tuner_list; j < ARRAY_SIZE(tuner_list); j++, p_tuner_list++) {
1154 if (!(strncmp(p_dst_type->device_id, p_tuner_list->fw_name, 7)) &&
1155 p_tuner_list->tuner_type == state->tuner_type) {
1156 dprintk(verbose, DST_ERROR, 1, "[%s] has a [%s]",
1157 p_dst_type->device_id, p_tuner_list->tuner_name);
1158 }
1159 }
893 break; 1160 break;
894 } 1161 }
895 } 1162 }
@@ -900,10 +1167,10 @@ static int dst_get_device_id(struct dst_state *state)
900 use_dst_type = DST_TYPE_IS_SAT; 1167 use_dst_type = DST_TYPE_IS_SAT;
901 use_type_flags = DST_TYPE_HAS_SYMDIV; 1168 use_type_flags = DST_TYPE_HAS_SYMDIV;
902 } 1169 }
903 dst_type_print(use_dst_type); 1170 dst_type_print(state, use_dst_type);
904 state->type_flags = use_type_flags; 1171 state->type_flags = use_type_flags;
905 state->dst_type = use_dst_type; 1172 state->dst_type = use_dst_type;
906 dst_type_flags_print(state->type_flags); 1173 dst_type_flags_print(state);
907 1174
908 return 0; 1175 return 0;
909} 1176}
@@ -911,15 +1178,15 @@ static int dst_get_device_id(struct dst_state *state)
911static int dst_probe(struct dst_state *state) 1178static int dst_probe(struct dst_state *state)
912{ 1179{
913 mutex_init(&state->dst_mutex); 1180 mutex_init(&state->dst_mutex);
914 if ((rdc_8820_reset(state)) < 0) { 1181 if (dst_addons & DST_TYPE_HAS_CA) {
915 dprintk(verbose, DST_ERROR, 1, "RDC 8820 RESET Failed."); 1182 if ((rdc_8820_reset(state)) < 0) {
916 return -1; 1183 dprintk(verbose, DST_ERROR, 1, "RDC 8820 RESET Failed.");
917 } 1184 return -1;
918 if (dst_addons & DST_TYPE_HAS_CA) 1185 }
919 msleep(4000); 1186 msleep(4000);
920 else 1187 } else {
921 msleep(100); 1188 msleep(100);
922 1189 }
923 if ((dst_comm_init(state)) < 0) { 1190 if ((dst_comm_init(state)) < 0) {
924 dprintk(verbose, DST_ERROR, 1, "DST Initialization Failed."); 1191 dprintk(verbose, DST_ERROR, 1, "DST Initialization Failed.");
925 return -1; 1192 return -1;
@@ -931,7 +1198,6 @@ static int dst_probe(struct dst_state *state)
931 } 1198 }
932 if (dst_get_mac(state) < 0) { 1199 if (dst_get_mac(state) < 0) {
933 dprintk(verbose, DST_INFO, 1, "MAC: Unsupported command"); 1200 dprintk(verbose, DST_INFO, 1, "MAC: Unsupported command");
934 return 0;
935 } 1201 }
936 if ((state->type_flags & DST_TYPE_HAS_MULTI_FE) || (state->type_flags & DST_TYPE_HAS_FW_BUILD)) { 1202 if ((state->type_flags & DST_TYPE_HAS_MULTI_FE) || (state->type_flags & DST_TYPE_HAS_FW_BUILD)) {
937 if (dst_get_tuner_info(state) < 0) 1203 if (dst_get_tuner_info(state) < 0)
@@ -1048,6 +1314,10 @@ static int dst_get_signal(struct dst_state *state)
1048 state->decode_lock = (state->rxbuffer[1]) ? 1 : 0; 1314 state->decode_lock = (state->rxbuffer[1]) ? 1 : 0;
1049 state->decode_strength = state->rxbuffer[4] << 8; 1315 state->decode_strength = state->rxbuffer[4] << 8;
1050 state->decode_snr = state->rxbuffer[3] << 8; 1316 state->decode_snr = state->rxbuffer[3] << 8;
1317 } else if (state->dst_type == DST_TYPE_IS_ATSC) {
1318 state->decode_lock = (state->rxbuffer[6] == 0x00) ? 1 : 0;
1319 state->decode_strength = state->rxbuffer[4] << 8;
1320 state->decode_snr = state->rxbuffer[2] << 8 | state->rxbuffer[3];
1051 } 1321 }
1052 state->cur_jiff = jiffies; 1322 state->cur_jiff = jiffies;
1053 } 1323 }
@@ -1078,8 +1348,9 @@ static int dst_get_tuna(struct dst_state *state)
1078 state->diseq_flags &= ~(HAS_LOCK); 1348 state->diseq_flags &= ~(HAS_LOCK);
1079 if (!dst_wait_dst_ready(state, NO_DELAY)) 1349 if (!dst_wait_dst_ready(state, NO_DELAY))
1080 return -EIO; 1350 return -EIO;
1081 if (state->type_flags & DST_TYPE_HAS_NEWTUNE) 1351 if ((state->type_flags & DST_TYPE_HAS_VLF) &&
1082 /* how to get variable length reply ???? */ 1352 !(state->dst_type == DST_TYPE_IS_ATSC))
1353
1083 retval = read_dst(state, state->rx_tuna, 10); 1354 retval = read_dst(state, state->rx_tuna, 10);
1084 else 1355 else
1085 retval = read_dst(state, &state->rx_tuna[2], FIXED_COMM); 1356 retval = read_dst(state, &state->rx_tuna[2], FIXED_COMM);
@@ -1087,7 +1358,10 @@ static int dst_get_tuna(struct dst_state *state)
1087 dprintk(verbose, DST_DEBUG, 1, "read not successful"); 1358 dprintk(verbose, DST_DEBUG, 1, "read not successful");
1088 return retval; 1359 return retval;
1089 } 1360 }
1090 if (state->type_flags & DST_TYPE_HAS_NEWTUNE) { 1361 if ((state->type_flags & DST_TYPE_HAS_VLF) &&
1362 !(state->dst_type == DST_TYPE_IS_CABLE) &&
1363 !(state->dst_type == DST_TYPE_IS_ATSC)) {
1364
1091 if (state->rx_tuna[9] != dst_check_sum(&state->rx_tuna[0], 9)) { 1365 if (state->rx_tuna[9] != dst_check_sum(&state->rx_tuna[0], 9)) {
1092 dprintk(verbose, DST_INFO, 1, "checksum failure ? "); 1366 dprintk(verbose, DST_INFO, 1, "checksum failure ? ");
1093 return -EIO; 1367 return -EIO;
@@ -1133,7 +1407,10 @@ static int dst_write_tuna(struct dvb_frontend *fe)
1133 dprintk(verbose, DST_DEBUG, 1, "DST Communication initialization failed."); 1407 dprintk(verbose, DST_DEBUG, 1, "DST Communication initialization failed.");
1134 goto error; 1408 goto error;
1135 } 1409 }
1136 if (state->type_flags & DST_TYPE_HAS_NEWTUNE) { 1410// if (state->type_flags & DST_TYPE_HAS_NEWTUNE) {
1411 if ((state->type_flags & DST_TYPE_HAS_VLF) &&
1412 (!(state->dst_type == DST_TYPE_IS_ATSC))) {
1413
1137 state->tx_tuna[9] = dst_check_sum(&state->tx_tuna[0], 9); 1414 state->tx_tuna[9] = dst_check_sum(&state->tx_tuna[0], 9);
1138 retval = write_dst(state, &state->tx_tuna[0], 10); 1415 retval = write_dst(state, &state->tx_tuna[0], 10);
1139 } else { 1416 } else {
@@ -1189,9 +1466,12 @@ static int dst_set_diseqc(struct dvb_frontend *fe, struct dvb_diseqc_master_cmd
1189 1466
1190 if (state->dst_type != DST_TYPE_IS_SAT) 1467 if (state->dst_type != DST_TYPE_IS_SAT)
1191 return 0; 1468 return 0;
1192 if (cmd->msg_len == 0 || cmd->msg_len > 4) 1469 if (cmd->msg_len > 0 && cmd->msg_len < 5)
1470 memcpy(&paket[3], cmd->msg, cmd->msg_len);
1471 else if (cmd->msg_len == 5 && state->dst_hw_cap & DST_TYPE_HAS_DISEQC5)
1472 memcpy(&paket[2], cmd->msg, cmd->msg_len);
1473 else
1193 return -EINVAL; 1474 return -EINVAL;
1194 memcpy(&paket[3], cmd->msg, cmd->msg_len);
1195 paket[7] = dst_check_sum(&paket[0], 7); 1475 paket[7] = dst_check_sum(&paket[0], 7);
1196 dst_command(state, paket, 8); 1476 dst_command(state, paket, 8);
1197 return 0; 1477 return 0;
@@ -1287,8 +1567,9 @@ static int dst_init(struct dvb_frontend *fe)
1287 static u8 sat_tuna_204[] = { 0x00, 0x00, 0x03, 0xb6, 0x01, 0x55, 0xbd, 0x50, 0x00, 0x00 }; 1567 static u8 sat_tuna_204[] = { 0x00, 0x00, 0x03, 0xb6, 0x01, 0x55, 0xbd, 0x50, 0x00, 0x00 };
1288 static u8 ter_tuna_188[] = { 0x09, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 }; 1568 static u8 ter_tuna_188[] = { 0x09, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 };
1289 static u8 ter_tuna_204[] = { 0x00, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 }; 1569 static u8 ter_tuna_204[] = { 0x00, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 };
1290 static u8 cab_tuna_204[] = { 0x00, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 };
1291 static u8 cab_tuna_188[] = { 0x09, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 }; 1570 static u8 cab_tuna_188[] = { 0x09, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 };
1571 static u8 cab_tuna_204[] = { 0x00, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 };
1572 static u8 atsc_tuner[] = { 0x00, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 };
1292 1573
1293 state->inversion = INVERSION_OFF; 1574 state->inversion = INVERSION_OFF;
1294 state->voltage = SEC_VOLTAGE_13; 1575 state->voltage = SEC_VOLTAGE_13;
@@ -1298,11 +1579,13 @@ static int dst_init(struct dvb_frontend *fe)
1298 state->bandwidth = BANDWIDTH_7_MHZ; 1579 state->bandwidth = BANDWIDTH_7_MHZ;
1299 state->cur_jiff = jiffies; 1580 state->cur_jiff = jiffies;
1300 if (state->dst_type == DST_TYPE_IS_SAT) 1581 if (state->dst_type == DST_TYPE_IS_SAT)
1301 memcpy(state->tx_tuna, ((state->type_flags & DST_TYPE_HAS_NEWTUNE) ? sat_tuna_188 : sat_tuna_204), sizeof (sat_tuna_204)); 1582 memcpy(state->tx_tuna, ((state->type_flags & DST_TYPE_HAS_VLF) ? sat_tuna_188 : sat_tuna_204), sizeof (sat_tuna_204));
1302 else if (state->dst_type == DST_TYPE_IS_TERR) 1583 else if (state->dst_type == DST_TYPE_IS_TERR)
1303 memcpy(state->tx_tuna, ((state->type_flags & DST_TYPE_HAS_NEWTUNE) ? ter_tuna_188 : ter_tuna_204), sizeof (ter_tuna_204)); 1584 memcpy(state->tx_tuna, ((state->type_flags & DST_TYPE_HAS_VLF) ? ter_tuna_188 : ter_tuna_204), sizeof (ter_tuna_204));
1304 else if (state->dst_type == DST_TYPE_IS_CABLE) 1585 else if (state->dst_type == DST_TYPE_IS_CABLE)
1305 memcpy(state->tx_tuna, ((state->type_flags & DST_TYPE_HAS_NEWTUNE) ? cab_tuna_188 : cab_tuna_204), sizeof (cab_tuna_204)); 1586 memcpy(state->tx_tuna, ((state->type_flags & DST_TYPE_HAS_VLF) ? cab_tuna_188 : cab_tuna_204), sizeof (cab_tuna_204));
1587 else if (state->dst_type == DST_TYPE_IS_ATSC)
1588 memcpy(state->tx_tuna, atsc_tuner, sizeof (atsc_tuner));
1306 1589
1307 return 0; 1590 return 0;
1308} 1591}
@@ -1341,7 +1624,36 @@ static int dst_read_snr(struct dvb_frontend *fe, u16 *snr)
1341 return 0; 1624 return 0;
1342} 1625}
1343 1626
1344static int dst_set_frontend(struct dvb_frontend* fe, 1627static int dst_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *p)
1628{
1629 struct dst_state *state = fe->demodulator_priv;
1630
1631 if (p != NULL) {
1632 dst_set_freq(state, p->frequency);
1633 dprintk(verbose, DST_DEBUG, 1, "Set Frequency=[%d]", p->frequency);
1634
1635 if (state->dst_type == DST_TYPE_IS_SAT) {
1636 if (state->type_flags & DST_TYPE_HAS_OBS_REGS)
1637 dst_set_inversion(state, p->inversion);
1638 dst_set_fec(state, p->u.qpsk.fec_inner);
1639 dst_set_symbolrate(state, p->u.qpsk.symbol_rate);
1640 dst_set_polarization(state);
1641 dprintk(verbose, DST_DEBUG, 1, "Set Symbolrate=[%d]", p->u.qpsk.symbol_rate);
1642
1643 } else if (state->dst_type == DST_TYPE_IS_TERR)
1644 dst_set_bandwidth(state, p->u.ofdm.bandwidth);
1645 else if (state->dst_type == DST_TYPE_IS_CABLE) {
1646 dst_set_fec(state, p->u.qam.fec_inner);
1647 dst_set_symbolrate(state, p->u.qam.symbol_rate);
1648 dst_set_modulation(state, p->u.qam.modulation);
1649 }
1650 dst_write_tuna(fe);
1651 }
1652
1653 return 0;
1654}
1655
1656static int dst_tune_frontend(struct dvb_frontend* fe,
1345 struct dvb_frontend_parameters* p, 1657 struct dvb_frontend_parameters* p,
1346 unsigned int mode_flags, 1658 unsigned int mode_flags,
1347 int *delay, 1659 int *delay,
@@ -1378,6 +1690,11 @@ static int dst_set_frontend(struct dvb_frontend* fe,
1378 return 0; 1690 return 0;
1379} 1691}
1380 1692
1693static int dst_get_tuning_algo(struct dvb_frontend *fe)
1694{
1695 return dst_algo;
1696}
1697
1381static int dst_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *p) 1698static int dst_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *p)
1382{ 1699{
1383 struct dst_state *state = fe->demodulator_priv; 1700 struct dst_state *state = fe->demodulator_priv;
@@ -1408,6 +1725,7 @@ static void dst_release(struct dvb_frontend *fe)
1408static struct dvb_frontend_ops dst_dvbt_ops; 1725static struct dvb_frontend_ops dst_dvbt_ops;
1409static struct dvb_frontend_ops dst_dvbs_ops; 1726static struct dvb_frontend_ops dst_dvbs_ops;
1410static struct dvb_frontend_ops dst_dvbc_ops; 1727static struct dvb_frontend_ops dst_dvbc_ops;
1728static struct dvb_frontend_ops dst_atsc_ops;
1411 1729
1412struct dst_state *dst_attach(struct dst_state *state, struct dvb_adapter *dvb_adapter) 1730struct dst_state *dst_attach(struct dst_state *state, struct dvb_adapter *dvb_adapter)
1413{ 1731{
@@ -1417,24 +1735,25 @@ struct dst_state *dst_attach(struct dst_state *state, struct dvb_adapter *dvb_ad
1417 return NULL; 1735 return NULL;
1418 } 1736 }
1419 /* determine settings based on type */ 1737 /* determine settings based on type */
1738 /* create dvb_frontend */
1420 switch (state->dst_type) { 1739 switch (state->dst_type) {
1421 case DST_TYPE_IS_TERR: 1740 case DST_TYPE_IS_TERR:
1422 memcpy(&state->ops, &dst_dvbt_ops, sizeof(struct dvb_frontend_ops)); 1741 memcpy(&state->frontend.ops, &dst_dvbt_ops, sizeof(struct dvb_frontend_ops));
1423 break; 1742 break;
1424 case DST_TYPE_IS_CABLE: 1743 case DST_TYPE_IS_CABLE:
1425 memcpy(&state->ops, &dst_dvbc_ops, sizeof(struct dvb_frontend_ops)); 1744 memcpy(&state->frontend.ops, &dst_dvbc_ops, sizeof(struct dvb_frontend_ops));
1426 break; 1745 break;
1427 case DST_TYPE_IS_SAT: 1746 case DST_TYPE_IS_SAT:
1428 memcpy(&state->ops, &dst_dvbs_ops, sizeof(struct dvb_frontend_ops)); 1747 memcpy(&state->frontend.ops, &dst_dvbs_ops, sizeof(struct dvb_frontend_ops));
1748 break;
1749 case DST_TYPE_IS_ATSC:
1750 memcpy(&state->frontend.ops, &dst_atsc_ops, sizeof(struct dvb_frontend_ops));
1429 break; 1751 break;
1430 default: 1752 default:
1431 dprintk(verbose, DST_ERROR, 1, "unknown DST type. please report to the LinuxTV.org DVB mailinglist."); 1753 dprintk(verbose, DST_ERROR, 1, "unknown DST type. please report to the LinuxTV.org DVB mailinglist.");
1432 kfree(state); 1754 kfree(state);
1433 return NULL; 1755 return NULL;
1434 } 1756 }
1435
1436 /* create dvb_frontend */
1437 state->frontend.ops = &state->ops;
1438 state->frontend.demodulator_priv = state; 1757 state->frontend.demodulator_priv = state;
1439 1758
1440 return state; /* Manu (DST is a card not a frontend) */ 1759 return state; /* Manu (DST is a card not a frontend) */
@@ -1455,8 +1774,10 @@ static struct dvb_frontend_ops dst_dvbt_ops = {
1455 1774
1456 .release = dst_release, 1775 .release = dst_release,
1457 .init = dst_init, 1776 .init = dst_init,
1458 .tune = dst_set_frontend, 1777 .tune = dst_tune_frontend,
1778 .set_frontend = dst_set_frontend,
1459 .get_frontend = dst_get_frontend, 1779 .get_frontend = dst_get_frontend,
1780 .get_frontend_algo = dst_get_tuning_algo,
1460 .read_status = dst_read_status, 1781 .read_status = dst_read_status,
1461 .read_signal_strength = dst_read_signal_strength, 1782 .read_signal_strength = dst_read_signal_strength,
1462 .read_snr = dst_read_snr, 1783 .read_snr = dst_read_snr,
@@ -1479,8 +1800,10 @@ static struct dvb_frontend_ops dst_dvbs_ops = {
1479 1800
1480 .release = dst_release, 1801 .release = dst_release,
1481 .init = dst_init, 1802 .init = dst_init,
1482 .tune = dst_set_frontend, 1803 .tune = dst_tune_frontend,
1804 .set_frontend = dst_set_frontend,
1483 .get_frontend = dst_get_frontend, 1805 .get_frontend = dst_get_frontend,
1806 .get_frontend_algo = dst_get_tuning_algo,
1484 .read_status = dst_read_status, 1807 .read_status = dst_read_status,
1485 .read_signal_strength = dst_read_signal_strength, 1808 .read_signal_strength = dst_read_signal_strength,
1486 .read_snr = dst_read_snr, 1809 .read_snr = dst_read_snr,
@@ -1506,13 +1829,38 @@ static struct dvb_frontend_ops dst_dvbc_ops = {
1506 1829
1507 .release = dst_release, 1830 .release = dst_release,
1508 .init = dst_init, 1831 .init = dst_init,
1509 .tune = dst_set_frontend, 1832 .tune = dst_tune_frontend,
1833 .set_frontend = dst_set_frontend,
1834 .get_frontend = dst_get_frontend,
1835 .get_frontend_algo = dst_get_tuning_algo,
1836 .read_status = dst_read_status,
1837 .read_signal_strength = dst_read_signal_strength,
1838 .read_snr = dst_read_snr,
1839};
1840
1841static struct dvb_frontend_ops dst_atsc_ops = {
1842 .info = {
1843 .name = "DST ATSC",
1844 .type = FE_ATSC,
1845 .frequency_stepsize = 62500,
1846 .frequency_min = 510000000,
1847 .frequency_max = 858000000,
1848 .symbol_rate_min = 1000000,
1849 .symbol_rate_max = 45000000,
1850 .caps = FE_CAN_FEC_AUTO | FE_CAN_QAM_AUTO | FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB
1851 },
1852
1853 .release = dst_release,
1854 .init = dst_init,
1855 .tune = dst_tune_frontend,
1856 .set_frontend = dst_set_frontend,
1510 .get_frontend = dst_get_frontend, 1857 .get_frontend = dst_get_frontend,
1858 .get_frontend_algo = dst_get_tuning_algo,
1511 .read_status = dst_read_status, 1859 .read_status = dst_read_status,
1512 .read_signal_strength = dst_read_signal_strength, 1860 .read_signal_strength = dst_read_signal_strength,
1513 .read_snr = dst_read_snr, 1861 .read_snr = dst_read_snr,
1514}; 1862};
1515 1863
1516MODULE_DESCRIPTION("DST DVB-S/T/C Combo Frontend driver"); 1864MODULE_DESCRIPTION("DST DVB-S/T/C/ATSC Combo Frontend driver");
1517MODULE_AUTHOR("Jamie Honan, Manu Abraham"); 1865MODULE_AUTHOR("Jamie Honan, Manu Abraham");
1518MODULE_LICENSE("GPL"); 1866MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/bt8xx/dst_ca.c b/drivers/media/dvb/bt8xx/dst_ca.c
index f6b49a801eba..fa923b9b346e 100644
--- a/drivers/media/dvb/bt8xx/dst_ca.c
+++ b/drivers/media/dvb/bt8xx/dst_ca.c
@@ -68,6 +68,13 @@ static int ca_set_pid(void)
68 return -EOPNOTSUPP; 68 return -EOPNOTSUPP;
69} 69}
70 70
71static void put_command_and_length(u8 *data, int command, int length)
72{
73 data[0] = (command >> 16) & 0xff;
74 data[1] = (command >> 8) & 0xff;
75 data[2] = command & 0xff;
76 data[3] = length;
77}
71 78
72static void put_checksum(u8 *check_string, int length) 79static void put_checksum(u8 *check_string, int length)
73{ 80{
@@ -124,15 +131,18 @@ static int dst_put_ci(struct dst_state *state, u8 *data, int len, u8 *ca_string,
124 u8 dst_ca_comm_err = 0; 131 u8 dst_ca_comm_err = 0;
125 132
126 while (dst_ca_comm_err < RETRIES) { 133 while (dst_ca_comm_err < RETRIES) {
127 dst_comm_init(state);
128 dprintk(verbose, DST_CA_NOTICE, 1, " Put Command"); 134 dprintk(verbose, DST_CA_NOTICE, 1, " Put Command");
129 if (dst_ci_command(state, data, ca_string, len, read)) { // If error 135 if (dst_ci_command(state, data, ca_string, len, read)) { // If error
130 dst_error_recovery(state); 136 dst_error_recovery(state);
131 dst_ca_comm_err++; // work required here. 137 dst_ca_comm_err++; // work required here.
138 } else {
139 break;
132 } 140 }
133 break;
134 } 141 }
135 142
143 if(dst_ca_comm_err == RETRIES)
144 return -1;
145
136 return 0; 146 return 0;
137} 147}
138 148
@@ -140,6 +150,7 @@ static int dst_put_ci(struct dst_state *state, u8 *data, int len, u8 *ca_string,
140 150
141static int ca_get_app_info(struct dst_state *state) 151static int ca_get_app_info(struct dst_state *state)
142{ 152{
153 int length, str_length;
143 static u8 command[8] = {0x07, 0x40, 0x01, 0x00, 0x01, 0x00, 0x00, 0xff}; 154 static u8 command[8] = {0x07, 0x40, 0x01, 0x00, 0x01, 0x00, 0x00, 0xff};
144 155
145 put_checksum(&command[0], command[0]); 156 put_checksum(&command[0], command[0]);
@@ -154,6 +165,68 @@ static int ca_get_app_info(struct dst_state *state)
154 (state->messages[10] << 8) | state->messages[11], __FUNCTION__, (char *)(&state->messages[12])); 165 (state->messages[10] << 8) | state->messages[11], __FUNCTION__, (char *)(&state->messages[12]));
155 dprintk(verbose, DST_CA_INFO, 1, " =================================================================================================="); 166 dprintk(verbose, DST_CA_INFO, 1, " ==================================================================================================");
156 167
168 // Transform dst message to correct application_info message
169 length = state->messages[5];
170 str_length = length - 6;
171 if (str_length < 0) {
172 str_length = 0;
173 dprintk(verbose, DST_CA_ERROR, 1, "Invalid string length returned in ca_get_app_info(). Recovering.");
174 }
175
176 // First, the command and length fields
177 put_command_and_length(&state->messages[0], CA_APP_INFO, length);
178
179 // Copy application_type, application_manufacturer and manufacturer_code
180 memcpy(&state->messages[4], &state->messages[7], 5);
181
182 // Set string length and copy string
183 state->messages[9] = str_length;
184 memcpy(&state->messages[10], &state->messages[12], str_length);
185
186 return 0;
187}
188
189static int ca_get_ca_info(struct dst_state *state)
190{
191 int srcPtr, dstPtr, i, num_ids;
192 static u8 slot_command[8] = {0x07, 0x40, 0x00, 0x00, 0x02, 0x00, 0x00, 0xff};
193 const int in_system_id_pos = 8, out_system_id_pos = 4, in_num_ids_pos = 7;
194
195 put_checksum(&slot_command[0], slot_command[0]);
196 if ((dst_put_ci(state, slot_command, sizeof (slot_command), state->messages, GET_REPLY)) < 0) {
197 dprintk(verbose, DST_CA_ERROR, 1, " -->dst_put_ci FAILED !");
198 return -1;
199 }
200 dprintk(verbose, DST_CA_INFO, 1, " -->dst_put_ci SUCCESS !");
201
202 // Print raw data
203 dprintk(verbose, DST_CA_INFO, 0, " DST data = [");
204 for (i = 0; i < state->messages[0] + 1; i++) {
205 dprintk(verbose, DST_CA_INFO, 0, " 0x%02x", state->messages[i]);
206 }
207 dprintk(verbose, DST_CA_INFO, 0, "]\n");
208
209 // Set the command and length of the output
210 num_ids = state->messages[in_num_ids_pos];
211 if (num_ids >= 100) {
212 num_ids = 100;
213 dprintk(verbose, DST_CA_ERROR, 1, "Invalid number of ids (>100). Recovering.");
214 }
215 put_command_and_length(&state->messages[0], CA_INFO, num_ids * 2);
216
217 dprintk(verbose, DST_CA_INFO, 0, " CA_INFO = [");
218 srcPtr = in_system_id_pos;
219 dstPtr = out_system_id_pos;
220 for(i = 0; i < num_ids; i++) {
221 dprintk(verbose, DST_CA_INFO, 0, " 0x%02x%02x", state->messages[srcPtr + 0], state->messages[srcPtr + 1]);
222 // Append to output
223 state->messages[dstPtr + 0] = state->messages[srcPtr + 0];
224 state->messages[dstPtr + 1] = state->messages[srcPtr + 1];
225 srcPtr += 2;
226 dstPtr += 2;
227 }
228 dprintk(verbose, DST_CA_INFO, 0, "]\n");
229
157 return 0; 230 return 0;
158} 231}
159 232
@@ -174,7 +247,7 @@ static int ca_get_slot_caps(struct dst_state *state, struct ca_caps *p_ca_caps,
174 247
175 dprintk(verbose, DST_CA_INFO, 1, " Slot cap = [%d]", slot_cap[7]); 248 dprintk(verbose, DST_CA_INFO, 1, " Slot cap = [%d]", slot_cap[7]);
176 dprintk(verbose, DST_CA_INFO, 0, "===================================\n"); 249 dprintk(verbose, DST_CA_INFO, 0, "===================================\n");
177 for (i = 0; i < 8; i++) 250 for (i = 0; i < slot_cap[0] + 1; i++)
178 dprintk(verbose, DST_CA_INFO, 0, " %d", slot_cap[i]); 251 dprintk(verbose, DST_CA_INFO, 0, " %d", slot_cap[i]);
179 dprintk(verbose, DST_CA_INFO, 0, "\n"); 252 dprintk(verbose, DST_CA_INFO, 0, "\n");
180 253
@@ -260,6 +333,11 @@ static int ca_get_message(struct dst_state *state, struct ca_msg *p_ca_message,
260 if (copy_to_user(arg, p_ca_message, sizeof (struct ca_msg)) ) 333 if (copy_to_user(arg, p_ca_message, sizeof (struct ca_msg)) )
261 return -EFAULT; 334 return -EFAULT;
262 break; 335 break;
336 case CA_INFO:
337 memcpy(p_ca_message->msg, state->messages, 128);
338 if (copy_to_user(arg, p_ca_message, sizeof (struct ca_msg)) )
339 return -EFAULT;
340 break;
263 } 341 }
264 } 342 }
265 343
@@ -302,7 +380,7 @@ static int write_to_8820(struct dst_state *state, struct ca_msg *hw_buffer, u8 l
302 rdc_reset_state(state); 380 rdc_reset_state(state);
303 return -1; 381 return -1;
304 } 382 }
305 dprintk(verbose, DST_CA_NOTICE, 1, " DST-CI Command succes."); 383 dprintk(verbose, DST_CA_NOTICE, 1, " DST-CI Command success.");
306 384
307 return 0; 385 return 0;
308} 386}
@@ -340,6 +418,7 @@ static int debug_string(u8 *msg, u32 length, u32 offset)
340 return 0; 418 return 0;
341} 419}
342 420
421
343static int ca_set_pmt(struct dst_state *state, struct ca_msg *p_ca_message, struct ca_msg *hw_buffer, u8 reply, u8 query) 422static int ca_set_pmt(struct dst_state *state, struct ca_msg *p_ca_message, struct ca_msg *hw_buffer, u8 reply, u8 query)
344{ 423{
345 u32 length = 0; 424 u32 length = 0;
@@ -455,6 +534,16 @@ static int ca_send_message(struct dst_state *state, struct ca_msg *p_ca_message,
455 } 534 }
456 dprintk(verbose, DST_CA_INFO, 1, " -->CA_APP_INFO_ENQUIRY Success !"); 535 dprintk(verbose, DST_CA_INFO, 1, " -->CA_APP_INFO_ENQUIRY Success !");
457 break; 536 break;
537 case CA_INFO_ENQUIRY:
538 dprintk(verbose, DST_CA_INFO, 1, " Getting CA Information");
539
540 if ((ca_get_ca_info(state)) < 0) {
541 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_INFO_ENQUIRY Failed !");
542 result = -1;
543 goto free_mem_and_exit;
544 }
545 dprintk(verbose, DST_CA_INFO, 1, " -->CA_INFO_ENQUIRY Success !");
546 break;
458 } 547 }
459 } 548 }
460free_mem_and_exit: 549free_mem_and_exit:
@@ -473,18 +562,15 @@ static int dst_ca_ioctl(struct inode *inode, struct file *file, unsigned int cmd
473 void __user *arg = (void __user *)ioctl_arg; 562 void __user *arg = (void __user *)ioctl_arg;
474 int result = 0; 563 int result = 0;
475 564
476 if ((p_ca_message = (struct ca_msg *) kmalloc(sizeof (struct ca_msg), GFP_KERNEL)) == NULL) { 565 p_ca_message = kmalloc(sizeof (struct ca_msg), GFP_KERNEL);
477 dprintk(verbose, DST_CA_ERROR, 1, " Memory allocation failure"); 566 p_ca_slot_info = kmalloc(sizeof (struct ca_slot_info), GFP_KERNEL);
478 return -ENOMEM; 567 p_ca_caps = kmalloc(sizeof (struct ca_caps), GFP_KERNEL);
479 } 568 if (!p_ca_message || !p_ca_slot_info || !p_ca_caps) {
480 if ((p_ca_slot_info = (struct ca_slot_info *) kmalloc(sizeof (struct ca_slot_info), GFP_KERNEL)) == NULL) {
481 dprintk(verbose, DST_CA_ERROR, 1, " Memory allocation failure"); 569 dprintk(verbose, DST_CA_ERROR, 1, " Memory allocation failure");
482 return -ENOMEM; 570 result = -ENOMEM;
483 } 571 goto free_mem_and_exit;
484 if ((p_ca_caps = (struct ca_caps *) kmalloc(sizeof (struct ca_caps), GFP_KERNEL)) == NULL) {
485 dprintk(verbose, DST_CA_ERROR, 1, " Memory allocation failure");
486 return -ENOMEM;
487 } 572 }
573
488 /* We have now only the standard ioctl's, the driver is upposed to handle internals. */ 574 /* We have now only the standard ioctl's, the driver is upposed to handle internals. */
489 switch (cmd) { 575 switch (cmd) {
490 case CA_SEND_MSG: 576 case CA_SEND_MSG:
@@ -582,7 +668,7 @@ static int dst_ca_release(struct inode *inode, struct file *file)
582 668
583static ssize_t dst_ca_read(struct file *file, char __user *buffer, size_t length, loff_t *offset) 669static ssize_t dst_ca_read(struct file *file, char __user *buffer, size_t length, loff_t *offset)
584{ 670{
585 int bytes_read = 0; 671 ssize_t bytes_read = 0;
586 672
587 dprintk(verbose, DST_CA_DEBUG, 1, " Device read."); 673 dprintk(verbose, DST_CA_DEBUG, 1, " Device read.");
588 674
diff --git a/drivers/media/dvb/bt8xx/dst_common.h b/drivers/media/dvb/bt8xx/dst_common.h
index 51d4e043716c..0677b047b3a7 100644
--- a/drivers/media/dvb/bt8xx/dst_common.h
+++ b/drivers/media/dvb/bt8xx/dst_common.h
@@ -42,7 +42,7 @@
42#define DST_TYPE_IS_CABLE 2 42#define DST_TYPE_IS_CABLE 2
43#define DST_TYPE_IS_ATSC 3 43#define DST_TYPE_IS_ATSC 3
44 44
45#define DST_TYPE_HAS_NEWTUNE 1 45#define DST_TYPE_HAS_TS188 1
46#define DST_TYPE_HAS_TS204 2 46#define DST_TYPE_HAS_TS204 2
47#define DST_TYPE_HAS_SYMDIV 4 47#define DST_TYPE_HAS_SYMDIV 4
48#define DST_TYPE_HAS_FW_1 8 48#define DST_TYPE_HAS_FW_1 8
@@ -52,6 +52,9 @@
52#define DST_TYPE_HAS_OBS_REGS 128 52#define DST_TYPE_HAS_OBS_REGS 128
53#define DST_TYPE_HAS_INC_COUNT 256 53#define DST_TYPE_HAS_INC_COUNT 256
54#define DST_TYPE_HAS_MULTI_FE 512 54#define DST_TYPE_HAS_MULTI_FE 512
55#define DST_TYPE_HAS_NEWTUNE_2 1024
56#define DST_TYPE_HAS_DBOARD 2048
57#define DST_TYPE_HAS_VLF 4096
55 58
56/* Card capability list */ 59/* Card capability list */
57 60
@@ -64,6 +67,20 @@
64#define DST_TYPE_HAS_ANALOG 64 /* Analog inputs */ 67#define DST_TYPE_HAS_ANALOG 64 /* Analog inputs */
65#define DST_TYPE_HAS_SESSION 128 68#define DST_TYPE_HAS_SESSION 128
66 69
70#define TUNER_TYPE_MULTI 1
71#define TUNER_TYPE_UNKNOWN 2
72/* DVB-S */
73#define TUNER_TYPE_L64724 4
74#define TUNER_TYPE_STV0299 8
75#define TUNER_TYPE_MB86A15 16
76
77/* DVB-T */
78#define TUNER_TYPE_TDA10046 32
79
80/* ATSC */
81#define TUNER_TYPE_NXT200x 64
82
83
67#define RDC_8820_PIO_0_DISABLE 0 84#define RDC_8820_PIO_0_DISABLE 0
68#define RDC_8820_PIO_0_ENABLE 1 85#define RDC_8820_PIO_0_ENABLE 1
69#define RDC_8820_INT 2 86#define RDC_8820_INT 2
@@ -84,8 +101,6 @@ struct dst_state {
84 101
85 struct bt878* bt; 102 struct bt878* bt;
86 103
87 struct dvb_frontend_ops ops;
88
89 /* configuration settings */ 104 /* configuration settings */
90 const struct dst_config* config; 105 const struct dst_config* config;
91 106
@@ -121,8 +136,17 @@ struct dst_state {
121 u8 card_info[8]; 136 u8 card_info[8];
122 u8 vendor[8]; 137 u8 vendor[8];
123 u8 board_info[8]; 138 u8 board_info[8];
124 139 u32 tuner_type;
140 char *tuner_name;
125 struct mutex dst_mutex; 141 struct mutex dst_mutex;
142 u8 fw_name[8];
143};
144
145struct tuner_types {
146 u32 tuner_type;
147 char *tuner_name;
148 char *board_name;
149 char *fw_name;
126}; 150};
127 151
128struct dst_types { 152struct dst_types {
@@ -131,6 +155,7 @@ struct dst_types {
131 u8 dst_type; 155 u8 dst_type;
132 u32 type_flags; 156 u32 type_flags;
133 u32 dst_feature; 157 u32 dst_feature;
158 u32 tuner_type;
134}; 159};
135 160
136struct dst_config 161struct dst_config
diff --git a/drivers/media/dvb/bt8xx/dvb-bt8xx.c b/drivers/media/dvb/bt8xx/dvb-bt8xx.c
index ccc7b2eb4a2d..b715b972d2fc 100644
--- a/drivers/media/dvb/bt8xx/dvb-bt8xx.c
+++ b/drivers/media/dvb/bt8xx/dvb-bt8xx.c
@@ -147,12 +147,15 @@ static int thomson_dtt7579_demod_init(struct dvb_frontend* fe)
147 return 0; 147 return 0;
148} 148}
149 149
150static int thomson_dtt7579_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params, u8* pllbuf) 150static int thomson_dtt7579_tuner_calc_regs(struct dvb_frontend* fe, struct dvb_frontend_parameters* params, u8* pllbuf, int buf_len)
151{ 151{
152 u32 div; 152 u32 div;
153 unsigned char bs = 0; 153 unsigned char bs = 0;
154 unsigned char cp = 0; 154 unsigned char cp = 0;
155 155
156 if (buf_len < 5)
157 return -EINVAL;
158
156 div = (((params->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6; 159 div = (((params->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6;
157 160
158 if (params->frequency < 542000000) 161 if (params->frequency < 542000000)
@@ -169,22 +172,25 @@ static int thomson_dtt7579_pll_set(struct dvb_frontend* fe, struct dvb_frontend_
169 else 172 else
170 bs = 0x08; 173 bs = 0x08;
171 174
172 pllbuf[0] = 0xc0; // Note: non-linux standard PLL i2c address 175 pllbuf[0] = 0x60;
173 pllbuf[1] = div >> 8; 176 pllbuf[1] = div >> 8;
174 pllbuf[2] = div & 0xff; 177 pllbuf[2] = div & 0xff;
175 pllbuf[3] = cp; 178 pllbuf[3] = cp;
176 pllbuf[4] = bs; 179 pllbuf[4] = bs;
177 180
178 return 0; 181 return 5;
179} 182}
180 183
181static struct mt352_config thomson_dtt7579_config = { 184static struct mt352_config thomson_dtt7579_config = {
182 .demod_address = 0x0f, 185 .demod_address = 0x0f,
183 .demod_init = thomson_dtt7579_demod_init, 186 .demod_init = thomson_dtt7579_demod_init,
184 .pll_set = thomson_dtt7579_pll_set,
185}; 187};
186 188
187static int cx24108_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) 189static struct zl10353_config thomson_dtt7579_zl10353_config = {
190 .demod_address = 0x0f,
191};
192
193static int cx24108_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
188{ 194{
189 u32 freq = params->frequency; 195 u32 freq = params->frequency;
190 196
@@ -237,7 +243,7 @@ static int cx24108_pll_set(struct dvb_frontend* fe, struct dvb_frontend_paramete
237 return 0; 243 return 0;
238} 244}
239 245
240static int pinnsat_pll_init(struct dvb_frontend* fe) 246static int pinnsat_tuner_init(struct dvb_frontend* fe)
241{ 247{
242 struct dvb_bt8xx_card *card = fe->dvb->priv; 248 struct dvb_bt8xx_card *card = fe->dvb->priv;
243 249
@@ -247,7 +253,7 @@ static int pinnsat_pll_init(struct dvb_frontend* fe)
247 return 0; 253 return 0;
248} 254}
249 255
250static int pinnsat_pll_sleep(struct dvb_frontend* fe) 256static int pinnsat_tuner_sleep(struct dvb_frontend* fe)
251{ 257{
252 struct dvb_bt8xx_card *card = fe->dvb->priv; 258 struct dvb_bt8xx_card *card = fe->dvb->priv;
253 259
@@ -258,12 +264,9 @@ static int pinnsat_pll_sleep(struct dvb_frontend* fe)
258 264
259static struct cx24110_config pctvsat_config = { 265static struct cx24110_config pctvsat_config = {
260 .demod_address = 0x55, 266 .demod_address = 0x55,
261 .pll_init = pinnsat_pll_init,
262 .pll_set = cx24108_pll_set,
263 .pll_sleep = pinnsat_pll_sleep,
264}; 267};
265 268
266static int microtune_mt7202dtf_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) 269static int microtune_mt7202dtf_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
267{ 270{
268 struct dvb_bt8xx_card *card = (struct dvb_bt8xx_card *) fe->dvb->priv; 271 struct dvb_bt8xx_card *card = (struct dvb_bt8xx_card *) fe->dvb->priv;
269 u8 cfg, cpump, band_select; 272 u8 cfg, cpump, band_select;
@@ -297,6 +300,8 @@ static int microtune_mt7202dtf_pll_set(struct dvb_frontend* fe, struct dvb_front
297 data[2] = ((div >> 10) & 0x60) | cfg; 300 data[2] = ((div >> 10) & 0x60) | cfg;
298 data[3] = (cpump << 6) | band_select; 301 data[3] = (cpump << 6) | band_select;
299 302
303 if (fe->ops.i2c_gate_ctrl)
304 fe->ops.i2c_gate_ctrl(fe, 1);
300 i2c_transfer(card->i2c_adapter, &msg, 1); 305 i2c_transfer(card->i2c_adapter, &msg, 1);
301 return (div * 166666 - 36000000); 306 return (div * 166666 - 36000000);
302} 307}
@@ -310,7 +315,6 @@ static int microtune_mt7202dtf_request_firmware(struct dvb_frontend* fe, const s
310 315
311static struct sp887x_config microtune_mt7202dtf_config = { 316static struct sp887x_config microtune_mt7202dtf_config = {
312 .demod_address = 0x70, 317 .demod_address = 0x70,
313 .pll_set = microtune_mt7202dtf_pll_set,
314 .request_firmware = microtune_mt7202dtf_request_firmware, 318 .request_firmware = microtune_mt7202dtf_request_firmware,
315}; 319};
316 320
@@ -337,12 +341,14 @@ static int advbt771_samsung_tdtc9251dh0_demod_init(struct dvb_frontend* fe)
337 return 0; 341 return 0;
338} 342}
339 343
340static int advbt771_samsung_tdtc9251dh0_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params, u8* pllbuf) 344static int advbt771_samsung_tdtc9251dh0_tuner_calc_regs(struct dvb_frontend* fe, struct dvb_frontend_parameters* params, u8* pllbuf, int buf_len)
341{ 345{
342 u32 div; 346 u32 div;
343 unsigned char bs = 0; 347 unsigned char bs = 0;
344 unsigned char cp = 0; 348 unsigned char cp = 0;
345 349
350 if (buf_len < 5) return -EINVAL;
351
346 div = (((params->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6; 352 div = (((params->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6;
347 353
348 if (params->frequency < 150000000) 354 if (params->frequency < 150000000)
@@ -383,19 +389,18 @@ static int advbt771_samsung_tdtc9251dh0_pll_set(struct dvb_frontend* fe, struct
383 else 389 else
384 bs = 0x08; 390 bs = 0x08;
385 391
386 pllbuf[0] = 0xc2; // Note: non-linux standard PLL i2c address 392 pllbuf[0] = 0x61;
387 pllbuf[1] = div >> 8; 393 pllbuf[1] = div >> 8;
388 pllbuf[2] = div & 0xff; 394 pllbuf[2] = div & 0xff;
389 pllbuf[3] = cp; 395 pllbuf[3] = cp;
390 pllbuf[4] = bs; 396 pllbuf[4] = bs;
391 397
392 return 0; 398 return 5;
393} 399}
394 400
395static struct mt352_config advbt771_samsung_tdtc9251dh0_config = { 401static struct mt352_config advbt771_samsung_tdtc9251dh0_config = {
396 .demod_address = 0x0f, 402 .demod_address = 0x0f,
397 .demod_init = advbt771_samsung_tdtc9251dh0_demod_init, 403 .demod_init = advbt771_samsung_tdtc9251dh0_demod_init,
398 .pll_set = advbt771_samsung_tdtc9251dh0_pll_set,
399}; 404};
400 405
401static struct dst_config dst_config = { 406static struct dst_config dst_config = {
@@ -455,7 +460,7 @@ static struct or51211_config or51211_config = {
455 .sleep = or51211_sleep, 460 .sleep = or51211_sleep,
456}; 461};
457 462
458static int vp3021_alps_tded4_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) 463static int vp3021_alps_tded4_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
459{ 464{
460 struct dvb_bt8xx_card *card = (struct dvb_bt8xx_card *) fe->dvb->priv; 465 struct dvb_bt8xx_card *card = (struct dvb_bt8xx_card *) fe->dvb->priv;
461 u8 buf[4]; 466 u8 buf[4];
@@ -478,6 +483,8 @@ static int vp3021_alps_tded4_pll_set(struct dvb_frontend* fe, struct dvb_fronten
478 else 483 else
479 return -EINVAL; 484 return -EINVAL;
480 485
486 if (fe->ops.i2c_gate_ctrl)
487 fe->ops.i2c_gate_ctrl(fe, 1);
481 i2c_transfer(card->i2c_adapter, &msg, 1); 488 i2c_transfer(card->i2c_adapter, &msg, 1);
482 return 0; 489 return 0;
483} 490}
@@ -485,7 +492,6 @@ static int vp3021_alps_tded4_pll_set(struct dvb_frontend* fe, struct dvb_fronten
485static struct nxt6000_config vp3021_alps_tded4_config = { 492static struct nxt6000_config vp3021_alps_tded4_config = {
486 .demod_address = 0x0a, 493 .demod_address = 0x0a,
487 .clock_inversion = 1, 494 .clock_inversion = 1,
488 .pll_set = vp3021_alps_tded4_pll_set,
489}; 495};
490 496
491static int digitv_alps_tded4_demod_init(struct dvb_frontend* fe) 497static int digitv_alps_tded4_demod_init(struct dvb_frontend* fe)
@@ -506,14 +512,17 @@ static int digitv_alps_tded4_demod_init(struct dvb_frontend* fe)
506 return 0; 512 return 0;
507} 513}
508 514
509static int digitv_alps_tded4_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params, u8* pllbuf) 515static int digitv_alps_tded4_tuner_calc_regs(struct dvb_frontend* fe, struct dvb_frontend_parameters* params, u8* pllbuf, int buf_len)
510{ 516{
511 u32 div; 517 u32 div;
512 struct dvb_ofdm_parameters *op = &params->u.ofdm; 518 struct dvb_ofdm_parameters *op = &params->u.ofdm;
513 519
520 if (buf_len < 5)
521 return -EINVAL;
522
514 div = (((params->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6; 523 div = (((params->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6;
515 524
516 pllbuf[0] = 0xc2; 525 pllbuf[0] = 0x61;
517 pllbuf[1] = (div >> 8) & 0x7F; 526 pllbuf[1] = (div >> 8) & 0x7F;
518 pllbuf[2] = div & 0xFF; 527 pllbuf[2] = div & 0xFF;
519 pllbuf[3] = 0x85; 528 pllbuf[3] = 0x85;
@@ -530,7 +539,7 @@ static int digitv_alps_tded4_pll_set(struct dvb_frontend* fe, struct dvb_fronten
530 if (op->bandwidth == 8) 539 if (op->bandwidth == 8)
531 pllbuf[4] |= 0x04; 540 pllbuf[4] |= 0x04;
532 541
533 return 0; 542 return 5;
534} 543}
535 544
536static void digitv_alps_tded4_reset(struct dvb_bt8xx_card *bt) 545static void digitv_alps_tded4_reset(struct dvb_bt8xx_card *bt)
@@ -557,43 +566,18 @@ static void digitv_alps_tded4_reset(struct dvb_bt8xx_card *bt)
557static struct mt352_config digitv_alps_tded4_config = { 566static struct mt352_config digitv_alps_tded4_config = {
558 .demod_address = 0x0a, 567 .demod_address = 0x0a,
559 .demod_init = digitv_alps_tded4_demod_init, 568 .demod_init = digitv_alps_tded4_demod_init,
560 .pll_set = digitv_alps_tded4_pll_set,
561}; 569};
562 570
563static int tdvs_tua6034_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) 571static int tdvs_tua6034_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
564{ 572{
565 struct dvb_bt8xx_card *card = (struct dvb_bt8xx_card *) fe->dvb->priv; 573 struct dvb_bt8xx_card *card = (struct dvb_bt8xx_card *) fe->dvb->priv;
566 u8 buf[4]; 574 return lg_h06xf_pll_set(fe, card->i2c_adapter, params);
567 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) };
568 int err;
569
570 dvb_pll_configure(&dvb_pll_tdvs_tua6034, buf, params->frequency, 0);
571 dprintk("%s: tuner at 0x%02x bytes: 0x%02x 0x%02x 0x%02x 0x%02x\n",
572 __FUNCTION__, msg.addr, buf[0],buf[1],buf[2],buf[3]);
573 if ((err = i2c_transfer(card->i2c_adapter, &msg, 1)) != 1) {
574 printk(KERN_WARNING "dvb-bt8xx: %s error "
575 "(addr %02x <- %02x, err = %i)\n",
576 __FUNCTION__, buf[0], buf[1], err);
577 if (err < 0)
578 return err;
579 else
580 return -EREMOTEIO;
581 }
582
583 /* Set the Auxiliary Byte. */
584 buf[2] &= ~0x20;
585 buf[2] |= 0x18;
586 buf[3] = 0x50;
587 i2c_transfer(card->i2c_adapter, &msg, 1);
588
589 return 0;
590} 575}
591 576
592static struct lgdt330x_config tdvs_tua6034_config = { 577static struct lgdt330x_config tdvs_tua6034_config = {
593 .demod_address = 0x0e, 578 .demod_address = 0x0e,
594 .demod_chip = LGDT3303, 579 .demod_chip = LGDT3303,
595 .serial_mpeg = 0x40, /* TPSERIAL for 3303 in TOP_CONTROL */ 580 .serial_mpeg = 0x40, /* TPSERIAL for 3303 in TOP_CONTROL */
596 .pll_set = tdvs_tua6034_pll_set,
597}; 581};
598 582
599static void lgdt330x_reset(struct dvb_bt8xx_card *bt) 583static void lgdt330x_reset(struct dvb_bt8xx_card *bt)
@@ -617,17 +601,25 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type)
617 switch(type) { 601 switch(type) {
618 case BTTV_BOARD_DVICO_DVBT_LITE: 602 case BTTV_BOARD_DVICO_DVBT_LITE:
619 card->fe = mt352_attach(&thomson_dtt7579_config, card->i2c_adapter); 603 card->fe = mt352_attach(&thomson_dtt7579_config, card->i2c_adapter);
604
605 if (card->fe == NULL)
606 card->fe = zl10353_attach(&thomson_dtt7579_zl10353_config,
607 card->i2c_adapter);
608
620 if (card->fe != NULL) { 609 if (card->fe != NULL) {
621 card->fe->ops->info.frequency_min = 174000000; 610 card->fe->ops.tuner_ops.calc_regs = thomson_dtt7579_tuner_calc_regs;
622 card->fe->ops->info.frequency_max = 862000000; 611 card->fe->ops.info.frequency_min = 174000000;
612 card->fe->ops.info.frequency_max = 862000000;
623 } 613 }
624 break; 614 break;
625 615
626 case BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE: 616 case BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE:
627 lgdt330x_reset(card); 617 lgdt330x_reset(card);
628 card->fe = lgdt330x_attach(&tdvs_tua6034_config, card->i2c_adapter); 618 card->fe = lgdt330x_attach(&tdvs_tua6034_config, card->i2c_adapter);
629 if (card->fe != NULL) 619 if (card->fe != NULL) {
620 card->fe->ops.tuner_ops.set_params = tdvs_tua6034_tuner_set_params;
630 dprintk ("dvb_bt8xx: lgdt330x detected\n"); 621 dprintk ("dvb_bt8xx: lgdt330x detected\n");
622 }
631 break; 623 break;
632 624
633 case BTTV_BOARD_NEBULA_DIGITV: 625 case BTTV_BOARD_NEBULA_DIGITV:
@@ -640,6 +632,7 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type)
640 digitv_alps_tded4_reset(card); 632 digitv_alps_tded4_reset(card);
641 card->fe = nxt6000_attach(&vp3021_alps_tded4_config, card->i2c_adapter); 633 card->fe = nxt6000_attach(&vp3021_alps_tded4_config, card->i2c_adapter);
642 if (card->fe != NULL) { 634 if (card->fe != NULL) {
635 card->fe->ops.tuner_ops.set_params = vp3021_alps_tded4_tuner_set_params;
643 dprintk ("dvb_bt8xx: an nxt6000 was detected on your digitv card\n"); 636 dprintk ("dvb_bt8xx: an nxt6000 was detected on your digitv card\n");
644 break; 637 break;
645 } 638 }
@@ -648,19 +641,25 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type)
648 digitv_alps_tded4_reset(card); 641 digitv_alps_tded4_reset(card);
649 card->fe = mt352_attach(&digitv_alps_tded4_config, card->i2c_adapter); 642 card->fe = mt352_attach(&digitv_alps_tded4_config, card->i2c_adapter);
650 643
651 if (card->fe != NULL) 644 if (card->fe != NULL) {
645 card->fe->ops.tuner_ops.calc_regs = digitv_alps_tded4_tuner_calc_regs;
652 dprintk ("dvb_bt8xx: an mt352 was detected on your digitv card\n"); 646 dprintk ("dvb_bt8xx: an mt352 was detected on your digitv card\n");
647 }
653 break; 648 break;
654 649
655 case BTTV_BOARD_AVDVBT_761: 650 case BTTV_BOARD_AVDVBT_761:
656 card->fe = sp887x_attach(&microtune_mt7202dtf_config, card->i2c_adapter); 651 card->fe = sp887x_attach(&microtune_mt7202dtf_config, card->i2c_adapter);
652 if (card->fe) {
653 card->fe->ops.tuner_ops.set_params = microtune_mt7202dtf_tuner_set_params;
654 }
657 break; 655 break;
658 656
659 case BTTV_BOARD_AVDVBT_771: 657 case BTTV_BOARD_AVDVBT_771:
660 card->fe = mt352_attach(&advbt771_samsung_tdtc9251dh0_config, card->i2c_adapter); 658 card->fe = mt352_attach(&advbt771_samsung_tdtc9251dh0_config, card->i2c_adapter);
661 if (card->fe != NULL) { 659 if (card->fe != NULL) {
662 card->fe->ops->info.frequency_min = 174000000; 660 card->fe->ops.tuner_ops.calc_regs = advbt771_samsung_tdtc9251dh0_tuner_calc_regs;
663 card->fe->ops->info.frequency_max = 862000000; 661 card->fe->ops.info.frequency_min = 174000000;
662 card->fe->ops.info.frequency_max = 862000000;
664 } 663 }
665 break; 664 break;
666 665
@@ -687,6 +686,11 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type)
687 686
688 case BTTV_BOARD_PINNACLESAT: 687 case BTTV_BOARD_PINNACLESAT:
689 card->fe = cx24110_attach(&pctvsat_config, card->i2c_adapter); 688 card->fe = cx24110_attach(&pctvsat_config, card->i2c_adapter);
689 if (card->fe) {
690 card->fe->ops.tuner_ops.init = pinnsat_tuner_init;
691 card->fe->ops.tuner_ops.sleep = pinnsat_tuner_sleep;
692 card->fe->ops.tuner_ops.set_params = cx24108_tuner_set_params;
693 }
690 break; 694 break;
691 695
692 case BTTV_BOARD_PC_HDTV: 696 case BTTV_BOARD_PC_HDTV:
@@ -703,8 +707,8 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type)
703 else 707 else
704 if (dvb_register_frontend(&card->dvb_adapter, card->fe)) { 708 if (dvb_register_frontend(&card->dvb_adapter, card->fe)) {
705 printk("dvb-bt8xx: Frontend registration failed!\n"); 709 printk("dvb-bt8xx: Frontend registration failed!\n");
706 if (card->fe->ops->release) 710 if (card->fe->ops.release)
707 card->fe->ops->release(card->fe); 711 card->fe->ops.release(card->fe);
708 card->fe = NULL; 712 card->fe = NULL;
709 } 713 }
710} 714}
@@ -713,7 +717,7 @@ static int __devinit dvb_bt8xx_load_card(struct dvb_bt8xx_card *card, u32 type)
713{ 717{
714 int result; 718 int result;
715 719
716 if ((result = dvb_register_adapter(&card->dvb_adapter, card->card_name, THIS_MODULE)) < 0) { 720 if ((result = dvb_register_adapter(&card->dvb_adapter, card->card_name, THIS_MODULE, &card->bt->dev->dev)) < 0) {
717 printk("dvb_bt8xx: dvb_register_adapter failed (errno = %d)\n", result); 721 printk("dvb_bt8xx: dvb_register_adapter failed (errno = %d)\n", result);
718 return result; 722 return result;
719 } 723 }
diff --git a/drivers/media/dvb/bt8xx/dvb-bt8xx.h b/drivers/media/dvb/bt8xx/dvb-bt8xx.h
index 00dd9fa54c82..4745a9017a19 100644
--- a/drivers/media/dvb/bt8xx/dvb-bt8xx.h
+++ b/drivers/media/dvb/bt8xx/dvb-bt8xx.h
@@ -37,6 +37,8 @@
37#include "cx24110.h" 37#include "cx24110.h"
38#include "or51211.h" 38#include "or51211.h"
39#include "lgdt330x.h" 39#include "lgdt330x.h"
40#include "lg_h06xf.h"
41#include "zl10353.h"
40 42
41struct dvb_bt8xx_card { 43struct dvb_bt8xx_card {
42 struct mutex lock; 44 struct mutex lock;
diff --git a/drivers/media/dvb/cinergyT2/Kconfig b/drivers/media/dvb/cinergyT2/Kconfig
index 6018fcdba1e6..b5cdd57ec6f5 100644
--- a/drivers/media/dvb/cinergyT2/Kconfig
+++ b/drivers/media/dvb/cinergyT2/Kconfig
@@ -64,7 +64,7 @@ config DVB_CINERGYT2_QUERY_INTERVAL
64config DVB_CINERGYT2_ENABLE_RC_INPUT_DEVICE 64config DVB_CINERGYT2_ENABLE_RC_INPUT_DEVICE
65 bool "Register the onboard IR Remote Control Receiver as Input Device" 65 bool "Register the onboard IR Remote Control Receiver as Input Device"
66 depends on DVB_CINERGYT2_TUNING 66 depends on DVB_CINERGYT2_TUNING
67 default "yes" 67 default y
68 help 68 help
69 Enable this option if you want to use the onboard Infrared Remote 69 Enable this option if you want to use the onboard Infrared Remote
70 Control Receiver as Linux-Input device. 70 Control Receiver as Linux-Input device.
diff --git a/drivers/media/dvb/cinergyT2/cinergyT2.c b/drivers/media/dvb/cinergyT2/cinergyT2.c
index 9325d039ea65..1b8953600425 100644
--- a/drivers/media/dvb/cinergyT2/cinergyT2.c
+++ b/drivers/media/dvb/cinergyT2/cinergyT2.c
@@ -544,15 +544,19 @@ static unsigned int cinergyt2_poll (struct file *file, struct poll_table_struct
544{ 544{
545 struct dvb_device *dvbdev = file->private_data; 545 struct dvb_device *dvbdev = file->private_data;
546 struct cinergyt2 *cinergyt2 = dvbdev->priv; 546 struct cinergyt2 *cinergyt2 = dvbdev->priv;
547 unsigned int mask = 0;
547 548
548 if (cinergyt2->disconnect_pending || mutex_lock_interruptible(&cinergyt2->sem)) 549 if (cinergyt2->disconnect_pending || mutex_lock_interruptible(&cinergyt2->sem))
549 return -ERESTARTSYS; 550 return -ERESTARTSYS;
550 551
551 poll_wait(file, &cinergyt2->poll_wq, wait); 552 poll_wait(file, &cinergyt2->poll_wq, wait);
552 553
554 if (cinergyt2->pending_fe_events != 0)
555 mask |= (POLLIN | POLLRDNORM | POLLPRI);
556
553 mutex_unlock(&cinergyt2->sem); 557 mutex_unlock(&cinergyt2->sem);
554 558
555 return (POLLIN | POLLRDNORM | POLLPRI); 559 return mask;
556} 560}
557 561
558 562
@@ -902,7 +906,7 @@ static int cinergyt2_probe (struct usb_interface *intf,
902 return -ENOMEM; 906 return -ENOMEM;
903 } 907 }
904 908
905 if ((err = dvb_register_adapter(&cinergyt2->adapter, DRIVER_NAME, THIS_MODULE)) < 0) { 909 if ((err = dvb_register_adapter(&cinergyt2->adapter, DRIVER_NAME, THIS_MODULE, &cinergyt2->udev->dev)) < 0) {
906 kfree(cinergyt2); 910 kfree(cinergyt2);
907 return err; 911 return err;
908 } 912 }
diff --git a/drivers/media/dvb/dvb-core/Makefile b/drivers/media/dvb/dvb-core/Makefile
index 7adb50c1e8eb..11054657fdb5 100644
--- a/drivers/media/dvb/dvb-core/Makefile
+++ b/drivers/media/dvb/dvb-core/Makefile
@@ -2,8 +2,8 @@
2# Makefile for the kernel DVB device drivers. 2# Makefile for the kernel DVB device drivers.
3# 3#
4 4
5dvb-core-objs = dvbdev.o dmxdev.o dvb_demux.o dvb_filter.o \ 5dvb-core-objs = dvbdev.o dmxdev.o dvb_demux.o dvb_filter.o \
6 dvb_ca_en50221.o dvb_frontend.o \ 6 dvb_ca_en50221.o dvb_frontend.o \
7 dvb_net.o dvb_ringbuffer.o 7 dvb_net.o dvb_ringbuffer.o dvb_math.o
8 8
9obj-$(CONFIG_DVB_CORE) += dvb-core.o 9obj-$(CONFIG_DVB_CORE) += dvb-core.o
diff --git a/drivers/media/dvb/dvb-core/dmxdev.c b/drivers/media/dvb/dvb-core/dmxdev.c
index 04578df3f249..988499dfddf8 100644
--- a/drivers/media/dvb/dvb-core/dmxdev.c
+++ b/drivers/media/dvb/dvb-core/dmxdev.c
@@ -872,9 +872,6 @@ static int dvb_demux_do_ioctl(struct inode *inode, struct file *file,
872 mutex_unlock(&dmxdevfilter->mutex); 872 mutex_unlock(&dmxdevfilter->mutex);
873 break; 873 break;
874 874
875 case DMX_GET_EVENT:
876 break;
877
878 case DMX_GET_PES_PIDS: 875 case DMX_GET_PES_PIDS:
879 if (!dmxdev->demux->get_pes_pids) { 876 if (!dmxdev->demux->get_pes_pids) {
880 ret = -EINVAL; 877 ret = -EINVAL;
diff --git a/drivers/media/dvb/dvb-core/dvb_ca_en50221.c b/drivers/media/dvb/dvb-core/dvb_ca_en50221.c
index 00347a750681..2a03bf53cb29 100644
--- a/drivers/media/dvb/dvb-core/dvb_ca_en50221.c
+++ b/drivers/media/dvb/dvb-core/dvb_ca_en50221.c
@@ -1060,8 +1060,18 @@ static int dvb_ca_en50221_thread(void *data)
1060 break; 1060 break;
1061 1061
1062 case DVB_CA_SLOTSTATE_VALIDATE: 1062 case DVB_CA_SLOTSTATE_VALIDATE:
1063 if (dvb_ca_en50221_parse_attributes(ca, slot) 1063 if (dvb_ca_en50221_parse_attributes(ca, slot) != 0) {
1064 != 0) { 1064 /* we need this extra check for annoying interfaces like the budget-av */
1065 if ((!(ca->flags & DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE)) &&
1066 (ca->pub->poll_slot_status)) {
1067 int status = ca->pub->poll_slot_status(ca->pub, slot, 0);
1068 if (!(status & DVB_CA_EN50221_POLL_CAM_PRESENT)) {
1069 ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_NONE;
1070 dvb_ca_en50221_thread_update_delay(ca);
1071 break;
1072 }
1073 }
1074
1065 printk("dvb_ca adapter %d: Invalid PC card inserted :(\n", 1075 printk("dvb_ca adapter %d: Invalid PC card inserted :(\n",
1066 ca->dvbdev->adapter->num); 1076 ca->dvbdev->adapter->num);
1067 ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_INVALID; 1077 ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_INVALID;
@@ -1108,6 +1118,17 @@ static int dvb_ca_en50221_thread(void *data)
1108 1118
1109 case DVB_CA_SLOTSTATE_LINKINIT: 1119 case DVB_CA_SLOTSTATE_LINKINIT:
1110 if (dvb_ca_en50221_link_init(ca, slot) != 0) { 1120 if (dvb_ca_en50221_link_init(ca, slot) != 0) {
1121 /* we need this extra check for annoying interfaces like the budget-av */
1122 if ((!(ca->flags & DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE)) &&
1123 (ca->pub->poll_slot_status)) {
1124 int status = ca->pub->poll_slot_status(ca->pub, slot, 0);
1125 if (!(status & DVB_CA_EN50221_POLL_CAM_PRESENT)) {
1126 ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_NONE;
1127 dvb_ca_en50221_thread_update_delay(ca);
1128 break;
1129 }
1130 }
1131
1111 printk("dvb_ca adapter %d: DVB CAM link initialisation failed :(\n", ca->dvbdev->adapter->num); 1132 printk("dvb_ca adapter %d: DVB CAM link initialisation failed :(\n", ca->dvbdev->adapter->num);
1112 ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_INVALID; 1133 ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_INVALID;
1113 dvb_ca_en50221_thread_update_delay(ca); 1134 dvb_ca_en50221_thread_update_delay(ca);
diff --git a/drivers/media/dvb/dvb-core/dvb_demux.c b/drivers/media/dvb/dvb-core/dvb_demux.c
index 83ec5e06c482..fcff5eab21a3 100644
--- a/drivers/media/dvb/dvb-core/dvb_demux.c
+++ b/drivers/media/dvb/dvb-core/dvb_demux.c
@@ -473,7 +473,7 @@ void dvb_dmx_swfilter_204(struct dvb_demux *demux, const u8 *buf, size_t count)
473 goto bailout; 473 goto bailout;
474 } 474 }
475 memcpy(&demux->tsbuf[i], buf, j); 475 memcpy(&demux->tsbuf[i], buf, j);
476 if ((demux->tsbuf[0] == 0x47) | (demux->tsbuf[0] == 0xB8)) { 476 if ((demux->tsbuf[0] == 0x47) || (demux->tsbuf[0] == 0xB8)) {
477 memcpy(tmppack, demux->tsbuf, 188); 477 memcpy(tmppack, demux->tsbuf, 188);
478 if (tmppack[0] == 0xB8) 478 if (tmppack[0] == 0xB8)
479 tmppack[0] = 0x47; 479 tmppack[0] = 0x47;
@@ -484,7 +484,7 @@ void dvb_dmx_swfilter_204(struct dvb_demux *demux, const u8 *buf, size_t count)
484 } 484 }
485 485
486 while (p < count) { 486 while (p < count) {
487 if ((buf[p] == 0x47) | (buf[p] == 0xB8)) { 487 if ((buf[p] == 0x47) || (buf[p] == 0xB8)) {
488 if (count - p >= 204) { 488 if (count - p >= 204) {
489 memcpy(tmppack, &buf[p], 188); 489 memcpy(tmppack, &buf[p], 188);
490 if (tmppack[0] == 0xB8) 490 if (tmppack[0] == 0xB8)
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c
index a051790161b0..3152a54a2539 100644
--- a/drivers/media/dvb/dvb-core/dvb_frontend.c
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.c
@@ -56,7 +56,7 @@ MODULE_PARM_DESC(dvb_force_auto_inversion, "0: normal (default), 1: INVERSION_AU
56module_param(dvb_override_tune_delay, int, 0644); 56module_param(dvb_override_tune_delay, int, 0644);
57MODULE_PARM_DESC(dvb_override_tune_delay, "0: normal (default), >0 => delay in milliseconds to wait for lock after a tune attempt"); 57MODULE_PARM_DESC(dvb_override_tune_delay, "0: normal (default), >0 => delay in milliseconds to wait for lock after a tune attempt");
58module_param(dvb_powerdown_on_sleep, int, 0644); 58module_param(dvb_powerdown_on_sleep, int, 0644);
59MODULE_PARM_DESC(dvb_powerdown_on_sleep, "0: do not power down, 1: turn LNB volatage off on sleep (default)"); 59MODULE_PARM_DESC(dvb_powerdown_on_sleep, "0: do not power down, 1: turn LNB voltage off on sleep (default)");
60 60
61#define dprintk if (dvb_frontend_debug) printk 61#define dprintk if (dvb_frontend_debug) printk
62 62
@@ -72,6 +72,8 @@ MODULE_PARM_DESC(dvb_powerdown_on_sleep, "0: do not power down, 1: turn LNB vola
72#define FESTATE_SEARCHING_FAST (FESTATE_TUNING_FAST | FESTATE_ZIGZAG_FAST) 72#define FESTATE_SEARCHING_FAST (FESTATE_TUNING_FAST | FESTATE_ZIGZAG_FAST)
73#define FESTATE_SEARCHING_SLOW (FESTATE_TUNING_SLOW | FESTATE_ZIGZAG_SLOW) 73#define FESTATE_SEARCHING_SLOW (FESTATE_TUNING_SLOW | FESTATE_ZIGZAG_SLOW)
74#define FESTATE_LOSTLOCK (FESTATE_ZIGZAG_FAST | FESTATE_ZIGZAG_SLOW) 74#define FESTATE_LOSTLOCK (FESTATE_ZIGZAG_FAST | FESTATE_ZIGZAG_SLOW)
75
76#define FE_ALGO_HW 1
75/* 77/*
76 * FESTATE_IDLE. No tuning parameters have been supplied and the loop is idling. 78 * FESTATE_IDLE. No tuning parameters have been supplied and the loop is idling.
77 * FESTATE_RETUNE. Parameters have been supplied, but we have not yet performed the first tune. 79 * FESTATE_RETUNE. Parameters have been supplied, but we have not yet performed the first tune.
@@ -151,8 +153,8 @@ static void dvb_frontend_add_event(struct dvb_frontend *fe, fe_status_t status)
151 sizeof (struct dvb_frontend_parameters)); 153 sizeof (struct dvb_frontend_parameters));
152 154
153 if (status & FE_HAS_LOCK) 155 if (status & FE_HAS_LOCK)
154 if (fe->ops->get_frontend) 156 if (fe->ops.get_frontend)
155 fe->ops->get_frontend(fe, &e->parameters); 157 fe->ops.get_frontend(fe, &e->parameters);
156 158
157 events->eventw = wp; 159 events->eventw = wp;
158 160
@@ -211,10 +213,15 @@ static void dvb_frontend_init(struct dvb_frontend *fe)
211{ 213{
212 dprintk ("DVB: initialising frontend %i (%s)...\n", 214 dprintk ("DVB: initialising frontend %i (%s)...\n",
213 fe->dvb->num, 215 fe->dvb->num,
214 fe->ops->info.name); 216 fe->ops.info.name);
215 217
216 if (fe->ops->init) 218 if (fe->ops.init)
217 fe->ops->init(fe); 219 fe->ops.init(fe);
220 if (fe->ops.tuner_ops.init) {
221 fe->ops.tuner_ops.init(fe);
222 if (fe->ops.i2c_gate_ctrl)
223 fe->ops.i2c_gate_ctrl(fe, 0);
224 }
218} 225}
219 226
220void dvb_frontend_reinitialise(struct dvb_frontend *fe) 227void dvb_frontend_reinitialise(struct dvb_frontend *fe)
@@ -259,7 +266,7 @@ static int dvb_frontend_swzigzag_autotune(struct dvb_frontend *fe, int check_wra
259 u32 original_frequency = fepriv->parameters.frequency; 266 u32 original_frequency = fepriv->parameters.frequency;
260 267
261 /* are we using autoinversion? */ 268 /* are we using autoinversion? */
262 autoinversion = ((!(fe->ops->info.caps & FE_CAN_INVERSION_AUTO)) && 269 autoinversion = ((!(fe->ops.info.caps & FE_CAN_INVERSION_AUTO)) &&
263 (fepriv->parameters.inversion == INVERSION_AUTO)); 270 (fepriv->parameters.inversion == INVERSION_AUTO));
264 271
265 /* setup parameters correctly */ 272 /* setup parameters correctly */
@@ -329,8 +336,8 @@ static int dvb_frontend_swzigzag_autotune(struct dvb_frontend *fe, int check_wra
329 fepriv->parameters.frequency += fepriv->lnb_drift; 336 fepriv->parameters.frequency += fepriv->lnb_drift;
330 if (autoinversion) 337 if (autoinversion)
331 fepriv->parameters.inversion = fepriv->inversion; 338 fepriv->parameters.inversion = fepriv->inversion;
332 if (fe->ops->set_frontend) 339 if (fe->ops.set_frontend)
333 fe->ops->set_frontend(fe, &fepriv->parameters); 340 fe->ops.set_frontend(fe, &fepriv->parameters);
334 341
335 fepriv->parameters.frequency = original_frequency; 342 fepriv->parameters.frequency = original_frequency;
336 fepriv->parameters.inversion = original_inversion; 343 fepriv->parameters.inversion = original_inversion;
@@ -354,8 +361,8 @@ static void dvb_frontend_swzigzag(struct dvb_frontend *fe)
354 /* in SCAN mode, we just set the frontend when asked and leave it alone */ 361 /* in SCAN mode, we just set the frontend when asked and leave it alone */
355 if (fepriv->tune_mode_flags & FE_TUNE_MODE_ONESHOT) { 362 if (fepriv->tune_mode_flags & FE_TUNE_MODE_ONESHOT) {
356 if (fepriv->state & FESTATE_RETUNE) { 363 if (fepriv->state & FESTATE_RETUNE) {
357 if (fe->ops->set_frontend) 364 if (fe->ops.set_frontend)
358 fe->ops->set_frontend(fe, &fepriv->parameters); 365 fe->ops.set_frontend(fe, &fepriv->parameters);
359 fepriv->state = FESTATE_TUNED; 366 fepriv->state = FESTATE_TUNED;
360 } 367 }
361 fepriv->delay = 3*HZ; 368 fepriv->delay = 3*HZ;
@@ -367,8 +374,8 @@ static void dvb_frontend_swzigzag(struct dvb_frontend *fe)
367 if (fepriv->state & FESTATE_RETUNE) { 374 if (fepriv->state & FESTATE_RETUNE) {
368 s = 0; 375 s = 0;
369 } else { 376 } else {
370 if (fe->ops->read_status) 377 if (fe->ops.read_status)
371 fe->ops->read_status(fe, &s); 378 fe->ops.read_status(fe, &s);
372 if (s != fepriv->status) { 379 if (s != fepriv->status) {
373 dvb_frontend_add_event(fe, s); 380 dvb_frontend_add_event(fe, s);
374 fepriv->status = s; 381 fepriv->status = s;
@@ -381,7 +388,7 @@ static void dvb_frontend_swzigzag(struct dvb_frontend *fe)
381 fepriv->state = FESTATE_TUNED; 388 fepriv->state = FESTATE_TUNED;
382 389
383 /* if we're tuned, then we have determined the correct inversion */ 390 /* if we're tuned, then we have determined the correct inversion */
384 if ((!(fe->ops->info.caps & FE_CAN_INVERSION_AUTO)) && 391 if ((!(fe->ops.info.caps & FE_CAN_INVERSION_AUTO)) &&
385 (fepriv->parameters.inversion == INVERSION_AUTO)) { 392 (fepriv->parameters.inversion == INVERSION_AUTO)) {
386 fepriv->parameters.inversion = fepriv->inversion; 393 fepriv->parameters.inversion = fepriv->inversion;
387 } 394 }
@@ -405,7 +412,7 @@ static void dvb_frontend_swzigzag(struct dvb_frontend *fe)
405 /* don't actually do anything if we're in the LOSTLOCK state, 412 /* don't actually do anything if we're in the LOSTLOCK state,
406 * the frontend is set to FE_CAN_RECOVER, and the max_drift is 0 */ 413 * the frontend is set to FE_CAN_RECOVER, and the max_drift is 0 */
407 if ((fepriv->state & FESTATE_LOSTLOCK) && 414 if ((fepriv->state & FESTATE_LOSTLOCK) &&
408 (fe->ops->info.caps & FE_CAN_RECOVER) && (fepriv->max_drift == 0)) { 415 (fe->ops.info.caps & FE_CAN_RECOVER) && (fepriv->max_drift == 0)) {
409 dvb_frontend_swzigzag_update_delay(fepriv, s & FE_HAS_LOCK); 416 dvb_frontend_swzigzag_update_delay(fepriv, s & FE_HAS_LOCK);
410 return; 417 return;
411 } 418 }
@@ -540,16 +547,16 @@ static int dvb_frontend_thread(void *data)
540 if (fepriv->reinitialise) { 547 if (fepriv->reinitialise) {
541 dvb_frontend_init(fe); 548 dvb_frontend_init(fe);
542 if (fepriv->tone != -1) { 549 if (fepriv->tone != -1) {
543 fe->ops->set_tone(fe, fepriv->tone); 550 fe->ops.set_tone(fe, fepriv->tone);
544 } 551 }
545 if (fepriv->voltage != -1) { 552 if (fepriv->voltage != -1) {
546 fe->ops->set_voltage(fe, fepriv->voltage); 553 fe->ops.set_voltage(fe, fepriv->voltage);
547 } 554 }
548 fepriv->reinitialise = 0; 555 fepriv->reinitialise = 0;
549 } 556 }
550 557
551 /* do an iteration of the tuning loop */ 558 /* do an iteration of the tuning loop */
552 if (fe->ops->tune) { 559 if (fe->ops.get_frontend_algo(fe) == FE_ALGO_HW) {
553 /* have we been asked to retune? */ 560 /* have we been asked to retune? */
554 params = NULL; 561 params = NULL;
555 if (fepriv->state & FESTATE_RETUNE) { 562 if (fepriv->state & FESTATE_RETUNE) {
@@ -557,7 +564,7 @@ static int dvb_frontend_thread(void *data)
557 fepriv->state = FESTATE_TUNED; 564 fepriv->state = FESTATE_TUNED;
558 } 565 }
559 566
560 fe->ops->tune(fe, params, fepriv->tune_mode_flags, &fepriv->delay, &s); 567 fe->ops.tune(fe, params, fepriv->tune_mode_flags, &fepriv->delay, &s);
561 if (s != fepriv->status) { 568 if (s != fepriv->status) {
562 dvb_frontend_add_event(fe, s); 569 dvb_frontend_add_event(fe, s);
563 fepriv->status = s; 570 fepriv->status = s;
@@ -569,10 +576,15 @@ static int dvb_frontend_thread(void *data)
569 576
570 if (dvb_shutdown_timeout) { 577 if (dvb_shutdown_timeout) {
571 if (dvb_powerdown_on_sleep) 578 if (dvb_powerdown_on_sleep)
572 if (fe->ops->set_voltage) 579 if (fe->ops.set_voltage)
573 fe->ops->set_voltage(fe, SEC_VOLTAGE_OFF); 580 fe->ops.set_voltage(fe, SEC_VOLTAGE_OFF);
574 if (fe->ops->sleep) 581 if (fe->ops.tuner_ops.sleep) {
575 fe->ops->sleep(fe); 582 fe->ops.tuner_ops.sleep(fe);
583 if (fe->ops.i2c_gate_ctrl)
584 fe->ops.i2c_gate_ctrl(fe, 0);
585 }
586 if (fe->ops.sleep)
587 fe->ops.sleep(fe);
576 } 588 }
577 589
578 fepriv->thread_pid = 0; 590 fepriv->thread_pid = 0;
@@ -724,7 +736,7 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file,
724 switch (cmd) { 736 switch (cmd) {
725 case FE_GET_INFO: { 737 case FE_GET_INFO: {
726 struct dvb_frontend_info* info = parg; 738 struct dvb_frontend_info* info = parg;
727 memcpy(info, &fe->ops->info, sizeof(struct dvb_frontend_info)); 739 memcpy(info, &fe->ops.info, sizeof(struct dvb_frontend_info));
728 740
729 /* Force the CAN_INVERSION_AUTO bit on. If the frontend doesn't 741 /* Force the CAN_INVERSION_AUTO bit on. If the frontend doesn't
730 * do it, it is done for it. */ 742 * do it, it is done for it. */
@@ -744,58 +756,58 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file,
744 break; 756 break;
745 } 757 }
746 758
747 if (fe->ops->read_status) 759 if (fe->ops.read_status)
748 err = fe->ops->read_status(fe, status); 760 err = fe->ops.read_status(fe, status);
749 break; 761 break;
750 } 762 }
751 case FE_READ_BER: 763 case FE_READ_BER:
752 if (fe->ops->read_ber) 764 if (fe->ops.read_ber)
753 err = fe->ops->read_ber(fe, (__u32*) parg); 765 err = fe->ops.read_ber(fe, (__u32*) parg);
754 break; 766 break;
755 767
756 case FE_READ_SIGNAL_STRENGTH: 768 case FE_READ_SIGNAL_STRENGTH:
757 if (fe->ops->read_signal_strength) 769 if (fe->ops.read_signal_strength)
758 err = fe->ops->read_signal_strength(fe, (__u16*) parg); 770 err = fe->ops.read_signal_strength(fe, (__u16*) parg);
759 break; 771 break;
760 772
761 case FE_READ_SNR: 773 case FE_READ_SNR:
762 if (fe->ops->read_snr) 774 if (fe->ops.read_snr)
763 err = fe->ops->read_snr(fe, (__u16*) parg); 775 err = fe->ops.read_snr(fe, (__u16*) parg);
764 break; 776 break;
765 777
766 case FE_READ_UNCORRECTED_BLOCKS: 778 case FE_READ_UNCORRECTED_BLOCKS:
767 if (fe->ops->read_ucblocks) 779 if (fe->ops.read_ucblocks)
768 err = fe->ops->read_ucblocks(fe, (__u32*) parg); 780 err = fe->ops.read_ucblocks(fe, (__u32*) parg);
769 break; 781 break;
770 782
771 783
772 case FE_DISEQC_RESET_OVERLOAD: 784 case FE_DISEQC_RESET_OVERLOAD:
773 if (fe->ops->diseqc_reset_overload) { 785 if (fe->ops.diseqc_reset_overload) {
774 err = fe->ops->diseqc_reset_overload(fe); 786 err = fe->ops.diseqc_reset_overload(fe);
775 fepriv->state = FESTATE_DISEQC; 787 fepriv->state = FESTATE_DISEQC;
776 fepriv->status = 0; 788 fepriv->status = 0;
777 } 789 }
778 break; 790 break;
779 791
780 case FE_DISEQC_SEND_MASTER_CMD: 792 case FE_DISEQC_SEND_MASTER_CMD:
781 if (fe->ops->diseqc_send_master_cmd) { 793 if (fe->ops.diseqc_send_master_cmd) {
782 err = fe->ops->diseqc_send_master_cmd(fe, (struct dvb_diseqc_master_cmd*) parg); 794 err = fe->ops.diseqc_send_master_cmd(fe, (struct dvb_diseqc_master_cmd*) parg);
783 fepriv->state = FESTATE_DISEQC; 795 fepriv->state = FESTATE_DISEQC;
784 fepriv->status = 0; 796 fepriv->status = 0;
785 } 797 }
786 break; 798 break;
787 799
788 case FE_DISEQC_SEND_BURST: 800 case FE_DISEQC_SEND_BURST:
789 if (fe->ops->diseqc_send_burst) { 801 if (fe->ops.diseqc_send_burst) {
790 err = fe->ops->diseqc_send_burst(fe, (fe_sec_mini_cmd_t) parg); 802 err = fe->ops.diseqc_send_burst(fe, (fe_sec_mini_cmd_t) parg);
791 fepriv->state = FESTATE_DISEQC; 803 fepriv->state = FESTATE_DISEQC;
792 fepriv->status = 0; 804 fepriv->status = 0;
793 } 805 }
794 break; 806 break;
795 807
796 case FE_SET_TONE: 808 case FE_SET_TONE:
797 if (fe->ops->set_tone) { 809 if (fe->ops.set_tone) {
798 err = fe->ops->set_tone(fe, (fe_sec_tone_mode_t) parg); 810 err = fe->ops.set_tone(fe, (fe_sec_tone_mode_t) parg);
799 fepriv->tone = (fe_sec_tone_mode_t) parg; 811 fepriv->tone = (fe_sec_tone_mode_t) parg;
800 fepriv->state = FESTATE_DISEQC; 812 fepriv->state = FESTATE_DISEQC;
801 fepriv->status = 0; 813 fepriv->status = 0;
@@ -803,8 +815,8 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file,
803 break; 815 break;
804 816
805 case FE_SET_VOLTAGE: 817 case FE_SET_VOLTAGE:
806 if (fe->ops->set_voltage) { 818 if (fe->ops.set_voltage) {
807 err = fe->ops->set_voltage(fe, (fe_sec_voltage_t) parg); 819 err = fe->ops.set_voltage(fe, (fe_sec_voltage_t) parg);
808 fepriv->voltage = (fe_sec_voltage_t) parg; 820 fepriv->voltage = (fe_sec_voltage_t) parg;
809 fepriv->state = FESTATE_DISEQC; 821 fepriv->state = FESTATE_DISEQC;
810 fepriv->status = 0; 822 fepriv->status = 0;
@@ -812,11 +824,11 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file,
812 break; 824 break;
813 825
814 case FE_DISHNETWORK_SEND_LEGACY_CMD: 826 case FE_DISHNETWORK_SEND_LEGACY_CMD:
815 if (fe->ops->dishnetwork_send_legacy_command) { 827 if (fe->ops.dishnetwork_send_legacy_command) {
816 err = fe->ops->dishnetwork_send_legacy_command(fe, (unsigned long) parg); 828 err = fe->ops.dishnetwork_send_legacy_command(fe, (unsigned long) parg);
817 fepriv->state = FESTATE_DISEQC; 829 fepriv->state = FESTATE_DISEQC;
818 fepriv->status = 0; 830 fepriv->status = 0;
819 } else if (fe->ops->set_voltage) { 831 } else if (fe->ops.set_voltage) {
820 /* 832 /*
821 * NOTE: This is a fallback condition. Some frontends 833 * NOTE: This is a fallback condition. Some frontends
822 * (stv0299 for instance) take longer than 8msec to 834 * (stv0299 for instance) take longer than 8msec to
@@ -846,7 +858,7 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file,
846 /* before sending a command, initialize by sending 858 /* before sending a command, initialize by sending
847 * a 32ms 18V to the switch 859 * a 32ms 18V to the switch
848 */ 860 */
849 fe->ops->set_voltage(fe, SEC_VOLTAGE_18); 861 fe->ops.set_voltage(fe, SEC_VOLTAGE_18);
850 dvb_frontend_sleep_until(&nexttime, 32000); 862 dvb_frontend_sleep_until(&nexttime, 32000);
851 863
852 for (i = 0; i < 9; i++) { 864 for (i = 0; i < 9; i++) {
@@ -854,7 +866,7 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file,
854 do_gettimeofday(&tv[i + 1]); 866 do_gettimeofday(&tv[i + 1]);
855 if ((cmd & 0x01) != last) { 867 if ((cmd & 0x01) != last) {
856 /* set voltage to (last ? 13V : 18V) */ 868 /* set voltage to (last ? 13V : 18V) */
857 fe->ops->set_voltage(fe, (last) ? SEC_VOLTAGE_13 : SEC_VOLTAGE_18); 869 fe->ops.set_voltage(fe, (last) ? SEC_VOLTAGE_13 : SEC_VOLTAGE_18);
858 last = (last) ? 0 : 1; 870 last = (last) ? 0 : 1;
859 } 871 }
860 cmd = cmd >> 1; 872 cmd = cmd >> 1;
@@ -874,13 +886,13 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file,
874 break; 886 break;
875 887
876 case FE_DISEQC_RECV_SLAVE_REPLY: 888 case FE_DISEQC_RECV_SLAVE_REPLY:
877 if (fe->ops->diseqc_recv_slave_reply) 889 if (fe->ops.diseqc_recv_slave_reply)
878 err = fe->ops->diseqc_recv_slave_reply(fe, (struct dvb_diseqc_slave_reply*) parg); 890 err = fe->ops.diseqc_recv_slave_reply(fe, (struct dvb_diseqc_slave_reply*) parg);
879 break; 891 break;
880 892
881 case FE_ENABLE_HIGH_LNB_VOLTAGE: 893 case FE_ENABLE_HIGH_LNB_VOLTAGE:
882 if (fe->ops->enable_high_lnb_voltage) 894 if (fe->ops.enable_high_lnb_voltage)
883 err = fe->ops->enable_high_lnb_voltage(fe, (long) parg); 895 err = fe->ops.enable_high_lnb_voltage(fe, (long) parg);
884 break; 896 break;
885 897
886 case FE_SET_FRONTEND: { 898 case FE_SET_FRONTEND: {
@@ -898,7 +910,7 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file,
898 fepriv->parameters.inversion = INVERSION_AUTO; 910 fepriv->parameters.inversion = INVERSION_AUTO;
899 fetunesettings.parameters.inversion = INVERSION_AUTO; 911 fetunesettings.parameters.inversion = INVERSION_AUTO;
900 } 912 }
901 if (fe->ops->info.type == FE_OFDM) { 913 if (fe->ops.info.type == FE_OFDM) {
902 /* without hierachical coding code_rate_LP is irrelevant, 914 /* without hierachical coding code_rate_LP is irrelevant,
903 * so we tolerate the otherwise invalid FEC_NONE setting */ 915 * so we tolerate the otherwise invalid FEC_NONE setting */
904 if (fepriv->parameters.u.ofdm.hierarchy_information == HIERARCHY_NONE && 916 if (fepriv->parameters.u.ofdm.hierarchy_information == HIERARCHY_NONE &&
@@ -907,13 +919,13 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file,
907 } 919 }
908 920
909 /* get frontend-specific tuning settings */ 921 /* get frontend-specific tuning settings */
910 if (fe->ops->get_tune_settings && (fe->ops->get_tune_settings(fe, &fetunesettings) == 0)) { 922 if (fe->ops.get_tune_settings && (fe->ops.get_tune_settings(fe, &fetunesettings) == 0)) {
911 fepriv->min_delay = (fetunesettings.min_delay_ms * HZ) / 1000; 923 fepriv->min_delay = (fetunesettings.min_delay_ms * HZ) / 1000;
912 fepriv->max_drift = fetunesettings.max_drift; 924 fepriv->max_drift = fetunesettings.max_drift;
913 fepriv->step_size = fetunesettings.step_size; 925 fepriv->step_size = fetunesettings.step_size;
914 } else { 926 } else {
915 /* default values */ 927 /* default values */
916 switch(fe->ops->info.type) { 928 switch(fe->ops.info.type) {
917 case FE_QPSK: 929 case FE_QPSK:
918 fepriv->min_delay = HZ/20; 930 fepriv->min_delay = HZ/20;
919 fepriv->step_size = fepriv->parameters.u.qpsk.symbol_rate / 16000; 931 fepriv->step_size = fepriv->parameters.u.qpsk.symbol_rate / 16000;
@@ -928,11 +940,13 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file,
928 940
929 case FE_OFDM: 941 case FE_OFDM:
930 fepriv->min_delay = HZ/20; 942 fepriv->min_delay = HZ/20;
931 fepriv->step_size = fe->ops->info.frequency_stepsize * 2; 943 fepriv->step_size = fe->ops.info.frequency_stepsize * 2;
932 fepriv->max_drift = (fe->ops->info.frequency_stepsize * 2) + 1; 944 fepriv->max_drift = (fe->ops.info.frequency_stepsize * 2) + 1;
933 break; 945 break;
934 case FE_ATSC: 946 case FE_ATSC:
935 printk("dvb-core: FE_ATSC not handled yet.\n"); 947 fepriv->min_delay = HZ/20;
948 fepriv->step_size = 0;
949 fepriv->max_drift = 0;
936 break; 950 break;
937 } 951 }
938 } 952 }
@@ -952,9 +966,9 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file,
952 break; 966 break;
953 967
954 case FE_GET_FRONTEND: 968 case FE_GET_FRONTEND:
955 if (fe->ops->get_frontend) { 969 if (fe->ops.get_frontend) {
956 memcpy (parg, &fepriv->parameters, sizeof (struct dvb_frontend_parameters)); 970 memcpy (parg, &fepriv->parameters, sizeof (struct dvb_frontend_parameters));
957 err = fe->ops->get_frontend(fe, (struct dvb_frontend_parameters*) parg); 971 err = fe->ops.get_frontend(fe, (struct dvb_frontend_parameters*) parg);
958 } 972 }
959 break; 973 break;
960 974
@@ -1067,7 +1081,7 @@ int dvb_register_frontend(struct dvb_adapter* dvb,
1067 1081
1068 printk ("DVB: registering frontend %i (%s)...\n", 1082 printk ("DVB: registering frontend %i (%s)...\n",
1069 fe->dvb->num, 1083 fe->dvb->num,
1070 fe->ops->info.name); 1084 fe->ops.info.name);
1071 1085
1072 dvb_register_device (fe->dvb, &fepriv->dvbdev, &dvbdev_template, 1086 dvb_register_device (fe->dvb, &fepriv->dvbdev, &dvbdev_template,
1073 fe, DVB_DEVICE_FRONTEND); 1087 fe, DVB_DEVICE_FRONTEND);
@@ -1085,10 +1099,15 @@ int dvb_unregister_frontend(struct dvb_frontend* fe)
1085 mutex_lock(&frontend_mutex); 1099 mutex_lock(&frontend_mutex);
1086 dvb_unregister_device (fepriv->dvbdev); 1100 dvb_unregister_device (fepriv->dvbdev);
1087 dvb_frontend_stop (fe); 1101 dvb_frontend_stop (fe);
1088 if (fe->ops->release) 1102 if (fe->ops.tuner_ops.release) {
1089 fe->ops->release(fe); 1103 fe->ops.tuner_ops.release(fe);
1104 if (fe->ops.i2c_gate_ctrl)
1105 fe->ops.i2c_gate_ctrl(fe, 0);
1106 }
1107 if (fe->ops.release)
1108 fe->ops.release(fe);
1090 else 1109 else
1091 printk("dvb_frontend: Demodulator (%s) does not have a release callback!\n", fe->ops->info.name); 1110 printk("dvb_frontend: Demodulator (%s) does not have a release callback!\n", fe->ops.info.name);
1092 /* fe is invalid now */ 1111 /* fe is invalid now */
1093 kfree(fepriv); 1112 kfree(fepriv);
1094 mutex_unlock(&frontend_mutex); 1113 mutex_unlock(&frontend_mutex);
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.h b/drivers/media/dvb/dvb-core/dvb_frontend.h
index 5926a3b745c9..2887e2b862a4 100644
--- a/drivers/media/dvb/dvb-core/dvb_frontend.h
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.h
@@ -49,6 +49,44 @@ struct dvb_frontend_tune_settings {
49 49
50struct dvb_frontend; 50struct dvb_frontend;
51 51
52struct dvb_tuner_info {
53 char name[128];
54
55 u32 frequency_min;
56 u32 frequency_max;
57 u32 frequency_step;
58
59 u32 bandwidth_min;
60 u32 bandwidth_max;
61 u32 bandwidth_step;
62};
63
64struct dvb_tuner_ops {
65
66 struct dvb_tuner_info info;
67
68 int (*release)(struct dvb_frontend *fe);
69 int (*init)(struct dvb_frontend *fe);
70 int (*sleep)(struct dvb_frontend *fe);
71
72 /** This is for simple PLLs - set all parameters in one go. */
73 int (*set_params)(struct dvb_frontend *fe, struct dvb_frontend_parameters *p);
74
75 /** This is support for demods like the mt352 - fills out the supplied buffer with what to write. */
76 int (*calc_regs)(struct dvb_frontend *fe, struct dvb_frontend_parameters *p, u8 *buf, int buf_len);
77
78 int (*get_frequency)(struct dvb_frontend *fe, u32 *frequency);
79 int (*get_bandwidth)(struct dvb_frontend *fe, u32 *bandwidth);
80
81#define TUNER_STATUS_LOCKED 1
82 int (*get_status)(struct dvb_frontend *fe, u32 *status);
83
84 /** These are provided seperately from set_params in order to facilitate silicon
85 * tuners which require sophisticated tuning loops, controlling each parameter seperately. */
86 int (*set_frequency)(struct dvb_frontend *fe, u32 frequency);
87 int (*set_bandwidth)(struct dvb_frontend *fe, u32 bandwidth);
88};
89
52struct dvb_frontend_ops { 90struct dvb_frontend_ops {
53 91
54 struct dvb_frontend_info info; 92 struct dvb_frontend_info info;
@@ -64,6 +102,8 @@ struct dvb_frontend_ops {
64 unsigned int mode_flags, 102 unsigned int mode_flags,
65 int *delay, 103 int *delay,
66 fe_status_t *status); 104 fe_status_t *status);
105 /* get frontend tuning algorithm from the module */
106 int (*get_frontend_algo)(struct dvb_frontend *fe);
67 107
68 /* these two are only used for the swzigzag code */ 108 /* these two are only used for the swzigzag code */
69 int (*set_frontend)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params); 109 int (*set_frontend)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
@@ -86,6 +126,8 @@ struct dvb_frontend_ops {
86 int (*enable_high_lnb_voltage)(struct dvb_frontend* fe, long arg); 126 int (*enable_high_lnb_voltage)(struct dvb_frontend* fe, long arg);
87 int (*dishnetwork_send_legacy_command)(struct dvb_frontend* fe, unsigned long cmd); 127 int (*dishnetwork_send_legacy_command)(struct dvb_frontend* fe, unsigned long cmd);
88 int (*i2c_gate_ctrl)(struct dvb_frontend* fe, int enable); 128 int (*i2c_gate_ctrl)(struct dvb_frontend* fe, int enable);
129
130 struct dvb_tuner_ops tuner_ops;
89}; 131};
90 132
91#define MAX_EVENT 8 133#define MAX_EVENT 8
@@ -100,9 +142,10 @@ struct dvb_fe_events {
100}; 142};
101 143
102struct dvb_frontend { 144struct dvb_frontend {
103 struct dvb_frontend_ops* ops; 145 struct dvb_frontend_ops ops;
104 struct dvb_adapter *dvb; 146 struct dvb_adapter *dvb;
105 void* demodulator_priv; 147 void* demodulator_priv;
148 void* tuner_priv;
106 void* frontend_priv; 149 void* frontend_priv;
107 void* misc_priv; 150 void* misc_priv;
108}; 151};
diff --git a/drivers/media/dvb/dvb-core/dvb_math.c b/drivers/media/dvb/dvb-core/dvb_math.c
new file mode 100644
index 000000000000..beb7c93aa6cb
--- /dev/null
+++ b/drivers/media/dvb/dvb-core/dvb_math.c
@@ -0,0 +1,145 @@
1/*
2 * dvb-math provides some complex fixed-point math
3 * operations shared between the dvb related stuff
4 *
5 * Copyright (C) 2006 Christoph Pfister (christophpfister@gmail.com)
6 *
7 * This library is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU Lesser General Public License as
9 * published by the Free Software Foundation; either version 2.1 of
10 * the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21
22#include <linux/bitops.h>
23#include <linux/kernel.h>
24#include <linux/module.h>
25#include <asm/bug.h>
26#include "dvb_math.h"
27
28static const unsigned short logtable[256] = {
29 0x0000, 0x0171, 0x02e0, 0x044e, 0x05ba, 0x0725, 0x088e, 0x09f7,
30 0x0b5d, 0x0cc3, 0x0e27, 0x0f8a, 0x10eb, 0x124b, 0x13aa, 0x1508,
31 0x1664, 0x17bf, 0x1919, 0x1a71, 0x1bc8, 0x1d1e, 0x1e73, 0x1fc6,
32 0x2119, 0x226a, 0x23ba, 0x2508, 0x2656, 0x27a2, 0x28ed, 0x2a37,
33 0x2b80, 0x2cc8, 0x2e0f, 0x2f54, 0x3098, 0x31dc, 0x331e, 0x345f,
34 0x359f, 0x36de, 0x381b, 0x3958, 0x3a94, 0x3bce, 0x3d08, 0x3e41,
35 0x3f78, 0x40af, 0x41e4, 0x4319, 0x444c, 0x457f, 0x46b0, 0x47e1,
36 0x4910, 0x4a3f, 0x4b6c, 0x4c99, 0x4dc5, 0x4eef, 0x5019, 0x5142,
37 0x526a, 0x5391, 0x54b7, 0x55dc, 0x5700, 0x5824, 0x5946, 0x5a68,
38 0x5b89, 0x5ca8, 0x5dc7, 0x5ee5, 0x6003, 0x611f, 0x623a, 0x6355,
39 0x646f, 0x6588, 0x66a0, 0x67b7, 0x68ce, 0x69e4, 0x6af8, 0x6c0c,
40 0x6d20, 0x6e32, 0x6f44, 0x7055, 0x7165, 0x7274, 0x7383, 0x7490,
41 0x759d, 0x76aa, 0x77b5, 0x78c0, 0x79ca, 0x7ad3, 0x7bdb, 0x7ce3,
42 0x7dea, 0x7ef0, 0x7ff6, 0x80fb, 0x81ff, 0x8302, 0x8405, 0x8507,
43 0x8608, 0x8709, 0x8809, 0x8908, 0x8a06, 0x8b04, 0x8c01, 0x8cfe,
44 0x8dfa, 0x8ef5, 0x8fef, 0x90e9, 0x91e2, 0x92db, 0x93d2, 0x94ca,
45 0x95c0, 0x96b6, 0x97ab, 0x98a0, 0x9994, 0x9a87, 0x9b7a, 0x9c6c,
46 0x9d5e, 0x9e4f, 0x9f3f, 0xa02e, 0xa11e, 0xa20c, 0xa2fa, 0xa3e7,
47 0xa4d4, 0xa5c0, 0xa6ab, 0xa796, 0xa881, 0xa96a, 0xaa53, 0xab3c,
48 0xac24, 0xad0c, 0xadf2, 0xaed9, 0xafbe, 0xb0a4, 0xb188, 0xb26c,
49 0xb350, 0xb433, 0xb515, 0xb5f7, 0xb6d9, 0xb7ba, 0xb89a, 0xb97a,
50 0xba59, 0xbb38, 0xbc16, 0xbcf4, 0xbdd1, 0xbead, 0xbf8a, 0xc065,
51 0xc140, 0xc21b, 0xc2f5, 0xc3cf, 0xc4a8, 0xc580, 0xc658, 0xc730,
52 0xc807, 0xc8de, 0xc9b4, 0xca8a, 0xcb5f, 0xcc34, 0xcd08, 0xcddc,
53 0xceaf, 0xcf82, 0xd054, 0xd126, 0xd1f7, 0xd2c8, 0xd399, 0xd469,
54 0xd538, 0xd607, 0xd6d6, 0xd7a4, 0xd872, 0xd93f, 0xda0c, 0xdad9,
55 0xdba5, 0xdc70, 0xdd3b, 0xde06, 0xded0, 0xdf9a, 0xe063, 0xe12c,
56 0xe1f5, 0xe2bd, 0xe385, 0xe44c, 0xe513, 0xe5d9, 0xe69f, 0xe765,
57 0xe82a, 0xe8ef, 0xe9b3, 0xea77, 0xeb3b, 0xebfe, 0xecc1, 0xed83,
58 0xee45, 0xef06, 0xefc8, 0xf088, 0xf149, 0xf209, 0xf2c8, 0xf387,
59 0xf446, 0xf505, 0xf5c3, 0xf680, 0xf73e, 0xf7fb, 0xf8b7, 0xf973,
60 0xfa2f, 0xfaea, 0xfba5, 0xfc60, 0xfd1a, 0xfdd4, 0xfe8e, 0xff47
61};
62
63unsigned int intlog2(u32 value)
64{
65 /**
66 * returns: log2(value) * 2^24
67 * wrong result if value = 0 (log2(0) is undefined)
68 */
69 unsigned int msb;
70 unsigned int logentry;
71 unsigned int significand;
72 unsigned int interpolation;
73
74 if (unlikely(value == 0)) {
75 WARN_ON(1);
76 return 0;
77 }
78
79 /* first detect the msb (count begins at 0) */
80 msb = fls(value) - 1;
81
82 /**
83 * now we use a logtable after the following method:
84 *
85 * log2(2^x * y) * 2^24 = x * 2^24 + log2(y) * 2^24
86 * where x = msb and therefore 1 <= y < 2
87 * first y is determined by shifting the value left
88 * so that msb is bit 31
89 * 0x00231f56 -> 0x8C7D5800
90 * the result is y * 2^31 -> "significand"
91 * then the highest 9 bits are used for a table lookup
92 * the highest bit is discarded because it's always set
93 * the highest nine bits in our example are 100011000
94 * so we would use the entry 0x18
95 */
96 significand = value << (31 - msb);
97 logentry = (significand >> 23) & 0xff;
98
99 /**
100 * last step we do is interpolation because of the
101 * limitations of the log table the error is that part of
102 * the significand which isn't used for lookup then we
103 * compute the ratio between the error and the next table entry
104 * and interpolate it between the log table entry used and the
105 * next one the biggest error possible is 0x7fffff
106 * (in our example it's 0x7D5800)
107 * needed value for next table entry is 0x800000
108 * so the interpolation is
109 * (error / 0x800000) * (logtable_next - logtable_current)
110 * in the implementation the division is moved to the end for
111 * better accuracy there is also an overflow correction if
112 * logtable_next is 256
113 */
114 interpolation = ((significand & 0x7fffff) *
115 ((logtable[(logentry + 1) & 0xff] -
116 logtable[logentry]) & 0xffff)) >> 15;
117
118 /* now we return the result */
119 return ((msb << 24) + (logtable[logentry] << 8) + interpolation);
120}
121EXPORT_SYMBOL(intlog2);
122
123unsigned int intlog10(u32 value)
124{
125 /**
126 * returns: log10(value) * 2^24
127 * wrong result if value = 0 (log10(0) is undefined)
128 */
129 u64 log;
130
131 if (unlikely(value == 0)) {
132 WARN_ON(1);
133 return 0;
134 }
135
136 log = intlog2(value);
137
138 /**
139 * we use the following method:
140 * log10(x) = log2(x) * log10(2)
141 */
142
143 return (log * 646456993) >> 31;
144}
145EXPORT_SYMBOL(intlog10);
diff --git a/drivers/media/dvb/dvb-core/dvb_math.h b/drivers/media/dvb/dvb-core/dvb_math.h
new file mode 100644
index 000000000000..aecc867e9404
--- /dev/null
+++ b/drivers/media/dvb/dvb-core/dvb_math.h
@@ -0,0 +1,58 @@
1/*
2 * dvb-math provides some complex fixed-point math
3 * operations shared between the dvb related stuff
4 *
5 * Copyright (C) 2006 Christoph Pfister (christophpfister@gmail.com)
6 *
7 * This library is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU Lesser General Public License as
9 * published by the Free Software Foundation; either version 2.1 of
10 * the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21
22#ifndef __DVB_MATH_H
23#define __DVB_MATH_H
24
25#include <linux/types.h>
26
27/**
28 * computes log2 of a value; the result is shifted left by 24 bits
29 *
30 * to use rational values you can use the following method:
31 * intlog2(value) = intlog2(value * 2^x) - x * 2^24
32 *
33 * example: intlog2(8) will give 3 << 24 = 3 * 2^24
34 * example: intlog2(9) will give 3 << 24 + ... = 3.16... * 2^24
35 * example: intlog2(1.5) = intlog2(3) - 2^24 = 0.584... * 2^24
36 *
37 * @param value The value (must be != 0)
38 * @return log2(value) * 2^24
39 */
40extern unsigned int intlog2(u32 value);
41
42/**
43 * computes log10 of a value; the result is shifted left by 24 bits
44 *
45 * to use rational values you can use the following method:
46 * intlog10(value) = intlog10(value * 10^x) - x * 2^24
47 *
48 * example: intlog10(1000) will give 3 << 24 = 3 * 2^24
49 * due to the implementation intlog10(1000) might be not exactly 3 * 2^24
50 *
51 * look at intlog2 for similar examples
52 *
53 * @param value The value (must be != 0)
54 * @return log10(value) * 2^24
55 */
56extern unsigned int intlog10(u32 value);
57
58#endif
diff --git a/drivers/media/dvb/dvb-core/dvb_net.c b/drivers/media/dvb/dvb-core/dvb_net.c
index 9fd87521a163..8859ab74f0fe 100644
--- a/drivers/media/dvb/dvb-core/dvb_net.c
+++ b/drivers/media/dvb/dvb-core/dvb_net.c
@@ -12,7 +12,7 @@
12 * Hilmar Linder <hlinder@cosy.sbg.ac.at> 12 * Hilmar Linder <hlinder@cosy.sbg.ac.at>
13 * and Wolfram Stering <wstering@cosy.sbg.ac.at> 13 * and Wolfram Stering <wstering@cosy.sbg.ac.at>
14 * 14 *
15 * ULE Decaps according to draft-ietf-ipdvb-ule-03.txt. 15 * ULE Decaps according to RFC 4326.
16 * 16 *
17 * This program is free software; you can redistribute it and/or 17 * This program is free software; you can redistribute it and/or
18 * modify it under the terms of the GNU General Public License 18 * modify it under the terms of the GNU General Public License
@@ -42,6 +42,9 @@
42 * Bugfixes and robustness improvements. 42 * Bugfixes and robustness improvements.
43 * Filtering on dest MAC addresses, if present (D-Bit = 0) 43 * Filtering on dest MAC addresses, if present (D-Bit = 0)
44 * ULE_DEBUG compile-time option. 44 * ULE_DEBUG compile-time option.
45 * Apr 2006: cp v3: Bugfixes and compliency with RFC 4326 (ULE) by
46 * Christian Praehauser <cpraehaus@cosy.sbg.ac.at>,
47 * Paris Lodron University of Salzburg.
45 */ 48 */
46 49
47/* 50/*
@@ -49,9 +52,6 @@
49 * 52 *
50 * Unloading does not work for 2.6.9 kernels: a refcount doesn't go to zero. 53 * Unloading does not work for 2.6.9 kernels: a refcount doesn't go to zero.
51 * 54 *
52 * TS_FEED callback is called once for every single TS cell although it is
53 * registered (in dvb_net_feed_start()) for 100 TS cells (used for dvb_net_ule()).
54 *
55 */ 55 */
56 56
57#include <linux/module.h> 57#include <linux/module.h>
@@ -89,6 +89,9 @@ static inline __u32 iov_crc32( __u32 c, struct kvec *iov, unsigned int cnt )
89 89
90#ifdef ULE_DEBUG 90#ifdef ULE_DEBUG
91 91
92#define MAC_ADDR_PRINTFMT "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x"
93#define MAX_ADDR_PRINTFMT_ARGS(macap) (macap)[0],(macap)[1],(macap)[2],(macap)[3],(macap)[4],(macap)[5]
94
92#define isprint(c) ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9')) 95#define isprint(c) ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9'))
93 96
94static void hexdump( const unsigned char *buf, unsigned short len ) 97static void hexdump( const unsigned char *buf, unsigned short len )
@@ -214,6 +217,8 @@ static unsigned short dvb_net_eth_type_trans(struct sk_buff *skb,
214#define ULE_TEST 0 217#define ULE_TEST 0
215#define ULE_BRIDGED 1 218#define ULE_BRIDGED 1
216 219
220#define ULE_OPTEXTHDR_PADDING 0
221
217static int ule_test_sndu( struct dvb_net_priv *p ) 222static int ule_test_sndu( struct dvb_net_priv *p )
218{ 223{
219 return -1; 224 return -1;
@@ -221,14 +226,28 @@ static int ule_test_sndu( struct dvb_net_priv *p )
221 226
222static int ule_bridged_sndu( struct dvb_net_priv *p ) 227static int ule_bridged_sndu( struct dvb_net_priv *p )
223{ 228{
224 /* BRIDGE SNDU handling sucks in draft-ietf-ipdvb-ule-03.txt. 229 struct ethhdr *hdr = (struct ethhdr*) p->ule_next_hdr;
225 * This has to be the last extension header, otherwise it won't work. 230 if(ntohs(hdr->h_proto) < 1536) {
226 * Blame the authors! 231 int framelen = p->ule_sndu_len - ((p->ule_next_hdr+sizeof(struct ethhdr)) - p->ule_skb->data);
232 /* A frame Type < 1536 for a bridged frame, introduces a LLC Length field. */
233 if(framelen != ntohs(hdr->h_proto)) {
234 return -1;
235 }
236 }
237 /* Note:
238 * From RFC4326:
239 * "A bridged SNDU is a Mandatory Extension Header of Type 1.
240 * It must be the final (or only) extension header specified in the header chain of a SNDU."
241 * The 'ule_bridged' flag will cause the extension header processing loop to terminate.
227 */ 242 */
228 p->ule_bridged = 1; 243 p->ule_bridged = 1;
229 return 0; 244 return 0;
230} 245}
231 246
247static int ule_exthdr_padding(struct dvb_net_priv *p)
248{
249 return 0;
250}
232 251
233/** Handle ULE extension headers. 252/** Handle ULE extension headers.
234 * Function is called after a successful CRC32 verification of an ULE SNDU to complete its decoding. 253 * Function is called after a successful CRC32 verification of an ULE SNDU to complete its decoding.
@@ -242,7 +261,8 @@ static int handle_one_ule_extension( struct dvb_net_priv *p )
242 { [0] = ule_test_sndu, [1] = ule_bridged_sndu, [2] = NULL, }; 261 { [0] = ule_test_sndu, [1] = ule_bridged_sndu, [2] = NULL, };
243 262
244 /* Table of optional extension header handlers. The header type is the index. */ 263 /* Table of optional extension header handlers. The header type is the index. */
245 static int (*ule_optional_ext_handlers[255])( struct dvb_net_priv *p ) = { NULL, }; 264 static int (*ule_optional_ext_handlers[255])( struct dvb_net_priv *p ) =
265 { [0] = ule_exthdr_padding, [1] = NULL, };
246 266
247 int ext_len = 0; 267 int ext_len = 0;
248 unsigned char hlen = (p->ule_sndu_type & 0x0700) >> 8; 268 unsigned char hlen = (p->ule_sndu_type & 0x0700) >> 8;
@@ -253,25 +273,31 @@ static int handle_one_ule_extension( struct dvb_net_priv *p )
253 /* Mandatory extension header */ 273 /* Mandatory extension header */
254 if (ule_mandatory_ext_handlers[htype]) { 274 if (ule_mandatory_ext_handlers[htype]) {
255 ext_len = ule_mandatory_ext_handlers[htype]( p ); 275 ext_len = ule_mandatory_ext_handlers[htype]( p );
256 p->ule_next_hdr += ext_len; 276 if(ext_len >= 0) {
257 if (! p->ule_bridged) { 277 p->ule_next_hdr += ext_len;
258 p->ule_sndu_type = ntohs( *(unsigned short *)p->ule_next_hdr ); 278 if (!p->ule_bridged) {
259 p->ule_next_hdr += 2; 279 p->ule_sndu_type = ntohs(*(unsigned short *)p->ule_next_hdr);
260 } else { 280 p->ule_next_hdr += 2;
261 p->ule_sndu_type = ntohs( *(unsigned short *)(p->ule_next_hdr + ((p->ule_dbit ? 2 : 3) * ETH_ALEN)) ); 281 } else {
262 /* This assures the extension handling loop will terminate. */ 282 p->ule_sndu_type = ntohs(*(unsigned short *)(p->ule_next_hdr + ((p->ule_dbit ? 2 : 3) * ETH_ALEN)));
283 /* This assures the extension handling loop will terminate. */
284 }
263 } 285 }
286 // else: extension handler failed or SNDU should be discarded
264 } else 287 } else
265 ext_len = -1; /* SNDU has to be discarded. */ 288 ext_len = -1; /* SNDU has to be discarded. */
266 } else { 289 } else {
267 /* Optional extension header. Calculate the length. */ 290 /* Optional extension header. Calculate the length. */
268 ext_len = hlen << 2; 291 ext_len = hlen << 1;
269 /* Process the optional extension header according to its type. */ 292 /* Process the optional extension header according to its type. */
270 if (ule_optional_ext_handlers[htype]) 293 if (ule_optional_ext_handlers[htype])
271 (void)ule_optional_ext_handlers[htype]( p ); 294 (void)ule_optional_ext_handlers[htype]( p );
272 p->ule_next_hdr += ext_len; 295 p->ule_next_hdr += ext_len;
273 p->ule_sndu_type = ntohs( *(unsigned short *)p->ule_next_hdr ); 296 p->ule_sndu_type = ntohs( *(unsigned short *)(p->ule_next_hdr-2) );
274 p->ule_next_hdr += 2; 297 /*
298 * note: the length of the next header type is included in the
299 * length of THIS optional extension header
300 */
275 } 301 }
276 302
277 return ext_len; 303 return ext_len;
@@ -284,8 +310,14 @@ static int handle_ule_extensions( struct dvb_net_priv *p )
284 p->ule_next_hdr = p->ule_skb->data; 310 p->ule_next_hdr = p->ule_skb->data;
285 do { 311 do {
286 l = handle_one_ule_extension( p ); 312 l = handle_one_ule_extension( p );
287 if (l == -1) return -1; /* Stop extension header processing and discard SNDU. */ 313 if (l < 0)
314 return l; /* Stop extension header processing and discard SNDU. */
288 total_ext_len += l; 315 total_ext_len += l;
316#ifdef ULE_DEBUG
317 dprintk("handle_ule_extensions: ule_next_hdr=%p, ule_sndu_type=%i, "
318 "l=%i, total_ext_len=%i\n", p->ule_next_hdr,
319 (int) p->ule_sndu_type, l, total_ext_len);
320#endif
289 321
290 } while (p->ule_sndu_type < 1536); 322 } while (p->ule_sndu_type < 1536);
291 323
@@ -355,8 +387,8 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len )
355 if (priv->ule_skb) { 387 if (priv->ule_skb) {
356 dev_kfree_skb( priv->ule_skb ); 388 dev_kfree_skb( priv->ule_skb );
357 /* Prepare for next SNDU. */ 389 /* Prepare for next SNDU. */
358 ((struct dvb_net_priv *) dev->priv)->stats.rx_errors++; 390 priv->stats.rx_errors++;
359 ((struct dvb_net_priv *) dev->priv)->stats.rx_frame_errors++; 391 priv->stats.rx_frame_errors++;
360 } 392 }
361 reset_ule(priv); 393 reset_ule(priv);
362 priv->need_pusi = 1; 394 priv->need_pusi = 1;
@@ -396,27 +428,25 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len )
396 } 428 }
397 } 429 }
398 430
399 /* Check continuity counter. */
400 if (new_ts) { 431 if (new_ts) {
432 /* Check continuity counter. */
401 if ((ts[3] & 0x0F) == priv->tscc) 433 if ((ts[3] & 0x0F) == priv->tscc)
402 priv->tscc = (priv->tscc + 1) & 0x0F; 434 priv->tscc = (priv->tscc + 1) & 0x0F;
403 else { 435 else {
404 /* TS discontinuity handling: */ 436 /* TS discontinuity handling: */
405 printk(KERN_WARNING "%lu: TS discontinuity: got %#x, " 437 printk(KERN_WARNING "%lu: TS discontinuity: got %#x, "
406 "exptected %#x.\n", priv->ts_count, ts[3] & 0x0F, priv->tscc); 438 "expected %#x.\n", priv->ts_count, ts[3] & 0x0F, priv->tscc);
407 /* Drop partly decoded SNDU, reset state, resync on PUSI. */ 439 /* Drop partly decoded SNDU, reset state, resync on PUSI. */
408 if (priv->ule_skb) { 440 if (priv->ule_skb) {
409 dev_kfree_skb( priv->ule_skb ); 441 dev_kfree_skb( priv->ule_skb );
410 /* Prepare for next SNDU. */ 442 /* Prepare for next SNDU. */
411 // reset_ule(priv); moved to below. 443 // reset_ule(priv); moved to below.
412 ((struct dvb_net_priv *) dev->priv)->stats.rx_errors++; 444 priv->stats.rx_errors++;
413 ((struct dvb_net_priv *) dev->priv)->stats.rx_frame_errors++; 445 priv->stats.rx_frame_errors++;
414 } 446 }
415 reset_ule(priv); 447 reset_ule(priv);
416 /* skip to next PUSI. */ 448 /* skip to next PUSI. */
417 priv->need_pusi = 1; 449 priv->need_pusi = 1;
418 ts += TS_SZ;
419 priv->ts_count++;
420 continue; 450 continue;
421 } 451 }
422 /* If we still have an incomplete payload, but PUSI is 452 /* If we still have an incomplete payload, but PUSI is
@@ -425,7 +455,7 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len )
425 * cells (continuity counter wrap). */ 455 * cells (continuity counter wrap). */
426 if (ts[1] & TS_PUSI) { 456 if (ts[1] & TS_PUSI) {
427 if (! priv->need_pusi) { 457 if (! priv->need_pusi) {
428 if (*from_where > 181) { 458 if (!(*from_where < (ts_remain-1)) || *from_where != priv->ule_sndu_remain) {
429 /* Pointer field is invalid. Drop this TS cell and any started ULE SNDU. */ 459 /* Pointer field is invalid. Drop this TS cell and any started ULE SNDU. */
430 printk(KERN_WARNING "%lu: Invalid pointer " 460 printk(KERN_WARNING "%lu: Invalid pointer "
431 "field: %u.\n", priv->ts_count, *from_where); 461 "field: %u.\n", priv->ts_count, *from_where);
@@ -438,8 +468,6 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len )
438 } 468 }
439 reset_ule(priv); 469 reset_ule(priv);
440 priv->need_pusi = 1; 470 priv->need_pusi = 1;
441 ts += TS_SZ;
442 priv->ts_count++;
443 continue; 471 continue;
444 } 472 }
445 /* Skip pointer field (we're processing a 473 /* Skip pointer field (we're processing a
@@ -452,8 +480,8 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len )
452 if (priv->ule_sndu_remain > 183) { 480 if (priv->ule_sndu_remain > 183) {
453 /* Current SNDU lacks more data than there could be available in the 481 /* Current SNDU lacks more data than there could be available in the
454 * current TS cell. */ 482 * current TS cell. */
455 ((struct dvb_net_priv *) dev->priv)->stats.rx_errors++; 483 priv->stats.rx_errors++;
456 ((struct dvb_net_priv *) dev->priv)->stats.rx_length_errors++; 484 priv->stats.rx_length_errors++;
457 printk(KERN_WARNING "%lu: Expected %d more SNDU bytes, but " 485 printk(KERN_WARNING "%lu: Expected %d more SNDU bytes, but "
458 "got PUSI (pf %d, ts_remain %d). Flushing incomplete payload.\n", 486 "got PUSI (pf %d, ts_remain %d). Flushing incomplete payload.\n",
459 priv->ts_count, priv->ule_sndu_remain, ts[4], ts_remain); 487 priv->ts_count, priv->ule_sndu_remain, ts[4], ts_remain);
@@ -492,9 +520,11 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len )
492 } else 520 } else
493 priv->ule_dbit = 0; 521 priv->ule_dbit = 0;
494 522
495 if (priv->ule_sndu_len > 32763) { 523 if (priv->ule_sndu_len < 5) {
496 printk(KERN_WARNING "%lu: Invalid ULE SNDU length %u. " 524 printk(KERN_WARNING "%lu: Invalid ULE SNDU length %u. "
497 "Resyncing.\n", priv->ts_count, priv->ule_sndu_len); 525 "Resyncing.\n", priv->ts_count, priv->ule_sndu_len);
526 priv->stats.rx_errors++;
527 priv->stats.rx_length_errors++;
498 priv->ule_sndu_len = 0; 528 priv->ule_sndu_len = 0;
499 priv->need_pusi = 1; 529 priv->need_pusi = 1;
500 new_ts = 1; 530 new_ts = 1;
@@ -608,58 +638,103 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len )
608 ule_dump = 1; 638 ule_dump = 1;
609#endif 639#endif
610 640
611 ((struct dvb_net_priv *) dev->priv)->stats.rx_errors++; 641 priv->stats.rx_errors++;
612 ((struct dvb_net_priv *) dev->priv)->stats.rx_crc_errors++; 642 priv->stats.rx_crc_errors++;
613 dev_kfree_skb(priv->ule_skb); 643 dev_kfree_skb(priv->ule_skb);
614 } else { 644 } else {
615 /* CRC32 verified OK. */ 645 /* CRC32 verified OK. */
646 u8 dest_addr[ETH_ALEN];
647 static const u8 bc_addr[ETH_ALEN] =
648 { [ 0 ... ETH_ALEN-1] = 0xff };
649
650 /* CRC32 was OK. Remove it from skb. */
651 priv->ule_skb->tail -= 4;
652 priv->ule_skb->len -= 4;
653
654 if (!priv->ule_dbit) {
655 /*
656 * The destination MAC address is the
657 * next data in the skb. It comes
658 * before any extension headers.
659 *
660 * Check if the payload of this SNDU
661 * should be passed up the stack.
662 */
663 register int drop = 0;
664 if (priv->rx_mode != RX_MODE_PROMISC) {
665 if (priv->ule_skb->data[0] & 0x01) {
666 /* multicast or broadcast */
667 if (memcmp(priv->ule_skb->data, bc_addr, ETH_ALEN)) {
668 /* multicast */
669 if (priv->rx_mode == RX_MODE_MULTI) {
670 int i;
671 for(i = 0; i < priv->multi_num && memcmp(priv->ule_skb->data, priv->multi_macs[i], ETH_ALEN); i++)
672 ;
673 if (i == priv->multi_num)
674 drop = 1;
675 } else if (priv->rx_mode != RX_MODE_ALL_MULTI)
676 drop = 1; /* no broadcast; */
677 /* else: all multicast mode: accept all multicast packets */
678 }
679 /* else: broadcast */
680 }
681 else if (memcmp(priv->ule_skb->data, dev->dev_addr, ETH_ALEN))
682 drop = 1;
683 /* else: destination address matches the MAC address of our receiver device */
684 }
685 /* else: promiscious mode; pass everything up the stack */
686
687 if (drop) {
688#ifdef ULE_DEBUG
689 dprintk("Dropping SNDU: MAC destination address does not match: dest addr: "MAC_ADDR_PRINTFMT", dev addr: "MAC_ADDR_PRINTFMT"\n",
690 MAX_ADDR_PRINTFMT_ARGS(priv->ule_skb->data), MAX_ADDR_PRINTFMT_ARGS(dev->dev_addr));
691#endif
692 dev_kfree_skb(priv->ule_skb);
693 goto sndu_done;
694 }
695 else
696 {
697 memcpy(dest_addr, priv->ule_skb->data, ETH_ALEN);
698 skb_pull(priv->ule_skb, ETH_ALEN);
699 }
700 }
701
616 /* Handle ULE Extension Headers. */ 702 /* Handle ULE Extension Headers. */
617 if (priv->ule_sndu_type < 1536) { 703 if (priv->ule_sndu_type < 1536) {
618 /* There is an extension header. Handle it accordingly. */ 704 /* There is an extension header. Handle it accordingly. */
619 int l = handle_ule_extensions( priv ); 705 int l = handle_ule_extensions(priv);
620 if (l < 0) { 706 if (l < 0) {
621 /* Mandatory extension header unknown or TEST SNDU. Drop it. */ 707 /* Mandatory extension header unknown or TEST SNDU. Drop it. */
622 // printk( KERN_WARNING "Dropping SNDU, extension headers.\n" ); 708 // printk( KERN_WARNING "Dropping SNDU, extension headers.\n" );
623 dev_kfree_skb( priv->ule_skb ); 709 dev_kfree_skb(priv->ule_skb);
624 goto sndu_done; 710 goto sndu_done;
625 } 711 }
626 skb_pull( priv->ule_skb, l ); 712 skb_pull(priv->ule_skb, l);
627 } 713 }
628 714
629 /* CRC32 was OK. Remove it from skb. */ 715 /*
630 priv->ule_skb->tail -= 4; 716 * Construct/assure correct ethernet header.
631 priv->ule_skb->len -= 4; 717 * Note: in bridged mode (priv->ule_bridged !=
632 718 * 0) we already have the (original) ethernet
633 /* Filter on receiver's destination MAC address, if present. */ 719 * header at the start of the payload (after
634 if (!priv->ule_dbit) { 720 * optional dest. address and any extension
635 /* The destination MAC address is the next data in the skb. */ 721 * headers).
636 if (memcmp( priv->ule_skb->data, dev->dev_addr, ETH_ALEN )) { 722 */
637 /* MAC addresses don't match. Drop SNDU. */ 723
638 // printk( KERN_WARNING "Dropping SNDU, MAC address.\n" ); 724 if (!priv->ule_bridged) {
639 dev_kfree_skb( priv->ule_skb ); 725 skb_push(priv->ule_skb, ETH_HLEN);
640 goto sndu_done; 726 ethh = (struct ethhdr *)priv->ule_skb->data;
641 } 727 if (!priv->ule_dbit) {
642 if (! priv->ule_bridged) { 728 /* dest_addr buffer is only valid if priv->ule_dbit == 0 */
643 skb_push( priv->ule_skb, ETH_ALEN + 2 ); 729 memcpy(ethh->h_dest, dest_addr, ETH_ALEN);
644 ethh = (struct ethhdr *)priv->ule_skb->data; 730 memset(ethh->h_source, 0, ETH_ALEN);
645 memcpy( ethh->h_dest, ethh->h_source, ETH_ALEN );
646 memset( ethh->h_source, 0, ETH_ALEN );
647 ethh->h_proto = htons( priv->ule_sndu_type );
648 } else {
649 /* Skip the Receiver destination MAC address. */
650 skb_pull( priv->ule_skb, ETH_ALEN );
651 }
652 } else {
653 if (! priv->ule_bridged) {
654 skb_push( priv->ule_skb, ETH_HLEN );
655 ethh = (struct ethhdr *)priv->ule_skb->data;
656 memcpy( ethh->h_dest, dev->dev_addr, ETH_ALEN );
657 memset( ethh->h_source, 0, ETH_ALEN );
658 ethh->h_proto = htons( priv->ule_sndu_type );
659 } else {
660 /* skb is in correct state; nothing to do. */
661 } 731 }
732 else /* zeroize source and dest */
733 memset( ethh, 0, ETH_ALEN*2 );
734
735 ethh->h_proto = htons(priv->ule_sndu_type);
662 } 736 }
737 /* else: skb is in correct state; nothing to do. */
663 priv->ule_bridged = 0; 738 priv->ule_bridged = 0;
664 739
665 /* Stuff into kernel's protocol stack. */ 740 /* Stuff into kernel's protocol stack. */
@@ -668,8 +743,8 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len )
668 * receive the packet anyhow. */ 743 * receive the packet anyhow. */
669 /* if (priv->ule_dbit && skb->pkt_type == PACKET_OTHERHOST) 744 /* if (priv->ule_dbit && skb->pkt_type == PACKET_OTHERHOST)
670 priv->ule_skb->pkt_type = PACKET_HOST; */ 745 priv->ule_skb->pkt_type = PACKET_HOST; */
671 ((struct dvb_net_priv *) dev->priv)->stats.rx_packets++; 746 priv->stats.rx_packets++;
672 ((struct dvb_net_priv *) dev->priv)->stats.rx_bytes += priv->ule_skb->len; 747 priv->stats.rx_bytes += priv->ule_skb->len;
673 netif_rx(priv->ule_skb); 748 netif_rx(priv->ule_skb);
674 } 749 }
675 sndu_done: 750 sndu_done:
@@ -944,7 +1019,7 @@ static int dvb_net_feed_start(struct net_device *dev)
944 dprintk("%s: start filtering\n", __FUNCTION__); 1019 dprintk("%s: start filtering\n", __FUNCTION__);
945 priv->secfeed->start_filtering(priv->secfeed); 1020 priv->secfeed->start_filtering(priv->secfeed);
946 } else if (priv->feedtype == DVB_NET_FEEDTYPE_ULE) { 1021 } else if (priv->feedtype == DVB_NET_FEEDTYPE_ULE) {
947 struct timespec timeout = { 0, 30000000 }; // 30 msec 1022 struct timespec timeout = { 0, 10000000 }; // 10 msec
948 1023
949 /* we have payloads encapsulated in TS */ 1024 /* we have payloads encapsulated in TS */
950 dprintk("%s: alloc tsfeed\n", __FUNCTION__); 1025 dprintk("%s: alloc tsfeed\n", __FUNCTION__);
@@ -956,10 +1031,13 @@ static int dvb_net_feed_start(struct net_device *dev)
956 1031
957 /* Set netdevice pointer for ts decaps callback. */ 1032 /* Set netdevice pointer for ts decaps callback. */
958 priv->tsfeed->priv = (void *)dev; 1033 priv->tsfeed->priv = (void *)dev;
959 ret = priv->tsfeed->set(priv->tsfeed, priv->pid, 1034 ret = priv->tsfeed->set(priv->tsfeed,
960 TS_PACKET, DMX_TS_PES_OTHER, 1035 priv->pid, /* pid */
1036 TS_PACKET, /* type */
1037 DMX_TS_PES_OTHER, /* pes type */
961 32768, /* circular buffer size */ 1038 32768, /* circular buffer size */
962 timeout); 1039 timeout /* timeout */
1040 );
963 1041
964 if (ret < 0) { 1042 if (ret < 0) {
965 printk("%s: could not set ts feed\n", dev->name); 1043 printk("%s: could not set ts feed\n", dev->name);
diff --git a/drivers/media/dvb/dvb-core/dvbdev.c b/drivers/media/dvb/dvb-core/dvbdev.c
index 3852430d0260..134c2bbbeeb5 100644
--- a/drivers/media/dvb/dvb-core/dvbdev.c
+++ b/drivers/media/dvb/dvb-core/dvbdev.c
@@ -236,7 +236,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
236 "dvb/adapter%d/%s%d", adap->num, dnames[type], id); 236 "dvb/adapter%d/%s%d", adap->num, dnames[type], id);
237 237
238 class_device_create(dvb_class, NULL, MKDEV(DVB_MAJOR, nums2minor(adap->num, type, id)), 238 class_device_create(dvb_class, NULL, MKDEV(DVB_MAJOR, nums2minor(adap->num, type, id)),
239 NULL, "dvb%d.%s%d", adap->num, dnames[type], id); 239 adap->device, "dvb%d.%s%d", adap->num, dnames[type], id);
240 240
241 dprintk("DVB: register adapter%d/%s%d @ minor: %i (0x%02x)\n", 241 dprintk("DVB: register adapter%d/%s%d @ minor: %i (0x%02x)\n",
242 adap->num, dnames[type], id, nums2minor(adap->num, type, id), 242 adap->num, dnames[type], id, nums2minor(adap->num, type, id),
@@ -285,7 +285,7 @@ skip:
285} 285}
286 286
287 287
288int dvb_register_adapter(struct dvb_adapter *adap, const char *name, struct module *module) 288int dvb_register_adapter(struct dvb_adapter *adap, const char *name, struct module *module, struct device *device)
289{ 289{
290 int num; 290 int num;
291 291
@@ -306,6 +306,7 @@ int dvb_register_adapter(struct dvb_adapter *adap, const char *name, struct modu
306 adap->num = num; 306 adap->num = num;
307 adap->name = name; 307 adap->name = name;
308 adap->module = module; 308 adap->module = module;
309 adap->device = device;
309 310
310 list_add_tail (&adap->list_head, &dvb_adapter_list); 311 list_add_tail (&adap->list_head, &dvb_adapter_list);
311 312
diff --git a/drivers/media/dvb/dvb-core/dvbdev.h b/drivers/media/dvb/dvb-core/dvbdev.h
index 74ed5853f0fb..d7a976d040d7 100644
--- a/drivers/media/dvb/dvb-core/dvbdev.h
+++ b/drivers/media/dvb/dvb-core/dvbdev.h
@@ -51,6 +51,8 @@ struct dvb_adapter {
51 u8 proposed_mac [6]; 51 u8 proposed_mac [6];
52 void* priv; 52 void* priv;
53 53
54 struct device *device;
55
54 struct module *module; 56 struct module *module;
55}; 57};
56 58
@@ -76,7 +78,7 @@ struct dvb_device {
76}; 78};
77 79
78 80
79extern int dvb_register_adapter (struct dvb_adapter *adap, const char *name, struct module *module); 81extern int dvb_register_adapter (struct dvb_adapter *adap, const char *name, struct module *module, struct device *device);
80extern int dvb_unregister_adapter (struct dvb_adapter *adap); 82extern int dvb_unregister_adapter (struct dvb_adapter *adap);
81 83
82extern int dvb_register_device (struct dvb_adapter *adap, 84extern int dvb_register_device (struct dvb_adapter *adap,
diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig
index e388fb1567d6..3bc6722a6443 100644
--- a/drivers/media/dvb/dvb-usb/Kconfig
+++ b/drivers/media/dvb/dvb-usb/Kconfig
@@ -88,6 +88,7 @@ config DVB_USB_CXUSB
88 select DVB_CX22702 88 select DVB_CX22702
89 select DVB_LGDT330X 89 select DVB_LGDT330X
90 select DVB_MT352 90 select DVB_MT352
91 select DVB_ZL10353
91 help 92 help
92 Say Y here to support the Conexant USB2.0 hybrid reference design. 93 Say Y here to support the Conexant USB2.0 hybrid reference design.
93 Currently, only DVB and ATSC modes are supported, analog mode 94 Currently, only DVB and ATSC modes are supported, analog mode
@@ -130,6 +131,15 @@ config DVB_USB_VP702X
130 131
131 DVB-S USB2.0 receivers. 132 DVB-S USB2.0 receivers.
132 133
134config DVB_USB_GP8PSK
135 tristate "GENPIX 8PSK->USB module support"
136 depends on DVB_USB
137 help
138 Say Y here to support the
139 GENPIX 8psk module
140
141 DVB-S USB2.0 receivers.
142
133config DVB_USB_NOVA_T_USB2 143config DVB_USB_NOVA_T_USB2
134 tristate "Hauppauge WinTV-NOVA-T usb2 DVB-T USB2.0 support" 144 tristate "Hauppauge WinTV-NOVA-T usb2 DVB-T USB2.0 support"
135 depends on DVB_USB 145 depends on DVB_USB
diff --git a/drivers/media/dvb/dvb-usb/Makefile b/drivers/media/dvb/dvb-usb/Makefile
index 2dc9aad9681e..9643f56c7fe9 100644
--- a/drivers/media/dvb/dvb-usb/Makefile
+++ b/drivers/media/dvb/dvb-usb/Makefile
@@ -7,6 +7,9 @@ obj-$(CONFIG_DVB_USB_VP7045) += dvb-usb-vp7045.o
7dvb-usb-vp702x-objs = vp702x.o vp702x-fe.o 7dvb-usb-vp702x-objs = vp702x.o vp702x-fe.o
8obj-$(CONFIG_DVB_USB_VP702X) += dvb-usb-vp702x.o 8obj-$(CONFIG_DVB_USB_VP702X) += dvb-usb-vp702x.o
9 9
10dvb-usb-gp8psk-objs = gp8psk.o gp8psk-fe.o
11obj-$(CONFIG_DVB_USB_GP8PSK) += dvb-usb-gp8psk.o
12
10dvb-usb-dtt200u-objs = dtt200u.o dtt200u-fe.o 13dvb-usb-dtt200u-objs = dtt200u.o dtt200u-fe.o
11obj-$(CONFIG_DVB_USB_DTT200U) += dvb-usb-dtt200u.o 14obj-$(CONFIG_DVB_USB_DTT200U) += dvb-usb-dtt200u.o
12 15
diff --git a/drivers/media/dvb/dvb-usb/cxusb.c b/drivers/media/dvb/dvb-usb/cxusb.c
index 1f0d3e995c8d..ae23bdde42a8 100644
--- a/drivers/media/dvb/dvb-usb/cxusb.c
+++ b/drivers/media/dvb/dvb-usb/cxusb.c
@@ -27,8 +27,10 @@
27 27
28#include "cx22702.h" 28#include "cx22702.h"
29#include "lgdt330x.h" 29#include "lgdt330x.h"
30#include "lg_h06xf.h"
30#include "mt352.h" 31#include "mt352.h"
31#include "mt352_priv.h" 32#include "mt352_priv.h"
33#include "zl10353.h"
32 34
33/* debug */ 35/* debug */
34int dvb_usb_cxusb_debug; 36int dvb_usb_cxusb_debug;
@@ -322,32 +324,37 @@ static int cxusb_mt352_demod_init(struct dvb_frontend* fe)
322 return 0; 324 return 0;
323} 325}
324 326
327static int cxusb_lgh064f_tuner_set_params(struct dvb_frontend *fe,
328 struct dvb_frontend_parameters *fep)
329{
330 struct dvb_usb_device *d = fe->dvb->priv;
331 return lg_h06xf_pll_set(fe, &d->i2c_adap, fep);
332}
333
325static struct cx22702_config cxusb_cx22702_config = { 334static struct cx22702_config cxusb_cx22702_config = {
326 .demod_address = 0x63, 335 .demod_address = 0x63,
327 336
328 .output_mode = CX22702_PARALLEL_OUTPUT, 337 .output_mode = CX22702_PARALLEL_OUTPUT,
329
330 .pll_init = dvb_usb_pll_init_i2c,
331 .pll_set = dvb_usb_pll_set_i2c,
332}; 338};
333 339
334static struct lgdt330x_config cxusb_lgdt3303_config = { 340static struct lgdt330x_config cxusb_lgdt3303_config = {
335 .demod_address = 0x0e, 341 .demod_address = 0x0e,
336 .demod_chip = LGDT3303, 342 .demod_chip = LGDT3303,
337 .pll_set = dvb_usb_pll_set_i2c,
338}; 343};
339 344
340static struct mt352_config cxusb_dee1601_config = { 345static struct mt352_config cxusb_dee1601_config = {
341 .demod_address = 0x0f, 346 .demod_address = 0x0f,
342 .demod_init = cxusb_dee1601_demod_init, 347 .demod_init = cxusb_dee1601_demod_init,
343 .pll_set = dvb_usb_pll_set,
344}; 348};
345 349
346struct mt352_config cxusb_mt352_config = { 350static struct zl10353_config cxusb_zl10353_dee1601_config = {
351 .demod_address = 0x0f,
352};
353
354static struct mt352_config cxusb_mt352_config = {
347 /* used in both lgz201 and th7579 */ 355 /* used in both lgz201 and th7579 */
348 .demod_address = 0x0f, 356 .demod_address = 0x0f,
349 .demod_init = cxusb_mt352_demod_init, 357 .demod_init = cxusb_mt352_demod_init,
350 .pll_set = dvb_usb_pll_set,
351}; 358};
352 359
353/* Callbacks for DVB USB */ 360/* Callbacks for DVB USB */
@@ -357,17 +364,10 @@ static int cxusb_fmd1216me_tuner_attach(struct dvb_usb_device *d)
357 d->pll_addr = 0x61; 364 d->pll_addr = 0x61;
358 memcpy(d->pll_init, bpll, 4); 365 memcpy(d->pll_init, bpll, 4);
359 d->pll_desc = &dvb_pll_fmd1216me; 366 d->pll_desc = &dvb_pll_fmd1216me;
360 return 0;
361}
362 367
363static int cxusb_lgh064f_tuner_attach(struct dvb_usb_device *d) 368 d->fe->ops.tuner_ops.init = dvb_usb_tuner_init_i2c;
364{ 369 d->fe->ops.tuner_ops.set_params = dvb_usb_tuner_set_params_i2c;
365 u8 bpll[4] = { 0x00, 0x00, 0x18, 0x50 }; 370
366 /* bpll[2] : unset bit 3, set bits 4&5
367 bpll[3] : 0x50 - digital, 0x20 - analog */
368 d->pll_addr = 0x61;
369 memcpy(d->pll_init, bpll, 4);
370 d->pll_desc = &dvb_pll_tdvs_tua6034;
371 return 0; 371 return 0;
372} 372}
373 373
@@ -375,6 +375,7 @@ static int cxusb_dee1601_tuner_attach(struct dvb_usb_device *d)
375{ 375{
376 d->pll_addr = 0x61; 376 d->pll_addr = 0x61;
377 d->pll_desc = &dvb_pll_thomson_dtt7579; 377 d->pll_desc = &dvb_pll_thomson_dtt7579;
378 d->fe->ops.tuner_ops.calc_regs = dvb_usb_tuner_calc_regs;
378 return 0; 379 return 0;
379} 380}
380 381
@@ -382,6 +383,7 @@ static int cxusb_lgz201_tuner_attach(struct dvb_usb_device *d)
382{ 383{
383 d->pll_addr = 0x61; 384 d->pll_addr = 0x61;
384 d->pll_desc = &dvb_pll_lg_z201; 385 d->pll_desc = &dvb_pll_lg_z201;
386 d->fe->ops.tuner_ops.calc_regs = dvb_usb_tuner_calc_regs;
385 return 0; 387 return 0;
386} 388}
387 389
@@ -389,6 +391,13 @@ static int cxusb_dtt7579_tuner_attach(struct dvb_usb_device *d)
389{ 391{
390 d->pll_addr = 0x60; 392 d->pll_addr = 0x60;
391 d->pll_desc = &dvb_pll_thomson_dtt7579; 393 d->pll_desc = &dvb_pll_thomson_dtt7579;
394 d->fe->ops.tuner_ops.calc_regs = dvb_usb_tuner_calc_regs;
395 return 0;
396}
397
398static int cxusb_lgdt3303_tuner_attach(struct dvb_usb_device *d)
399{
400 d->fe->ops.tuner_ops.set_params = cxusb_lgh064f_tuner_set_params;
392 return 0; 401 return 0;
393} 402}
394 403
@@ -439,7 +448,8 @@ static int cxusb_dee1601_frontend_attach(struct dvb_usb_device *d)
439 448
440 cxusb_ctrl_msg(d,CMD_DIGITAL, NULL, 0, NULL, 0); 449 cxusb_ctrl_msg(d,CMD_DIGITAL, NULL, 0, NULL, 0);
441 450
442 if ((d->fe = mt352_attach(&cxusb_dee1601_config, &d->i2c_adap)) != NULL) 451 if (((d->fe = mt352_attach(&cxusb_dee1601_config, &d->i2c_adap)) != NULL) ||
452 ((d->fe = zl10353_attach(&cxusb_zl10353_dee1601_config, &d->i2c_adap)) != NULL))
443 return 0; 453 return 0;
444 454
445 return -EIO; 455 return -EIO;
@@ -555,7 +565,7 @@ static struct dvb_usb_properties cxusb_bluebird_lgh064f_properties = {
555 .streaming_ctrl = cxusb_streaming_ctrl, 565 .streaming_ctrl = cxusb_streaming_ctrl,
556 .power_ctrl = cxusb_bluebird_power_ctrl, 566 .power_ctrl = cxusb_bluebird_power_ctrl,
557 .frontend_attach = cxusb_lgdt3303_frontend_attach, 567 .frontend_attach = cxusb_lgdt3303_frontend_attach,
558 .tuner_attach = cxusb_lgh064f_tuner_attach, 568 .tuner_attach = cxusb_lgdt3303_tuner_attach,
559 569
560 .i2c_algo = &cxusb_i2c_algo, 570 .i2c_algo = &cxusb_i2c_algo,
561 571
diff --git a/drivers/media/dvb/dvb-usb/dibusb-common.c b/drivers/media/dvb/dvb-usb/dibusb-common.c
index 2d52b76671d3..abd75b4a350d 100644
--- a/drivers/media/dvb/dvb-usb/dibusb-common.c
+++ b/drivers/media/dvb/dvb-usb/dibusb-common.c
@@ -173,11 +173,10 @@ int dibusb_dib3000mc_frontend_attach(struct dvb_usb_device *d)
173 struct dib3000_config demod_cfg; 173 struct dib3000_config demod_cfg;
174 struct dibusb_state *st = d->priv; 174 struct dibusb_state *st = d->priv;
175 175
176 demod_cfg.pll_set = dvb_usb_pll_set_i2c;
177 demod_cfg.pll_init = dvb_usb_pll_init_i2c;
178
179 for (demod_cfg.demod_address = 0x8; demod_cfg.demod_address < 0xd; demod_cfg.demod_address++) 176 for (demod_cfg.demod_address = 0x8; demod_cfg.demod_address < 0xd; demod_cfg.demod_address++)
180 if ((d->fe = dib3000mc_attach(&demod_cfg,&d->i2c_adap,&st->ops)) != NULL) { 177 if ((d->fe = dib3000mc_attach(&demod_cfg,&d->i2c_adap,&st->ops)) != NULL) {
178 d->fe->ops.tuner_ops.init = dvb_usb_tuner_init_i2c;
179 d->fe->ops.tuner_ops.set_params = dvb_usb_tuner_set_params_i2c;
181 d->tuner_pass_ctrl = st->ops.tuner_pass_ctrl; 180 d->tuner_pass_ctrl = st->ops.tuner_pass_ctrl;
182 return 0; 181 return 0;
183 } 182 }
@@ -190,6 +189,10 @@ int dibusb_dib3000mc_tuner_attach (struct dvb_usb_device *d)
190{ 189{
191 d->pll_addr = 0x60; 190 d->pll_addr = 0x60;
192 d->pll_desc = &dvb_pll_env57h1xd5; 191 d->pll_desc = &dvb_pll_env57h1xd5;
192
193 d->fe->ops.tuner_ops.init = dvb_usb_tuner_init_i2c;
194 d->fe->ops.tuner_ops.set_params = dvb_usb_tuner_set_params_i2c;
195
193 return 0; 196 return 0;
194} 197}
195EXPORT_SYMBOL(dibusb_dib3000mc_tuner_attach); 198EXPORT_SYMBOL(dibusb_dib3000mc_tuner_attach);
diff --git a/drivers/media/dvb/dvb-usb/dibusb-mb.c b/drivers/media/dvb/dvb-usb/dibusb-mb.c
index dd5a13195886..f4c45f386ebc 100644
--- a/drivers/media/dvb/dvb-usb/dibusb-mb.c
+++ b/drivers/media/dvb/dvb-usb/dibusb-mb.c
@@ -20,11 +20,12 @@ static int dibusb_dib3000mb_frontend_attach(struct dvb_usb_device *d)
20 struct dibusb_state *st = d->priv; 20 struct dibusb_state *st = d->priv;
21 21
22 demod_cfg.demod_address = 0x8; 22 demod_cfg.demod_address = 0x8;
23 demod_cfg.pll_set = dvb_usb_pll_set_i2c;
24 demod_cfg.pll_init = dvb_usb_pll_init_i2c;
25 23
26 if ((d->fe = dib3000mb_attach(&demod_cfg,&d->i2c_adap,&st->ops)) == NULL) 24 if ((d->fe = dib3000mb_attach(&demod_cfg,&d->i2c_adap,&st->ops)) == NULL) {
25 d->fe->ops.tuner_ops.init = dvb_usb_tuner_init_i2c;
26 d->fe->ops.tuner_ops.set_params = dvb_usb_tuner_set_params_i2c;
27 return -ENODEV; 27 return -ENODEV;
28 }
28 29
29 d->tuner_pass_ctrl = st->ops.tuner_pass_ctrl; 30 d->tuner_pass_ctrl = st->ops.tuner_pass_ctrl;
30 31
diff --git a/drivers/media/dvb/dvb-usb/digitv.c b/drivers/media/dvb/dvb-usb/digitv.c
index 91136c00ce9d..c14d9efb48fd 100644
--- a/drivers/media/dvb/dvb-usb/digitv.c
+++ b/drivers/media/dvb/dvb-usb/digitv.c
@@ -112,27 +112,30 @@ static int digitv_mt352_demod_init(struct dvb_frontend *fe)
112 112
113static struct mt352_config digitv_mt352_config = { 113static struct mt352_config digitv_mt352_config = {
114 .demod_init = digitv_mt352_demod_init, 114 .demod_init = digitv_mt352_demod_init,
115 .pll_set = dvb_usb_pll_set,
116}; 115};
117 116
118static int digitv_nxt6000_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep) 117static int digitv_nxt6000_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep)
119{ 118{
120 struct dvb_usb_device *d = fe->dvb->priv; 119 struct dvb_usb_device *d = fe->dvb->priv;
121 u8 b[5]; 120 u8 b[5];
122 dvb_usb_pll_set(fe,fep,b); 121 dvb_usb_tuner_calc_regs(fe,fep,b, 5);
123 return digitv_ctrl_msg(d,USB_WRITE_TUNER,0,&b[1],4,NULL,0); 122 return digitv_ctrl_msg(d,USB_WRITE_TUNER,0,&b[1],4,NULL,0);
124} 123}
125 124
126static struct nxt6000_config digitv_nxt6000_config = { 125static struct nxt6000_config digitv_nxt6000_config = {
127 .clock_inversion = 1, 126 .clock_inversion = 1,
128 .pll_set = digitv_nxt6000_pll_set,
129}; 127};
130 128
131static int digitv_frontend_attach(struct dvb_usb_device *d) 129static int digitv_frontend_attach(struct dvb_usb_device *d)
132{ 130{
133 if ((d->fe = mt352_attach(&digitv_mt352_config, &d->i2c_adap)) != NULL || 131 if ((d->fe = mt352_attach(&digitv_mt352_config, &d->i2c_adap)) != NULL) {
134 (d->fe = nxt6000_attach(&digitv_nxt6000_config, &d->i2c_adap)) != NULL) 132 d->fe->ops.tuner_ops.calc_regs = dvb_usb_tuner_calc_regs;
135 return 0; 133 return 0;
134 }
135 if ((d->fe = nxt6000_attach(&digitv_nxt6000_config, &d->i2c_adap)) != NULL) {
136 d->fe->ops.tuner_ops.set_params = digitv_nxt6000_tuner_set_params;
137 return 0;
138 }
136 return -EIO; 139 return -EIO;
137} 140}
138 141
diff --git a/drivers/media/dvb/dvb-usb/dtt200u-fe.c b/drivers/media/dvb/dvb-usb/dtt200u-fe.c
index cd21ddbfd054..17413adec7a1 100644
--- a/drivers/media/dvb/dvb-usb/dtt200u-fe.c
+++ b/drivers/media/dvb/dvb-usb/dtt200u-fe.c
@@ -18,7 +18,6 @@ struct dtt200u_fe_state {
18 18
19 struct dvb_frontend_parameters fep; 19 struct dvb_frontend_parameters fep;
20 struct dvb_frontend frontend; 20 struct dvb_frontend frontend;
21 struct dvb_frontend_ops ops;
22}; 21};
23 22
24static int dtt200u_fe_read_status(struct dvb_frontend* fe, fe_status_t *stat) 23static int dtt200u_fe_read_status(struct dvb_frontend* fe, fe_status_t *stat)
@@ -163,16 +162,13 @@ struct dvb_frontend* dtt200u_fe_attach(struct dvb_usb_device *d)
163 deb_info("attaching frontend dtt200u\n"); 162 deb_info("attaching frontend dtt200u\n");
164 163
165 state->d = d; 164 state->d = d;
166 memcpy(&state->ops,&dtt200u_fe_ops,sizeof(struct dvb_frontend_ops));
167 165
168 state->frontend.ops = &state->ops; 166 memcpy(&state->frontend.ops,&dtt200u_fe_ops,sizeof(struct dvb_frontend_ops));
169 state->frontend.demodulator_priv = state; 167 state->frontend.demodulator_priv = state;
170 168
171 goto success; 169 return &state->frontend;
172error: 170error:
173 return NULL; 171 return NULL;
174success:
175 return &state->frontend;
176} 172}
177 173
178static struct dvb_frontend_ops dtt200u_fe_ops = { 174static struct dvb_frontend_ops dtt200u_fe_ops = {
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c b/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c
index 6fa92100248b..ec631708c394 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c
@@ -82,7 +82,7 @@ int dvb_usb_dvb_init(struct dvb_usb_device *d)
82 int ret; 82 int ret;
83 83
84 if ((ret = dvb_register_adapter(&d->dvb_adap, d->desc->name, 84 if ((ret = dvb_register_adapter(&d->dvb_adap, d->desc->name,
85 d->owner)) < 0) { 85 d->owner, &d->udev->dev)) < 0) {
86 deb_info("dvb_register_adapter failed: error %d", ret); 86 deb_info("dvb_register_adapter failed: error %d", ret);
87 goto err; 87 goto err;
88 } 88 }
@@ -121,16 +121,15 @@ int dvb_usb_dvb_init(struct dvb_usb_device *d)
121 121
122 dvb_net_init(&d->dvb_adap, &d->dvb_net, &d->demux.dmx); 122 dvb_net_init(&d->dvb_adap, &d->dvb_net, &d->demux.dmx);
123 123
124 goto success; 124 d->state |= DVB_USB_STATE_DVB;
125 return 0;
126
125err_dmx_dev: 127err_dmx_dev:
126 dvb_dmx_release(&d->demux); 128 dvb_dmx_release(&d->demux);
127err_dmx: 129err_dmx:
128 dvb_unregister_adapter(&d->dvb_adap); 130 dvb_unregister_adapter(&d->dvb_adap);
129err: 131err:
130 return ret; 132 return ret;
131success:
132 d->state |= DVB_USB_STATE_DVB;
133 return 0;
134} 133}
135 134
136int dvb_usb_dvb_exit(struct dvb_usb_device *d) 135int dvb_usb_dvb_exit(struct dvb_usb_device *d)
@@ -184,13 +183,13 @@ int dvb_usb_fe_init(struct dvb_usb_device* d)
184 183
185 /* re-assign sleep and wakeup functions */ 184 /* re-assign sleep and wakeup functions */
186 if (d->fe != NULL) { 185 if (d->fe != NULL) {
187 d->fe_init = d->fe->ops->init; d->fe->ops->init = dvb_usb_fe_wakeup; 186 d->fe_init = d->fe->ops.init; d->fe->ops.init = dvb_usb_fe_wakeup;
188 d->fe_sleep = d->fe->ops->sleep; d->fe->ops->sleep = dvb_usb_fe_sleep; 187 d->fe_sleep = d->fe->ops.sleep; d->fe->ops.sleep = dvb_usb_fe_sleep;
189 188
190 if (dvb_register_frontend(&d->dvb_adap, d->fe)) { 189 if (dvb_register_frontend(&d->dvb_adap, d->fe)) {
191 err("Frontend registration failed."); 190 err("Frontend registration failed.");
192 if (d->fe->ops->release) 191 if (d->fe->ops.release)
193 d->fe->ops->release(d->fe); 192 d->fe->ops.release(d->fe);
194 d->fe = NULL; 193 d->fe = NULL;
195 return -ENODEV; 194 return -ENODEV;
196 } 195 }
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c b/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c
index 9b254532af4d..6b611a725093 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c
@@ -46,7 +46,7 @@ int dvb_usb_i2c_exit(struct dvb_usb_device *d)
46 return 0; 46 return 0;
47} 47}
48 48
49int dvb_usb_pll_init_i2c(struct dvb_frontend *fe) 49int dvb_usb_tuner_init_i2c(struct dvb_frontend *fe)
50{ 50{
51 struct dvb_usb_device *d = fe->dvb->priv; 51 struct dvb_usb_device *d = fe->dvb->priv;
52 struct i2c_msg msg = { .addr = d->pll_addr, .flags = 0, .buf = d->pll_init, .len = 4 }; 52 struct i2c_msg msg = { .addr = d->pll_addr, .flags = 0, .buf = d->pll_init, .len = 4 };
@@ -63,6 +63,8 @@ int dvb_usb_pll_init_i2c(struct dvb_frontend *fe)
63 deb_pll("pll-buf: %x %x %x %x\n",d->pll_init[0],d->pll_init[1], 63 deb_pll("pll-buf: %x %x %x %x\n",d->pll_init[0],d->pll_init[1],
64 d->pll_init[2],d->pll_init[3]); 64 d->pll_init[2],d->pll_init[3]);
65 65
66 if (fe->ops.i2c_gate_ctrl)
67 fe->ops.i2c_gate_ctrl(fe, 1);
66 if (i2c_transfer (&d->i2c_adap, &msg, 1) != 1) { 68 if (i2c_transfer (&d->i2c_adap, &msg, 1) != 1) {
67 err("tuner i2c write failed for pll_init."); 69 err("tuner i2c write failed for pll_init.");
68 ret = -EREMOTEIO; 70 ret = -EREMOTEIO;
@@ -73,38 +75,42 @@ int dvb_usb_pll_init_i2c(struct dvb_frontend *fe)
73 d->tuner_pass_ctrl(fe,0,d->pll_addr); 75 d->tuner_pass_ctrl(fe,0,d->pll_addr);
74 return ret; 76 return ret;
75} 77}
76EXPORT_SYMBOL(dvb_usb_pll_init_i2c); 78EXPORT_SYMBOL(dvb_usb_tuner_init_i2c);
77 79
78int dvb_usb_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep, u8 b[5]) 80int dvb_usb_tuner_calc_regs(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep, u8 *b, int buf_len)
79{ 81{
80 struct dvb_usb_device *d = fe->dvb->priv; 82 struct dvb_usb_device *d = fe->dvb->priv;
81 83
84 if (buf_len != 5)
85 return -EINVAL;
82 if (d->pll_desc == NULL) 86 if (d->pll_desc == NULL)
83 return 0; 87 return 0;
84 88
85 deb_pll("pll addr: %x, freq: %d %p\n",d->pll_addr,fep->frequency,d->pll_desc); 89 deb_pll("pll addr: %x, freq: %d %p\n",d->pll_addr,fep->frequency,d->pll_desc);
86 90
87 b[0] = d->pll_addr << 1; 91 b[0] = d->pll_addr;
88 dvb_pll_configure(d->pll_desc,&b[1],fep->frequency,fep->u.ofdm.bandwidth); 92 dvb_pll_configure(d->pll_desc,&b[1],fep->frequency,fep->u.ofdm.bandwidth);
89 93
90 deb_pll("pll-buf: %x %x %x %x %x\n",b[0],b[1],b[2],b[3],b[4]); 94 deb_pll("pll-buf: %x %x %x %x %x\n",b[0],b[1],b[2],b[3],b[4]);
91 95
92 return 0; 96 return 5;
93} 97}
94EXPORT_SYMBOL(dvb_usb_pll_set); 98EXPORT_SYMBOL(dvb_usb_tuner_calc_regs);
95 99
96int dvb_usb_pll_set_i2c(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep) 100int dvb_usb_tuner_set_params_i2c(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep)
97{ 101{
98 struct dvb_usb_device *d = fe->dvb->priv; 102 struct dvb_usb_device *d = fe->dvb->priv;
99 int ret = 0; 103 int ret = 0;
100 u8 b[5]; 104 u8 b[5];
101 struct i2c_msg msg = { .addr = d->pll_addr, .flags = 0, .buf = &b[1], .len = 4 }; 105 struct i2c_msg msg = { .addr = d->pll_addr, .flags = 0, .buf = &b[1], .len = 4 };
102 106
103 dvb_usb_pll_set(fe,fep,b); 107 dvb_usb_tuner_calc_regs(fe,fep,b,5);
104 108
105 if (d->tuner_pass_ctrl) 109 if (d->tuner_pass_ctrl)
106 d->tuner_pass_ctrl(fe,1,d->pll_addr); 110 d->tuner_pass_ctrl(fe,1,d->pll_addr);
107 111
112 if (fe->ops.i2c_gate_ctrl)
113 fe->ops.i2c_gate_ctrl(fe, 1);
108 if (i2c_transfer (&d->i2c_adap, &msg, 1) != 1) { 114 if (i2c_transfer (&d->i2c_adap, &msg, 1) != 1) {
109 err("tuner i2c write failed for pll_set."); 115 err("tuner i2c write failed for pll_set.");
110 ret = -EREMOTEIO; 116 ret = -EREMOTEIO;
@@ -116,4 +122,4 @@ int dvb_usb_pll_set_i2c(struct dvb_frontend *fe, struct dvb_frontend_parameters
116 122
117 return ret; 123 return ret;
118} 124}
119EXPORT_SYMBOL(dvb_usb_pll_set_i2c); 125EXPORT_SYMBOL(dvb_usb_tuner_set_params_i2c);
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
index cb239049b098..95698918bc11 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
@@ -31,6 +31,7 @@
31#define USB_VID_VISIONPLUS 0x13d3 31#define USB_VID_VISIONPLUS 0x13d3
32#define USB_VID_TWINHAN 0x1822 32#define USB_VID_TWINHAN 0x1822
33#define USB_VID_ULTIMA_ELECTRONIC 0x05d8 33#define USB_VID_ULTIMA_ELECTRONIC 0x05d8
34#define USB_VID_GENPIX 0x09c0
34 35
35/* Product IDs */ 36/* Product IDs */
36#define USB_PID_ADSTECH_USB2_COLD 0xa333 37#define USB_PID_ADSTECH_USB2_COLD 0xa333
@@ -104,5 +105,6 @@
104#define USB_PID_KYE_DVB_T_WARM 0x701f 105#define USB_PID_KYE_DVB_T_WARM 0x701f
105#define USB_PID_PCTV_200E 0x020e 106#define USB_PID_PCTV_200E 0x020e
106#define USB_PID_PCTV_400E 0x020f 107#define USB_PID_PCTV_400E 0x020f
107 108#define USB_PID_GENPIX_8PSK_COLD 0x0200
109#define USB_PID_GENPIX_8PSK_WARM 0x0201
108#endif 110#endif
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb.h b/drivers/media/dvb/dvb-usb/dvb-usb.h
index fead958a57e3..4cf9f89c51bf 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb.h
+++ b/drivers/media/dvb/dvb-usb/dvb-usb.h
@@ -330,9 +330,9 @@ extern int dvb_usb_generic_write(struct dvb_usb_device *, u8 *, u16);
330extern int dvb_usb_nec_rc_key_to_event(struct dvb_usb_device *, u8[], u32 *, int *); 330extern int dvb_usb_nec_rc_key_to_event(struct dvb_usb_device *, u8[], u32 *, int *);
331 331
332/* commonly used pll init and set functions */ 332/* commonly used pll init and set functions */
333extern int dvb_usb_pll_init_i2c(struct dvb_frontend *); 333extern int dvb_usb_tuner_init_i2c(struct dvb_frontend *);
334extern int dvb_usb_pll_set(struct dvb_frontend *, struct dvb_frontend_parameters *, u8[]); 334extern int dvb_usb_tuner_calc_regs(struct dvb_frontend *, struct dvb_frontend_parameters *, u8 *buf, int buf_len);
335extern int dvb_usb_pll_set_i2c(struct dvb_frontend *, struct dvb_frontend_parameters *); 335extern int dvb_usb_tuner_set_params_i2c(struct dvb_frontend *, struct dvb_frontend_parameters *);
336 336
337/* commonly used firmware download types and function */ 337/* commonly used firmware download types and function */
338struct hexline { 338struct hexline {
diff --git a/drivers/media/dvb/dvb-usb/gp8psk-fe.c b/drivers/media/dvb/dvb-usb/gp8psk-fe.c
new file mode 100644
index 000000000000..6ccbdc9cd772
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/gp8psk-fe.c
@@ -0,0 +1,272 @@
1/* DVB USB compliant Linux driver for the
2 * - GENPIX 8pks/qpsk USB2.0 DVB-S module
3 *
4 * Copyright (C) 2006 Alan Nisota (alannisota@gmail.com)
5 *
6 * Thanks to GENPIX for the sample code used to implement this module.
7 *
8 * This module is based off the vp7045 and vp702x modules
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the Free
12 * Software Foundation, version 2.
13 *
14 * see Documentation/dvb/README.dvb-usb for more information
15 */
16#include "gp8psk.h"
17
18struct gp8psk_fe_state {
19 struct dvb_frontend fe;
20
21 struct dvb_usb_device *d;
22
23 u16 snr;
24
25 unsigned long next_snr_check;
26};
27
28static int gp8psk_fe_read_status(struct dvb_frontend* fe, fe_status_t *status)
29{
30 struct gp8psk_fe_state *st = fe->demodulator_priv;
31 u8 lock;
32
33 if (gp8psk_usb_in_op(st->d, GET_SIGNAL_LOCK, 0, 0, &lock,1))
34 return -EINVAL;
35
36 if (lock)
37 *status = FE_HAS_LOCK | FE_HAS_SYNC | FE_HAS_VITERBI | FE_HAS_SIGNAL | FE_HAS_CARRIER;
38 else
39 *status = 0;
40
41 return 0;
42}
43
44/* not supported by this Frontend */
45static int gp8psk_fe_read_ber(struct dvb_frontend* fe, u32 *ber)
46{
47 (void) fe;
48 *ber = 0;
49 return 0;
50}
51
52/* not supported by this Frontend */
53static int gp8psk_fe_read_unc_blocks(struct dvb_frontend* fe, u32 *unc)
54{
55 (void) fe;
56 *unc = 0;
57 return 0;
58}
59
60static int gp8psk_fe_read_snr(struct dvb_frontend* fe, u16 *snr)
61{
62 struct gp8psk_fe_state *st = fe->demodulator_priv;
63 u8 buf[2];
64
65 if (time_after(jiffies,st->next_snr_check)) {
66 gp8psk_usb_in_op(st->d,GET_SIGNAL_STRENGTH,0,0,buf,2);
67 *snr = (int)(buf[1]) << 8 | buf[0];
68 /* snr is reported in dBu*256 */
69 /* snr / 38.4 ~= 100% strength */
70 /* snr * 17 returns 100% strength as 65535 */
71 if (*snr <= 3855)
72 *snr = (*snr<<4) + *snr; // snr * 17
73 else
74 *snr = 65535;
75 st->next_snr_check = jiffies + (10*HZ)/1000;
76 } else {
77 *snr = st->snr;
78 }
79 return 0;
80}
81
82static int gp8psk_fe_read_signal_strength(struct dvb_frontend* fe, u16 *strength)
83{
84 return gp8psk_fe_read_snr(fe, strength);
85}
86
87static int gp8psk_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune)
88{
89 tune->min_delay_ms = 800;
90 return 0;
91}
92
93static int gp8psk_fe_set_frontend(struct dvb_frontend* fe,
94 struct dvb_frontend_parameters *fep)
95{
96 struct gp8psk_fe_state *state = fe->demodulator_priv;
97 u8 cmd[10];
98 u32 freq = fep->frequency * 1000;
99
100 cmd[4] = freq & 0xff;
101 cmd[5] = (freq >> 8) & 0xff;
102 cmd[6] = (freq >> 16) & 0xff;
103 cmd[7] = (freq >> 24) & 0xff;
104
105 switch(fe->ops.info.type) {
106 case FE_QPSK:
107 cmd[0] = fep->u.qpsk.symbol_rate & 0xff;
108 cmd[1] = (fep->u.qpsk.symbol_rate >> 8) & 0xff;
109 cmd[2] = (fep->u.qpsk.symbol_rate >> 16) & 0xff;
110 cmd[3] = (fep->u.qpsk.symbol_rate >> 24) & 0xff;
111 cmd[8] = ADV_MOD_DVB_QPSK;
112 cmd[9] = 0x03; /*ADV_MOD_FEC_XXX*/
113 break;
114 default:
115 // other modes are unsuported right now
116 cmd[0] = 0;
117 cmd[1] = 0;
118 cmd[2] = 0;
119 cmd[3] = 0;
120 cmd[8] = 0;
121 cmd[9] = 0;
122 break;
123 }
124
125 gp8psk_usb_out_op(state->d,TUNE_8PSK,0,0,cmd,10);
126
127 state->next_snr_check = jiffies;
128
129 return 0;
130}
131
132static int gp8psk_fe_get_frontend(struct dvb_frontend* fe,
133 struct dvb_frontend_parameters *fep)
134{
135 return 0;
136}
137
138
139static int gp8psk_fe_send_diseqc_msg (struct dvb_frontend* fe,
140 struct dvb_diseqc_master_cmd *m)
141{
142 struct gp8psk_fe_state *st = fe->demodulator_priv;
143
144 deb_fe("%s\n",__FUNCTION__);
145
146 if (gp8psk_usb_out_op(st->d,SEND_DISEQC_COMMAND, m->msg[0], 0,
147 m->msg, m->msg_len)) {
148 return -EINVAL;
149 }
150 return 0;
151}
152
153static int gp8psk_fe_send_diseqc_burst (struct dvb_frontend* fe,
154 fe_sec_mini_cmd_t burst)
155{
156 struct gp8psk_fe_state *st = fe->demodulator_priv;
157 u8 cmd;
158
159 deb_fe("%s\n",__FUNCTION__);
160
161 /* These commands are certainly wrong */
162 cmd = (burst == SEC_MINI_A) ? 0x00 : 0x01;
163
164 if (gp8psk_usb_out_op(st->d,SEND_DISEQC_COMMAND, cmd, 0,
165 &cmd, 0)) {
166 return -EINVAL;
167 }
168 return 0;
169}
170
171static int gp8psk_fe_set_tone (struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
172{
173 struct gp8psk_fe_state* state = fe->demodulator_priv;
174
175 if (gp8psk_usb_out_op(state->d,SET_22KHZ_TONE,
176 (tone == SEC_TONE_ON), 0, NULL, 0)) {
177 return -EINVAL;
178 }
179 return 0;
180}
181
182static int gp8psk_fe_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltage)
183{
184 struct gp8psk_fe_state* state = fe->demodulator_priv;
185
186 if (gp8psk_usb_out_op(state->d,SET_LNB_VOLTAGE,
187 voltage == SEC_VOLTAGE_18, 0, NULL, 0)) {
188 return -EINVAL;
189 }
190 return 0;
191}
192
193static int gp8psk_fe_send_legacy_dish_cmd (struct dvb_frontend* fe, unsigned long sw_cmd)
194{
195 struct gp8psk_fe_state* state = fe->demodulator_priv;
196 u8 cmd = sw_cmd & 0x7f;
197
198 if (gp8psk_usb_out_op(state->d,SET_DN_SWITCH, cmd, 0,
199 NULL, 0)) {
200 return -EINVAL;
201 }
202 if (gp8psk_usb_out_op(state->d,SET_LNB_VOLTAGE, !!(sw_cmd & 0x80),
203 0, NULL, 0)) {
204 return -EINVAL;
205 }
206
207 return 0;
208}
209
210static void gp8psk_fe_release(struct dvb_frontend* fe)
211{
212 struct gp8psk_fe_state *state = fe->demodulator_priv;
213 kfree(state);
214}
215
216static struct dvb_frontend_ops gp8psk_fe_ops;
217
218struct dvb_frontend * gp8psk_fe_attach(struct dvb_usb_device *d)
219{
220 struct gp8psk_fe_state *s = kzalloc(sizeof(struct gp8psk_fe_state), GFP_KERNEL);
221 if (s == NULL)
222 goto error;
223
224 s->d = d;
225 memcpy(&s->fe.ops, &gp8psk_fe_ops, sizeof(struct dvb_frontend_ops));
226 s->fe.demodulator_priv = s;
227
228 goto success;
229error:
230 return NULL;
231success:
232 return &s->fe;
233}
234
235
236static struct dvb_frontend_ops gp8psk_fe_ops = {
237 .info = {
238 .name = "Genpix 8psk-USB DVB-S",
239 .type = FE_QPSK,
240 .frequency_min = 950000,
241 .frequency_max = 2150000,
242 .frequency_stepsize = 100,
243 .symbol_rate_min = 1000000,
244 .symbol_rate_max = 45000000,
245 .symbol_rate_tolerance = 500, /* ppm */
246 .caps = FE_CAN_INVERSION_AUTO |
247 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
248 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
249 FE_CAN_QPSK
250 },
251
252 .release = gp8psk_fe_release,
253
254 .init = NULL,
255 .sleep = NULL,
256
257 .set_frontend = gp8psk_fe_set_frontend,
258 .get_frontend = gp8psk_fe_get_frontend,
259 .get_tune_settings = gp8psk_fe_get_tune_settings,
260
261 .read_status = gp8psk_fe_read_status,
262 .read_ber = gp8psk_fe_read_ber,
263 .read_signal_strength = gp8psk_fe_read_signal_strength,
264 .read_snr = gp8psk_fe_read_snr,
265 .read_ucblocks = gp8psk_fe_read_unc_blocks,
266
267 .diseqc_send_master_cmd = gp8psk_fe_send_diseqc_msg,
268 .diseqc_send_burst = gp8psk_fe_send_diseqc_burst,
269 .set_tone = gp8psk_fe_set_tone,
270 .set_voltage = gp8psk_fe_set_voltage,
271 .dishnetwork_send_legacy_command = gp8psk_fe_send_legacy_dish_cmd,
272};
diff --git a/drivers/media/dvb/dvb-usb/gp8psk.c b/drivers/media/dvb/dvb-usb/gp8psk.c
new file mode 100644
index 000000000000..9a98f3fdae31
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/gp8psk.c
@@ -0,0 +1,256 @@
1/* DVB USB compliant Linux driver for the
2 * - GENPIX 8pks/qpsk USB2.0 DVB-S module
3 *
4 * Copyright (C) 2006 Alan Nisota (alannisota@gmail.com)
5 *
6 * Thanks to GENPIX for the sample code used to implement this module.
7 *
8 * This module is based off the vp7045 and vp702x modules
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the Free
12 * Software Foundation, version 2.
13 *
14 * see Documentation/dvb/README.dvb-usb for more information
15 */
16#include "gp8psk.h"
17
18/* debug */
19static char bcm4500_firmware[] = "dvb-usb-gp8psk-02.fw";
20int dvb_usb_gp8psk_debug;
21module_param_named(debug,dvb_usb_gp8psk_debug, int, 0644);
22MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2,rc=4 (or-able))." DVB_USB_DEBUG_STATUS);
23
24int gp8psk_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen)
25{
26 int ret = 0,try = 0;
27
28 if ((ret = mutex_lock_interruptible(&d->usb_mutex)))
29 return ret;
30
31 while (ret >= 0 && ret != blen && try < 3) {
32 ret = usb_control_msg(d->udev,
33 usb_rcvctrlpipe(d->udev,0),
34 req,
35 USB_TYPE_VENDOR | USB_DIR_IN,
36 value,index,b,blen,
37 2000);
38 deb_info("reading number %d (ret: %d)\n",try,ret);
39 try++;
40 }
41
42 if (ret < 0 || ret != blen) {
43 warn("usb in operation failed.");
44 ret = -EIO;
45 } else
46 ret = 0;
47
48 deb_xfer("in: req. %x, val: %x, ind: %x, buffer: ",req,value,index);
49 debug_dump(b,blen,deb_xfer);
50
51 mutex_unlock(&d->usb_mutex);
52
53 return ret;
54}
55
56int gp8psk_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value,
57 u16 index, u8 *b, int blen)
58{
59 int ret;
60
61 deb_xfer("out: req. %x, val: %x, ind: %x, buffer: ",req,value,index);
62 debug_dump(b,blen,deb_xfer);
63
64 if ((ret = mutex_lock_interruptible(&d->usb_mutex)))
65 return ret;
66
67 if (usb_control_msg(d->udev,
68 usb_sndctrlpipe(d->udev,0),
69 req,
70 USB_TYPE_VENDOR | USB_DIR_OUT,
71 value,index,b,blen,
72 2000) != blen) {
73 warn("usb out operation failed.");
74 ret = -EIO;
75 } else
76 ret = 0;
77 mutex_unlock(&d->usb_mutex);
78
79 return ret;
80}
81
82static int gp8psk_load_bcm4500fw(struct dvb_usb_device *d)
83{
84 int ret;
85 const struct firmware *fw = NULL;
86 u8 *ptr, *buf;
87 if ((ret = request_firmware(&fw, bcm4500_firmware,
88 &d->udev->dev)) != 0) {
89 err("did not find the bcm4500 firmware file. (%s) "
90 "Please see linux/Documentation/dvb/ for more details on firmware-problems. (%d)",
91 bcm4500_firmware,ret);
92 return ret;
93 }
94
95 ret = -EINVAL;
96
97 if (gp8psk_usb_out_op(d, LOAD_BCM4500,1,0,NULL, 0))
98 goto out_rel_fw;
99
100 info("downloaidng bcm4500 firmware from file '%s'",bcm4500_firmware);
101
102 ptr = fw->data;
103 buf = kmalloc(512, GFP_KERNEL | GFP_DMA);
104
105 while (ptr[0] != 0xff) {
106 u16 buflen = ptr[0] + 4;
107 if (ptr + buflen >= fw->data + fw->size) {
108 err("failed to load bcm4500 firmware.");
109 goto out_free;
110 }
111 memcpy(buf, ptr, buflen);
112 if (dvb_usb_generic_write(d, buf, buflen)) {
113 err("failed to load bcm4500 firmware.");
114 goto out_free;
115 }
116 ptr += buflen;
117 }
118
119 ret = 0;
120
121out_free:
122 kfree(buf);
123out_rel_fw:
124 release_firmware(fw);
125
126 return ret;
127}
128
129static int gp8psk_power_ctrl(struct dvb_usb_device *d, int onoff)
130{
131 u8 status, buf;
132 if (onoff) {
133 gp8psk_usb_in_op(d, GET_8PSK_CONFIG,0,0,&status,1);
134 if (! (status & 0x01)) /* started */
135 if (gp8psk_usb_in_op(d, BOOT_8PSK, 1, 0, &buf, 1))
136 return -EINVAL;
137
138 if (! (status & 0x02)) /* BCM4500 firmware loaded */
139 if(gp8psk_load_bcm4500fw(d))
140 return EINVAL;
141
142 if (! (status & 0x04)) /* LNB Power */
143 if (gp8psk_usb_in_op(d, START_INTERSIL, 1, 0,
144 &buf, 1))
145 return EINVAL;
146
147 /* Set DVB mode */
148 if(gp8psk_usb_out_op(d, SET_DVB_MODE, 1, 0, NULL, 0))
149 return -EINVAL;
150 gp8psk_usb_in_op(d, GET_8PSK_CONFIG,0,0,&status,1);
151 } else {
152 /* Turn off LNB power */
153 if (gp8psk_usb_in_op(d, START_INTERSIL, 0, 0, &buf, 1))
154 return EINVAL;
155 /* Turn off 8psk power */
156 if (gp8psk_usb_in_op(d, BOOT_8PSK, 0, 0, &buf, 1))
157 return -EINVAL;
158
159 }
160 return 0;
161}
162
163
164static int gp8psk_streaming_ctrl(struct dvb_usb_device *d, int onoff)
165{
166 return gp8psk_usb_out_op(d, ARM_TRANSFER, onoff, 0 , NULL, 0);
167}
168
169static int gp8psk_frontend_attach(struct dvb_usb_device *d)
170{
171 d->fe = gp8psk_fe_attach(d);
172
173 return 0;
174}
175
176static struct dvb_usb_properties gp8psk_properties;
177
178static int gp8psk_usb_probe(struct usb_interface *intf,
179 const struct usb_device_id *id)
180{
181 return dvb_usb_device_init(intf,&gp8psk_properties,THIS_MODULE,NULL);
182}
183
184static struct usb_device_id gp8psk_usb_table [] = {
185 { USB_DEVICE(USB_VID_GENPIX, USB_PID_GENPIX_8PSK_COLD) },
186 { USB_DEVICE(USB_VID_GENPIX, USB_PID_GENPIX_8PSK_WARM) },
187 { 0 },
188};
189MODULE_DEVICE_TABLE(usb, gp8psk_usb_table);
190
191static struct dvb_usb_properties gp8psk_properties = {
192 .caps = 0,
193
194 .usb_ctrl = CYPRESS_FX2,
195 .firmware = "dvb-usb-gp8psk-01.fw",
196
197 .streaming_ctrl = gp8psk_streaming_ctrl,
198 .power_ctrl = gp8psk_power_ctrl,
199 .frontend_attach = gp8psk_frontend_attach,
200
201 .generic_bulk_ctrl_endpoint = 0x01,
202 /* parameter for the MPEG2-data transfer */
203 .urb = {
204 .type = DVB_USB_BULK,
205 .count = 7,
206 .endpoint = 0x82,
207 .u = {
208 .bulk = {
209 .buffersize = 8192,
210 }
211 }
212 },
213
214 .num_device_descs = 1,
215 .devices = {
216 { .name = "Genpix 8PSK-USB DVB-S USB2.0 receiver",
217 .cold_ids = { &gp8psk_usb_table[0], NULL },
218 .warm_ids = { &gp8psk_usb_table[1], NULL },
219 },
220 { 0 },
221 }
222};
223
224/* usb specific object needed to register this driver with the usb subsystem */
225static struct usb_driver gp8psk_usb_driver = {
226 .name = "dvb_usb_gp8psk",
227 .probe = gp8psk_usb_probe,
228 .disconnect = dvb_usb_device_exit,
229 .id_table = gp8psk_usb_table,
230};
231
232/* module stuff */
233static int __init gp8psk_usb_module_init(void)
234{
235 int result;
236 if ((result = usb_register(&gp8psk_usb_driver))) {
237 err("usb_register failed. (%d)",result);
238 return result;
239 }
240
241 return 0;
242}
243
244static void __exit gp8psk_usb_module_exit(void)
245{
246 /* deregister this driver from the USB subsystem */
247 usb_deregister(&gp8psk_usb_driver);
248}
249
250module_init(gp8psk_usb_module_init);
251module_exit(gp8psk_usb_module_exit);
252
253MODULE_AUTHOR("Alan Nisota <alannisota@gamil.com>");
254MODULE_DESCRIPTION("Driver for Genpix 8psk-USB DVB-S USB2.0");
255MODULE_VERSION("1.0");
256MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/gp8psk.h b/drivers/media/dvb/dvb-usb/gp8psk.h
new file mode 100644
index 000000000000..3eba7061011c
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/gp8psk.h
@@ -0,0 +1,79 @@
1/* DVB USB compliant Linux driver for the
2 * - GENPIX 8pks/qpsk USB2.0 DVB-S module
3 *
4 * Copyright (C) 2006 Alan Nisota (alannisota@gmail.com)
5 *
6 * Thanks to GENPIX for the sample code used to implement this module.
7 *
8 * This module is based off the vp7045 and vp702x modules
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the Free
12 * Software Foundation, version 2.
13 *
14 * see Documentation/dvb/README.dvb-usb for more information
15 */
16#ifndef _DVB_USB_GP8PSK_H_
17#define _DVB_USB_GP8PSK_H_
18
19#define DVB_USB_LOG_PREFIX "gp8psk"
20#include "dvb-usb.h"
21
22extern int dvb_usb_gp8psk_debug;
23#define deb_info(args...) dprintk(dvb_usb_gp8psk_debug,0x01,args)
24#define deb_xfer(args...) dprintk(dvb_usb_gp8psk_debug,0x02,args)
25#define deb_rc(args...) dprintk(dvb_usb_gp8psk_debug,0x04,args)
26#define deb_fe(args...) dprintk(dvb_usb_gp8psk_debug,0x08,args)
27/* gp8psk commands */
28
29/* Twinhan Vendor requests */
30#define TH_COMMAND_IN 0xC0
31#define TH_COMMAND_OUT 0xC1
32
33/* command bytes */
34#define GET_8PSK_CONFIG 0x80
35#define SET_8PSK_CONFIG 0x81
36#define ARM_TRANSFER 0x85
37#define TUNE_8PSK 0x86
38#define GET_SIGNAL_STRENGTH 0x87
39#define LOAD_BCM4500 0x88
40#define BOOT_8PSK 0x89
41#define START_INTERSIL 0x8A
42#define SET_LNB_VOLTAGE 0x8B
43#define SET_22KHZ_TONE 0x8C
44#define SEND_DISEQC_COMMAND 0x8D
45#define SET_DVB_MODE 0x8E
46#define SET_DN_SWITCH 0x8F
47#define GET_SIGNAL_LOCK 0x90
48
49/* Satellite modulation modes */
50#define ADV_MOD_DVB_QPSK 0 /* DVB-S QPSK */
51#define ADV_MOD_TURBO_QPSK 1 /* Turbo QPSK */
52#define ADV_MOD_TURBO_8PSK 2 /* Turbo 8PSK (also used for Trellis 8PSK) */
53#define ADV_MOD_TURBO_16QAM 3 /* Turbo 16QAM (also used for Trellis 8PSK) */
54
55#define ADV_MOD_DCII_C_QPSK 4 /* Digicipher II Combo */
56#define ADV_MOD_DCII_I_QPSK 5 /* Digicipher II I-stream */
57#define ADV_MOD_DCII_Q_QPSK 6 /* Digicipher II Q-stream */
58#define ADV_MOD_DCII_C_OQPSK 7 /* Digicipher II offset QPSK */
59#define ADV_MOD_DSS_QPSK 8 /* DSS (DIRECTV) QPSK */
60#define ADV_MOD_DVB_BPSK 9 /* DVB-S BPSK */
61
62#define GET_USB_SPEED 0x07
63 #define USB_SPEED_LOW 0
64 #define USB_SPEED_FULL 1
65 #define USB_SPEED_HIGH 2
66
67#define RESET_FX2 0x13
68
69#define FW_VERSION_READ 0x0B
70#define VENDOR_STRING_READ 0x0C
71#define PRODUCT_STRING_READ 0x0D
72#define FW_BCD_VERSION_READ 0x14
73
74extern struct dvb_frontend * gp8psk_fe_attach(struct dvb_usb_device *d);
75extern int gp8psk_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen);
76extern int gp8psk_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value,
77 u16 index, u8 *b, int blen);
78
79#endif
diff --git a/drivers/media/dvb/dvb-usb/umt-010.c b/drivers/media/dvb/dvb-usb/umt-010.c
index 14f1911c79bb..97d74da0dad8 100644
--- a/drivers/media/dvb/dvb-usb/umt-010.c
+++ b/drivers/media/dvb/dvb-usb/umt-010.c
@@ -57,7 +57,6 @@ static int umt_mt352_frontend_attach(struct dvb_usb_device *d)
57 memset(&umt_config,0,sizeof(struct mt352_config)); 57 memset(&umt_config,0,sizeof(struct mt352_config));
58 umt_config.demod_init = umt_mt352_demod_init; 58 umt_config.demod_init = umt_mt352_demod_init;
59 umt_config.demod_address = 0xf; 59 umt_config.demod_address = 0xf;
60 umt_config.pll_set = dvb_usb_pll_set;
61 60
62 d->fe = mt352_attach(&umt_config, &d->i2c_adap); 61 d->fe = mt352_attach(&umt_config, &d->i2c_adap);
63 62
@@ -68,6 +67,7 @@ static int umt_tuner_attach (struct dvb_usb_device *d)
68{ 67{
69 d->pll_addr = 0x61; 68 d->pll_addr = 0x61;
70 d->pll_desc = &dvb_pll_tua6034; 69 d->pll_desc = &dvb_pll_tua6034;
70 d->fe->ops.tuner_ops.calc_regs = dvb_usb_tuner_calc_regs;
71 return 0; 71 return 0;
72} 72}
73 73
diff --git a/drivers/media/dvb/dvb-usb/vp702x-fe.c b/drivers/media/dvb/dvb-usb/vp702x-fe.c
index 2a89f8c5da99..d4da494132ec 100644
--- a/drivers/media/dvb/dvb-usb/vp702x-fe.c
+++ b/drivers/media/dvb/dvb-usb/vp702x-fe.c
@@ -287,17 +287,16 @@ struct dvb_frontend * vp702x_fe_attach(struct dvb_usb_device *d)
287 goto error; 287 goto error;
288 288
289 s->d = d; 289 s->d = d;
290 s->fe.ops = &vp702x_fe_ops; 290
291 memcpy(&s->fe.ops,&vp702x_fe_ops,sizeof(struct dvb_frontend_ops));
291 s->fe.demodulator_priv = s; 292 s->fe.demodulator_priv = s;
292 293
293 s->lnb_buf[1] = SET_LNB_POWER; 294 s->lnb_buf[1] = SET_LNB_POWER;
294 s->lnb_buf[3] = 0xff; /* 0=tone burst, 2=data burst, ff=off */ 295 s->lnb_buf[3] = 0xff; /* 0=tone burst, 2=data burst, ff=off */
295 296
296 goto success; 297 return &s->fe;
297error: 298error:
298 return NULL; 299 return NULL;
299success:
300 return &s->fe;
301} 300}
302 301
303 302
diff --git a/drivers/media/dvb/dvb-usb/vp7045-fe.c b/drivers/media/dvb/dvb-usb/vp7045-fe.c
index 9999336aeeb6..8452eef90322 100644
--- a/drivers/media/dvb/dvb-usb/vp7045-fe.c
+++ b/drivers/media/dvb/dvb-usb/vp7045-fe.c
@@ -23,8 +23,6 @@
23 23
24struct vp7045_fe_state { 24struct vp7045_fe_state {
25 struct dvb_frontend fe; 25 struct dvb_frontend fe;
26 struct dvb_frontend_ops ops;
27
28 struct dvb_usb_device *d; 26 struct dvb_usb_device *d;
29}; 27};
30 28
@@ -151,15 +149,12 @@ struct dvb_frontend * vp7045_fe_attach(struct dvb_usb_device *d)
151 goto error; 149 goto error;
152 150
153 s->d = d; 151 s->d = d;
154 memcpy(&s->ops, &vp7045_fe_ops, sizeof(struct dvb_frontend_ops)); 152 memcpy(&s->fe.ops, &vp7045_fe_ops, sizeof(struct dvb_frontend_ops));
155 s->fe.ops = &s->ops;
156 s->fe.demodulator_priv = s; 153 s->fe.demodulator_priv = s;
157 154
158 goto success; 155 return &s->fe;
159error: 156error:
160 return NULL; 157 return NULL;
161success:
162 return &s->fe;
163} 158}
164 159
165 160
diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig
index 37d5e0af1683..0ef361f0309b 100644
--- a/drivers/media/dvb/frontends/Kconfig
+++ b/drivers/media/dvb/frontends/Kconfig
@@ -157,7 +157,7 @@ config DVB_STV0297
157 help 157 help
158 A DVB-C tuner module. Say Y when you want to support this frontend. 158 A DVB-C tuner module. Say Y when you want to support this frontend.
159 159
160comment "ATSC (North American/Korean Terresterial DTV) frontends" 160comment "ATSC (North American/Korean Terrestrial/Cable DTV) frontends"
161 depends on DVB_CORE 161 depends on DVB_CORE
162 162
163config DVB_NXT200X 163config DVB_NXT200X
@@ -216,4 +216,20 @@ config DVB_LGDT330X
216 An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want 216 An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
217 to support this frontend. 217 to support this frontend.
218 218
219
220comment "Miscellaneous devices"
221 depends on DVB_CORE
222
223config DVB_LNBP21
224 tristate "LNBP21 SEC controller"
225 depends on DVB_CORE
226 help
227 An SEC control chip.
228
229config DVB_ISL6421
230 tristate "ISL6421 SEC controller"
231 depends on DVB_CORE
232 help
233 An SEC control chip.
234
219endmenu 235endmenu
diff --git a/drivers/media/dvb/frontends/Makefile b/drivers/media/dvb/frontends/Makefile
index d09b6071fbaf..5222245c7f59 100644
--- a/drivers/media/dvb/frontends/Makefile
+++ b/drivers/media/dvb/frontends/Makefile
@@ -31,3 +31,5 @@ obj-$(CONFIG_DVB_BCM3510) += bcm3510.o
31obj-$(CONFIG_DVB_S5H1420) += s5h1420.o 31obj-$(CONFIG_DVB_S5H1420) += s5h1420.o
32obj-$(CONFIG_DVB_LGDT330X) += lgdt330x.o 32obj-$(CONFIG_DVB_LGDT330X) += lgdt330x.o
33obj-$(CONFIG_DVB_CX24123) += cx24123.o 33obj-$(CONFIG_DVB_CX24123) += cx24123.o
34obj-$(CONFIG_DVB_LNBP21) += lnbp21.o
35obj-$(CONFIG_DVB_ISL6421) += isl6421.o
diff --git a/drivers/media/dvb/frontends/bcm3510.c b/drivers/media/dvb/frontends/bcm3510.c
index 1708a1d4893e..baeb311de893 100644
--- a/drivers/media/dvb/frontends/bcm3510.c
+++ b/drivers/media/dvb/frontends/bcm3510.c
@@ -48,7 +48,6 @@
48struct bcm3510_state { 48struct bcm3510_state {
49 49
50 struct i2c_adapter* i2c; 50 struct i2c_adapter* i2c;
51 struct dvb_frontend_ops ops;
52 const struct bcm3510_config* config; 51 const struct bcm3510_config* config;
53 struct dvb_frontend frontend; 52 struct dvb_frontend frontend;
54 53
@@ -791,10 +790,9 @@ struct dvb_frontend* bcm3510_attach(const struct bcm3510_config *config,
791 790
792 state->config = config; 791 state->config = config;
793 state->i2c = i2c; 792 state->i2c = i2c;
794 memcpy(&state->ops, &bcm3510_ops, sizeof(struct dvb_frontend_ops));
795 793
796 /* create dvb_frontend */ 794 /* create dvb_frontend */
797 state->frontend.ops = &state->ops; 795 memcpy(&state->frontend.ops, &bcm3510_ops, sizeof(struct dvb_frontend_ops));
798 state->frontend.demodulator_priv = state; 796 state->frontend.demodulator_priv = state;
799 797
800 mutex_init(&state->hab_mutex); 798 mutex_init(&state->hab_mutex);
diff --git a/drivers/media/dvb/frontends/bsbe1.h b/drivers/media/dvb/frontends/bsbe1.h
index 78573b22ada9..d8f65738e5d2 100644
--- a/drivers/media/dvb/frontends/bsbe1.h
+++ b/drivers/media/dvb/frontends/bsbe1.h
@@ -89,12 +89,13 @@ static int alps_bsbe1_set_symbol_rate(struct dvb_frontend* fe, u32 srate, u32 ra
89 return 0; 89 return 0;
90} 90}
91 91
92static int alps_bsbe1_pll_set(struct dvb_frontend* fe, struct i2c_adapter *i2c, struct dvb_frontend_parameters* params) 92static int alps_bsbe1_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters *params)
93{ 93{
94 int ret; 94 int ret;
95 u8 data[4]; 95 u8 data[4];
96 u32 div; 96 u32 div;
97 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) }; 97 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) };
98 struct i2c_adapter *i2c = fe->tuner_priv;
98 99
99 if ((params->frequency < 950000) || (params->frequency > 2150000)) 100 if ((params->frequency < 950000) || (params->frequency > 2150000))
100 return -EINVAL; 101 return -EINVAL;
@@ -105,6 +106,8 @@ static int alps_bsbe1_pll_set(struct dvb_frontend* fe, struct i2c_adapter *i2c,
105 data[2] = 0x80 | ((div & 0x18000) >> 10) | 4; 106 data[2] = 0x80 | ((div & 0x18000) >> 10) | 4;
106 data[3] = (params->frequency > 1530000) ? 0xE0 : 0xE4; 107 data[3] = (params->frequency > 1530000) ? 0xE0 : 0xE4;
107 108
109 if (fe->ops.i2c_gate_ctrl)
110 fe->ops.i2c_gate_ctrl(fe, 1);
108 ret = i2c_transfer(i2c, &msg, 1); 111 ret = i2c_transfer(i2c, &msg, 1);
109 return (ret != 1) ? -EIO : 0; 112 return (ret != 1) ? -EIO : 0;
110} 113}
@@ -117,7 +120,6 @@ static struct stv0299_config alps_bsbe1_config = {
117 .skip_reinit = 0, 120 .skip_reinit = 0,
118 .min_delay_ms = 100, 121 .min_delay_ms = 100,
119 .set_symbol_rate = alps_bsbe1_set_symbol_rate, 122 .set_symbol_rate = alps_bsbe1_set_symbol_rate,
120 .pll_set = alps_bsbe1_pll_set,
121}; 123};
122 124
123#endif 125#endif
diff --git a/drivers/media/dvb/frontends/bsru6.h b/drivers/media/dvb/frontends/bsru6.h
index 2a5366ce79cc..e231cd84b3a1 100644
--- a/drivers/media/dvb/frontends/bsru6.h
+++ b/drivers/media/dvb/frontends/bsru6.h
@@ -101,11 +101,12 @@ static int alps_bsru6_set_symbol_rate(struct dvb_frontend *fe, u32 srate, u32 ra
101 return 0; 101 return 0;
102} 102}
103 103
104static int alps_bsru6_pll_set(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct dvb_frontend_parameters *params) 104static int alps_bsru6_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
105{ 105{
106 u8 buf[4]; 106 u8 buf[4];
107 u32 div; 107 u32 div;
108 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) }; 108 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) };
109 struct i2c_adapter *i2c = fe->tuner_priv;
109 110
110 if ((params->frequency < 950000) || (params->frequency > 2150000)) 111 if ((params->frequency < 950000) || (params->frequency > 2150000))
111 return -EINVAL; 112 return -EINVAL;
@@ -119,6 +120,8 @@ static int alps_bsru6_pll_set(struct dvb_frontend *fe, struct i2c_adapter *i2c,
119 if (params->frequency > 1530000) 120 if (params->frequency > 1530000)
120 buf[3] = 0xc0; 121 buf[3] = 0xc0;
121 122
123 if (fe->ops.i2c_gate_ctrl)
124 fe->ops.i2c_gate_ctrl(fe, 1);
122 if (i2c_transfer(i2c, &msg, 1) != 1) 125 if (i2c_transfer(i2c, &msg, 1) != 1)
123 return -EIO; 126 return -EIO;
124 return 0; 127 return 0;
@@ -134,7 +137,6 @@ static struct stv0299_config alps_bsru6_config = {
134 .volt13_op0_op1 = STV0299_VOLT13_OP1, 137 .volt13_op0_op1 = STV0299_VOLT13_OP1,
135 .min_delay_ms = 100, 138 .min_delay_ms = 100,
136 .set_symbol_rate = alps_bsru6_set_symbol_rate, 139 .set_symbol_rate = alps_bsru6_set_symbol_rate,
137 .pll_set = alps_bsru6_pll_set,
138}; 140};
139 141
140#endif 142#endif
diff --git a/drivers/media/dvb/frontends/cx22700.c b/drivers/media/dvb/frontends/cx22700.c
index 755f774f6b7d..3c7c09a362b2 100644
--- a/drivers/media/dvb/frontends/cx22700.c
+++ b/drivers/media/dvb/frontends/cx22700.c
@@ -34,8 +34,6 @@ struct cx22700_state {
34 34
35 struct i2c_adapter* i2c; 35 struct i2c_adapter* i2c;
36 36
37 struct dvb_frontend_ops ops;
38
39 const struct cx22700_config* config; 37 const struct cx22700_config* config;
40 38
41 struct dvb_frontend frontend; 39 struct dvb_frontend frontend;
@@ -247,12 +245,6 @@ static int cx22700_init (struct dvb_frontend* fe)
247 245
248 cx22700_writereg (state, 0x00, 0x01); 246 cx22700_writereg (state, 0x00, 0x01);
249 247
250 if (state->config->pll_init) {
251 cx22700_writereg (state, 0x0a, 0x00); /* open i2c bus switch */
252 state->config->pll_init(fe);
253 cx22700_writereg (state, 0x0a, 0x01); /* close i2c bus switch */
254 }
255
256 return 0; 248 return 0;
257} 249}
258 250
@@ -333,9 +325,11 @@ static int cx22700_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_par
333 cx22700_writereg (state, 0x00, 0x02); /* XXX CHECKME: soft reset*/ 325 cx22700_writereg (state, 0x00, 0x02); /* XXX CHECKME: soft reset*/
334 cx22700_writereg (state, 0x00, 0x00); 326 cx22700_writereg (state, 0x00, 0x00);
335 327
336 cx22700_writereg (state, 0x0a, 0x00); /* open i2c bus switch */ 328 if (fe->ops.tuner_ops.set_params) {
337 state->config->pll_set(fe, p); 329 fe->ops.tuner_ops.set_params(fe, p);
338 cx22700_writereg (state, 0x0a, 0x01); /* close i2c bus switch */ 330 if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
331 }
332
339 cx22700_set_inversion (state, p->inversion); 333 cx22700_set_inversion (state, p->inversion);
340 cx22700_set_tps (state, &p->u.ofdm); 334 cx22700_set_tps (state, &p->u.ofdm);
341 cx22700_writereg (state, 0x37, 0x01); /* PAL loop filter off */ 335 cx22700_writereg (state, 0x37, 0x01); /* PAL loop filter off */
@@ -353,6 +347,17 @@ static int cx22700_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_par
353 return cx22700_get_tps (state, &p->u.ofdm); 347 return cx22700_get_tps (state, &p->u.ofdm);
354} 348}
355 349
350static int cx22700_i2c_gate_ctrl(struct dvb_frontend* fe, int enable)
351{
352 struct cx22700_state* state = fe->demodulator_priv;
353
354 if (enable) {
355 return cx22700_writereg(state, 0x0a, 0x00);
356 } else {
357 return cx22700_writereg(state, 0x0a, 0x01);
358 }
359}
360
356static int cx22700_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings) 361static int cx22700_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings)
357{ 362{
358 fesettings->min_delay_ms = 150; 363 fesettings->min_delay_ms = 150;
@@ -381,13 +386,12 @@ struct dvb_frontend* cx22700_attach(const struct cx22700_config* config,
381 /* setup the state */ 386 /* setup the state */
382 state->config = config; 387 state->config = config;
383 state->i2c = i2c; 388 state->i2c = i2c;
384 memcpy(&state->ops, &cx22700_ops, sizeof(struct dvb_frontend_ops));
385 389
386 /* check if the demod is there */ 390 /* check if the demod is there */
387 if (cx22700_readreg(state, 0x07) < 0) goto error; 391 if (cx22700_readreg(state, 0x07) < 0) goto error;
388 392
389 /* create dvb_frontend */ 393 /* create dvb_frontend */
390 state->frontend.ops = &state->ops; 394 memcpy(&state->frontend.ops, &cx22700_ops, sizeof(struct dvb_frontend_ops));
391 state->frontend.demodulator_priv = state; 395 state->frontend.demodulator_priv = state;
392 return &state->frontend; 396 return &state->frontend;
393 397
@@ -413,6 +417,7 @@ static struct dvb_frontend_ops cx22700_ops = {
413 .release = cx22700_release, 417 .release = cx22700_release,
414 418
415 .init = cx22700_init, 419 .init = cx22700_init,
420 .i2c_gate_ctrl = cx22700_i2c_gate_ctrl,
416 421
417 .set_frontend = cx22700_set_frontend, 422 .set_frontend = cx22700_set_frontend,
418 .get_frontend = cx22700_get_frontend, 423 .get_frontend = cx22700_get_frontend,
diff --git a/drivers/media/dvb/frontends/cx22700.h b/drivers/media/dvb/frontends/cx22700.h
index c9145b45874b..dcd8979c1a15 100644
--- a/drivers/media/dvb/frontends/cx22700.h
+++ b/drivers/media/dvb/frontends/cx22700.h
@@ -29,10 +29,6 @@ struct cx22700_config
29{ 29{
30 /* the demodulator's i2c address */ 30 /* the demodulator's i2c address */
31 u8 demod_address; 31 u8 demod_address;
32
33 /* PLL maintenance */
34 int (*pll_init)(struct dvb_frontend* fe);
35 int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
36}; 32};
37 33
38extern struct dvb_frontend* cx22700_attach(const struct cx22700_config* config, 34extern struct dvb_frontend* cx22700_attach(const struct cx22700_config* config,
diff --git a/drivers/media/dvb/frontends/cx22702.c b/drivers/media/dvb/frontends/cx22702.c
index 0fc899f81c5e..4106d46c957f 100644
--- a/drivers/media/dvb/frontends/cx22702.c
+++ b/drivers/media/dvb/frontends/cx22702.c
@@ -40,8 +40,6 @@ struct cx22702_state {
40 40
41 struct i2c_adapter* i2c; 41 struct i2c_adapter* i2c;
42 42
43 struct dvb_frontend_ops ops;
44
45 /* configuration settings */ 43 /* configuration settings */
46 const struct cx22702_config* config; 44 const struct cx22702_config* config;
47 45
@@ -211,22 +209,10 @@ static int cx22702_set_tps (struct dvb_frontend* fe, struct dvb_frontend_paramet
211 u8 val; 209 u8 val;
212 struct cx22702_state* state = fe->demodulator_priv; 210 struct cx22702_state* state = fe->demodulator_priv;
213 211
214 /* set PLL */ 212 if (fe->ops.tuner_ops.set_params) {
215 cx22702_i2c_gate_ctrl(fe, 1); 213 fe->ops.tuner_ops.set_params(fe, p);
216 if (state->config->pll_set) { 214 if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
217 state->config->pll_set(fe, p);
218 } else if (state->config->pll_desc) {
219 u8 pllbuf[4];
220 struct i2c_msg msg = { .addr = state->config->pll_address,
221 .buf = pllbuf, .len = 4 };
222 dvb_pll_configure(state->config->pll_desc, pllbuf,
223 p->frequency,
224 p->u.ofdm.bandwidth);
225 i2c_transfer(state->i2c, &msg, 1);
226 } else {
227 BUG();
228 } 215 }
229 cx22702_i2c_gate_ctrl(fe, 0);
230 216
231 /* set inversion */ 217 /* set inversion */
232 cx22702_set_inversion (state, p->inversion); 218 cx22702_set_inversion (state, p->inversion);
@@ -358,10 +344,6 @@ static int cx22702_init (struct dvb_frontend* fe)
358 344
359 cx22702_writereg (state, 0xf8, (state->config->output_mode << 1) & 0x02); 345 cx22702_writereg (state, 0xf8, (state->config->output_mode << 1) & 0x02);
360 346
361 /* init PLL */
362 if (state->config->pll_init)
363 state->config->pll_init(fe);
364
365 cx22702_i2c_gate_ctrl(fe, 0); 347 cx22702_i2c_gate_ctrl(fe, 0);
366 348
367 return 0; 349 return 0;
@@ -495,7 +477,6 @@ struct dvb_frontend* cx22702_attach(const struct cx22702_config* config,
495 /* setup the state */ 477 /* setup the state */
496 state->config = config; 478 state->config = config;
497 state->i2c = i2c; 479 state->i2c = i2c;
498 memcpy(&state->ops, &cx22702_ops, sizeof(struct dvb_frontend_ops));
499 state->prevUCBlocks = 0; 480 state->prevUCBlocks = 0;
500 481
501 /* check if the demod is there */ 482 /* check if the demod is there */
@@ -503,7 +484,7 @@ struct dvb_frontend* cx22702_attach(const struct cx22702_config* config,
503 goto error; 484 goto error;
504 485
505 /* create dvb_frontend */ 486 /* create dvb_frontend */
506 state->frontend.ops = &state->ops; 487 memcpy(&state->frontend.ops, &cx22702_ops, sizeof(struct dvb_frontend_ops));
507 state->frontend.demodulator_priv = state; 488 state->frontend.demodulator_priv = state;
508 return &state->frontend; 489 return &state->frontend;
509 490
@@ -530,6 +511,7 @@ static struct dvb_frontend_ops cx22702_ops = {
530 .release = cx22702_release, 511 .release = cx22702_release,
531 512
532 .init = cx22702_init, 513 .init = cx22702_init,
514 .i2c_gate_ctrl = cx22702_i2c_gate_ctrl,
533 515
534 .set_frontend = cx22702_set_tps, 516 .set_frontend = cx22702_set_tps,
535 .get_frontend = cx22702_get_frontend, 517 .get_frontend = cx22702_get_frontend,
@@ -540,7 +522,6 @@ static struct dvb_frontend_ops cx22702_ops = {
540 .read_signal_strength = cx22702_read_signal_strength, 522 .read_signal_strength = cx22702_read_signal_strength,
541 .read_snr = cx22702_read_snr, 523 .read_snr = cx22702_read_snr,
542 .read_ucblocks = cx22702_read_ucblocks, 524 .read_ucblocks = cx22702_read_ucblocks,
543 .i2c_gate_ctrl = cx22702_i2c_gate_ctrl,
544}; 525};
545 526
546module_param(debug, int, 0644); 527module_param(debug, int, 0644);
diff --git a/drivers/media/dvb/frontends/cx22702.h b/drivers/media/dvb/frontends/cx22702.h
index 5633976a58f1..7f2f241e5d44 100644
--- a/drivers/media/dvb/frontends/cx22702.h
+++ b/drivers/media/dvb/frontends/cx22702.h
@@ -39,13 +39,6 @@ struct cx22702_config
39#define CX22702_PARALLEL_OUTPUT 0 39#define CX22702_PARALLEL_OUTPUT 0
40#define CX22702_SERIAL_OUTPUT 1 40#define CX22702_SERIAL_OUTPUT 1
41 u8 output_mode; 41 u8 output_mode;
42
43 /* PLL maintenance */
44 u8 pll_address;
45 struct dvb_pll_desc *pll_desc;
46
47 int (*pll_init)(struct dvb_frontend* fe);
48 int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
49}; 42};
50 43
51extern struct dvb_frontend* cx22702_attach(const struct cx22702_config* config, 44extern struct dvb_frontend* cx22702_attach(const struct cx22702_config* config,
diff --git a/drivers/media/dvb/frontends/cx24110.c b/drivers/media/dvb/frontends/cx24110.c
index f3edf8b517dd..ce3c7398bac9 100644
--- a/drivers/media/dvb/frontends/cx24110.c
+++ b/drivers/media/dvb/frontends/cx24110.c
@@ -36,8 +36,6 @@ struct cx24110_state {
36 36
37 struct i2c_adapter* i2c; 37 struct i2c_adapter* i2c;
38 38
39 struct dvb_frontend_ops ops;
40
41 const struct cx24110_config* config; 39 const struct cx24110_config* config;
42 40
43 struct dvb_frontend frontend; 41 struct dvb_frontend frontend;
@@ -250,7 +248,7 @@ static int cx24110_set_symbolrate (struct cx24110_state* state, u32 srate)
250 static const u32 bands[]={5000000UL,15000000UL,90999000UL/2}; 248 static const u32 bands[]={5000000UL,15000000UL,90999000UL/2};
251 int i; 249 int i;
252 250
253dprintk("cx24110 debug: entering %s(%d)\n",__FUNCTION__,srate); 251 dprintk("cx24110 debug: entering %s(%d)\n",__FUNCTION__,srate);
254 if (srate>90999000UL/2) 252 if (srate>90999000UL/2)
255 srate=90999000UL/2; 253 srate=90999000UL/2;
256 if (srate<500000) 254 if (srate<500000)
@@ -366,17 +364,6 @@ static int cx24110_initfe(struct dvb_frontend* fe)
366 cx24110_writereg(state, cx24110_regdata[i].reg, cx24110_regdata[i].data); 364 cx24110_writereg(state, cx24110_regdata[i].reg, cx24110_regdata[i].data);
367 }; 365 };
368 366
369 if (state->config->pll_init) state->config->pll_init(fe);
370
371 return 0;
372}
373
374static int cx24110_sleep(struct dvb_frontend *fe)
375{
376 struct cx24110_state *state = fe->demodulator_priv;
377
378 if (state->config->pll_sleep)
379 return state->config->pll_sleep(fe);
380 return 0; 367 return 0;
381} 368}
382 369
@@ -548,7 +535,12 @@ static int cx24110_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_par
548{ 535{
549 struct cx24110_state *state = fe->demodulator_priv; 536 struct cx24110_state *state = fe->demodulator_priv;
550 537
551 state->config->pll_set(fe, p); 538
539 if (fe->ops.tuner_ops.set_params) {
540 fe->ops.tuner_ops.set_params(fe, p);
541 if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
542 }
543
552 cx24110_set_inversion (state, p->inversion); 544 cx24110_set_inversion (state, p->inversion);
553 cx24110_set_fec (state, p->u.qpsk.fec_inner); 545 cx24110_set_fec (state, p->u.qpsk.fec_inner);
554 cx24110_set_symbolrate (state, p->u.qpsk.symbol_rate); 546 cx24110_set_symbolrate (state, p->u.qpsk.symbol_rate);
@@ -612,7 +604,6 @@ struct dvb_frontend* cx24110_attach(const struct cx24110_config* config,
612 /* setup the state */ 604 /* setup the state */
613 state->config = config; 605 state->config = config;
614 state->i2c = i2c; 606 state->i2c = i2c;
615 memcpy(&state->ops, &cx24110_ops, sizeof(struct dvb_frontend_ops));
616 state->lastber = 0; 607 state->lastber = 0;
617 state->lastbler = 0; 608 state->lastbler = 0;
618 state->lastesn0 = 0; 609 state->lastesn0 = 0;
@@ -622,7 +613,7 @@ struct dvb_frontend* cx24110_attach(const struct cx24110_config* config,
622 if ((ret != 0x5a) && (ret != 0x69)) goto error; 613 if ((ret != 0x5a) && (ret != 0x69)) goto error;
623 614
624 /* create dvb_frontend */ 615 /* create dvb_frontend */
625 state->frontend.ops = &state->ops; 616 memcpy(&state->frontend.ops, &cx24110_ops, sizeof(struct dvb_frontend_ops));
626 state->frontend.demodulator_priv = state; 617 state->frontend.demodulator_priv = state;
627 return &state->frontend; 618 return &state->frontend;
628 619
@@ -651,7 +642,6 @@ static struct dvb_frontend_ops cx24110_ops = {
651 .release = cx24110_release, 642 .release = cx24110_release,
652 643
653 .init = cx24110_initfe, 644 .init = cx24110_initfe,
654 .sleep = cx24110_sleep,
655 .set_frontend = cx24110_set_frontend, 645 .set_frontend = cx24110_set_frontend,
656 .get_frontend = cx24110_get_frontend, 646 .get_frontend = cx24110_get_frontend,
657 .read_status = cx24110_read_status, 647 .read_status = cx24110_read_status,
diff --git a/drivers/media/dvb/frontends/cx24110.h b/drivers/media/dvb/frontends/cx24110.h
index 609ac642b406..b354a64e0e74 100644
--- a/drivers/media/dvb/frontends/cx24110.h
+++ b/drivers/media/dvb/frontends/cx24110.h
@@ -31,11 +31,6 @@ struct cx24110_config
31{ 31{
32 /* the demodulator's i2c address */ 32 /* the demodulator's i2c address */
33 u8 demod_address; 33 u8 demod_address;
34
35 /* PLL maintenance */
36 int (*pll_init)(struct dvb_frontend* fe);
37 int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
38 int (*pll_sleep)(struct dvb_frontend* fe);
39}; 34};
40 35
41extern struct dvb_frontend* cx24110_attach(const struct cx24110_config* config, 36extern struct dvb_frontend* cx24110_attach(const struct cx24110_config* config,
diff --git a/drivers/media/dvb/frontends/cx24123.c b/drivers/media/dvb/frontends/cx24123.c
index 691dc840dcc0..f2f795cba56a 100644
--- a/drivers/media/dvb/frontends/cx24123.c
+++ b/drivers/media/dvb/frontends/cx24123.c
@@ -41,14 +41,12 @@ static int debug;
41struct cx24123_state 41struct cx24123_state
42{ 42{
43 struct i2c_adapter* i2c; 43 struct i2c_adapter* i2c;
44 struct dvb_frontend_ops ops;
45 const struct cx24123_config* config; 44 const struct cx24123_config* config;
46 45
47 struct dvb_frontend frontend; 46 struct dvb_frontend frontend;
48 47
49 u32 lastber; 48 u32 lastber;
50 u16 snr; 49 u16 snr;
51 u8 lnbreg;
52 50
53 /* Some PLL specifics for tuning */ 51 /* Some PLL specifics for tuning */
54 u32 VCAarg; 52 u32 VCAarg;
@@ -249,29 +247,6 @@ static int cx24123_writereg(struct cx24123_state* state, int reg, int data)
249 return 0; 247 return 0;
250} 248}
251 249
252static int cx24123_writelnbreg(struct cx24123_state* state, int reg, int data)
253{
254 u8 buf[] = { reg, data };
255 /* fixme: put the intersil addr int the config */
256 struct i2c_msg msg = { .addr = 0x08, .flags = 0, .buf = buf, .len = 2 };
257 int err;
258
259 if (debug>1)
260 printk("cx24123: %s: writeln addr=0x08, reg 0x%02x, value 0x%02x\n",
261 __FUNCTION__,reg, data);
262
263 if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) {
264 printk("%s: writelnbreg error (err == %i, reg == 0x%02x,"
265 " data == 0x%02x)\n", __FUNCTION__, err, reg, data);
266 return -EREMOTEIO;
267 }
268
269 /* cache the write, no way to read back */
270 state->lnbreg = data;
271
272 return 0;
273}
274
275static int cx24123_readreg(struct cx24123_state* state, u8 reg) 250static int cx24123_readreg(struct cx24123_state* state, u8 reg)
276{ 251{
277 int ret; 252 int ret;
@@ -295,11 +270,6 @@ static int cx24123_readreg(struct cx24123_state* state, u8 reg)
295 return b1[0]; 270 return b1[0];
296} 271}
297 272
298static int cx24123_readlnbreg(struct cx24123_state* state, u8 reg)
299{
300 return state->lnbreg;
301}
302
303static int cx24123_set_inversion(struct cx24123_state* state, fe_spectral_inversion_t inversion) 273static int cx24123_set_inversion(struct cx24123_state* state, fe_spectral_inversion_t inversion)
304{ 274{
305 u8 nom_reg = cx24123_readreg(state, 0x0e); 275 u8 nom_reg = cx24123_readreg(state, 0x0e);
@@ -458,8 +428,8 @@ static int cx24123_set_symbolrate(struct cx24123_state* state, u32 srate)
458 u8 pll_mult; 428 u8 pll_mult;
459 429
460 /* check if symbol rate is within limits */ 430 /* check if symbol rate is within limits */
461 if ((srate > state->ops.info.symbol_rate_max) || 431 if ((srate > state->frontend.ops.info.symbol_rate_max) ||
462 (srate < state->ops.info.symbol_rate_min)) 432 (srate < state->frontend.ops.info.symbol_rate_min))
463 return -EOPNOTSUPP;; 433 return -EOPNOTSUPP;;
464 434
465 /* choose the sampling rate high enough for the required operation, 435 /* choose the sampling rate high enough for the required operation,
@@ -687,13 +657,6 @@ static int cx24123_initfe(struct dvb_frontend* fe)
687 for (i = 0; i < sizeof(cx24123_regdata) / sizeof(cx24123_regdata[0]); i++) 657 for (i = 0; i < sizeof(cx24123_regdata) / sizeof(cx24123_regdata[0]); i++)
688 cx24123_writereg(state, cx24123_regdata[i].reg, cx24123_regdata[i].data); 658 cx24123_writereg(state, cx24123_regdata[i].reg, cx24123_regdata[i].data);
689 659
690 if (state->config->pll_init)
691 state->config->pll_init(fe);
692
693 /* Configure the LNB for 14V */
694 if (state->config->use_isl6421)
695 cx24123_writelnbreg(state, 0x0, 0x2a);
696
697 return 0; 660 return 0;
698} 661}
699 662
@@ -702,50 +665,18 @@ static int cx24123_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage
702 struct cx24123_state *state = fe->demodulator_priv; 665 struct cx24123_state *state = fe->demodulator_priv;
703 u8 val; 666 u8 val;
704 667
705 switch (state->config->use_isl6421) { 668 val = cx24123_readreg(state, 0x29) & ~0x40;
706
707 case 1:
708 669
709 val = cx24123_readlnbreg(state, 0x0); 670 switch (voltage) {
710 671 case SEC_VOLTAGE_13:
711 switch (voltage) { 672 dprintk("%s: setting voltage 13V\n", __FUNCTION__);
712 case SEC_VOLTAGE_13: 673 return cx24123_writereg(state, 0x29, val | 0x80);
713 dprintk("%s: isl6421 voltage = 13V\n",__FUNCTION__); 674 case SEC_VOLTAGE_18:
714 return cx24123_writelnbreg(state, 0x0, val & 0x32); /* V 13v */ 675 dprintk("%s: setting voltage 18V\n", __FUNCTION__);
715 case SEC_VOLTAGE_18: 676 return cx24123_writereg(state, 0x29, val & 0x7f);
716 dprintk("%s: isl6421 voltage = 18V\n",__FUNCTION__); 677 default:
717 return cx24123_writelnbreg(state, 0x0, val | 0x04); /* H 18v */ 678 return -EINVAL;
718 case SEC_VOLTAGE_OFF: 679 };
719 dprintk("%s: isl5421 voltage off\n",__FUNCTION__);
720 return cx24123_writelnbreg(state, 0x0, val & 0x30);
721 default:
722 return -EINVAL;
723 };
724
725 case 0:
726
727 val = cx24123_readreg(state, 0x29);
728
729 switch (voltage) {
730 case SEC_VOLTAGE_13:
731 dprintk("%s: setting voltage 13V\n", __FUNCTION__);
732 if (state->config->enable_lnb_voltage)
733 state->config->enable_lnb_voltage(fe, 1);
734 return cx24123_writereg(state, 0x29, val | 0x80);
735 case SEC_VOLTAGE_18:
736 dprintk("%s: setting voltage 18V\n", __FUNCTION__);
737 if (state->config->enable_lnb_voltage)
738 state->config->enable_lnb_voltage(fe, 1);
739 return cx24123_writereg(state, 0x29, val & 0x7f);
740 case SEC_VOLTAGE_OFF:
741 dprintk("%s: setting voltage off\n", __FUNCTION__);
742 if (state->config->enable_lnb_voltage)
743 state->config->enable_lnb_voltage(fe, 0);
744 return 0;
745 default:
746 return -EINVAL;
747 };
748 }
749 680
750 return 0; 681 return 0;
751} 682}
@@ -766,27 +697,20 @@ static void cx24123_wait_for_diseqc(struct cx24123_state *state)
766static int cx24123_send_diseqc_msg(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd *cmd) 697static int cx24123_send_diseqc_msg(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd *cmd)
767{ 698{
768 struct cx24123_state *state = fe->demodulator_priv; 699 struct cx24123_state *state = fe->demodulator_priv;
769 int i, val; 700 int i, val, tone;
770 701
771 dprintk("%s:\n",__FUNCTION__); 702 dprintk("%s:\n",__FUNCTION__);
772 703
773 /* check if continuous tone has been stopped */ 704 /* stop continuous tone if enabled */
774 if (state->config->use_isl6421) 705 tone = cx24123_readreg(state, 0x29);
775 val = cx24123_readlnbreg(state, 0x00) & 0x10; 706 if (tone & 0x10)
776 else 707 cx24123_writereg(state, 0x29, tone & ~0x50);
777 val = cx24123_readreg(state, 0x29) & 0x10;
778
779
780 if (val) {
781 printk("%s: ERROR: attempt to send diseqc command before tone is off\n", __FUNCTION__);
782 return -ENOTSUPP;
783 }
784 708
785 /* wait for diseqc queue ready */ 709 /* wait for diseqc queue ready */
786 cx24123_wait_for_diseqc(state); 710 cx24123_wait_for_diseqc(state);
787 711
788 /* select tone mode */ 712 /* select tone mode */
789 cx24123_writereg(state, 0x2a, cx24123_readreg(state, 0x2a) & 0xf8); 713 cx24123_writereg(state, 0x2a, cx24123_readreg(state, 0x2a) & 0xfb);
790 714
791 for (i = 0; i < cmd->msg_len; i++) 715 for (i = 0; i < cmd->msg_len; i++)
792 cx24123_writereg(state, 0x2C + i, cmd->msg[i]); 716 cx24123_writereg(state, 0x2C + i, cmd->msg[i]);
@@ -797,36 +721,33 @@ static int cx24123_send_diseqc_msg(struct dvb_frontend* fe, struct dvb_diseqc_ma
797 /* wait for diseqc message to finish sending */ 721 /* wait for diseqc message to finish sending */
798 cx24123_wait_for_diseqc(state); 722 cx24123_wait_for_diseqc(state);
799 723
724 /* restart continuous tone if enabled */
725 if (tone & 0x10) {
726 cx24123_writereg(state, 0x29, tone & ~0x40);
727 }
728
800 return 0; 729 return 0;
801} 730}
802 731
803static int cx24123_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t burst) 732static int cx24123_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t burst)
804{ 733{
805 struct cx24123_state *state = fe->demodulator_priv; 734 struct cx24123_state *state = fe->demodulator_priv;
806 int val; 735 int val, tone;
807 736
808 dprintk("%s:\n", __FUNCTION__); 737 dprintk("%s:\n", __FUNCTION__);
809 738
810 /* check if continuous tone has been stoped */ 739 /* stop continuous tone if enabled */
811 if (state->config->use_isl6421) 740 tone = cx24123_readreg(state, 0x29);
812 val = cx24123_readlnbreg(state, 0x00) & 0x10; 741 if (tone & 0x10)
813 else 742 cx24123_writereg(state, 0x29, tone & ~0x50);
814 val = cx24123_readreg(state, 0x29) & 0x10;
815
816
817 if (val) {
818 printk("%s: ERROR: attempt to send diseqc command before tone is off\n", __FUNCTION__);
819 return -ENOTSUPP;
820 }
821 743
744 /* wait for diseqc queue ready */
822 cx24123_wait_for_diseqc(state); 745 cx24123_wait_for_diseqc(state);
823 746
824 /* select tone mode */ 747 /* select tone mode */
825 val = cx24123_readreg(state, 0x2a) & 0xf8; 748 cx24123_writereg(state, 0x2a, cx24123_readreg(state, 0x2a) | 0x4);
826 cx24123_writereg(state, 0x2a, val | 0x04); 749 msleep(30);
827
828 val = cx24123_readreg(state, 0x29); 750 val = cx24123_readreg(state, 0x29);
829
830 if (burst == SEC_MINI_A) 751 if (burst == SEC_MINI_A)
831 cx24123_writereg(state, 0x29, ((val & 0x90) | 0x40 | 0x00)); 752 cx24123_writereg(state, 0x29, ((val & 0x90) | 0x40 | 0x00));
832 else if (burst == SEC_MINI_B) 753 else if (burst == SEC_MINI_B)
@@ -835,7 +756,12 @@ static int cx24123_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t
835 return -EINVAL; 756 return -EINVAL;
836 757
837 cx24123_wait_for_diseqc(state); 758 cx24123_wait_for_diseqc(state);
759 cx24123_writereg(state, 0x2a, cx24123_readreg(state, 0x2a) & 0xfb);
838 760
761 /* restart continuous tone if enabled */
762 if (tone & 0x10) {
763 cx24123_writereg(state, 0x29, tone & ~0x40);
764 }
839 return 0; 765 return 0;
840} 766}
841 767
@@ -976,38 +902,21 @@ static int cx24123_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
976 struct cx24123_state *state = fe->demodulator_priv; 902 struct cx24123_state *state = fe->demodulator_priv;
977 u8 val; 903 u8 val;
978 904
979 switch (state->config->use_isl6421) { 905 /* wait for diseqc queue ready */
980 case 1: 906 cx24123_wait_for_diseqc(state);
981
982 val = cx24123_readlnbreg(state, 0x0);
983
984 switch (tone) {
985 case SEC_TONE_ON:
986 dprintk("%s: isl6421 sec tone on\n",__FUNCTION__);
987 return cx24123_writelnbreg(state, 0x0, val | 0x10);
988 case SEC_TONE_OFF:
989 dprintk("%s: isl6421 sec tone off\n",__FUNCTION__);
990 return cx24123_writelnbreg(state, 0x0, val & 0x2f);
991 default:
992 printk("%s: CASE reached default with tone=%d\n", __FUNCTION__, tone);
993 return -EINVAL;
994 }
995
996 case 0:
997 907
998 val = cx24123_readreg(state, 0x29); 908 val = cx24123_readreg(state, 0x29) & ~0x40;
999 909
1000 switch (tone) { 910 switch (tone) {
1001 case SEC_TONE_ON: 911 case SEC_TONE_ON:
1002 dprintk("%s: setting tone on\n", __FUNCTION__); 912 dprintk("%s: setting tone on\n", __FUNCTION__);
1003 return cx24123_writereg(state, 0x29, val | 0x10); 913 return cx24123_writereg(state, 0x29, val | 0x10);
1004 case SEC_TONE_OFF: 914 case SEC_TONE_OFF:
1005 dprintk("%s: setting tone off\n",__FUNCTION__); 915 dprintk("%s: setting tone off\n",__FUNCTION__);
1006 return cx24123_writereg(state, 0x29, val & 0xef); 916 return cx24123_writereg(state, 0x29, val & 0xef);
1007 default: 917 default:
1008 printk("%s: CASE reached default with tone=%d\n", __FUNCTION__, tone); 918 printk("%s: CASE reached default with tone=%d\n", __FUNCTION__, tone);
1009 return -EINVAL; 919 return -EINVAL;
1010 }
1011 } 920 }
1012 921
1013 return 0; 922 return 0;
@@ -1040,10 +949,8 @@ struct dvb_frontend* cx24123_attach(const struct cx24123_config* config,
1040 /* setup the state */ 949 /* setup the state */
1041 state->config = config; 950 state->config = config;
1042 state->i2c = i2c; 951 state->i2c = i2c;
1043 memcpy(&state->ops, &cx24123_ops, sizeof(struct dvb_frontend_ops));
1044 state->lastber = 0; 952 state->lastber = 0;
1045 state->snr = 0; 953 state->snr = 0;
1046 state->lnbreg = 0;
1047 state->VCAarg = 0; 954 state->VCAarg = 0;
1048 state->VGAarg = 0; 955 state->VGAarg = 0;
1049 state->bandselectarg = 0; 956 state->bandselectarg = 0;
@@ -1059,7 +966,7 @@ struct dvb_frontend* cx24123_attach(const struct cx24123_config* config,
1059 } 966 }
1060 967
1061 /* create dvb_frontend */ 968 /* create dvb_frontend */
1062 state->frontend.ops = &state->ops; 969 memcpy(&state->frontend.ops, &cx24123_ops, sizeof(struct dvb_frontend_ops));
1063 state->frontend.demodulator_priv = state; 970 state->frontend.demodulator_priv = state;
1064 return &state->frontend; 971 return &state->frontend;
1065 972
diff --git a/drivers/media/dvb/frontends/cx24123.h b/drivers/media/dvb/frontends/cx24123.h
index 0c922b5e9263..9606f825935c 100644
--- a/drivers/media/dvb/frontends/cx24123.h
+++ b/drivers/media/dvb/frontends/cx24123.h
@@ -28,21 +28,8 @@ struct cx24123_config
28 /* the demodulator's i2c address */ 28 /* the demodulator's i2c address */
29 u8 demod_address; 29 u8 demod_address;
30 30
31 /*
32 cards like Hauppauge Nova-S Plus/Nova-SE2 use an Intersil ISL6421 chip
33 for LNB control, while KWorld DVB-S 100 use the LNBDC and LNBTone bits
34 from register 0x29 of the CX24123 demodulator
35 */
36 int use_isl6421;
37
38 /* PLL maintenance */
39 int (*pll_init)(struct dvb_frontend* fe);
40 int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
41
42 /* Need to set device param for start_dma */ 31 /* Need to set device param for start_dma */
43 int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured); 32 int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured);
44
45 void (*enable_lnb_voltage)(struct dvb_frontend* fe, int on);
46}; 33};
47 34
48extern struct dvb_frontend* cx24123_attach(const struct cx24123_config* config, 35extern struct dvb_frontend* cx24123_attach(const struct cx24123_config* config,
diff --git a/drivers/media/dvb/frontends/dib3000-common.h b/drivers/media/dvb/frontends/dib3000-common.h
index c31d6df15472..be1c0d3e1389 100644
--- a/drivers/media/dvb/frontends/dib3000-common.h
+++ b/drivers/media/dvb/frontends/dib3000-common.h
@@ -38,8 +38,6 @@
38struct dib3000_state { 38struct dib3000_state {
39 struct i2c_adapter* i2c; 39 struct i2c_adapter* i2c;
40 40
41 struct dvb_frontend_ops ops;
42
43/* configuration settings */ 41/* configuration settings */
44 struct dib3000_config config; 42 struct dib3000_config config;
45 43
diff --git a/drivers/media/dvb/frontends/dib3000.h b/drivers/media/dvb/frontends/dib3000.h
index 2d5475b5c063..ec927628d273 100644
--- a/drivers/media/dvb/frontends/dib3000.h
+++ b/drivers/media/dvb/frontends/dib3000.h
@@ -30,10 +30,6 @@ struct dib3000_config
30{ 30{
31 /* the demodulator's i2c address */ 31 /* the demodulator's i2c address */
32 u8 demod_address; 32 u8 demod_address;
33
34 /* PLL maintenance and the i2c address of the PLL */
35 int (*pll_init)(struct dvb_frontend *fe);
36 int (*pll_set)(struct dvb_frontend *fe, struct dvb_frontend_parameters* params);
37}; 33};
38 34
39struct dib_fe_xfer_ops 35struct dib_fe_xfer_ops
diff --git a/drivers/media/dvb/frontends/dib3000mb.c b/drivers/media/dvb/frontends/dib3000mb.c
index ae589adb1c0a..7c6dc7e30900 100644
--- a/drivers/media/dvb/frontends/dib3000mb.c
+++ b/drivers/media/dvb/frontends/dib3000mb.c
@@ -60,8 +60,9 @@ static int dib3000mb_set_frontend(struct dvb_frontend* fe,
60 fe_code_rate_t fe_cr = FEC_NONE; 60 fe_code_rate_t fe_cr = FEC_NONE;
61 int search_state, seq; 61 int search_state, seq;
62 62
63 if (tuner && state->config.pll_set) { 63 if (tuner && fe->ops.tuner_ops.set_params) {
64 state->config.pll_set(fe, fep); 64 fe->ops.tuner_ops.set_params(fe, fep);
65 if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
65 66
66 deb_setf("bandwidth: "); 67 deb_setf("bandwidth: ");
67 switch (ofdm->bandwidth) { 68 switch (ofdm->bandwidth) {
@@ -386,9 +387,6 @@ static int dib3000mb_fe_init(struct dvb_frontend* fe, int mobile_mode)
386 387
387 wr(DIB3000MB_REG_DATA_IN_DIVERSITY, DIB3000MB_DATA_DIVERSITY_IN_OFF); 388 wr(DIB3000MB_REG_DATA_IN_DIVERSITY, DIB3000MB_DATA_DIVERSITY_IN_OFF);
388 389
389 if (state->config.pll_init)
390 state->config.pll_init(fe);
391
392 return 0; 390 return 0;
393} 391}
394 392
@@ -707,7 +705,6 @@ struct dvb_frontend* dib3000mb_attach(const struct dib3000_config* config,
707 /* setup the state */ 705 /* setup the state */
708 state->i2c = i2c; 706 state->i2c = i2c;
709 memcpy(&state->config,config,sizeof(struct dib3000_config)); 707 memcpy(&state->config,config,sizeof(struct dib3000_config));
710 memcpy(&state->ops, &dib3000mb_ops, sizeof(struct dvb_frontend_ops));
711 708
712 /* check for the correct demod */ 709 /* check for the correct demod */
713 if (rd(DIB3000_REG_MANUFACTOR_ID) != DIB3000_I2C_ID_DIBCOM) 710 if (rd(DIB3000_REG_MANUFACTOR_ID) != DIB3000_I2C_ID_DIBCOM)
@@ -717,7 +714,7 @@ struct dvb_frontend* dib3000mb_attach(const struct dib3000_config* config,
717 goto error; 714 goto error;
718 715
719 /* create dvb_frontend */ 716 /* create dvb_frontend */
720 state->frontend.ops = &state->ops; 717 memcpy(&state->frontend.ops, &dib3000mb_ops, sizeof(struct dvb_frontend_ops));
721 state->frontend.demodulator_priv = state; 718 state->frontend.demodulator_priv = state;
722 719
723 /* set the xfer operations */ 720 /* set the xfer operations */
diff --git a/drivers/media/dvb/frontends/dib3000mc.c b/drivers/media/dvb/frontends/dib3000mc.c
index 3b303dbb6156..6c3be2529980 100644
--- a/drivers/media/dvb/frontends/dib3000mc.c
+++ b/drivers/media/dvb/frontends/dib3000mc.c
@@ -462,8 +462,9 @@ static int dib3000mc_set_frontend(struct dvb_frontend* fe,
462 int search_state,auto_val; 462 int search_state,auto_val;
463 u16 val; 463 u16 val;
464 464
465 if (tuner && state->config.pll_set) { /* initial call from dvb */ 465 if (tuner && fe->ops.tuner_ops.set_params) { /* initial call from dvb */
466 state->config.pll_set(fe,fep); 466 fe->ops.tuner_ops.set_params(fe, fep);
467 if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
467 468
468 state->last_tuned_freq = fep->frequency; 469 state->last_tuned_freq = fep->frequency;
469 // if (!scanboost) { 470 // if (!scanboost) {
@@ -642,9 +643,6 @@ static int dib3000mc_fe_init(struct dvb_frontend* fe, int mobile_mode)
642 643
643 set_or(DIB3000MC_REG_CLK_CFG_7,DIB3000MC_CLK_CFG_7_DIV_IN_OFF); 644 set_or(DIB3000MC_REG_CLK_CFG_7,DIB3000MC_CLK_CFG_7_DIV_IN_OFF);
644 645
645 if (state->config.pll_init)
646 state->config.pll_init(fe);
647
648 deb_info("init end\n"); 646 deb_info("init end\n");
649 return 0; 647 return 0;
650} 648}
@@ -839,7 +837,6 @@ struct dvb_frontend* dib3000mc_attach(const struct dib3000_config* config,
839 /* setup the state */ 837 /* setup the state */
840 state->i2c = i2c; 838 state->i2c = i2c;
841 memcpy(&state->config,config,sizeof(struct dib3000_config)); 839 memcpy(&state->config,config,sizeof(struct dib3000_config));
842 memcpy(&state->ops, &dib3000mc_ops, sizeof(struct dvb_frontend_ops));
843 840
844 /* check for the correct demod */ 841 /* check for the correct demod */
845 if (rd(DIB3000_REG_MANUFACTOR_ID) != DIB3000_I2C_ID_DIBCOM) 842 if (rd(DIB3000_REG_MANUFACTOR_ID) != DIB3000_I2C_ID_DIBCOM)
@@ -859,7 +856,7 @@ struct dvb_frontend* dib3000mc_attach(const struct dib3000_config* config,
859 } 856 }
860 857
861 /* create dvb_frontend */ 858 /* create dvb_frontend */
862 state->frontend.ops = &state->ops; 859 memcpy(&state->frontend.ops, &dib3000mc_ops, sizeof(struct dvb_frontend_ops));
863 state->frontend.demodulator_priv = state; 860 state->frontend.demodulator_priv = state;
864 861
865 /* set the xfer operations */ 862 /* set the xfer operations */
@@ -876,6 +873,7 @@ error:
876 kfree(state); 873 kfree(state);
877 return NULL; 874 return NULL;
878} 875}
876EXPORT_SYMBOL(dib3000mc_attach);
879 877
880static struct dvb_frontend_ops dib3000mc_ops = { 878static struct dvb_frontend_ops dib3000mc_ops = {
881 879
@@ -914,5 +912,3 @@ static struct dvb_frontend_ops dib3000mc_ops = {
914MODULE_AUTHOR(DRIVER_AUTHOR); 912MODULE_AUTHOR(DRIVER_AUTHOR);
915MODULE_DESCRIPTION(DRIVER_DESC); 913MODULE_DESCRIPTION(DRIVER_DESC);
916MODULE_LICENSE("GPL"); 914MODULE_LICENSE("GPL");
917
918EXPORT_SYMBOL(dib3000mc_attach);
diff --git a/drivers/media/dvb/frontends/dvb-pll.c b/drivers/media/dvb/frontends/dvb-pll.c
index 791706ec1da3..a189683454b7 100644
--- a/drivers/media/dvb/frontends/dvb-pll.c
+++ b/drivers/media/dvb/frontends/dvb-pll.c
@@ -227,10 +227,10 @@ struct dvb_pll_desc dvb_pll_tua6034 = {
227EXPORT_SYMBOL(dvb_pll_tua6034); 227EXPORT_SYMBOL(dvb_pll_tua6034);
228 228
229/* Infineon TUA6034 229/* Infineon TUA6034
230 * used in LG TDVS H061F and LG TDVS H062F 230 * used in LG TDVS-H061F, LG TDVS-H062F and LG TDVS-H064F
231 */ 231 */
232struct dvb_pll_desc dvb_pll_tdvs_tua6034 = { 232struct dvb_pll_desc dvb_pll_lg_tdvs_h06xf = {
233 .name = "LG/Infineon TUA6034", 233 .name = "LG TDVS-H06xF",
234 .min = 54000000, 234 .min = 54000000,
235 .max = 863000000, 235 .max = 863000000,
236 .count = 3, 236 .count = 3,
@@ -240,7 +240,7 @@ struct dvb_pll_desc dvb_pll_tdvs_tua6034 = {
240 { 999999999, 44000000, 62500, 0xce, 0x04 }, 240 { 999999999, 44000000, 62500, 0xce, 0x04 },
241 }, 241 },
242}; 242};
243EXPORT_SYMBOL(dvb_pll_tdvs_tua6034); 243EXPORT_SYMBOL(dvb_pll_lg_tdvs_h06xf);
244 244
245/* Philips FMD1216ME 245/* Philips FMD1216ME
246 * used in Medion Hybrid PCMCIA card and USB Box 246 * used in Medion Hybrid PCMCIA card and USB Box
@@ -419,6 +419,19 @@ struct dvb_pll_desc dvb_pll_thomson_fe6600 = {
419}; 419};
420EXPORT_SYMBOL(dvb_pll_thomson_fe6600); 420EXPORT_SYMBOL(dvb_pll_thomson_fe6600);
421 421
422struct dvb_pll_priv {
423 /* i2c details */
424 int pll_i2c_address;
425 struct i2c_adapter *i2c;
426
427 /* the PLL descriptor */
428 struct dvb_pll_desc *pll_desc;
429
430 /* cached frequency/bandwidth */
431 u32 frequency;
432 u32 bandwidth;
433};
434
422/* ----------------------------------------------------------- */ 435/* ----------------------------------------------------------- */
423/* code */ 436/* code */
424 437
@@ -443,7 +456,8 @@ int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf,
443 if (debug) 456 if (debug)
444 printk("pll: %s: freq=%d bw=%d | i=%d/%d\n", 457 printk("pll: %s: freq=%d bw=%d | i=%d/%d\n",
445 desc->name, freq, bandwidth, i, desc->count); 458 desc->name, freq, bandwidth, i, desc->count);
446 BUG_ON(i == desc->count); 459 if (i == desc->count)
460 return -EINVAL;
447 461
448 div = (freq + desc->entries[i].offset) / desc->entries[i].stepsize; 462 div = (freq + desc->entries[i].offset) / desc->entries[i].stepsize;
449 buf[0] = div >> 8; 463 buf[0] = div >> 8;
@@ -462,6 +476,163 @@ int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf,
462} 476}
463EXPORT_SYMBOL(dvb_pll_configure); 477EXPORT_SYMBOL(dvb_pll_configure);
464 478
479static int dvb_pll_release(struct dvb_frontend *fe)
480{
481 if (fe->tuner_priv)
482 kfree(fe->tuner_priv);
483 fe->tuner_priv = NULL;
484 return 0;
485}
486
487static int dvb_pll_sleep(struct dvb_frontend *fe)
488{
489 struct dvb_pll_priv *priv = fe->tuner_priv;
490 u8 buf[4];
491 struct i2c_msg msg =
492 { .addr = priv->pll_i2c_address, .flags = 0, .buf = buf, .len = sizeof(buf) };
493 int i;
494 int result;
495
496 for (i = 0; i < priv->pll_desc->count; i++) {
497 if (priv->pll_desc->entries[i].limit == 0)
498 break;
499 }
500 if (i == priv->pll_desc->count)
501 return 0;
502
503 buf[0] = 0;
504 buf[1] = 0;
505 buf[2] = priv->pll_desc->entries[i].config;
506 buf[3] = priv->pll_desc->entries[i].cb;
507
508 if (fe->ops.i2c_gate_ctrl)
509 fe->ops.i2c_gate_ctrl(fe, 1);
510 if ((result = i2c_transfer(priv->i2c, &msg, 1)) != 1) {
511 return result;
512 }
513
514 return 0;
515}
516
517static int dvb_pll_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
518{
519 struct dvb_pll_priv *priv = fe->tuner_priv;
520 u8 buf[4];
521 struct i2c_msg msg =
522 { .addr = priv->pll_i2c_address, .flags = 0, .buf = buf, .len = sizeof(buf) };
523 int result;
524 u32 div;
525 int i;
526 u32 bandwidth = 0;
527
528 if (priv->i2c == NULL)
529 return -EINVAL;
530
531 // DVBT bandwidth only just now
532 if (fe->ops.info.type == FE_OFDM) {
533 bandwidth = params->u.ofdm.bandwidth;
534 }
535
536 if ((result = dvb_pll_configure(priv->pll_desc, buf, params->frequency, bandwidth)) != 0)
537 return result;
538
539 if (fe->ops.i2c_gate_ctrl)
540 fe->ops.i2c_gate_ctrl(fe, 1);
541 if ((result = i2c_transfer(priv->i2c, &msg, 1)) != 1) {
542 return result;
543 }
544
545 // calculate the frequency we set it to
546 for (i = 0; i < priv->pll_desc->count; i++) {
547 if (params->frequency > priv->pll_desc->entries[i].limit)
548 continue;
549 break;
550 }
551 div = (params->frequency + priv->pll_desc->entries[i].offset) / priv->pll_desc->entries[i].stepsize;
552 priv->frequency = (div * priv->pll_desc->entries[i].stepsize) - priv->pll_desc->entries[i].offset;
553 priv->bandwidth = bandwidth;
554
555 return 0;
556}
557
558static int dvb_pll_calc_regs(struct dvb_frontend *fe, struct dvb_frontend_parameters *params, u8 *buf, int buf_len)
559{
560 struct dvb_pll_priv *priv = fe->tuner_priv;
561 int result;
562 u32 div;
563 int i;
564 u32 bandwidth = 0;
565
566 if (buf_len < 5)
567 return -EINVAL;
568
569 // DVBT bandwidth only just now
570 if (fe->ops.info.type == FE_OFDM) {
571 bandwidth = params->u.ofdm.bandwidth;
572 }
573
574 if ((result = dvb_pll_configure(priv->pll_desc, buf+1, params->frequency, bandwidth)) != 0)
575 return result;
576 buf[0] = priv->pll_i2c_address;
577
578 // calculate the frequency we set it to
579 for (i = 0; i < priv->pll_desc->count; i++) {
580 if (params->frequency > priv->pll_desc->entries[i].limit)
581 continue;
582 break;
583 }
584 div = (params->frequency + priv->pll_desc->entries[i].offset) / priv->pll_desc->entries[i].stepsize;
585 priv->frequency = (div * priv->pll_desc->entries[i].stepsize) - priv->pll_desc->entries[i].offset;
586 priv->bandwidth = bandwidth;
587
588 return 5;
589}
590
591static int dvb_pll_get_frequency(struct dvb_frontend *fe, u32 *frequency)
592{
593 struct dvb_pll_priv *priv = fe->tuner_priv;
594 *frequency = priv->frequency;
595 return 0;
596}
597
598static int dvb_pll_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
599{
600 struct dvb_pll_priv *priv = fe->tuner_priv;
601 *bandwidth = priv->bandwidth;
602 return 0;
603}
604
605static struct dvb_tuner_ops dvb_pll_tuner_ops = {
606 .release = dvb_pll_release,
607 .sleep = dvb_pll_sleep,
608 .set_params = dvb_pll_set_params,
609 .calc_regs = dvb_pll_calc_regs,
610 .get_frequency = dvb_pll_get_frequency,
611 .get_bandwidth = dvb_pll_get_bandwidth,
612};
613
614int dvb_pll_attach(struct dvb_frontend *fe, int pll_addr, struct i2c_adapter *i2c, struct dvb_pll_desc *desc)
615{
616 struct dvb_pll_priv *priv = NULL;
617
618 priv = kzalloc(sizeof(struct dvb_pll_priv), GFP_KERNEL);
619 if (priv == NULL)
620 return -ENOMEM;
621
622 priv->pll_i2c_address = pll_addr;
623 priv->i2c = i2c;
624 priv->pll_desc = desc;
625
626 memcpy(&fe->ops.tuner_ops, &dvb_pll_tuner_ops, sizeof(struct dvb_tuner_ops));
627 strncpy(fe->ops.tuner_ops.info.name, desc->name, 128);
628 fe->ops.tuner_ops.info.frequency_min = desc->min;
629 fe->ops.tuner_ops.info.frequency_min = desc->max;
630
631 fe->tuner_priv = priv;
632 return 0;
633}
634EXPORT_SYMBOL(dvb_pll_attach);
635
465MODULE_DESCRIPTION("dvb pll library"); 636MODULE_DESCRIPTION("dvb pll library");
466MODULE_AUTHOR("Gerd Knorr"); 637MODULE_AUTHOR("Gerd Knorr");
467MODULE_LICENSE("GPL"); 638MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/dvb-pll.h b/drivers/media/dvb/frontends/dvb-pll.h
index 2b8461784989..66361cd18807 100644
--- a/drivers/media/dvb/frontends/dvb-pll.h
+++ b/drivers/media/dvb/frontends/dvb-pll.h
@@ -5,6 +5,9 @@
5#ifndef __DVB_PLL_H__ 5#ifndef __DVB_PLL_H__
6#define __DVB_PLL_H__ 6#define __DVB_PLL_H__
7 7
8#include <linux/i2c.h>
9#include "dvb_frontend.h"
10
8struct dvb_pll_desc { 11struct dvb_pll_desc {
9 char *name; 12 char *name;
10 u32 min; 13 u32 min;
@@ -31,7 +34,7 @@ extern struct dvb_pll_desc dvb_pll_unknown_1;
31extern struct dvb_pll_desc dvb_pll_tua6010xs; 34extern struct dvb_pll_desc dvb_pll_tua6010xs;
32extern struct dvb_pll_desc dvb_pll_env57h1xd5; 35extern struct dvb_pll_desc dvb_pll_env57h1xd5;
33extern struct dvb_pll_desc dvb_pll_tua6034; 36extern struct dvb_pll_desc dvb_pll_tua6034;
34extern struct dvb_pll_desc dvb_pll_tdvs_tua6034; 37extern struct dvb_pll_desc dvb_pll_lg_tdvs_h06xf;
35extern struct dvb_pll_desc dvb_pll_tda665x; 38extern struct dvb_pll_desc dvb_pll_tda665x;
36extern struct dvb_pll_desc dvb_pll_fmd1216me; 39extern struct dvb_pll_desc dvb_pll_fmd1216me;
37extern struct dvb_pll_desc dvb_pll_tded4; 40extern struct dvb_pll_desc dvb_pll_tded4;
@@ -44,7 +47,18 @@ extern struct dvb_pll_desc dvb_pll_philips_td1316;
44 47
45extern struct dvb_pll_desc dvb_pll_thomson_fe6600; 48extern struct dvb_pll_desc dvb_pll_thomson_fe6600;
46 49
47int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf, 50extern int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf,
48 u32 freq, int bandwidth); 51 u32 freq, int bandwidth);
49 52
53/**
54 * Attach a dvb-pll to the supplied frontend structure.
55 *
56 * @param fe Frontend to attach to.
57 * @param pll_addr i2c address of the PLL (if used).
58 * @param i2c i2c adapter to use (set to NULL if not used).
59 * @param desc dvb_pll_desc to use.
60 * @return 0 on success, nonzero on failure.
61 */
62extern int dvb_pll_attach(struct dvb_frontend *fe, int pll_addr, struct i2c_adapter *i2c, struct dvb_pll_desc *desc);
63
50#endif 64#endif
diff --git a/drivers/media/dvb/frontends/dvb_dummy_fe.c b/drivers/media/dvb/frontends/dvb_dummy_fe.c
index 645946a992d9..6271b1e7f6ab 100644
--- a/drivers/media/dvb/frontends/dvb_dummy_fe.c
+++ b/drivers/media/dvb/frontends/dvb_dummy_fe.c
@@ -30,7 +30,6 @@
30 30
31 31
32struct dvb_dummy_fe_state { 32struct dvb_dummy_fe_state {
33 struct dvb_frontend_ops ops;
34 struct dvb_frontend frontend; 33 struct dvb_frontend frontend;
35}; 34};
36 35
@@ -77,6 +76,11 @@ static int dvb_dummy_fe_get_frontend(struct dvb_frontend* fe, struct dvb_fronten
77 76
78static int dvb_dummy_fe_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) 77static int dvb_dummy_fe_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
79{ 78{
79 if (fe->ops->tuner_ops->set_params) {
80 fe->ops->tuner_ops->set_params(fe, p);
81 if (fe->ops->i2c_gate_ctrl) fe->ops->i2c_gate_ctrl(fe, 0);
82 }
83
80 return 0; 84 return 0;
81} 85}
82 86
@@ -116,11 +120,8 @@ struct dvb_frontend* dvb_dummy_fe_ofdm_attach(void)
116 state = kmalloc(sizeof(struct dvb_dummy_fe_state), GFP_KERNEL); 120 state = kmalloc(sizeof(struct dvb_dummy_fe_state), GFP_KERNEL);
117 if (state == NULL) goto error; 121 if (state == NULL) goto error;
118 122
119 /* setup the state */
120 memcpy(&state->ops, &dvb_dummy_fe_ofdm_ops, sizeof(struct dvb_frontend_ops));
121
122 /* create dvb_frontend */ 123 /* create dvb_frontend */
123 state->frontend.ops = &state->ops; 124 memcpy(&state->frontend.ops, &dvb_dummy_fe_ofdm_ops, sizeof(struct dvb_frontend_ops));
124 state->frontend.demodulator_priv = state; 125 state->frontend.demodulator_priv = state;
125 return &state->frontend; 126 return &state->frontend;
126 127
@@ -139,11 +140,8 @@ struct dvb_frontend* dvb_dummy_fe_qpsk_attach()
139 state = kmalloc(sizeof(struct dvb_dummy_fe_state), GFP_KERNEL); 140 state = kmalloc(sizeof(struct dvb_dummy_fe_state), GFP_KERNEL);
140 if (state == NULL) goto error; 141 if (state == NULL) goto error;
141 142
142 /* setup the state */
143 memcpy(&state->ops, &dvb_dummy_fe_qpsk_ops, sizeof(struct dvb_frontend_ops));
144
145 /* create dvb_frontend */ 143 /* create dvb_frontend */
146 state->frontend.ops = &state->ops; 144 memcpy(&state->frontend.ops, &dvb_dummy_fe_qpsk_ops, sizeof(struct dvb_frontend_ops));
147 state->frontend.demodulator_priv = state; 145 state->frontend.demodulator_priv = state;
148 return &state->frontend; 146 return &state->frontend;
149 147
@@ -162,11 +160,8 @@ struct dvb_frontend* dvb_dummy_fe_qam_attach()
162 state = kmalloc(sizeof(struct dvb_dummy_fe_state), GFP_KERNEL); 160 state = kmalloc(sizeof(struct dvb_dummy_fe_state), GFP_KERNEL);
163 if (state == NULL) goto error; 161 if (state == NULL) goto error;
164 162
165 /* setup the state */
166 memcpy(&state->ops, &dvb_dummy_fe_qam_ops, sizeof(struct dvb_frontend_ops));
167
168 /* create dvb_frontend */ 163 /* create dvb_frontend */
169 state->frontend.ops = &state->ops; 164 memcpy(&state->frontend.ops, &dvb_dummy_fe_qam_ops, sizeof(struct dvb_frontend_ops));
170 state->frontend.demodulator_priv = state; 165 state->frontend.demodulator_priv = state;
171 return &state->frontend; 166 return &state->frontend;
172 167
diff --git a/drivers/media/dvb/frontends/isl6421.c b/drivers/media/dvb/frontends/isl6421.c
new file mode 100644
index 000000000000..58c34db31071
--- /dev/null
+++ b/drivers/media/dvb/frontends/isl6421.c
@@ -0,0 +1,149 @@
1/*
2 * isl6421.h - driver for lnb supply and control ic ISL6421
3 *
4 * Copyright (C) 2006 Andrew de Quincey
5 * Copyright (C) 2006 Oliver Endriss
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 *
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 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
23 *
24 *
25 * the project's page is at http://www.linuxtv.org
26 */
27#include <linux/delay.h>
28#include <linux/errno.h>
29#include <linux/init.h>
30#include <linux/kernel.h>
31#include <linux/module.h>
32#include <linux/moduleparam.h>
33#include <linux/string.h>
34#include <linux/slab.h>
35
36#include "dvb_frontend.h"
37#include "isl6421.h"
38
39struct isl6421 {
40 u8 config;
41 u8 override_or;
42 u8 override_and;
43 struct i2c_adapter *i2c;
44 u8 i2c_addr;
45 void (*release_chain)(struct dvb_frontend* fe);
46};
47
48static int isl6421_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
49{
50 struct isl6421 *isl6421 = (struct isl6421 *) fe->misc_priv;
51 struct i2c_msg msg = { .addr = isl6421->i2c_addr, .flags = 0,
52 .buf = &isl6421->config,
53 .len = sizeof(isl6421->config) };
54
55 isl6421->config &= ~(ISL6421_VSEL1 | ISL6421_EN1);
56
57 switch(voltage) {
58 case SEC_VOLTAGE_OFF:
59 break;
60 case SEC_VOLTAGE_13:
61 isl6421->config |= ISL6421_EN1;
62 break;
63 case SEC_VOLTAGE_18:
64 isl6421->config |= (ISL6421_EN1 | ISL6421_VSEL1);
65 break;
66 default:
67 return -EINVAL;
68 };
69
70 isl6421->config |= isl6421->override_or;
71 isl6421->config &= isl6421->override_and;
72
73 return (i2c_transfer(isl6421->i2c, &msg, 1) == 1) ? 0 : -EIO;
74}
75
76static int isl6421_enable_high_lnb_voltage(struct dvb_frontend *fe, long arg)
77{
78 struct isl6421 *isl6421 = (struct isl6421 *) fe->misc_priv;
79 struct i2c_msg msg = { .addr = isl6421->i2c_addr, .flags = 0,
80 .buf = &isl6421->config,
81 .len = sizeof(isl6421->config) };
82
83 if (arg)
84 isl6421->config |= ISL6421_LLC1;
85 else
86 isl6421->config &= ~ISL6421_LLC1;
87
88 isl6421->config |= isl6421->override_or;
89 isl6421->config &= isl6421->override_and;
90
91 return (i2c_transfer(isl6421->i2c, &msg, 1) == 1) ? 0 : -EIO;
92}
93
94static void isl6421_release(struct dvb_frontend *fe)
95{
96 struct isl6421 *isl6421 = (struct isl6421 *) fe->misc_priv;
97
98 /* power off */
99 isl6421_set_voltage(fe, SEC_VOLTAGE_OFF);
100
101 /* free data & call next release routine */
102 fe->ops.release = isl6421->release_chain;
103 kfree(fe->misc_priv);
104 fe->misc_priv = NULL;
105 if (fe->ops.release)
106 fe->ops.release(fe);
107}
108
109int isl6421_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 i2c_addr,
110 u8 override_set, u8 override_clear)
111{
112 struct isl6421 *isl6421 = kmalloc(sizeof(struct isl6421), GFP_KERNEL);
113 if (!isl6421)
114 return -ENOMEM;
115
116 /* default configuration */
117 isl6421->config = ISL6421_ISEL1;
118 isl6421->i2c = i2c;
119 isl6421->i2c_addr = i2c_addr;
120 fe->misc_priv = isl6421;
121
122 /* bits which should be forced to '1' */
123 isl6421->override_or = override_set;
124
125 /* bits which should be forced to '0' */
126 isl6421->override_and = ~override_clear;
127
128 /* detect if it is present or not */
129 if (isl6421_set_voltage(fe, SEC_VOLTAGE_OFF)) {
130 kfree(isl6421);
131 fe->misc_priv = NULL;
132 return -EIO;
133 }
134
135 /* install release callback */
136 isl6421->release_chain = fe->ops.release;
137 fe->ops.release = isl6421_release;
138
139 /* override frontend ops */
140 fe->ops.set_voltage = isl6421_set_voltage;
141 fe->ops.enable_high_lnb_voltage = isl6421_enable_high_lnb_voltage;
142
143 return 0;
144}
145EXPORT_SYMBOL(isl6421_attach);
146
147MODULE_DESCRIPTION("Driver for lnb supply and control ic isl6421");
148MODULE_AUTHOR("Andrew de Quincey & Oliver Endriss");
149MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/isl6421.h b/drivers/media/dvb/frontends/isl6421.h
new file mode 100644
index 000000000000..675f80a19b99
--- /dev/null
+++ b/drivers/media/dvb/frontends/isl6421.h
@@ -0,0 +1,46 @@
1/*
2 * isl6421.h - driver for lnb supply and control ic ISL6421
3 *
4 * Copyright (C) 2006 Andrew de Quincey
5 * Copyright (C) 2006 Oliver Endriss
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 *
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 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
23 *
24 *
25 * the project's page is at http://www.linuxtv.org
26 */
27
28#ifndef _ISL6421_H
29#define _ISL6421_H
30
31#include <linux/dvb/frontend.h>
32
33/* system register bits */
34#define ISL6421_OLF1 0x01
35#define ISL6421_EN1 0x02
36#define ISL6421_VSEL1 0x04
37#define ISL6421_LLC1 0x08
38#define ISL6421_ENT1 0x10
39#define ISL6421_ISEL1 0x20
40#define ISL6421_DCL 0x40
41
42/* override_set and override_clear control which system register bits (above) to always set & clear */
43extern int isl6421_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 i2c_addr,
44 u8 override_set, u8 override_clear);
45
46#endif
diff --git a/drivers/media/dvb/frontends/l64781.c b/drivers/media/dvb/frontends/l64781.c
index 1c7c91224472..f3bc82e44a28 100644
--- a/drivers/media/dvb/frontends/l64781.c
+++ b/drivers/media/dvb/frontends/l64781.c
@@ -32,7 +32,6 @@
32 32
33struct l64781_state { 33struct l64781_state {
34 struct i2c_adapter* i2c; 34 struct i2c_adapter* i2c;
35 struct dvb_frontend_ops ops;
36 const struct l64781_config* config; 35 const struct l64781_config* config;
37 struct dvb_frontend frontend; 36 struct dvb_frontend frontend;
38 37
@@ -141,7 +140,10 @@ static int apply_frontend_param (struct dvb_frontend* fe, struct dvb_frontend_pa
141 u8 val0x06; 140 u8 val0x06;
142 int bw = p->bandwidth - BANDWIDTH_8_MHZ; 141 int bw = p->bandwidth - BANDWIDTH_8_MHZ;
143 142
144 state->config->pll_set(fe, param); 143 if (fe->ops.tuner_ops.set_params) {
144 fe->ops.tuner_ops.set_params(fe, param);
145 if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
146 }
145 147
146 if (param->inversion != INVERSION_ON && 148 if (param->inversion != INVERSION_ON &&
147 param->inversion != INVERSION_OFF) 149 param->inversion != INVERSION_OFF)
@@ -463,8 +465,6 @@ static int l64781_init(struct dvb_frontend* fe)
463 /* Everything is two's complement, soft bit and CSI_OUT too */ 465 /* Everything is two's complement, soft bit and CSI_OUT too */
464 l64781_writereg (state, 0x1e, 0x09); 466 l64781_writereg (state, 0x1e, 0x09);
465 467
466 if (state->config->pll_init) state->config->pll_init(fe);
467
468 /* delay a bit after first init attempt */ 468 /* delay a bit after first init attempt */
469 if (state->first) { 469 if (state->first) {
470 state->first = 0; 470 state->first = 0;
@@ -508,7 +508,6 @@ struct dvb_frontend* l64781_attach(const struct l64781_config* config,
508 /* setup the state */ 508 /* setup the state */
509 state->config = config; 509 state->config = config;
510 state->i2c = i2c; 510 state->i2c = i2c;
511 memcpy(&state->ops, &l64781_ops, sizeof(struct dvb_frontend_ops));
512 state->first = 1; 511 state->first = 1;
513 512
514 /** 513 /**
@@ -554,7 +553,7 @@ struct dvb_frontend* l64781_attach(const struct l64781_config* config,
554 } 553 }
555 554
556 /* create dvb_frontend */ 555 /* create dvb_frontend */
557 state->frontend.ops = &state->ops; 556 memcpy(&state->frontend.ops, &l64781_ops, sizeof(struct dvb_frontend_ops));
558 state->frontend.demodulator_priv = state; 557 state->frontend.demodulator_priv = state;
559 return &state->frontend; 558 return &state->frontend;
560 559
diff --git a/drivers/media/dvb/frontends/l64781.h b/drivers/media/dvb/frontends/l64781.h
index 947f65f87465..83b8bc210274 100644
--- a/drivers/media/dvb/frontends/l64781.h
+++ b/drivers/media/dvb/frontends/l64781.h
@@ -29,10 +29,6 @@ struct l64781_config
29{ 29{
30 /* the demodulator's i2c address */ 30 /* the demodulator's i2c address */
31 u8 demod_address; 31 u8 demod_address;
32
33 /* PLL maintenance */
34 int (*pll_init)(struct dvb_frontend* fe);
35 int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
36}; 32};
37 33
38 34
diff --git a/drivers/media/dvb/frontends/lg_h06xf.h b/drivers/media/dvb/frontends/lg_h06xf.h
new file mode 100644
index 000000000000..754d51d11120
--- /dev/null
+++ b/drivers/media/dvb/frontends/lg_h06xf.h
@@ -0,0 +1,64 @@
1/*
2 * lg_h06xf.h - ATSC Tuner support for LG TDVS-H06xF
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 */
18
19#ifndef _LG_H06XF_H_
20#define _LG_H06XF_H_
21#include "dvb-pll.h"
22
23static int lg_h06xf_pll_set(struct dvb_frontend* fe, struct i2c_adapter* i2c_adap,
24 struct dvb_frontend_parameters* params)
25{
26 u8 buf[4];
27 struct i2c_msg msg = { .addr = 0x61, .flags = 0,
28 .buf = buf, .len = sizeof(buf) };
29 int err;
30
31 dvb_pll_configure(&dvb_pll_lg_tdvs_h06xf, buf, params->frequency, 0);
32 if (fe->ops.i2c_gate_ctrl)
33 fe->ops.i2c_gate_ctrl(fe, 1);
34 if ((err = i2c_transfer(i2c_adap, &msg, 1)) != 1) {
35 printk(KERN_WARNING "lg_h06xf: %s error "
36 "(addr %02x <- %02x, err = %i)\n",
37 __FUNCTION__, buf[0], buf[1], err);
38 if (err < 0)
39 return err;
40 else
41 return -EREMOTEIO;
42 }
43
44 /* Set the Auxiliary Byte. */
45 buf[0] = buf[2];
46 buf[0] &= ~0x20;
47 buf[0] |= 0x18;
48 buf[1] = 0x50;
49 msg.len = 2;
50 if (fe->ops.i2c_gate_ctrl)
51 fe->ops.i2c_gate_ctrl(fe, 1);
52 if ((err = i2c_transfer(i2c_adap, &msg, 1)) != 1) {
53 printk(KERN_WARNING "lg_h06xf: %s error "
54 "(addr %02x <- %02x, err = %i)\n",
55 __FUNCTION__, buf[0], buf[1], err);
56 if (err < 0)
57 return err;
58 else
59 return -EREMOTEIO;
60 }
61
62 return 0;
63}
64#endif
diff --git a/drivers/media/dvb/frontends/lgdt330x.c b/drivers/media/dvb/frontends/lgdt330x.c
index 4691ac54bc1d..6e8ad176e1a1 100644
--- a/drivers/media/dvb/frontends/lgdt330x.c
+++ b/drivers/media/dvb/frontends/lgdt330x.c
@@ -29,6 +29,7 @@
29 * DViCO FusionHDTV 5 Lite 29 * DViCO FusionHDTV 5 Lite
30 * DViCO FusionHDTV 5 USB Gold 30 * DViCO FusionHDTV 5 USB Gold
31 * Air2PC/AirStar 2 ATSC 3rd generation (HD5000) 31 * Air2PC/AirStar 2 ATSC 3rd generation (HD5000)
32 * pcHDTV HD5500
32 * 33 *
33 * TODO: 34 * TODO:
34 * signal strength always returns 0. 35 * signal strength always returns 0.
@@ -59,7 +60,6 @@ if (debug) printk(KERN_DEBUG "lgdt330x: " args); \
59struct lgdt330x_state 60struct lgdt330x_state
60{ 61{
61 struct i2c_adapter* i2c; 62 struct i2c_adapter* i2c;
62 struct dvb_frontend_ops ops;
63 63
64 /* Configuration settings */ 64 /* Configuration settings */
65 const struct lgdt330x_config* config; 65 const struct lgdt330x_config* config;
@@ -399,8 +399,10 @@ static int lgdt330x_set_parameters(struct dvb_frontend* fe,
399 } 399 }
400 400
401 /* Tune to the specified frequency */ 401 /* Tune to the specified frequency */
402 if (state->config->pll_set) 402 if (fe->ops.tuner_ops.set_params) {
403 state->config->pll_set(fe, param); 403 fe->ops.tuner_ops.set_params(fe, param);
404 if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
405 }
404 406
405 /* Keep track of the new frequency */ 407 /* Keep track of the new frequency */
406 /* FIXME this is the wrong way to do this... */ 408 /* FIXME this is the wrong way to do this... */
@@ -672,6 +674,7 @@ static int lgdt3303_read_snr(struct dvb_frontend* fe, u16* snr)
672 674
673 if (state->current_modulation == VSB_8) { 675 if (state->current_modulation == VSB_8) {
674 676
677 i2c_read_demod_bytes(state, 0x6e, buf, 5);
675 /* Phase Tracker Mean-Square Error Register for VSB */ 678 /* Phase Tracker Mean-Square Error Register for VSB */
676 noise = ((buf[0] & 7) << 16) | (buf[3] << 8) | buf[4]; 679 noise = ((buf[0] & 7) << 16) | (buf[3] << 8) | buf[4];
677 } else { 680 } else {
@@ -721,16 +724,19 @@ struct dvb_frontend* lgdt330x_attach(const struct lgdt330x_config* config,
721 /* Setup the state */ 724 /* Setup the state */
722 state->config = config; 725 state->config = config;
723 state->i2c = i2c; 726 state->i2c = i2c;
727
728 /* Create dvb_frontend */
724 switch (config->demod_chip) { 729 switch (config->demod_chip) {
725 case LGDT3302: 730 case LGDT3302:
726 memcpy(&state->ops, &lgdt3302_ops, sizeof(struct dvb_frontend_ops)); 731 memcpy(&state->frontend.ops, &lgdt3302_ops, sizeof(struct dvb_frontend_ops));
727 break; 732 break;
728 case LGDT3303: 733 case LGDT3303:
729 memcpy(&state->ops, &lgdt3303_ops, sizeof(struct dvb_frontend_ops)); 734 memcpy(&state->frontend.ops, &lgdt3303_ops, sizeof(struct dvb_frontend_ops));
730 break; 735 break;
731 default: 736 default:
732 goto error; 737 goto error;
733 } 738 }
739 state->frontend.demodulator_priv = state;
734 740
735 /* Verify communication with demod chip */ 741 /* Verify communication with demod chip */
736 if (i2c_read_demod_bytes(state, 2, buf, 1)) 742 if (i2c_read_demod_bytes(state, 2, buf, 1))
@@ -739,9 +745,6 @@ struct dvb_frontend* lgdt330x_attach(const struct lgdt330x_config* config,
739 state->current_frequency = -1; 745 state->current_frequency = -1;
740 state->current_modulation = -1; 746 state->current_modulation = -1;
741 747
742 /* Create dvb_frontend */
743 state->frontend.ops = &state->ops;
744 state->frontend.demodulator_priv = state;
745 return &state->frontend; 748 return &state->frontend;
746 749
747error: 750error:
diff --git a/drivers/media/dvb/frontends/lgdt330x.h b/drivers/media/dvb/frontends/lgdt330x.h
index 2a6529cccf1a..bad903c6f0f8 100644
--- a/drivers/media/dvb/frontends/lgdt330x.h
+++ b/drivers/media/dvb/frontends/lgdt330x.h
@@ -43,7 +43,6 @@ struct lgdt330x_config
43 43
44 /* PLL interface */ 44 /* PLL interface */
45 int (*pll_rf_set) (struct dvb_frontend* fe, int index); 45 int (*pll_rf_set) (struct dvb_frontend* fe, int index);
46 int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
47 46
48 /* Need to set device param for start_dma */ 47 /* Need to set device param for start_dma */
49 int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured); 48 int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured);
diff --git a/drivers/media/dvb/frontends/lnbp21.c b/drivers/media/dvb/frontends/lnbp21.c
new file mode 100644
index 000000000000..e933edc8dd29
--- /dev/null
+++ b/drivers/media/dvb/frontends/lnbp21.c
@@ -0,0 +1,145 @@
1/*
2 * lnbp21.h - driver for lnb supply and control ic lnbp21
3 *
4 * Copyright (C) 2006 Oliver Endriss
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
22 *
23 *
24 * the project's page is at http://www.linuxtv.org
25 */
26#include <linux/delay.h>
27#include <linux/errno.h>
28#include <linux/init.h>
29#include <linux/kernel.h>
30#include <linux/module.h>
31#include <linux/moduleparam.h>
32#include <linux/string.h>
33#include <linux/slab.h>
34
35#include "dvb_frontend.h"
36#include "lnbp21.h"
37
38struct lnbp21 {
39 u8 config;
40 u8 override_or;
41 u8 override_and;
42 struct i2c_adapter *i2c;
43 void (*release_chain)(struct dvb_frontend* fe);
44};
45
46static int lnbp21_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
47{
48 struct lnbp21 *lnbp21 = (struct lnbp21 *) fe->misc_priv;
49 struct i2c_msg msg = { .addr = 0x08, .flags = 0,
50 .buf = &lnbp21->config,
51 .len = sizeof(lnbp21->config) };
52
53 lnbp21->config &= ~(LNBP21_VSEL | LNBP21_EN);
54
55 switch(voltage) {
56 case SEC_VOLTAGE_OFF:
57 break;
58 case SEC_VOLTAGE_13:
59 lnbp21->config |= LNBP21_EN;
60 break;
61 case SEC_VOLTAGE_18:
62 lnbp21->config |= (LNBP21_EN | LNBP21_VSEL);
63 break;
64 default:
65 return -EINVAL;
66 };
67
68 lnbp21->config |= lnbp21->override_or;
69 lnbp21->config &= lnbp21->override_and;
70
71 return (i2c_transfer(lnbp21->i2c, &msg, 1) == 1) ? 0 : -EIO;
72}
73
74static int lnbp21_enable_high_lnb_voltage(struct dvb_frontend *fe, long arg)
75{
76 struct lnbp21 *lnbp21 = (struct lnbp21 *) fe->misc_priv;
77 struct i2c_msg msg = { .addr = 0x08, .flags = 0,
78 .buf = &lnbp21->config,
79 .len = sizeof(lnbp21->config) };
80
81 if (arg)
82 lnbp21->config |= LNBP21_LLC;
83 else
84 lnbp21->config &= ~LNBP21_LLC;
85
86 lnbp21->config |= lnbp21->override_or;
87 lnbp21->config &= lnbp21->override_and;
88
89 return (i2c_transfer(lnbp21->i2c, &msg, 1) == 1) ? 0 : -EIO;
90}
91
92static void lnbp21_release(struct dvb_frontend *fe)
93{
94 struct lnbp21 *lnbp21 = (struct lnbp21 *) fe->misc_priv;
95
96 /* LNBP power off */
97 lnbp21_set_voltage(fe, SEC_VOLTAGE_OFF);
98
99 /* free data & call next release routine */
100 fe->ops.release = lnbp21->release_chain;
101 kfree(fe->misc_priv);
102 fe->misc_priv = NULL;
103 if (fe->ops.release)
104 fe->ops.release(fe);
105}
106
107int lnbp21_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 override_set, u8 override_clear)
108{
109 struct lnbp21 *lnbp21 = kmalloc(sizeof(struct lnbp21), GFP_KERNEL);
110 if (!lnbp21)
111 return -ENOMEM;
112
113 /* default configuration */
114 lnbp21->config = LNBP21_ISEL;
115 lnbp21->i2c = i2c;
116 fe->misc_priv = lnbp21;
117
118 /* bits which should be forced to '1' */
119 lnbp21->override_or = override_set;
120
121 /* bits which should be forced to '0' */
122 lnbp21->override_and = ~override_clear;
123
124 /* detect if it is present or not */
125 if (lnbp21_set_voltage(fe, SEC_VOLTAGE_OFF)) {
126 kfree(lnbp21);
127 fe->misc_priv = NULL;
128 return -EIO;
129 }
130
131 /* install release callback */
132 lnbp21->release_chain = fe->ops.release;
133 fe->ops.release = lnbp21_release;
134
135 /* override frontend ops */
136 fe->ops.set_voltage = lnbp21_set_voltage;
137 fe->ops.enable_high_lnb_voltage = lnbp21_enable_high_lnb_voltage;
138
139 return 0;
140}
141EXPORT_SYMBOL(lnbp21_attach);
142
143MODULE_DESCRIPTION("Driver for lnb supply and control ic lnbp21");
144MODULE_AUTHOR("Oliver Endriss");
145MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/lnbp21.h b/drivers/media/dvb/frontends/lnbp21.h
index 0dcbe61b61b1..047a4ab68c01 100644
--- a/drivers/media/dvb/frontends/lnbp21.h
+++ b/drivers/media/dvb/frontends/lnbp21.h
@@ -27,7 +27,7 @@
27#ifndef _LNBP21_H 27#ifndef _LNBP21_H
28#define _LNBP21_H 28#define _LNBP21_H
29 29
30/* system register */ 30/* system register bits */
31#define LNBP21_OLF 0x01 31#define LNBP21_OLF 0x01
32#define LNBP21_OTF 0x02 32#define LNBP21_OTF 0x02
33#define LNBP21_EN 0x04 33#define LNBP21_EN 0x04
@@ -37,103 +37,9 @@
37#define LNBP21_ISEL 0x40 37#define LNBP21_ISEL 0x40
38#define LNBP21_PCL 0x80 38#define LNBP21_PCL 0x80
39 39
40struct lnbp21 { 40#include <linux/dvb/frontend.h>
41 u8 config;
42 u8 override_or;
43 u8 override_and;
44 struct i2c_adapter *i2c;
45 void (*release_chain)(struct dvb_frontend* fe);
46};
47 41
48static int lnbp21_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) 42/* override_set and override_clear control which system register bits (above) to always set & clear */
49{ 43extern int lnbp21_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 override_set, u8 override_clear);
50 struct lnbp21 *lnbp21 = (struct lnbp21 *) fe->misc_priv;
51 struct i2c_msg msg = { .addr = 0x08, .flags = 0,
52 .buf = &lnbp21->config,
53 .len = sizeof(lnbp21->config) };
54
55 lnbp21->config &= ~(LNBP21_VSEL | LNBP21_EN);
56
57 switch(voltage) {
58 case SEC_VOLTAGE_OFF:
59 break;
60 case SEC_VOLTAGE_13:
61 lnbp21->config |= LNBP21_EN;
62 break;
63 case SEC_VOLTAGE_18:
64 lnbp21->config |= (LNBP21_EN | LNBP21_VSEL);
65 break;
66 default:
67 return -EINVAL;
68 };
69
70 lnbp21->config |= lnbp21->override_or;
71 lnbp21->config &= lnbp21->override_and;
72
73 return (i2c_transfer(lnbp21->i2c, &msg, 1) == 1) ? 0 : -EIO;
74}
75
76static int lnbp21_enable_high_lnb_voltage(struct dvb_frontend *fe, long arg)
77{
78 struct lnbp21 *lnbp21 = (struct lnbp21 *) fe->misc_priv;
79 struct i2c_msg msg = { .addr = 0x08, .flags = 0,
80 .buf = &lnbp21->config,
81 .len = sizeof(lnbp21->config) };
82
83 if (arg)
84 lnbp21->config |= LNBP21_LLC;
85 else
86 lnbp21->config &= ~LNBP21_LLC;
87
88 lnbp21->config |= lnbp21->override_or;
89 lnbp21->config &= lnbp21->override_and;
90
91 return (i2c_transfer(lnbp21->i2c, &msg, 1) == 1) ? 0 : -EIO;
92}
93
94static void lnbp21_exit(struct dvb_frontend *fe)
95{
96 struct lnbp21 *lnbp21 = (struct lnbp21 *) fe->misc_priv;
97
98 /* LNBP power off */
99 lnbp21_set_voltage(fe, SEC_VOLTAGE_OFF);
100
101 /* free data & call next release routine */
102 fe->ops->release = lnbp21->release_chain;
103 kfree(fe->misc_priv);
104 fe->misc_priv = NULL;
105 if (fe->ops->release)
106 fe->ops->release(fe);
107}
108
109static int lnbp21_init(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 override_set, u8 override_clear)
110{
111 struct lnbp21 *lnbp21 = kmalloc(sizeof(struct lnbp21), GFP_KERNEL);
112
113 if (!lnbp21)
114 return -ENOMEM;
115
116 /* default configuration */
117 lnbp21->config = LNBP21_ISEL;
118
119 /* bits which should be forced to '1' */
120 lnbp21->override_or = override_set;
121
122 /* bits which should be forced to '0' */
123 lnbp21->override_and = ~override_clear;
124
125 /* install release callback */
126 lnbp21->release_chain = fe->ops->release;
127 fe->ops->release = lnbp21_exit;
128
129 /* override frontend ops */
130 fe->ops->set_voltage = lnbp21_set_voltage;
131 fe->ops->enable_high_lnb_voltage = lnbp21_enable_high_lnb_voltage;
132
133 lnbp21->i2c = i2c;
134 fe->misc_priv = lnbp21;
135
136 return lnbp21_set_voltage(fe, SEC_VOLTAGE_OFF);
137}
138 44
139#endif 45#endif
diff --git a/drivers/media/dvb/frontends/mt312.c b/drivers/media/dvb/frontends/mt312.c
index d3aea83cf218..1ef821825641 100644
--- a/drivers/media/dvb/frontends/mt312.c
+++ b/drivers/media/dvb/frontends/mt312.c
@@ -39,7 +39,6 @@
39 39
40struct mt312_state { 40struct mt312_state {
41 struct i2c_adapter* i2c; 41 struct i2c_adapter* i2c;
42 struct dvb_frontend_ops ops;
43 /* configuration settings */ 42 /* configuration settings */
44 const struct mt312_config* config; 43 const struct mt312_config* config;
45 struct dvb_frontend frontend; 44 struct dvb_frontend frontend;
@@ -277,12 +276,6 @@ static int mt312_initfe(struct dvb_frontend* fe)
277 if ((ret = mt312_writereg(state, CS_SW_LIM, 0x69)) < 0) 276 if ((ret = mt312_writereg(state, CS_SW_LIM, 0x69)) < 0)
278 return ret; 277 return ret;
279 278
280 if (state->config->pll_init) {
281 mt312_writereg(state, GPP_CTRL, 0x40);
282 state->config->pll_init(fe);
283 mt312_writereg(state, GPP_CTRL, 0x00);
284 }
285
286 return 0; 279 return 0;
287} 280}
288 281
@@ -477,16 +470,16 @@ static int mt312_set_frontend(struct dvb_frontend* fe,
477 470
478 dprintk("%s: Freq %d\n", __FUNCTION__, p->frequency); 471 dprintk("%s: Freq %d\n", __FUNCTION__, p->frequency);
479 472
480 if ((p->frequency < fe->ops->info.frequency_min) 473 if ((p->frequency < fe->ops.info.frequency_min)
481 || (p->frequency > fe->ops->info.frequency_max)) 474 || (p->frequency > fe->ops.info.frequency_max))
482 return -EINVAL; 475 return -EINVAL;
483 476
484 if ((p->inversion < INVERSION_OFF) 477 if ((p->inversion < INVERSION_OFF)
485 || (p->inversion > INVERSION_ON)) 478 || (p->inversion > INVERSION_ON))
486 return -EINVAL; 479 return -EINVAL;
487 480
488 if ((p->u.qpsk.symbol_rate < fe->ops->info.symbol_rate_min) 481 if ((p->u.qpsk.symbol_rate < fe->ops.info.symbol_rate_min)
489 || (p->u.qpsk.symbol_rate > fe->ops->info.symbol_rate_max)) 482 || (p->u.qpsk.symbol_rate > fe->ops.info.symbol_rate_max))
490 return -EINVAL; 483 return -EINVAL;
491 484
492 if ((p->u.qpsk.fec_inner < FEC_NONE) 485 if ((p->u.qpsk.fec_inner < FEC_NONE)
@@ -529,9 +522,10 @@ static int mt312_set_frontend(struct dvb_frontend* fe,
529 return -EINVAL; 522 return -EINVAL;
530 } 523 }
531 524
532 mt312_writereg(state, GPP_CTRL, 0x40); 525 if (fe->ops.tuner_ops.set_params) {
533 state->config->pll_set(fe, p); 526 fe->ops.tuner_ops.set_params(fe, p);
534 mt312_writereg(state, GPP_CTRL, 0x00); 527 if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
528 }
535 529
536 /* sr = (u16)(sr * 256.0 / 1000000.0) */ 530 /* sr = (u16)(sr * 256.0 / 1000000.0) */
537 sr = mt312_div(p->u.qpsk.symbol_rate * 4, 15625); 531 sr = mt312_div(p->u.qpsk.symbol_rate * 4, 15625);
@@ -578,6 +572,17 @@ static int mt312_get_frontend(struct dvb_frontend* fe,
578 return 0; 572 return 0;
579} 573}
580 574
575static int mt312_i2c_gate_ctrl(struct dvb_frontend* fe, int enable)
576{
577 struct mt312_state* state = fe->demodulator_priv;
578
579 if (enable) {
580 return mt312_writereg(state, GPP_CTRL, 0x40);
581 } else {
582 return mt312_writereg(state, GPP_CTRL, 0x00);
583 }
584}
585
581static int mt312_sleep(struct dvb_frontend* fe) 586static int mt312_sleep(struct dvb_frontend* fe)
582{ 587{
583 struct mt312_state *state = fe->demodulator_priv; 588 struct mt312_state *state = fe->demodulator_priv;
@@ -633,6 +638,7 @@ static struct dvb_frontend_ops vp310_mt312_ops = {
633 638
634 .init = mt312_initfe, 639 .init = mt312_initfe,
635 .sleep = mt312_sleep, 640 .sleep = mt312_sleep,
641 .i2c_gate_ctrl = mt312_i2c_gate_ctrl,
636 642
637 .set_frontend = mt312_set_frontend, 643 .set_frontend = mt312_set_frontend,
638 .get_frontend = mt312_get_frontend, 644 .get_frontend = mt312_get_frontend,
@@ -663,19 +669,22 @@ struct dvb_frontend* vp310_mt312_attach(const struct mt312_config* config,
663 /* setup the state */ 669 /* setup the state */
664 state->config = config; 670 state->config = config;
665 state->i2c = i2c; 671 state->i2c = i2c;
666 memcpy(&state->ops, &vp310_mt312_ops, sizeof(struct dvb_frontend_ops));
667 672
668 /* check if the demod is there */ 673 /* check if the demod is there */
669 if (mt312_readreg(state, ID, &state->id) < 0) 674 if (mt312_readreg(state, ID, &state->id) < 0)
670 goto error; 675 goto error;
671 676
677 /* create dvb_frontend */
678 memcpy(&state->frontend.ops, &vp310_mt312_ops, sizeof(struct dvb_frontend_ops));
679 state->frontend.demodulator_priv = state;
680
672 switch (state->id) { 681 switch (state->id) {
673 case ID_VP310: 682 case ID_VP310:
674 strcpy(state->ops.info.name, "Zarlink VP310 DVB-S"); 683 strcpy(state->frontend.ops.info.name, "Zarlink VP310 DVB-S");
675 state->frequency = 90; 684 state->frequency = 90;
676 break; 685 break;
677 case ID_MT312: 686 case ID_MT312:
678 strcpy(state->ops.info.name, "Zarlink MT312 DVB-S"); 687 strcpy(state->frontend.ops.info.name, "Zarlink MT312 DVB-S");
679 state->frequency = 60; 688 state->frequency = 60;
680 break; 689 break;
681 default: 690 default:
@@ -683,9 +692,6 @@ struct dvb_frontend* vp310_mt312_attach(const struct mt312_config* config,
683 goto error; 692 goto error;
684 } 693 }
685 694
686 /* create dvb_frontend */
687 state->frontend.ops = &state->ops;
688 state->frontend.demodulator_priv = state;
689 return &state->frontend; 695 return &state->frontend;
690 696
691error: 697error:
diff --git a/drivers/media/dvb/frontends/mt312.h b/drivers/media/dvb/frontends/mt312.h
index 074d844f0139..666a1bd1c244 100644
--- a/drivers/media/dvb/frontends/mt312.h
+++ b/drivers/media/dvb/frontends/mt312.h
@@ -32,10 +32,6 @@ struct mt312_config
32{ 32{
33 /* the demodulator's i2c address */ 33 /* the demodulator's i2c address */
34 u8 demod_address; 34 u8 demod_address;
35
36 /* PLL maintenance */
37 int (*pll_init)(struct dvb_frontend* fe);
38 int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
39}; 35};
40 36
41struct dvb_frontend* vp310_mt312_attach(const struct mt312_config* config, 37struct dvb_frontend* vp310_mt312_attach(const struct mt312_config* config,
diff --git a/drivers/media/dvb/frontends/mt352.c b/drivers/media/dvb/frontends/mt352.c
index aaaec909ddf8..5de7376c94ce 100644
--- a/drivers/media/dvb/frontends/mt352.c
+++ b/drivers/media/dvb/frontends/mt352.c
@@ -45,7 +45,6 @@
45struct mt352_state { 45struct mt352_state {
46 struct i2c_adapter* i2c; 46 struct i2c_adapter* i2c;
47 struct dvb_frontend frontend; 47 struct dvb_frontend frontend;
48 struct dvb_frontend_ops ops;
49 48
50 /* configuration settings */ 49 /* configuration settings */
51 struct mt352_config config; 50 struct mt352_config config;
@@ -286,16 +285,25 @@ static int mt352_set_parameters(struct dvb_frontend* fe,
286 285
287 mt352_calc_nominal_rate(state, op->bandwidth, buf+4); 286 mt352_calc_nominal_rate(state, op->bandwidth, buf+4);
288 mt352_calc_input_freq(state, buf+6); 287 mt352_calc_input_freq(state, buf+6);
289 state->config.pll_set(fe, param, buf+8);
290 288
291 mt352_write(fe, buf, sizeof(buf));
292 if (state->config.no_tuner) { 289 if (state->config.no_tuner) {
293 /* start decoding */ 290 if (fe->ops.tuner_ops.set_params) {
291 fe->ops.tuner_ops.set_params(fe, param);
292 if (fe->ops.i2c_gate_ctrl)
293 fe->ops.i2c_gate_ctrl(fe, 0);
294 }
295
296 mt352_write(fe, buf, 8);
294 mt352_write(fe, fsm_go, 2); 297 mt352_write(fe, fsm_go, 2);
295 } else { 298 } else {
296 /* start tuning */ 299 if (fe->ops.tuner_ops.calc_regs) {
297 mt352_write(fe, tuner_go, 2); 300 fe->ops.tuner_ops.calc_regs(fe, param, buf+8, 5);
301 buf[8] <<= 1;
302 mt352_write(fe, buf, sizeof(buf));
303 mt352_write(fe, tuner_go, 2);
304 }
298 } 305 }
306
299 return 0; 307 return 0;
300} 308}
301 309
@@ -541,13 +549,12 @@ struct dvb_frontend* mt352_attach(const struct mt352_config* config,
541 /* setup the state */ 549 /* setup the state */
542 state->i2c = i2c; 550 state->i2c = i2c;
543 memcpy(&state->config,config,sizeof(struct mt352_config)); 551 memcpy(&state->config,config,sizeof(struct mt352_config));
544 memcpy(&state->ops, &mt352_ops, sizeof(struct dvb_frontend_ops));
545 552
546 /* check if the demod is there */ 553 /* check if the demod is there */
547 if (mt352_read_register(state, CHIP_ID) != ID_MT352) goto error; 554 if (mt352_read_register(state, CHIP_ID) != ID_MT352) goto error;
548 555
549 /* create dvb_frontend */ 556 /* create dvb_frontend */
550 state->frontend.ops = &state->ops; 557 memcpy(&state->frontend.ops, &mt352_ops, sizeof(struct dvb_frontend_ops));
551 state->frontend.demodulator_priv = state; 558 state->frontend.demodulator_priv = state;
552 return &state->frontend; 559 return &state->frontend;
553 560
diff --git a/drivers/media/dvb/frontends/mt352.h b/drivers/media/dvb/frontends/mt352.h
index 03040cd595bb..9e7ff4b8fe5f 100644
--- a/drivers/media/dvb/frontends/mt352.h
+++ b/drivers/media/dvb/frontends/mt352.h
@@ -49,12 +49,6 @@ struct mt352_config
49 49
50 /* Initialise the demodulator and PLL. Cannot be NULL */ 50 /* Initialise the demodulator and PLL. Cannot be NULL */
51 int (*demod_init)(struct dvb_frontend* fe); 51 int (*demod_init)(struct dvb_frontend* fe);
52
53 /* PLL setup - fill out the supplied 5 byte buffer with your PLL settings.
54 * byte0: Set to pll i2c address (nonlinux; left shifted by 1)
55 * byte1-4: PLL configuration.
56 */
57 int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params, u8* pllbuf);
58}; 52};
59 53
60extern struct dvb_frontend* mt352_attach(const struct mt352_config* config, 54extern struct dvb_frontend* mt352_attach(const struct mt352_config* config,
diff --git a/drivers/media/dvb/frontends/nxt200x.c b/drivers/media/dvb/frontends/nxt200x.c
index 9e3535394509..55671cb5255e 100644
--- a/drivers/media/dvb/frontends/nxt200x.c
+++ b/drivers/media/dvb/frontends/nxt200x.c
@@ -55,7 +55,6 @@
55struct nxt200x_state { 55struct nxt200x_state {
56 56
57 struct i2c_adapter* i2c; 57 struct i2c_adapter* i2c;
58 struct dvb_frontend_ops ops;
59 const struct nxt200x_config* config; 58 const struct nxt200x_config* config;
60 struct dvb_frontend frontend; 59 struct dvb_frontend frontend;
61 60
@@ -333,17 +332,17 @@ static int nxt200x_writetuner (struct nxt200x_state* state, u8* data)
333 332
334 dprintk("%s\n", __FUNCTION__); 333 dprintk("%s\n", __FUNCTION__);
335 334
336 dprintk("Tuner Bytes: %02X %02X %02X %02X\n", data[0], data[1], data[2], data[3]); 335 dprintk("Tuner Bytes: %02X %02X %02X %02X\n", data[1], data[2], data[3], data[4]);
337 336
338 /* if NXT2004, write directly to tuner. if NXT2002, write through NXT chip. 337 /* if NXT2004, write directly to tuner. if NXT2002, write through NXT chip.
339 * direct write is required for Philips TUV1236D and ALPS TDHU2 */ 338 * direct write is required for Philips TUV1236D and ALPS TDHU2 */
340 switch (state->demod_chip) { 339 switch (state->demod_chip) {
341 case NXT2004: 340 case NXT2004:
342 if (i2c_writebytes(state, state->config->pll_address, data, 4)) 341 if (i2c_writebytes(state, data[0], data+1, 4))
343 printk(KERN_WARNING "nxt200x: error writing to tuner\n"); 342 printk(KERN_WARNING "nxt200x: error writing to tuner\n");
344 /* wait until we have a lock */ 343 /* wait until we have a lock */
345 while (count < 20) { 344 while (count < 20) {
346 i2c_readbytes(state, state->config->pll_address, &buf, 1); 345 i2c_readbytes(state, data[0], &buf, 1);
347 if (buf & 0x40) 346 if (buf & 0x40)
348 return 0; 347 return 0;
349 msleep(100); 348 msleep(100);
@@ -361,10 +360,10 @@ static int nxt200x_writetuner (struct nxt200x_state* state, u8* data)
361 nxt200x_writebytes(state, 0x34, &buf, 1); 360 nxt200x_writebytes(state, 0x34, &buf, 1);
362 361
363 /* write actual tuner bytes */ 362 /* write actual tuner bytes */
364 nxt200x_writebytes(state, 0x36, data, 4); 363 nxt200x_writebytes(state, 0x36, data+1, 4);
365 364
366 /* set tuner i2c address */ 365 /* set tuner i2c address */
367 buf = state->config->pll_address; 366 buf = data[0] << 1;
368 nxt200x_writebytes(state, 0x35, &buf, 1); 367 nxt200x_writebytes(state, 0x35, &buf, 1);
369 368
370 /* write UC Opmode to begin transfer */ 369 /* write UC Opmode to begin transfer */
@@ -534,7 +533,7 @@ static int nxt200x_setup_frontend_parameters (struct dvb_frontend* fe,
534 struct dvb_frontend_parameters *p) 533 struct dvb_frontend_parameters *p)
535{ 534{
536 struct nxt200x_state* state = fe->demodulator_priv; 535 struct nxt200x_state* state = fe->demodulator_priv;
537 u8 buf[4]; 536 u8 buf[5];
538 537
539 /* stop the micro first */ 538 /* stop the micro first */
540 nxt200x_microcontroller_stop(state); 539 nxt200x_microcontroller_stop(state);
@@ -548,7 +547,9 @@ static int nxt200x_setup_frontend_parameters (struct dvb_frontend* fe,
548 } 547 }
549 548
550 /* get tuning information */ 549 /* get tuning information */
551 dvb_pll_configure(state->config->pll_desc, buf, p->frequency, 0); 550 if (fe->ops.tuner_ops.calc_regs) {
551 fe->ops.tuner_ops.calc_regs(fe, p, buf, 5);
552 }
552 553
553 /* set additional params */ 554 /* set additional params */
554 switch (p->u.vsb.modulation) { 555 switch (p->u.vsb.modulation) {
@@ -1159,7 +1160,6 @@ struct dvb_frontend* nxt200x_attach(const struct nxt200x_config* config,
1159 /* setup the state */ 1160 /* setup the state */
1160 state->config = config; 1161 state->config = config;
1161 state->i2c = i2c; 1162 state->i2c = i2c;
1162 memcpy(&state->ops, &nxt200x_ops, sizeof(struct dvb_frontend_ops));
1163 state->initialised = 0; 1163 state->initialised = 0;
1164 1164
1165 /* read card id */ 1165 /* read card id */
@@ -1198,7 +1198,7 @@ struct dvb_frontend* nxt200x_attach(const struct nxt200x_config* config,
1198 } 1198 }
1199 1199
1200 /* create dvb_frontend */ 1200 /* create dvb_frontend */
1201 state->frontend.ops = &state->ops; 1201 memcpy(&state->frontend.ops, &nxt200x_ops, sizeof(struct dvb_frontend_ops));
1202 state->frontend.demodulator_priv = state; 1202 state->frontend.demodulator_priv = state;
1203 return &state->frontend; 1203 return &state->frontend;
1204 1204
diff --git a/drivers/media/dvb/frontends/nxt200x.h b/drivers/media/dvb/frontends/nxt200x.h
index 1d9d70bc37ef..34d61735845b 100644
--- a/drivers/media/dvb/frontends/nxt200x.h
+++ b/drivers/media/dvb/frontends/nxt200x.h
@@ -38,10 +38,6 @@ struct nxt200x_config
38 /* the demodulator's i2c address */ 38 /* the demodulator's i2c address */
39 u8 demod_address; 39 u8 demod_address;
40 40
41 /* tuner information */
42 u8 pll_address;
43 struct dvb_pll_desc *pll_desc;
44
45 /* used to set pll input */ 41 /* used to set pll input */
46 int (*set_pll_input)(u8* buf, int input); 42 int (*set_pll_input)(u8* buf, int input);
47 43
diff --git a/drivers/media/dvb/frontends/nxt6000.c b/drivers/media/dvb/frontends/nxt6000.c
index a16eeba0020d..d313d7dcf386 100644
--- a/drivers/media/dvb/frontends/nxt6000.c
+++ b/drivers/media/dvb/frontends/nxt6000.c
@@ -33,7 +33,6 @@
33 33
34struct nxt6000_state { 34struct nxt6000_state {
35 struct i2c_adapter* i2c; 35 struct i2c_adapter* i2c;
36 struct dvb_frontend_ops ops;
37 /* configuration settings */ 36 /* configuration settings */
38 const struct nxt6000_config* config; 37 const struct nxt6000_config* config;
39 struct dvb_frontend frontend; 38 struct dvb_frontend frontend;
@@ -207,12 +206,6 @@ static void nxt6000_setup(struct dvb_frontend* fe)
207 nxt6000_writereg(state, SUB_DIAG_MODE_SEL, 0); 206 nxt6000_writereg(state, SUB_DIAG_MODE_SEL, 0);
208 207
209 nxt6000_writereg(state, TS_FORMAT, 0); 208 nxt6000_writereg(state, TS_FORMAT, 0);
210
211 if (state->config->pll_init) {
212 nxt6000_writereg(state, ENABLE_TUNER_IIC, 0x01); /* open i2c bus switch */
213 state->config->pll_init(fe);
214 nxt6000_writereg(state, ENABLE_TUNER_IIC, 0x00); /* close i2c bus switch */
215 }
216} 209}
217 210
218static void nxt6000_dump_status(struct nxt6000_state *state) 211static void nxt6000_dump_status(struct nxt6000_state *state)
@@ -469,9 +462,10 @@ static int nxt6000_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_par
469 struct nxt6000_state* state = fe->demodulator_priv; 462 struct nxt6000_state* state = fe->demodulator_priv;
470 int result; 463 int result;
471 464
472 nxt6000_writereg(state, ENABLE_TUNER_IIC, 0x01); /* open i2c bus switch */ 465 if (fe->ops.tuner_ops.set_params) {
473 state->config->pll_set(fe, param); 466 fe->ops.tuner_ops.set_params(fe, param);
474 nxt6000_writereg(state, ENABLE_TUNER_IIC, 0x00); /* close i2c bus switch */ 467 if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
468 }
475 469
476 if ((result = nxt6000_set_bandwidth(state, param->u.ofdm.bandwidth)) < 0) 470 if ((result = nxt6000_set_bandwidth(state, param->u.ofdm.bandwidth)) < 0)
477 return result; 471 return result;
@@ -532,6 +526,17 @@ static int nxt6000_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_fron
532 return 0; 526 return 0;
533} 527}
534 528
529static int nxt6000_i2c_gate_ctrl(struct dvb_frontend* fe, int enable)
530{
531 struct nxt6000_state* state = fe->demodulator_priv;
532
533 if (enable) {
534 return nxt6000_writereg(state, ENABLE_TUNER_IIC, 0x01);
535 } else {
536 return nxt6000_writereg(state, ENABLE_TUNER_IIC, 0x00);
537 }
538}
539
535static struct dvb_frontend_ops nxt6000_ops; 540static struct dvb_frontend_ops nxt6000_ops;
536 541
537struct dvb_frontend* nxt6000_attach(const struct nxt6000_config* config, 542struct dvb_frontend* nxt6000_attach(const struct nxt6000_config* config,
@@ -546,13 +551,12 @@ struct dvb_frontend* nxt6000_attach(const struct nxt6000_config* config,
546 /* setup the state */ 551 /* setup the state */
547 state->config = config; 552 state->config = config;
548 state->i2c = i2c; 553 state->i2c = i2c;
549 memcpy(&state->ops, &nxt6000_ops, sizeof(struct dvb_frontend_ops));
550 554
551 /* check if the demod is there */ 555 /* check if the demod is there */
552 if (nxt6000_readreg(state, OFDM_MSC_REV) != NXT6000ASICDEVICE) goto error; 556 if (nxt6000_readreg(state, OFDM_MSC_REV) != NXT6000ASICDEVICE) goto error;
553 557
554 /* create dvb_frontend */ 558 /* create dvb_frontend */
555 state->frontend.ops = &state->ops; 559 memcpy(&state->frontend.ops, &nxt6000_ops, sizeof(struct dvb_frontend_ops));
556 state->frontend.demodulator_priv = state; 560 state->frontend.demodulator_priv = state;
557 return &state->frontend; 561 return &state->frontend;
558 562
@@ -584,6 +588,7 @@ static struct dvb_frontend_ops nxt6000_ops = {
584 .release = nxt6000_release, 588 .release = nxt6000_release,
585 589
586 .init = nxt6000_init, 590 .init = nxt6000_init,
591 .i2c_gate_ctrl = nxt6000_i2c_gate_ctrl,
587 592
588 .get_tune_settings = nxt6000_fe_get_tune_settings, 593 .get_tune_settings = nxt6000_fe_get_tune_settings,
589 594
diff --git a/drivers/media/dvb/frontends/nxt6000.h b/drivers/media/dvb/frontends/nxt6000.h
index b7d9bead3002..117031d11708 100644
--- a/drivers/media/dvb/frontends/nxt6000.h
+++ b/drivers/media/dvb/frontends/nxt6000.h
@@ -31,10 +31,6 @@ struct nxt6000_config
31 31
32 /* should clock inversion be used? */ 32 /* should clock inversion be used? */
33 u8 clock_inversion:1; 33 u8 clock_inversion:1;
34
35 /* PLL maintenance */
36 int (*pll_init)(struct dvb_frontend* fe);
37 int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
38}; 34};
39 35
40extern struct dvb_frontend* nxt6000_attach(const struct nxt6000_config* config, 36extern struct dvb_frontend* nxt6000_attach(const struct nxt6000_config* config,
diff --git a/drivers/media/dvb/frontends/or51132.c b/drivers/media/dvb/frontends/or51132.c
index 80e0f28127b7..d20ab30c1e83 100644
--- a/drivers/media/dvb/frontends/or51132.c
+++ b/drivers/media/dvb/frontends/or51132.c
@@ -54,7 +54,6 @@ static int debug;
54struct or51132_state 54struct or51132_state
55{ 55{
56 struct i2c_adapter* i2c; 56 struct i2c_adapter* i2c;
57 struct dvb_frontend_ops ops;
58 57
59 /* Configuration settings */ 58 /* Configuration settings */
60 const struct or51132_config* config; 59 const struct or51132_config* config;
@@ -106,9 +105,8 @@ static int or51132_load_firmware (struct dvb_frontend* fe, const struct firmware
106{ 105{
107 struct or51132_state* state = fe->demodulator_priv; 106 struct or51132_state* state = fe->demodulator_priv;
108 static u8 run_buf[] = {0x7F,0x01}; 107 static u8 run_buf[] = {0x7F,0x01};
109 static u8 get_ver_buf[] = {0x04,0x00,0x30,0x00,0x00}; 108 u8 rec_buf[8];
110 u8 rec_buf[14]; 109 u8 cmd_buf[3];
111 u8 cmd_buf[14];
112 u32 firmwareAsize, firmwareBsize; 110 u32 firmwareAsize, firmwareBsize;
113 int i,ret; 111 int i,ret;
114 112
@@ -157,7 +155,6 @@ static int or51132_load_firmware (struct dvb_frontend* fe, const struct firmware
157 cmd_buf[0] = 0x10; 155 cmd_buf[0] = 0x10;
158 cmd_buf[1] = 0x10; 156 cmd_buf[1] = 0x10;
159 cmd_buf[2] = 0x00; 157 cmd_buf[2] = 0x00;
160 cmd_buf[3] = 0x00;
161 msleep(20); /* 20ms */ 158 msleep(20); /* 20ms */
162 if ((ret = i2c_writebytes(state,state->config->demod_address, 159 if ((ret = i2c_writebytes(state,state->config->demod_address,
163 cmd_buf,3))) { 160 cmd_buf,3))) {
@@ -167,8 +164,6 @@ static int or51132_load_firmware (struct dvb_frontend* fe, const struct firmware
167 164
168 cmd_buf[0] = 0x04; 165 cmd_buf[0] = 0x04;
169 cmd_buf[1] = 0x17; 166 cmd_buf[1] = 0x17;
170 cmd_buf[2] = 0x00;
171 cmd_buf[3] = 0x00;
172 msleep(20); /* 20ms */ 167 msleep(20); /* 20ms */
173 if ((ret = i2c_writebytes(state,state->config->demod_address, 168 if ((ret = i2c_writebytes(state,state->config->demod_address,
174 cmd_buf,2))) { 169 cmd_buf,2))) {
@@ -178,8 +173,6 @@ static int or51132_load_firmware (struct dvb_frontend* fe, const struct firmware
178 173
179 cmd_buf[0] = 0x00; 174 cmd_buf[0] = 0x00;
180 cmd_buf[1] = 0x00; 175 cmd_buf[1] = 0x00;
181 cmd_buf[2] = 0x00;
182 cmd_buf[3] = 0x00;
183 msleep(20); /* 20ms */ 176 msleep(20); /* 20ms */
184 if ((ret = i2c_writebytes(state,state->config->demod_address, 177 if ((ret = i2c_writebytes(state,state->config->demod_address,
185 cmd_buf,2))) { 178 cmd_buf,2))) {
@@ -189,7 +182,11 @@ static int or51132_load_firmware (struct dvb_frontend* fe, const struct firmware
189 182
190 for(i=0;i<4;i++) { 183 for(i=0;i<4;i++) {
191 msleep(20); /* 20ms */ 184 msleep(20); /* 20ms */
192 get_ver_buf[4] = i+1; 185 /* Once upon a time, this command might have had something
186 to do with getting the firmware version, but it's
187 not used anymore:
188 {0x04,0x00,0x30,0x00,i+1} */
189 /* Read 8 bytes, two bytes at a time */
193 if ((ret = i2c_readbytes(state,state->config->demod_address, 190 if ((ret = i2c_readbytes(state,state->config->demod_address,
194 &rec_buf[i*2],2))) { 191 &rec_buf[i*2],2))) {
195 printk(KERN_WARNING 192 printk(KERN_WARNING
@@ -208,7 +205,6 @@ static int or51132_load_firmware (struct dvb_frontend* fe, const struct firmware
208 cmd_buf[0] = 0x10; 205 cmd_buf[0] = 0x10;
209 cmd_buf[1] = 0x00; 206 cmd_buf[1] = 0x00;
210 cmd_buf[2] = 0x00; 207 cmd_buf[2] = 0x00;
211 cmd_buf[3] = 0x00;
212 msleep(20); /* 20ms */ 208 msleep(20); /* 20ms */
213 if ((ret = i2c_writebytes(state,state->config->demod_address, 209 if ((ret = i2c_writebytes(state,state->config->demod_address,
214 cmd_buf,3))) { 210 cmd_buf,3))) {
@@ -243,7 +239,7 @@ static int or51132_sleep(struct dvb_frontend* fe)
243static int or51132_setmode(struct dvb_frontend* fe) 239static int or51132_setmode(struct dvb_frontend* fe)
244{ 240{
245 struct or51132_state* state = fe->demodulator_priv; 241 struct or51132_state* state = fe->demodulator_priv;
246 unsigned char cmd_buf[4]; 242 unsigned char cmd_buf[3];
247 243
248 dprintk("setmode %d\n",(int)state->current_modulation); 244 dprintk("setmode %d\n",(int)state->current_modulation);
249 /* set operation mode in Receiver 1 register; */ 245 /* set operation mode in Receiver 1 register; */
@@ -263,7 +259,6 @@ static int or51132_setmode(struct dvb_frontend* fe)
263 default: 259 default:
264 printk("setmode:Modulation set to unsupported value\n"); 260 printk("setmode:Modulation set to unsupported value\n");
265 }; 261 };
266 cmd_buf[3] = 0x00;
267 if (i2c_writebytes(state,state->config->demod_address, 262 if (i2c_writebytes(state,state->config->demod_address,
268 cmd_buf,3)) { 263 cmd_buf,3)) {
269 printk(KERN_WARNING "or51132: set_mode error 1\n"); 264 printk(KERN_WARNING "or51132: set_mode error 1\n");
@@ -301,7 +296,6 @@ static int or51132_setmode(struct dvb_frontend* fe)
301 default: 296 default:
302 printk("setmode: Modulation set to unsupported value\n"); 297 printk("setmode: Modulation set to unsupported value\n");
303 }; 298 };
304 cmd_buf[3] = 0x00;
305 msleep(20); /* 20ms */ 299 msleep(20); /* 20ms */
306 if (i2c_writebytes(state,state->config->demod_address, 300 if (i2c_writebytes(state,state->config->demod_address,
307 cmd_buf,3)) { 301 cmd_buf,3)) {
@@ -313,52 +307,65 @@ static int or51132_setmode(struct dvb_frontend* fe)
313 return 0; 307 return 0;
314} 308}
315 309
310/* Some modulations use the same firmware. This classifies modulations
311 by the firmware they use. */
312#define MOD_FWCLASS_UNKNOWN 0
313#define MOD_FWCLASS_VSB 1
314#define MOD_FWCLASS_QAM 2
315static int modulation_fw_class(fe_modulation_t modulation)
316{
317 switch(modulation) {
318 case VSB_8:
319 return MOD_FWCLASS_VSB;
320 case QAM_AUTO:
321 case QAM_64:
322 case QAM_256:
323 return MOD_FWCLASS_QAM;
324 default:
325 return MOD_FWCLASS_UNKNOWN;
326 }
327}
328
316static int or51132_set_parameters(struct dvb_frontend* fe, 329static int or51132_set_parameters(struct dvb_frontend* fe,
317 struct dvb_frontend_parameters *param) 330 struct dvb_frontend_parameters *param)
318{ 331{
319 int ret; 332 int ret;
320 u8 buf[4];
321 struct or51132_state* state = fe->demodulator_priv; 333 struct or51132_state* state = fe->demodulator_priv;
322 const struct firmware *fw; 334 const struct firmware *fw;
323 335 const char *fwname;
324 /* Change only if we are actually changing the modulation */ 336 int clock_mode;
325 if (state->current_modulation != param->u.vsb.modulation) { 337
326 switch(param->u.vsb.modulation) { 338 /* Upload new firmware only if we need a different one */
327 case VSB_8: 339 if (modulation_fw_class(state->current_modulation) !=
340 modulation_fw_class(param->u.vsb.modulation)) {
341 switch(modulation_fw_class(param->u.vsb.modulation)) {
342 case MOD_FWCLASS_VSB:
328 dprintk("set_parameters VSB MODE\n"); 343 dprintk("set_parameters VSB MODE\n");
329 printk("or51132: Waiting for firmware upload(%s)...\n", 344 fwname = OR51132_VSB_FIRMWARE;
330 OR51132_VSB_FIRMWARE); 345
331 ret = request_firmware(&fw, OR51132_VSB_FIRMWARE,
332 &state->i2c->dev);
333 if (ret){
334 printk(KERN_WARNING "or51132: No firmware up"
335 "loaded(timeout or file not found?)\n");
336 return ret;
337 }
338 /* Set non-punctured clock for VSB */ 346 /* Set non-punctured clock for VSB */
339 state->config->set_ts_params(fe, 0); 347 clock_mode = 0;
340 break; 348 break;
341 case QAM_AUTO: 349 case MOD_FWCLASS_QAM:
342 case QAM_64:
343 case QAM_256:
344 dprintk("set_parameters QAM MODE\n"); 350 dprintk("set_parameters QAM MODE\n");
345 printk("or51132: Waiting for firmware upload(%s)...\n", 351 fwname = OR51132_QAM_FIRMWARE;
346 OR51132_QAM_FIRMWARE); 352
347 ret = request_firmware(&fw, OR51132_QAM_FIRMWARE,
348 &state->i2c->dev);
349 if (ret){
350 printk(KERN_WARNING "or51132: No firmware up"
351 "loaded(timeout or file not found?)\n");
352 return ret;
353 }
354 /* Set punctured clock for QAM */ 353 /* Set punctured clock for QAM */
355 state->config->set_ts_params(fe, 1); 354 clock_mode = 1;
356 break; 355 break;
357 default: 356 default:
358 printk("or51132:Modulation type(%d) UNSUPPORTED\n", 357 printk("or51132: Modulation type(%d) UNSUPPORTED\n",
359 param->u.vsb.modulation); 358 param->u.vsb.modulation);
360 return -1; 359 return -1;
361 }; 360 }
361 printk("or51132: Waiting for firmware upload(%s)...\n",
362 fwname);
363 ret = request_firmware(&fw, fwname, &state->i2c->dev);
364 if (ret) {
365 printk(KERN_WARNING "or51132: No firmware up"
366 "loaded(timeout or file not found?)\n");
367 return ret;
368 }
362 ret = or51132_load_firmware(fe, fw); 369 ret = or51132_load_firmware(fe, fw);
363 release_firmware(fw); 370 release_firmware(fw);
364 if (ret) { 371 if (ret) {
@@ -367,18 +374,18 @@ static int or51132_set_parameters(struct dvb_frontend* fe,
367 return ret; 374 return ret;
368 } 375 }
369 printk("or51132: Firmware upload complete.\n"); 376 printk("or51132: Firmware upload complete.\n");
370 377 state->config->set_ts_params(fe, clock_mode);
378 }
379 /* Change only if we are actually changing the modulation */
380 if (state->current_modulation != param->u.vsb.modulation) {
371 state->current_modulation = param->u.vsb.modulation; 381 state->current_modulation = param->u.vsb.modulation;
372 or51132_setmode(fe); 382 or51132_setmode(fe);
373 } 383 }
374 384
375 dvb_pll_configure(state->config->pll_desc, buf, 385 if (fe->ops.tuner_ops.set_params) {
376 param->frequency, 0); 386 fe->ops.tuner_ops.set_params(fe, param);
377 dprintk("set_parameters tuner bytes: 0x%02x 0x%02x " 387 if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
378 "0x%02x 0x%02x\n",buf[0],buf[1],buf[2],buf[3]); 388 }
379 if (i2c_writebytes(state, state->config->pll_address ,buf, 4))
380 printk(KERN_WARNING "or51132: set_parameters error "
381 "writing to tuner\n");
382 389
383 /* Set to current mode */ 390 /* Set to current mode */
384 or51132_setmode(fe); 391 or51132_setmode(fe);
@@ -388,6 +395,44 @@ static int or51132_set_parameters(struct dvb_frontend* fe,
388 return 0; 395 return 0;
389} 396}
390 397
398static int or51132_get_parameters(struct dvb_frontend* fe,
399 struct dvb_frontend_parameters *param)
400{
401 struct or51132_state* state = fe->demodulator_priv;
402 u8 buf[2];
403
404 /* Receiver Status */
405 buf[0]=0x04;
406 buf[1]=0x00;
407 msleep(30); /* 30ms */
408 if (i2c_writebytes(state,state->config->demod_address,buf,2)) {
409 printk(KERN_WARNING "or51132: get_parameters write error\n");
410 return -EREMOTEIO;
411 }
412 msleep(30); /* 30ms */
413 if (i2c_readbytes(state,state->config->demod_address,buf,2)) {
414 printk(KERN_WARNING "or51132: get_parameters read error\n");
415 return -EREMOTEIO;
416 }
417 switch(buf[0]) {
418 case 0x06: param->u.vsb.modulation = VSB_8; break;
419 case 0x43: param->u.vsb.modulation = QAM_64; break;
420 case 0x45: param->u.vsb.modulation = QAM_256; break;
421 default:
422 printk(KERN_WARNING "or51132: unknown status 0x%02x\n",
423 buf[0]);
424 return -EREMOTEIO;
425 }
426
427 /* FIXME: Read frequency from frontend, take AFC into account */
428 param->frequency = state->current_frequency;
429
430 /* FIXME: How to read inversion setting? Receiver 6 register? */
431 param->inversion = INVERSION_AUTO;
432
433 return 0;
434}
435
391static int or51132_read_status(struct dvb_frontend* fe, fe_status_t* status) 436static int or51132_read_status(struct dvb_frontend* fe, fe_status_t* status)
392{ 437{
393 struct or51132_state* state = fe->demodulator_priv; 438 struct or51132_state* state = fe->demodulator_priv;
@@ -572,12 +617,11 @@ struct dvb_frontend* or51132_attach(const struct or51132_config* config,
572 /* Setup the state */ 617 /* Setup the state */
573 state->config = config; 618 state->config = config;
574 state->i2c = i2c; 619 state->i2c = i2c;
575 memcpy(&state->ops, &or51132_ops, sizeof(struct dvb_frontend_ops));
576 state->current_frequency = -1; 620 state->current_frequency = -1;
577 state->current_modulation = -1; 621 state->current_modulation = -1;
578 622
579 /* Create dvb_frontend */ 623 /* Create dvb_frontend */
580 state->frontend.ops = &state->ops; 624 memcpy(&state->frontend.ops, &or51132_ops, sizeof(struct dvb_frontend_ops));
581 state->frontend.demodulator_priv = state; 625 state->frontend.demodulator_priv = state;
582 return &state->frontend; 626 return &state->frontend;
583 627
@@ -590,7 +634,7 @@ static struct dvb_frontend_ops or51132_ops = {
590 634
591 .info = { 635 .info = {
592 .name = "Oren OR51132 VSB/QAM Frontend", 636 .name = "Oren OR51132 VSB/QAM Frontend",
593 .type = FE_ATSC, 637 .type = FE_ATSC,
594 .frequency_min = 44000000, 638 .frequency_min = 44000000,
595 .frequency_max = 958000000, 639 .frequency_max = 958000000,
596 .frequency_stepsize = 166666, 640 .frequency_stepsize = 166666,
@@ -606,6 +650,7 @@ static struct dvb_frontend_ops or51132_ops = {
606 .sleep = or51132_sleep, 650 .sleep = or51132_sleep,
607 651
608 .set_frontend = or51132_set_parameters, 652 .set_frontend = or51132_set_parameters,
653 .get_frontend = or51132_get_parameters,
609 .get_tune_settings = or51132_get_tune_settings, 654 .get_tune_settings = or51132_get_tune_settings,
610 655
611 .read_status = or51132_read_status, 656 .read_status = or51132_read_status,
diff --git a/drivers/media/dvb/frontends/or51132.h b/drivers/media/dvb/frontends/or51132.h
index 622cdd18381b..89658883abf5 100644
--- a/drivers/media/dvb/frontends/or51132.h
+++ b/drivers/media/dvb/frontends/or51132.h
@@ -29,8 +29,6 @@ struct or51132_config
29{ 29{
30 /* The demodulator's i2c address */ 30 /* The demodulator's i2c address */
31 u8 demod_address; 31 u8 demod_address;
32 u8 pll_address;
33 struct dvb_pll_desc *pll_desc;
34 32
35 /* Need to set device param for start_dma */ 33 /* Need to set device param for start_dma */
36 int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured); 34 int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured);
diff --git a/drivers/media/dvb/frontends/or51211.c b/drivers/media/dvb/frontends/or51211.c
index 7c3aed1f546b..26bed616fabe 100644
--- a/drivers/media/dvb/frontends/or51211.c
+++ b/drivers/media/dvb/frontends/or51211.c
@@ -54,7 +54,6 @@ static u8 cmd_buf[] = {0x04,0x01,0x50,0x80,0x06}; // ATSC
54struct or51211_state { 54struct or51211_state {
55 55
56 struct i2c_adapter* i2c; 56 struct i2c_adapter* i2c;
57 struct dvb_frontend_ops ops;
58 57
59 /* Configuration settings */ 58 /* Configuration settings */
60 const struct or51211_config* config; 59 const struct or51211_config* config;
@@ -585,12 +584,11 @@ struct dvb_frontend* or51211_attach(const struct or51211_config* config,
585 /* Setup the state */ 584 /* Setup the state */
586 state->config = config; 585 state->config = config;
587 state->i2c = i2c; 586 state->i2c = i2c;
588 memcpy(&state->ops, &or51211_ops, sizeof(struct dvb_frontend_ops));
589 state->initialized = 0; 587 state->initialized = 0;
590 state->current_frequency = 0; 588 state->current_frequency = 0;
591 589
592 /* Create dvb_frontend */ 590 /* Create dvb_frontend */
593 state->frontend.ops = &state->ops; 591 memcpy(&state->frontend.ops, &or51211_ops, sizeof(struct dvb_frontend_ops));
594 state->frontend.demodulator_priv = state; 592 state->frontend.demodulator_priv = state;
595 return &state->frontend; 593 return &state->frontend;
596 594
diff --git a/drivers/media/dvb/frontends/s5h1420.c b/drivers/media/dvb/frontends/s5h1420.c
index d69477596921..2c2c344c4c64 100644
--- a/drivers/media/dvb/frontends/s5h1420.c
+++ b/drivers/media/dvb/frontends/s5h1420.c
@@ -38,7 +38,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
38 38
39struct s5h1420_state { 39struct s5h1420_state {
40 struct i2c_adapter* i2c; 40 struct i2c_adapter* i2c;
41 struct dvb_frontend_ops ops;
42 const struct s5h1420_config* config; 41 const struct s5h1420_config* config;
43 struct dvb_frontend frontend; 42 struct dvb_frontend frontend;
44 43
@@ -584,7 +583,6 @@ static int s5h1420_set_frontend(struct dvb_frontend* fe,
584 struct s5h1420_state* state = fe->demodulator_priv; 583 struct s5h1420_state* state = fe->demodulator_priv;
585 int frequency_delta; 584 int frequency_delta;
586 struct dvb_frontend_tune_settings fesettings; 585 struct dvb_frontend_tune_settings fesettings;
587 u32 tmp;
588 586
589 /* check if we should do a fast-tune */ 587 /* check if we should do a fast-tune */
590 memcpy(&fesettings.parameters, p, sizeof(struct dvb_frontend_parameters)); 588 memcpy(&fesettings.parameters, p, sizeof(struct dvb_frontend_parameters));
@@ -596,10 +594,17 @@ static int s5h1420_set_frontend(struct dvb_frontend* fe,
596 (state->fec_inner == p->u.qpsk.fec_inner) && 594 (state->fec_inner == p->u.qpsk.fec_inner) &&
597 (state->symbol_rate == p->u.qpsk.symbol_rate)) { 595 (state->symbol_rate == p->u.qpsk.symbol_rate)) {
598 596
599 if (state->config->pll_set) { 597 if (fe->ops.tuner_ops.set_params) {
600 s5h1420_writereg (state, 0x02, s5h1420_readreg(state,0x02) | 1); 598 fe->ops.tuner_ops.set_params(fe, p);
601 state->config->pll_set(fe, p, &tmp); 599 if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
600 }
601 if (fe->ops.tuner_ops.get_frequency) {
602 u32 tmp;
603 fe->ops.tuner_ops.get_frequency(fe, &tmp);
604 if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
602 s5h1420_setfreqoffset(state, p->frequency - tmp); 605 s5h1420_setfreqoffset(state, p->frequency - tmp);
606 } else {
607 s5h1420_setfreqoffset(state, 0);
603 } 608 }
604 return 0; 609 return 0;
605 } 610 }
@@ -646,9 +651,9 @@ static int s5h1420_set_frontend(struct dvb_frontend* fe,
646 s5h1420_writereg(state, 0x05, s5h1420_readreg(state, 0x05) | 1); 651 s5h1420_writereg(state, 0x05, s5h1420_readreg(state, 0x05) | 1);
647 652
648 /* set tuner PLL */ 653 /* set tuner PLL */
649 if (state->config->pll_set) { 654 if (fe->ops.tuner_ops.set_params) {
650 s5h1420_writereg (state, 0x02, s5h1420_readreg(state,0x02) | 1); 655 fe->ops.tuner_ops.set_params(fe, p);
651 state->config->pll_set(fe, p, &tmp); 656 if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
652 s5h1420_setfreqoffset(state, 0); 657 s5h1420_setfreqoffset(state, 0);
653 } 658 }
654 659
@@ -708,6 +713,17 @@ static int s5h1420_get_tune_settings(struct dvb_frontend* fe,
708 return 0; 713 return 0;
709} 714}
710 715
716static int s5h1420_i2c_gate_ctrl(struct dvb_frontend* fe, int enable)
717{
718 struct s5h1420_state* state = fe->demodulator_priv;
719
720 if (enable) {
721 return s5h1420_writereg (state, 0x02, s5h1420_readreg(state,0x02) | 1);
722 } else {
723 return s5h1420_writereg (state, 0x02, s5h1420_readreg(state,0x02) & 0xfe);
724 }
725}
726
711static int s5h1420_init (struct dvb_frontend* fe) 727static int s5h1420_init (struct dvb_frontend* fe)
712{ 728{
713 struct s5h1420_state* state = fe->demodulator_priv; 729 struct s5h1420_state* state = fe->demodulator_priv;
@@ -717,13 +733,6 @@ static int s5h1420_init (struct dvb_frontend* fe)
717 msleep(10); 733 msleep(10);
718 s5h1420_reset(state); 734 s5h1420_reset(state);
719 735
720 /* init PLL */
721 if (state->config->pll_init) {
722 s5h1420_writereg (state, 0x02, s5h1420_readreg(state,0x02) | 1);
723 state->config->pll_init(fe);
724 s5h1420_writereg (state, 0x02, s5h1420_readreg(state,0x02) & 0xfe);
725 }
726
727 return 0; 736 return 0;
728} 737}
729 738
@@ -756,7 +765,6 @@ struct dvb_frontend* s5h1420_attach(const struct s5h1420_config* config,
756 /* setup the state */ 765 /* setup the state */
757 state->config = config; 766 state->config = config;
758 state->i2c = i2c; 767 state->i2c = i2c;
759 memcpy(&state->ops, &s5h1420_ops, sizeof(struct dvb_frontend_ops));
760 state->postlocked = 0; 768 state->postlocked = 0;
761 state->fclk = 88000000; 769 state->fclk = 88000000;
762 state->tunedfreq = 0; 770 state->tunedfreq = 0;
@@ -769,7 +777,7 @@ struct dvb_frontend* s5h1420_attach(const struct s5h1420_config* config,
769 goto error; 777 goto error;
770 778
771 /* create dvb_frontend */ 779 /* create dvb_frontend */
772 state->frontend.ops = &state->ops; 780 memcpy(&state->frontend.ops, &s5h1420_ops, sizeof(struct dvb_frontend_ops));
773 state->frontend.demodulator_priv = state; 781 state->frontend.demodulator_priv = state;
774 return &state->frontend; 782 return &state->frontend;
775 783
@@ -800,6 +808,7 @@ static struct dvb_frontend_ops s5h1420_ops = {
800 808
801 .init = s5h1420_init, 809 .init = s5h1420_init,
802 .sleep = s5h1420_sleep, 810 .sleep = s5h1420_sleep,
811 .i2c_gate_ctrl = s5h1420_i2c_gate_ctrl,
803 812
804 .set_frontend = s5h1420_set_frontend, 813 .set_frontend = s5h1420_set_frontend,
805 .get_frontend = s5h1420_get_frontend, 814 .get_frontend = s5h1420_get_frontend,
diff --git a/drivers/media/dvb/frontends/s5h1420.h b/drivers/media/dvb/frontends/s5h1420.h
index 73296f13c324..4e39015fa67e 100644
--- a/drivers/media/dvb/frontends/s5h1420.h
+++ b/drivers/media/dvb/frontends/s5h1420.h
@@ -32,10 +32,6 @@ struct s5h1420_config
32 32
33 /* does the inversion require inversion? */ 33 /* does the inversion require inversion? */
34 u8 invert:1; 34 u8 invert:1;
35
36 /* PLL maintenance */
37 int (*pll_init)(struct dvb_frontend* fe);
38 int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params, u32* freqout);
39}; 35};
40 36
41extern struct dvb_frontend* s5h1420_attach(const struct s5h1420_config* config, 37extern struct dvb_frontend* s5h1420_attach(const struct s5h1420_config* config,
diff --git a/drivers/media/dvb/frontends/sp8870.c b/drivers/media/dvb/frontends/sp8870.c
index 73829e647e50..44ec5b9a4695 100644
--- a/drivers/media/dvb/frontends/sp8870.c
+++ b/drivers/media/dvb/frontends/sp8870.c
@@ -44,8 +44,6 @@ struct sp8870_state {
44 44
45 struct i2c_adapter* i2c; 45 struct i2c_adapter* i2c;
46 46
47 struct dvb_frontend_ops ops;
48
49 const struct sp8870_config* config; 47 const struct sp8870_config* config;
50 48
51 struct dvb_frontend frontend; 49 struct dvb_frontend frontend;
@@ -262,9 +260,10 @@ static int sp8870_set_frontend_parameters (struct dvb_frontend* fe,
262 sp8870_microcontroller_stop(state); 260 sp8870_microcontroller_stop(state);
263 261
264 // set tuner parameters 262 // set tuner parameters
265 sp8870_writereg(state, 0x206, 0x001); 263 if (fe->ops.tuner_ops.set_params) {
266 state->config->pll_set(fe, p); 264 fe->ops.tuner_ops.set_params(fe, p);
267 sp8870_writereg(state, 0x206, 0x000); 265 if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
266 }
268 267
269 // sample rate correction bit [23..17] 268 // sample rate correction bit [23..17]
270 sp8870_writereg(state, 0x0319, 0x000A); 269 sp8870_writereg(state, 0x0319, 0x000A);
@@ -349,13 +348,6 @@ static int sp8870_init (struct dvb_frontend* fe)
349 sp8870_writereg(state, 0x0D00, 0x010); 348 sp8870_writereg(state, 0x0D00, 0x010);
350 sp8870_writereg(state, 0x0D01, 0x000); 349 sp8870_writereg(state, 0x0D01, 0x000);
351 350
352 /* setup PLL */
353 if (state->config->pll_init) {
354 sp8870_writereg(state, 0x206, 0x001);
355 state->config->pll_init(fe);
356 sp8870_writereg(state, 0x206, 0x000);
357 }
358
359 return 0; 351 return 0;
360} 352}
361 353
@@ -541,6 +533,17 @@ static int sp8870_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend
541 return 0; 533 return 0;
542} 534}
543 535
536static int sp8870_i2c_gate_ctrl(struct dvb_frontend* fe, int enable)
537{
538 struct sp8870_state* state = fe->demodulator_priv;
539
540 if (enable) {
541 return sp8870_writereg(state, 0x206, 0x001);
542 } else {
543 return sp8870_writereg(state, 0x206, 0x000);
544 }
545}
546
544static void sp8870_release(struct dvb_frontend* fe) 547static void sp8870_release(struct dvb_frontend* fe)
545{ 548{
546 struct sp8870_state* state = fe->demodulator_priv; 549 struct sp8870_state* state = fe->demodulator_priv;
@@ -561,14 +564,13 @@ struct dvb_frontend* sp8870_attach(const struct sp8870_config* config,
561 /* setup the state */ 564 /* setup the state */
562 state->config = config; 565 state->config = config;
563 state->i2c = i2c; 566 state->i2c = i2c;
564 memcpy(&state->ops, &sp8870_ops, sizeof(struct dvb_frontend_ops));
565 state->initialised = 0; 567 state->initialised = 0;
566 568
567 /* check if the demod is there */ 569 /* check if the demod is there */
568 if (sp8870_readreg(state, 0x0200) < 0) goto error; 570 if (sp8870_readreg(state, 0x0200) < 0) goto error;
569 571
570 /* create dvb_frontend */ 572 /* create dvb_frontend */
571 state->frontend.ops = &state->ops; 573 memcpy(&state->frontend.ops, &sp8870_ops, sizeof(struct dvb_frontend_ops));
572 state->frontend.demodulator_priv = state; 574 state->frontend.demodulator_priv = state;
573 return &state->frontend; 575 return &state->frontend;
574 576
@@ -597,6 +599,7 @@ static struct dvb_frontend_ops sp8870_ops = {
597 599
598 .init = sp8870_init, 600 .init = sp8870_init,
599 .sleep = sp8870_sleep, 601 .sleep = sp8870_sleep,
602 .i2c_gate_ctrl = sp8870_i2c_gate_ctrl,
600 603
601 .set_frontend = sp8870_set_frontend, 604 .set_frontend = sp8870_set_frontend,
602 .get_tune_settings = sp8870_get_tune_settings, 605 .get_tune_settings = sp8870_get_tune_settings,
diff --git a/drivers/media/dvb/frontends/sp8870.h b/drivers/media/dvb/frontends/sp8870.h
index f3b555dbc960..93afbb969d6b 100644
--- a/drivers/media/dvb/frontends/sp8870.h
+++ b/drivers/media/dvb/frontends/sp8870.h
@@ -31,10 +31,6 @@ struct sp8870_config
31 /* the demodulator's i2c address */ 31 /* the demodulator's i2c address */
32 u8 demod_address; 32 u8 demod_address;
33 33
34 /* PLL maintenance */
35 int (*pll_init)(struct dvb_frontend* fe);
36 int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
37
38 /* request firmware for device */ 34 /* request firmware for device */
39 int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name); 35 int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name);
40}; 36};
diff --git a/drivers/media/dvb/frontends/sp887x.c b/drivers/media/dvb/frontends/sp887x.c
index eb8a602198ca..b0a2b02f6608 100644
--- a/drivers/media/dvb/frontends/sp887x.c
+++ b/drivers/media/dvb/frontends/sp887x.c
@@ -24,7 +24,6 @@
24 24
25struct sp887x_state { 25struct sp887x_state {
26 struct i2c_adapter* i2c; 26 struct i2c_adapter* i2c;
27 struct dvb_frontend_ops ops;
28 const struct sp887x_config* config; 27 const struct sp887x_config* config;
29 struct dvb_frontend frontend; 28 struct dvb_frontend frontend;
30 29
@@ -208,15 +207,6 @@ static int sp887x_initial_setup (struct dvb_frontend* fe, const struct firmware
208 /* bit 0x010: enable data valid signal */ 207 /* bit 0x010: enable data valid signal */
209 sp887x_writereg(state, 0xd00, 0x010); 208 sp887x_writereg(state, 0xd00, 0x010);
210 sp887x_writereg(state, 0x0d1, 0x000); 209 sp887x_writereg(state, 0x0d1, 0x000);
211
212 /* setup the PLL */
213 if (state->config->pll_init) {
214 sp887x_writereg(state, 0x206, 0x001);
215 state->config->pll_init(fe);
216 sp887x_writereg(state, 0x206, 0x000);
217 }
218
219 printk ("done.\n");
220 return 0; 210 return 0;
221}; 211};
222 212
@@ -362,9 +352,16 @@ static int sp887x_setup_frontend_parameters (struct dvb_frontend* fe,
362 sp887x_microcontroller_stop(state); 352 sp887x_microcontroller_stop(state);
363 353
364 /* setup the PLL */ 354 /* setup the PLL */
365 sp887x_writereg(state, 0x206, 0x001); 355 if (fe->ops.tuner_ops.set_params) {
366 actual_freq = state->config->pll_set(fe, p); 356 fe->ops.tuner_ops.set_params(fe, p);
367 sp887x_writereg(state, 0x206, 0x000); 357 if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
358 }
359 if (fe->ops.tuner_ops.get_frequency) {
360 fe->ops.tuner_ops.get_frequency(fe, &actual_freq);
361 if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
362 } else {
363 actual_freq = p->frequency;
364 }
368 365
369 /* read status reg in order to clear <pending irqs */ 366 /* read status reg in order to clear <pending irqs */
370 sp887x_readreg(state, 0x200); 367 sp887x_readreg(state, 0x200);
@@ -486,6 +483,17 @@ static int sp887x_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
486 return 0; 483 return 0;
487} 484}
488 485
486static int sp887x_i2c_gate_ctrl(struct dvb_frontend* fe, int enable)
487{
488 struct sp887x_state* state = fe->demodulator_priv;
489
490 if (enable) {
491 return sp887x_writereg(state, 0x206, 0x001);
492 } else {
493 return sp887x_writereg(state, 0x206, 0x000);
494 }
495}
496
489static int sp887x_sleep(struct dvb_frontend* fe) 497static int sp887x_sleep(struct dvb_frontend* fe)
490{ 498{
491 struct sp887x_state* state = fe->demodulator_priv; 499 struct sp887x_state* state = fe->demodulator_priv;
@@ -555,14 +563,13 @@ struct dvb_frontend* sp887x_attach(const struct sp887x_config* config,
555 /* setup the state */ 563 /* setup the state */
556 state->config = config; 564 state->config = config;
557 state->i2c = i2c; 565 state->i2c = i2c;
558 memcpy(&state->ops, &sp887x_ops, sizeof(struct dvb_frontend_ops));
559 state->initialised = 0; 566 state->initialised = 0;
560 567
561 /* check if the demod is there */ 568 /* check if the demod is there */
562 if (sp887x_readreg(state, 0x0200) < 0) goto error; 569 if (sp887x_readreg(state, 0x0200) < 0) goto error;
563 570
564 /* create dvb_frontend */ 571 /* create dvb_frontend */
565 state->frontend.ops = &state->ops; 572 memcpy(&state->frontend.ops, &sp887x_ops, sizeof(struct dvb_frontend_ops));
566 state->frontend.demodulator_priv = state; 573 state->frontend.demodulator_priv = state;
567 return &state->frontend; 574 return &state->frontend;
568 575
@@ -589,6 +596,7 @@ static struct dvb_frontend_ops sp887x_ops = {
589 596
590 .init = sp887x_init, 597 .init = sp887x_init,
591 .sleep = sp887x_sleep, 598 .sleep = sp887x_sleep,
599 .i2c_gate_ctrl = sp887x_i2c_gate_ctrl,
592 600
593 .set_frontend = sp887x_setup_frontend_parameters, 601 .set_frontend = sp887x_setup_frontend_parameters,
594 .get_tune_settings = sp887x_get_tune_settings, 602 .get_tune_settings = sp887x_get_tune_settings,
diff --git a/drivers/media/dvb/frontends/sp887x.h b/drivers/media/dvb/frontends/sp887x.h
index 6a05d8f8e8cc..c44b0ebdf1e2 100644
--- a/drivers/media/dvb/frontends/sp887x.h
+++ b/drivers/media/dvb/frontends/sp887x.h
@@ -13,12 +13,6 @@ struct sp887x_config
13 /* the demodulator's i2c address */ 13 /* the demodulator's i2c address */
14 u8 demod_address; 14 u8 demod_address;
15 15
16 /* PLL maintenance */
17 int (*pll_init)(struct dvb_frontend* fe);
18
19 /* this should return the actual frequency tuned to */
20 int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
21
22 /* request firmware for device */ 16 /* request firmware for device */
23 int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name); 17 int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name);
24}; 18};
diff --git a/drivers/media/dvb/frontends/stv0297.c b/drivers/media/dvb/frontends/stv0297.c
index eb15676d374f..1ca64249010c 100644
--- a/drivers/media/dvb/frontends/stv0297.c
+++ b/drivers/media/dvb/frontends/stv0297.c
@@ -32,7 +32,6 @@
32 32
33struct stv0297_state { 33struct stv0297_state {
34 struct i2c_adapter *i2c; 34 struct i2c_adapter *i2c;
35 struct dvb_frontend_ops ops;
36 const struct stv0297_config *config; 35 const struct stv0297_config *config;
37 struct dvb_frontend frontend; 36 struct dvb_frontend frontend;
38 37
@@ -68,19 +67,25 @@ static int stv0297_readreg(struct stv0297_state *state, u8 reg)
68 int ret; 67 int ret;
69 u8 b0[] = { reg }; 68 u8 b0[] = { reg };
70 u8 b1[] = { 0 }; 69 u8 b1[] = { 0 };
71 struct i2c_msg msg[] = { {.addr = state->config->demod_address,.flags = 0,.buf = b0,.len = 70 struct i2c_msg msg[] = { {.addr = state->config->demod_address,.flags = 0,.buf = b0,.len = 1},
72 1}, 71 {.addr = state->config->demod_address,.flags = I2C_M_RD,.buf = b1,.len = 1}
73 {.addr = state->config->demod_address,.flags = I2C_M_RD,.buf = b1,.len = 1} 72 };
74 };
75 73
76 // this device needs a STOP between the register and data 74 // this device needs a STOP between the register and data
77 if ((ret = i2c_transfer(state->i2c, &msg[0], 1)) != 1) { 75 if (state->config->stop_during_read) {
78 dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __FUNCTION__, reg, ret); 76 if ((ret = i2c_transfer(state->i2c, &msg[0], 1)) != 1) {
79 return -1; 77 dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __FUNCTION__, reg, ret);
80 } 78 return -1;
81 if ((ret = i2c_transfer(state->i2c, &msg[1], 1)) != 1) { 79 }
82 dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __FUNCTION__, reg, ret); 80 if ((ret = i2c_transfer(state->i2c, &msg[1], 1)) != 1) {
83 return -1; 81 dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __FUNCTION__, reg, ret);
82 return -1;
83 }
84 } else {
85 if ((ret = i2c_transfer(state->i2c, msg, 2)) != 2) {
86 dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __FUNCTION__, reg, ret);
87 return -1;
88 }
84 } 89 }
85 90
86 return b1[0]; 91 return b1[0];
@@ -107,13 +112,20 @@ static int stv0297_readregs(struct stv0297_state *state, u8 reg1, u8 * b, u8 len
107 }; 112 };
108 113
109 // this device needs a STOP between the register and data 114 // this device needs a STOP between the register and data
110 if ((ret = i2c_transfer(state->i2c, &msg[0], 1)) != 1) { 115 if (state->config->stop_during_read) {
111 dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __FUNCTION__, reg1, ret); 116 if ((ret = i2c_transfer(state->i2c, &msg[0], 1)) != 1) {
112 return -1; 117 dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __FUNCTION__, reg1, ret);
113 } 118 return -1;
114 if ((ret = i2c_transfer(state->i2c, &msg[1], 1)) != 1) { 119 }
115 dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __FUNCTION__, reg1, ret); 120 if ((ret = i2c_transfer(state->i2c, &msg[1], 1)) != 1) {
116 return -1; 121 dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __FUNCTION__, reg1, ret);
122 return -1;
123 }
124 } else {
125 if ((ret = i2c_transfer(state->i2c, msg, 2)) != 2) {
126 dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __FUNCTION__, reg1, ret);
127 return -1;
128 }
117 } 129 }
118 130
119 return 0; 131 return 0;
@@ -276,12 +288,14 @@ static int stv0297_set_inversion(struct stv0297_state *state, fe_spectral_invers
276 return 0; 288 return 0;
277} 289}
278 290
279int stv0297_enable_plli2c(struct dvb_frontend *fe) 291static int stv0297_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
280{ 292{
281 struct stv0297_state *state = fe->demodulator_priv; 293 struct stv0297_state *state = fe->demodulator_priv;
282 294
283 stv0297_writereg(state, 0x87, 0x78); 295 if (enable) {
284 stv0297_writereg(state, 0x86, 0xc8); 296 stv0297_writereg(state, 0x87, 0x78);
297 stv0297_writereg(state, 0x86, 0xc8);
298 }
285 299
286 return 0; 300 return 0;
287} 301}
@@ -296,9 +310,6 @@ static int stv0297_init(struct dvb_frontend *fe)
296 stv0297_writereg(state, state->config->inittab[i], state->config->inittab[i+1]); 310 stv0297_writereg(state, state->config->inittab[i], state->config->inittab[i+1]);
297 msleep(200); 311 msleep(200);
298 312
299 if (state->config->pll_init)
300 state->config->pll_init(fe);
301
302 return 0; 313 return 0;
303} 314}
304 315
@@ -389,7 +400,7 @@ static int stv0297_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_par
389 case QAM_32: 400 case QAM_32:
390 case QAM_64: 401 case QAM_64:
391 delay = 100; 402 delay = 100;
392 sweeprate = 1500; 403 sweeprate = 1000;
393 break; 404 break;
394 405
395 case QAM_128: 406 case QAM_128:
@@ -421,7 +432,10 @@ static int stv0297_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_par
421 } 432 }
422 433
423 stv0297_init(fe); 434 stv0297_init(fe);
424 state->config->pll_set(fe, p); 435 if (fe->ops.tuner_ops.set_params) {
436 fe->ops.tuner_ops.set_params(fe, p);
437 if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
438 }
425 439
426 /* clear software interrupts */ 440 /* clear software interrupts */
427 stv0297_writereg(state, 0x82, 0x0); 441 stv0297_writereg(state, 0x82, 0x0);
@@ -634,7 +648,6 @@ struct dvb_frontend *stv0297_attach(const struct stv0297_config *config,
634 /* setup the state */ 648 /* setup the state */
635 state->config = config; 649 state->config = config;
636 state->i2c = i2c; 650 state->i2c = i2c;
637 memcpy(&state->ops, &stv0297_ops, sizeof(struct dvb_frontend_ops));
638 state->base_freq = 0; 651 state->base_freq = 0;
639 652
640 /* check if the demod is there */ 653 /* check if the demod is there */
@@ -642,7 +655,7 @@ struct dvb_frontend *stv0297_attach(const struct stv0297_config *config,
642 goto error; 655 goto error;
643 656
644 /* create dvb_frontend */ 657 /* create dvb_frontend */
645 state->frontend.ops = &state->ops; 658 memcpy(&state->frontend.ops, &stv0297_ops, sizeof(struct dvb_frontend_ops));
646 state->frontend.demodulator_priv = state; 659 state->frontend.demodulator_priv = state;
647 return &state->frontend; 660 return &state->frontend;
648 661
@@ -668,6 +681,7 @@ static struct dvb_frontend_ops stv0297_ops = {
668 681
669 .init = stv0297_init, 682 .init = stv0297_init,
670 .sleep = stv0297_sleep, 683 .sleep = stv0297_sleep,
684 .i2c_gate_ctrl = stv0297_i2c_gate_ctrl,
671 685
672 .set_frontend = stv0297_set_frontend, 686 .set_frontend = stv0297_set_frontend,
673 .get_frontend = stv0297_get_frontend, 687 .get_frontend = stv0297_get_frontend,
@@ -684,4 +698,3 @@ MODULE_AUTHOR("Dennis Noermann and Andrew de Quincey");
684MODULE_LICENSE("GPL"); 698MODULE_LICENSE("GPL");
685 699
686EXPORT_SYMBOL(stv0297_attach); 700EXPORT_SYMBOL(stv0297_attach);
687EXPORT_SYMBOL(stv0297_enable_plli2c);
diff --git a/drivers/media/dvb/frontends/stv0297.h b/drivers/media/dvb/frontends/stv0297.h
index 9e53f019db71..1da5384fb985 100644
--- a/drivers/media/dvb/frontends/stv0297.h
+++ b/drivers/media/dvb/frontends/stv0297.h
@@ -38,13 +38,11 @@ struct stv0297_config
38 /* does the "inversion" need inverted? */ 38 /* does the "inversion" need inverted? */
39 u8 invert:1; 39 u8 invert:1;
40 40
41 /* PLL maintenance */ 41 /* set to 1 if the device requires an i2c STOP during reading */
42 int (*pll_init)(struct dvb_frontend* fe); 42 u8 stop_during_read:1;
43 int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
44}; 43};
45 44
46extern struct dvb_frontend* stv0297_attach(const struct stv0297_config* config, 45extern struct dvb_frontend* stv0297_attach(const struct stv0297_config* config,
47 struct i2c_adapter* i2c); 46 struct i2c_adapter* i2c);
48extern int stv0297_enable_plli2c(struct dvb_frontend* fe);
49 47
50#endif // STV0297_H 48#endif // STV0297_H
diff --git a/drivers/media/dvb/frontends/stv0299.c b/drivers/media/dvb/frontends/stv0299.c
index 5bcd00f792e6..96648a75440d 100644
--- a/drivers/media/dvb/frontends/stv0299.c
+++ b/drivers/media/dvb/frontends/stv0299.c
@@ -56,7 +56,6 @@
56 56
57struct stv0299_state { 57struct stv0299_state {
58 struct i2c_adapter* i2c; 58 struct i2c_adapter* i2c;
59 struct dvb_frontend_ops ops;
60 const struct stv0299_config* config; 59 const struct stv0299_config* config;
61 struct dvb_frontend frontend; 60 struct dvb_frontend frontend;
62 61
@@ -131,13 +130,6 @@ static int stv0299_readregs (struct stv0299_state* state, u8 reg1, u8 *b, u8 len
131 return ret == 2 ? 0 : ret; 130 return ret == 2 ? 0 : ret;
132} 131}
133 132
134int stv0299_enable_plli2c (struct dvb_frontend* fe)
135{
136 struct stv0299_state* state = fe->demodulator_priv;
137
138 return stv0299_writeregI(state, 0x05, 0xb5); /* enable i2c repeater on stv0299 */
139}
140
141static int stv0299_set_FEC (struct stv0299_state* state, fe_code_rate_t fec) 133static int stv0299_set_FEC (struct stv0299_state* state, fe_code_rate_t fec)
142{ 134{
143 dprintk ("%s\n", __FUNCTION__); 135 dprintk ("%s\n", __FUNCTION__);
@@ -457,12 +449,6 @@ static int stv0299_init (struct dvb_frontend* fe)
457 for (i=0; !(state->config->inittab[i] == 0xff && state->config->inittab[i+1] == 0xff); i+=2) 449 for (i=0; !(state->config->inittab[i] == 0xff && state->config->inittab[i+1] == 0xff); i+=2)
458 stv0299_writeregI(state, state->config->inittab[i], state->config->inittab[i+1]); 450 stv0299_writeregI(state, state->config->inittab[i], state->config->inittab[i+1]);
459 451
460 if (state->config->pll_init) {
461 stv0299_writeregI(state, 0x05, 0xb5); /* enable i2c repeater on stv0299 */
462 state->config->pll_init(fe, state->i2c);
463 stv0299_writeregI(state, 0x05, 0x35); /* disable i2c repeater on stv0299 */
464 }
465
466 return 0; 452 return 0;
467} 453}
468 454
@@ -560,9 +546,10 @@ static int stv0299_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_par
560 if (state->config->invert) invval = (~invval) & 1; 546 if (state->config->invert) invval = (~invval) & 1;
561 stv0299_writeregI(state, 0x0c, (stv0299_readreg(state, 0x0c) & 0xfe) | invval); 547 stv0299_writeregI(state, 0x0c, (stv0299_readreg(state, 0x0c) & 0xfe) | invval);
562 548
563 stv0299_writeregI(state, 0x05, 0xb5); /* enable i2c repeater on stv0299 */ 549 if (fe->ops.tuner_ops.set_params) {
564 state->config->pll_set(fe, state->i2c, p); 550 fe->ops.tuner_ops.set_params(fe, p);
565 stv0299_writeregI(state, 0x05, 0x35); /* disable i2c repeater on stv0299 */ 551 if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
552 }
566 553
567 stv0299_set_FEC (state, p->u.qpsk.fec_inner); 554 stv0299_set_FEC (state, p->u.qpsk.fec_inner);
568 stv0299_set_symbolrate (fe, p->u.qpsk.symbol_rate); 555 stv0299_set_symbolrate (fe, p->u.qpsk.symbol_rate);
@@ -611,6 +598,19 @@ static int stv0299_sleep(struct dvb_frontend* fe)
611 return 0; 598 return 0;
612} 599}
613 600
601static int stv0299_i2c_gate_ctrl(struct dvb_frontend* fe, int enable)
602{
603 struct stv0299_state* state = fe->demodulator_priv;
604
605 if (enable) {
606 stv0299_writeregI(state, 0x05, 0xb5);
607 } else {
608 stv0299_writeregI(state, 0x05, 0x35);
609 }
610 udelay(1);
611 return 0;
612}
613
614static int stv0299_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings) 614static int stv0299_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings)
615{ 615{
616 struct stv0299_state* state = fe->demodulator_priv; 616 struct stv0299_state* state = fe->demodulator_priv;
@@ -647,7 +647,6 @@ struct dvb_frontend* stv0299_attach(const struct stv0299_config* config,
647 /* setup the state */ 647 /* setup the state */
648 state->config = config; 648 state->config = config;
649 state->i2c = i2c; 649 state->i2c = i2c;
650 memcpy(&state->ops, &stv0299_ops, sizeof(struct dvb_frontend_ops));
651 state->initialised = 0; 650 state->initialised = 0;
652 state->tuner_frequency = 0; 651 state->tuner_frequency = 0;
653 state->symbol_rate = 0; 652 state->symbol_rate = 0;
@@ -664,7 +663,7 @@ struct dvb_frontend* stv0299_attach(const struct stv0299_config* config,
664 if (id != 0xa1 && id != 0x80) goto error; 663 if (id != 0xa1 && id != 0x80) goto error;
665 664
666 /* create dvb_frontend */ 665 /* create dvb_frontend */
667 state->frontend.ops = &state->ops; 666 memcpy(&state->frontend.ops, &stv0299_ops, sizeof(struct dvb_frontend_ops));
668 state->frontend.demodulator_priv = state; 667 state->frontend.demodulator_priv = state;
669 return &state->frontend; 668 return &state->frontend;
670 669
@@ -695,6 +694,7 @@ static struct dvb_frontend_ops stv0299_ops = {
695 694
696 .init = stv0299_init, 695 .init = stv0299_init,
697 .sleep = stv0299_sleep, 696 .sleep = stv0299_sleep,
697 .i2c_gate_ctrl = stv0299_i2c_gate_ctrl,
698 698
699 .set_frontend = stv0299_set_frontend, 699 .set_frontend = stv0299_set_frontend,
700 .get_frontend = stv0299_get_frontend, 700 .get_frontend = stv0299_get_frontend,
@@ -721,9 +721,8 @@ MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
721 721
722MODULE_DESCRIPTION("ST STV0299 DVB Demodulator driver"); 722MODULE_DESCRIPTION("ST STV0299 DVB Demodulator driver");
723MODULE_AUTHOR("Ralph Metzler, Holger Waechtler, Peter Schildmann, Felix Domke, " 723MODULE_AUTHOR("Ralph Metzler, Holger Waechtler, Peter Schildmann, Felix Domke, "
724 "Andreas Oberritter, Andrew de Quincey, Kenneth Aafløy"); 724 "Andreas Oberritter, Andrew de Quincey, Kenneth Aafly");
725MODULE_LICENSE("GPL"); 725MODULE_LICENSE("GPL");
726 726
727EXPORT_SYMBOL(stv0299_enable_plli2c);
728EXPORT_SYMBOL(stv0299_writereg); 727EXPORT_SYMBOL(stv0299_writereg);
729EXPORT_SYMBOL(stv0299_attach); 728EXPORT_SYMBOL(stv0299_attach);
diff --git a/drivers/media/dvb/frontends/stv0299.h b/drivers/media/dvb/frontends/stv0299.h
index 32c87b4c2f13..1504828e4232 100644
--- a/drivers/media/dvb/frontends/stv0299.h
+++ b/drivers/media/dvb/frontends/stv0299.h
@@ -87,14 +87,9 @@ struct stv0299_config
87 87
88 /* Set the symbol rate */ 88 /* Set the symbol rate */
89 int (*set_symbol_rate)(struct dvb_frontend* fe, u32 srate, u32 ratio); 89 int (*set_symbol_rate)(struct dvb_frontend* fe, u32 srate, u32 ratio);
90
91 /* PLL maintenance */
92 int (*pll_init)(struct dvb_frontend *fe, struct i2c_adapter *i2c);
93 int (*pll_set)(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct dvb_frontend_parameters *params);
94}; 90};
95 91
96extern int stv0299_writereg (struct dvb_frontend* fe, u8 reg, u8 data); 92extern int stv0299_writereg (struct dvb_frontend* fe, u8 reg, u8 data);
97extern int stv0299_enable_plli2c (struct dvb_frontend* fe);
98 93
99extern struct dvb_frontend* stv0299_attach(const struct stv0299_config* config, 94extern struct dvb_frontend* stv0299_attach(const struct stv0299_config* config,
100 struct i2c_adapter* i2c); 95 struct i2c_adapter* i2c);
diff --git a/drivers/media/dvb/frontends/tda10021.c b/drivers/media/dvb/frontends/tda10021.c
index 21255cac9793..e83ff2104c9b 100644
--- a/drivers/media/dvb/frontends/tda10021.c
+++ b/drivers/media/dvb/frontends/tda10021.c
@@ -36,7 +36,6 @@
36 36
37struct tda10021_state { 37struct tda10021_state {
38 struct i2c_adapter* i2c; 38 struct i2c_adapter* i2c;
39 struct dvb_frontend_ops ops;
40 /* configuration settings */ 39 /* configuration settings */
41 const struct tda10021_config* config; 40 const struct tda10021_config* config;
42 struct dvb_frontend frontend; 41 struct dvb_frontend frontend;
@@ -90,6 +89,14 @@ static int tda10021_writereg (struct tda10021_state* state, u8 reg, u8 data)
90 return (ret != 1) ? -EREMOTEIO : 0; 89 return (ret != 1) ? -EREMOTEIO : 0;
91} 90}
92 91
92int tda10021_write_byte(struct dvb_frontend* fe, int reg, int data)
93{
94 struct tda10021_state* state = fe->demodulator_priv;
95
96 return tda10021_writereg(state, reg, data);
97}
98EXPORT_SYMBOL(tda10021_write_byte);
99
93static u8 tda10021_readreg (struct tda10021_state* state, u8 reg) 100static u8 tda10021_readreg (struct tda10021_state* state, u8 reg)
94{ 101{
95 u8 b0 [] = { reg }; 102 u8 b0 [] = { reg };
@@ -225,13 +232,6 @@ static int tda10021_init (struct dvb_frontend *fe)
225 232
226 //Activate PLL 233 //Activate PLL
227 tda10021_writereg(state, 0x2a, tda10021_inittab[0x2a] & 0xef); 234 tda10021_writereg(state, 0x2a, tda10021_inittab[0x2a] & 0xef);
228
229 if (state->config->pll_init) {
230 lock_tuner(state);
231 state->config->pll_init(fe);
232 unlock_tuner(state);
233 }
234
235 return 0; 235 return 0;
236} 236}
237 237
@@ -259,9 +259,10 @@ static int tda10021_set_parameters (struct dvb_frontend *fe,
259 259
260 //printk("tda10021: set frequency to %d qam=%d symrate=%d\n", p->frequency,qam,p->u.qam.symbol_rate); 260 //printk("tda10021: set frequency to %d qam=%d symrate=%d\n", p->frequency,qam,p->u.qam.symbol_rate);
261 261
262 lock_tuner(state); 262 if (fe->ops.tuner_ops.set_params) {
263 state->config->pll_set(fe, p); 263 fe->ops.tuner_ops.set_params(fe, p);
264 unlock_tuner(state); 264 if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
265 }
265 266
266 tda10021_set_symbolrate (state, p->u.qam.symbol_rate); 267 tda10021_set_symbolrate (state, p->u.qam.symbol_rate);
267 tda10021_writereg (state, 0x34, state->pwm); 268 tda10021_writereg (state, 0x34, state->pwm);
@@ -376,6 +377,18 @@ static int tda10021_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_pa
376 return 0; 377 return 0;
377} 378}
378 379
380static int tda10021_i2c_gate_ctrl(struct dvb_frontend* fe, int enable)
381{
382 struct tda10021_state* state = fe->demodulator_priv;
383
384 if (enable) {
385 lock_tuner(state);
386 } else {
387 unlock_tuner(state);
388 }
389 return 0;
390}
391
379static int tda10021_sleep(struct dvb_frontend* fe) 392static int tda10021_sleep(struct dvb_frontend* fe)
380{ 393{
381 struct tda10021_state* state = fe->demodulator_priv; 394 struct tda10021_state* state = fe->demodulator_priv;
@@ -407,7 +420,6 @@ struct dvb_frontend* tda10021_attach(const struct tda10021_config* config,
407 /* setup the state */ 420 /* setup the state */
408 state->config = config; 421 state->config = config;
409 state->i2c = i2c; 422 state->i2c = i2c;
410 memcpy(&state->ops, &tda10021_ops, sizeof(struct dvb_frontend_ops));
411 state->pwm = pwm; 423 state->pwm = pwm;
412 state->reg0 = tda10021_inittab[0]; 424 state->reg0 = tda10021_inittab[0];
413 425
@@ -415,7 +427,7 @@ struct dvb_frontend* tda10021_attach(const struct tda10021_config* config,
415 if ((tda10021_readreg(state, 0x1a) & 0xf0) != 0x70) goto error; 427 if ((tda10021_readreg(state, 0x1a) & 0xf0) != 0x70) goto error;
416 428
417 /* create dvb_frontend */ 429 /* create dvb_frontend */
418 state->frontend.ops = &state->ops; 430 memcpy(&state->frontend.ops, &tda10021_ops, sizeof(struct dvb_frontend_ops));
419 state->frontend.demodulator_priv = state; 431 state->frontend.demodulator_priv = state;
420 return &state->frontend; 432 return &state->frontend;
421 433
@@ -448,6 +460,7 @@ static struct dvb_frontend_ops tda10021_ops = {
448 460
449 .init = tda10021_init, 461 .init = tda10021_init,
450 .sleep = tda10021_sleep, 462 .sleep = tda10021_sleep,
463 .i2c_gate_ctrl = tda10021_i2c_gate_ctrl,
451 464
452 .set_frontend = tda10021_set_parameters, 465 .set_frontend = tda10021_set_parameters,
453 .get_frontend = tda10021_get_frontend, 466 .get_frontend = tda10021_get_frontend,
diff --git a/drivers/media/dvb/frontends/tda10021.h b/drivers/media/dvb/frontends/tda10021.h
index 53be939e8c55..b1df4259bee9 100644
--- a/drivers/media/dvb/frontends/tda10021.h
+++ b/drivers/media/dvb/frontends/tda10021.h
@@ -30,13 +30,11 @@ struct tda10021_config
30{ 30{
31 /* the demodulator's i2c address */ 31 /* the demodulator's i2c address */
32 u8 demod_address; 32 u8 demod_address;
33
34 /* PLL maintenance */
35 int (*pll_init)(struct dvb_frontend* fe);
36 int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
37}; 33};
38 34
39extern struct dvb_frontend* tda10021_attach(const struct tda10021_config* config, 35extern struct dvb_frontend* tda10021_attach(const struct tda10021_config* config,
40 struct i2c_adapter* i2c, u8 pwm); 36 struct i2c_adapter* i2c, u8 pwm);
41 37
38extern int tda10021_write_byte(struct dvb_frontend* fe, int reg, int data);
39
42#endif // TDA10021_H 40#endif // TDA10021_H
diff --git a/drivers/media/dvb/frontends/tda1004x.c b/drivers/media/dvb/frontends/tda1004x.c
index b83dafa4e12c..59a2ed614fca 100644
--- a/drivers/media/dvb/frontends/tda1004x.c
+++ b/drivers/media/dvb/frontends/tda1004x.c
@@ -47,7 +47,6 @@ enum tda1004x_demod {
47 47
48struct tda1004x_state { 48struct tda1004x_state {
49 struct i2c_adapter* i2c; 49 struct i2c_adapter* i2c;
50 struct dvb_frontend_ops ops;
51 const struct tda1004x_config* config; 50 const struct tda1004x_config* config;
52 struct dvb_frontend frontend; 51 struct dvb_frontend frontend;
53 52
@@ -600,13 +599,6 @@ static int tda10045_init(struct dvb_frontend* fe)
600 599
601 tda1004x_write_mask(state, TDA1004X_CONFADC1, 0x10, 0); // wake up the ADC 600 tda1004x_write_mask(state, TDA1004X_CONFADC1, 0x10, 0); // wake up the ADC
602 601
603 // Init the PLL
604 if (state->config->pll_init) {
605 tda1004x_enable_tuner_i2c(state);
606 state->config->pll_init(fe);
607 tda1004x_disable_tuner_i2c(state);
608 }
609
610 // tda setup 602 // tda setup
611 tda1004x_write_mask(state, TDA1004X_CONFC4, 0x20, 0); // disable DSP watchdog timer 603 tda1004x_write_mask(state, TDA1004X_CONFC4, 0x20, 0); // disable DSP watchdog timer
612 tda1004x_write_mask(state, TDA1004X_AUTO, 8, 0); // select HP stream 604 tda1004x_write_mask(state, TDA1004X_AUTO, 8, 0); // select HP stream
@@ -635,16 +627,6 @@ static int tda10046_init(struct dvb_frontend* fe)
635 return -EIO; 627 return -EIO;
636 } 628 }
637 629
638 // Init the tuner PLL
639 if (state->config->pll_init) {
640 tda1004x_enable_tuner_i2c(state);
641 if (state->config->pll_init(fe)) {
642 printk(KERN_ERR "tda1004x: pll init failed\n");
643 return -EIO;
644 }
645 tda1004x_disable_tuner_i2c(state);
646 }
647
648 // tda setup 630 // tda setup
649 tda1004x_write_mask(state, TDA1004X_CONFC4, 0x20, 0); // disable DSP watchdog timer 631 tda1004x_write_mask(state, TDA1004X_CONFC4, 0x20, 0); // disable DSP watchdog timer
650 tda1004x_write_byteI(state, TDA1004X_AUTO, 0x87); // 100 ppm crystal, select HP stream 632 tda1004x_write_byteI(state, TDA1004X_AUTO, 0x87); // 100 ppm crystal, select HP stream
@@ -712,12 +694,10 @@ static int tda1004x_set_fe(struct dvb_frontend* fe,
712 } 694 }
713 695
714 // set frequency 696 // set frequency
715 tda1004x_enable_tuner_i2c(state); 697 if (fe->ops.tuner_ops.set_params) {
716 if (state->config->pll_set(fe, fe_params)) { 698 fe->ops.tuner_ops.set_params(fe, fe_params);
717 printk(KERN_ERR "tda1004x: pll set failed\n"); 699 if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
718 return -EIO;
719 } 700 }
720 tda1004x_disable_tuner_i2c(state);
721 701
722 // Hardcoded to use auto as much as possible on the TDA10045 as it 702 // Hardcoded to use auto as much as possible on the TDA10045 as it
723 // is very unreliable if AUTO mode is _not_ used. 703 // is very unreliable if AUTO mode is _not_ used.
@@ -1183,16 +1163,6 @@ static int tda1004x_sleep(struct dvb_frontend* fe)
1183 break; 1163 break;
1184 1164
1185 case TDA1004X_DEMOD_TDA10046: 1165 case TDA1004X_DEMOD_TDA10046:
1186 if (state->config->pll_sleep != NULL) {
1187 tda1004x_enable_tuner_i2c(state);
1188 state->config->pll_sleep(fe);
1189 if (state->config->if_freq != TDA10046_FREQ_052) {
1190 /* special hack for Philips EUROPA Based boards:
1191 * keep the I2c bridge open for tuner access in analog mode
1192 */
1193 tda1004x_disable_tuner_i2c(state);
1194 }
1195 }
1196 /* set outputs to tristate */ 1166 /* set outputs to tristate */
1197 tda1004x_write_byteI(state, TDA10046H_CONF_TRISTATE1, 0xff); 1167 tda1004x_write_byteI(state, TDA10046H_CONF_TRISTATE1, 0xff);
1198 tda1004x_write_mask(state, TDA1004X_CONFC4, 1, 1); 1168 tda1004x_write_mask(state, TDA1004X_CONFC4, 1, 1);
@@ -1202,6 +1172,17 @@ static int tda1004x_sleep(struct dvb_frontend* fe)
1202 return 0; 1172 return 0;
1203} 1173}
1204 1174
1175static int tda1004x_i2c_gate_ctrl(struct dvb_frontend* fe, int enable)
1176{
1177 struct tda1004x_state* state = fe->demodulator_priv;
1178
1179 if (enable) {
1180 return tda1004x_enable_tuner_i2c(state);
1181 } else {
1182 return tda1004x_disable_tuner_i2c(state);
1183 }
1184}
1185
1205static int tda1004x_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings) 1186static int tda1004x_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings)
1206{ 1187{
1207 fesettings->min_delay_ms = 800; 1188 fesettings->min_delay_ms = 800;
@@ -1235,6 +1216,7 @@ static struct dvb_frontend_ops tda10045_ops = {
1235 1216
1236 .init = tda10045_init, 1217 .init = tda10045_init,
1237 .sleep = tda1004x_sleep, 1218 .sleep = tda1004x_sleep,
1219 .i2c_gate_ctrl = tda1004x_i2c_gate_ctrl,
1238 1220
1239 .set_frontend = tda1004x_set_fe, 1221 .set_frontend = tda1004x_set_fe,
1240 .get_frontend = tda1004x_get_fe, 1222 .get_frontend = tda1004x_get_fe,
@@ -1260,7 +1242,6 @@ struct dvb_frontend* tda10045_attach(const struct tda1004x_config* config,
1260 /* setup the state */ 1242 /* setup the state */
1261 state->config = config; 1243 state->config = config;
1262 state->i2c = i2c; 1244 state->i2c = i2c;
1263 memcpy(&state->ops, &tda10045_ops, sizeof(struct dvb_frontend_ops));
1264 state->demod_type = TDA1004X_DEMOD_TDA10045; 1245 state->demod_type = TDA1004X_DEMOD_TDA10045;
1265 1246
1266 /* check if the demod is there */ 1247 /* check if the demod is there */
@@ -1270,7 +1251,7 @@ struct dvb_frontend* tda10045_attach(const struct tda1004x_config* config,
1270 } 1251 }
1271 1252
1272 /* create dvb_frontend */ 1253 /* create dvb_frontend */
1273 state->frontend.ops = &state->ops; 1254 memcpy(&state->frontend.ops, &tda10045_ops, sizeof(struct dvb_frontend_ops));
1274 state->frontend.demodulator_priv = state; 1255 state->frontend.demodulator_priv = state;
1275 return &state->frontend; 1256 return &state->frontend;
1276} 1257}
@@ -1293,6 +1274,7 @@ static struct dvb_frontend_ops tda10046_ops = {
1293 1274
1294 .init = tda10046_init, 1275 .init = tda10046_init,
1295 .sleep = tda1004x_sleep, 1276 .sleep = tda1004x_sleep,
1277 .i2c_gate_ctrl = tda1004x_i2c_gate_ctrl,
1296 1278
1297 .set_frontend = tda1004x_set_fe, 1279 .set_frontend = tda1004x_set_fe,
1298 .get_frontend = tda1004x_get_fe, 1280 .get_frontend = tda1004x_get_fe,
@@ -1318,7 +1300,6 @@ struct dvb_frontend* tda10046_attach(const struct tda1004x_config* config,
1318 /* setup the state */ 1300 /* setup the state */
1319 state->config = config; 1301 state->config = config;
1320 state->i2c = i2c; 1302 state->i2c = i2c;
1321 memcpy(&state->ops, &tda10046_ops, sizeof(struct dvb_frontend_ops));
1322 state->demod_type = TDA1004X_DEMOD_TDA10046; 1303 state->demod_type = TDA1004X_DEMOD_TDA10046;
1323 1304
1324 /* check if the demod is there */ 1305 /* check if the demod is there */
@@ -1328,7 +1309,7 @@ struct dvb_frontend* tda10046_attach(const struct tda1004x_config* config,
1328 } 1309 }
1329 1310
1330 /* create dvb_frontend */ 1311 /* create dvb_frontend */
1331 state->frontend.ops = &state->ops; 1312 memcpy(&state->frontend.ops, &tda10046_ops, sizeof(struct dvb_frontend_ops));
1332 state->frontend.demodulator_priv = state; 1313 state->frontend.demodulator_priv = state;
1333 return &state->frontend; 1314 return &state->frontend;
1334} 1315}
diff --git a/drivers/media/dvb/frontends/tda1004x.h b/drivers/media/dvb/frontends/tda1004x.h
index cc0c4af64067..b877b23ed734 100644
--- a/drivers/media/dvb/frontends/tda1004x.h
+++ b/drivers/media/dvb/frontends/tda1004x.h
@@ -66,11 +66,6 @@ struct tda1004x_config
66 /* AGC configuration */ 66 /* AGC configuration */
67 enum tda10046_agc agc_config; 67 enum tda10046_agc agc_config;
68 68
69 /* PLL maintenance */
70 int (*pll_init)(struct dvb_frontend* fe);
71 void (*pll_sleep)(struct dvb_frontend* fe);
72 int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
73
74 /* request firmware for device */ 69 /* request firmware for device */
75 /* set this to NULL if the card has a firmware EEPROM */ 70 /* set this to NULL if the card has a firmware EEPROM */
76 int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name); 71 int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name);
diff --git a/drivers/media/dvb/frontends/tda8083.c b/drivers/media/dvb/frontends/tda8083.c
index 91baa9cedd79..3aa45ebbac3d 100644
--- a/drivers/media/dvb/frontends/tda8083.c
+++ b/drivers/media/dvb/frontends/tda8083.c
@@ -37,7 +37,6 @@
37 37
38struct tda8083_state { 38struct tda8083_state {
39 struct i2c_adapter* i2c; 39 struct i2c_adapter* i2c;
40 struct dvb_frontend_ops ops;
41 /* configuration settings */ 40 /* configuration settings */
42 const struct tda8083_config* config; 41 const struct tda8083_config* config;
43 struct dvb_frontend frontend; 42 struct dvb_frontend frontend;
@@ -293,7 +292,11 @@ static int tda8083_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_par
293{ 292{
294 struct tda8083_state* state = fe->demodulator_priv; 293 struct tda8083_state* state = fe->demodulator_priv;
295 294
296 state->config->pll_set(fe, p); 295 if (fe->ops.tuner_ops.set_params) {
296 fe->ops.tuner_ops.set_params(fe, p);
297 if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
298 }
299
297 tda8083_set_inversion (state, p->inversion); 300 tda8083_set_inversion (state, p->inversion);
298 tda8083_set_fec (state, p->u.qpsk.fec_inner); 301 tda8083_set_fec (state, p->u.qpsk.fec_inner);
299 tda8083_set_symbolrate (state, p->u.qpsk.symbol_rate); 302 tda8083_set_symbolrate (state, p->u.qpsk.symbol_rate);
@@ -334,8 +337,6 @@ static int tda8083_init(struct dvb_frontend* fe)
334 for (i=0; i<44; i++) 337 for (i=0; i<44; i++)
335 tda8083_writereg (state, i, tda8083_init_tab[i]); 338 tda8083_writereg (state, i, tda8083_init_tab[i]);
336 339
337 if (state->config->pll_init) state->config->pll_init(fe);
338
339 tda8083_writereg (state, 0x00, 0x3c); 340 tda8083_writereg (state, 0x00, 0x3c);
340 tda8083_writereg (state, 0x00, 0x04); 341 tda8083_writereg (state, 0x00, 0x04);
341 342
@@ -395,13 +396,12 @@ struct dvb_frontend* tda8083_attach(const struct tda8083_config* config,
395 /* setup the state */ 396 /* setup the state */
396 state->config = config; 397 state->config = config;
397 state->i2c = i2c; 398 state->i2c = i2c;
398 memcpy(&state->ops, &tda8083_ops, sizeof(struct dvb_frontend_ops));
399 399
400 /* check if the demod is there */ 400 /* check if the demod is there */
401 if ((tda8083_readreg(state, 0x00)) != 0x05) goto error; 401 if ((tda8083_readreg(state, 0x00)) != 0x05) goto error;
402 402
403 /* create dvb_frontend */ 403 /* create dvb_frontend */
404 state->frontend.ops = &state->ops; 404 memcpy(&state->frontend.ops, &tda8083_ops, sizeof(struct dvb_frontend_ops));
405 state->frontend.demodulator_priv = state; 405 state->frontend.demodulator_priv = state;
406 return &state->frontend; 406 return &state->frontend;
407 407
diff --git a/drivers/media/dvb/frontends/tda8083.h b/drivers/media/dvb/frontends/tda8083.h
index 466663307bf1..e7a48f61ea2c 100644
--- a/drivers/media/dvb/frontends/tda8083.h
+++ b/drivers/media/dvb/frontends/tda8083.h
@@ -33,10 +33,6 @@ struct tda8083_config
33{ 33{
34 /* the demodulator's i2c address */ 34 /* the demodulator's i2c address */
35 u8 demod_address; 35 u8 demod_address;
36
37 /* PLL maintenance */
38 int (*pll_init)(struct dvb_frontend* fe);
39 int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
40}; 36};
41 37
42extern struct dvb_frontend* tda8083_attach(const struct tda8083_config* config, 38extern struct dvb_frontend* tda8083_attach(const struct tda8083_config* config,
diff --git a/drivers/media/dvb/frontends/ves1820.c b/drivers/media/dvb/frontends/ves1820.c
index ad8647a3c85e..6bffe85c161c 100644
--- a/drivers/media/dvb/frontends/ves1820.c
+++ b/drivers/media/dvb/frontends/ves1820.c
@@ -35,7 +35,6 @@
35 35
36struct ves1820_state { 36struct ves1820_state {
37 struct i2c_adapter* i2c; 37 struct i2c_adapter* i2c;
38 struct dvb_frontend_ops ops;
39 /* configuration settings */ 38 /* configuration settings */
40 const struct ves1820_config* config; 39 const struct ves1820_config* config;
41 struct dvb_frontend frontend; 40 struct dvb_frontend frontend;
@@ -204,9 +203,6 @@ static int ves1820_init(struct dvb_frontend* fe)
204 203
205 ves1820_writereg(state, 0x34, state->pwm); 204 ves1820_writereg(state, 0x34, state->pwm);
206 205
207 if (state->config->pll_init)
208 state->config->pll_init(fe);
209
210 return 0; 206 return 0;
211} 207}
212 208
@@ -223,7 +219,11 @@ static int ves1820_set_parameters(struct dvb_frontend* fe, struct dvb_frontend_p
223 if (real_qam < 0 || real_qam > 4) 219 if (real_qam < 0 || real_qam > 4)
224 return -EINVAL; 220 return -EINVAL;
225 221
226 state->config->pll_set(fe, p); 222 if (fe->ops.tuner_ops.set_params) {
223 fe->ops.tuner_ops.set_params(fe, p);
224 if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
225 }
226
227 ves1820_set_symbolrate(state, p->u.qam.symbol_rate); 227 ves1820_set_symbolrate(state, p->u.qam.symbol_rate);
228 ves1820_writereg(state, 0x34, state->pwm); 228 ves1820_writereg(state, 0x34, state->pwm);
229 229
@@ -380,7 +380,6 @@ struct dvb_frontend* ves1820_attach(const struct ves1820_config* config,
380 goto error; 380 goto error;
381 381
382 /* setup the state */ 382 /* setup the state */
383 memcpy(&state->ops, &ves1820_ops, sizeof(struct dvb_frontend_ops));
384 state->reg0 = ves1820_inittab[0]; 383 state->reg0 = ves1820_inittab[0];
385 state->config = config; 384 state->config = config;
386 state->i2c = i2c; 385 state->i2c = i2c;
@@ -393,12 +392,12 @@ struct dvb_frontend* ves1820_attach(const struct ves1820_config* config,
393 if (verbose) 392 if (verbose)
394 printk("ves1820: pwm=0x%02x\n", state->pwm); 393 printk("ves1820: pwm=0x%02x\n", state->pwm);
395 394
396 state->ops.info.symbol_rate_min = (state->config->xin / 2) / 64; /* SACLK/64 == (XIN/2)/64 */
397 state->ops.info.symbol_rate_max = (state->config->xin / 2) / 4; /* SACLK/4 */
398
399 /* create dvb_frontend */ 395 /* create dvb_frontend */
400 state->frontend.ops = &state->ops; 396 memcpy(&state->frontend.ops, &ves1820_ops, sizeof(struct dvb_frontend_ops));
397 state->frontend.ops.info.symbol_rate_min = (state->config->xin / 2) / 64; /* SACLK/64 == (XIN/2)/64 */
398 state->frontend.ops.info.symbol_rate_max = (state->config->xin / 2) / 4; /* SACLK/4 */
401 state->frontend.demodulator_priv = state; 399 state->frontend.demodulator_priv = state;
400
402 return &state->frontend; 401 return &state->frontend;
403 402
404error: 403error:
diff --git a/drivers/media/dvb/frontends/ves1820.h b/drivers/media/dvb/frontends/ves1820.h
index 355f130b1be8..520f09522fbb 100644
--- a/drivers/media/dvb/frontends/ves1820.h
+++ b/drivers/media/dvb/frontends/ves1820.h
@@ -39,10 +39,6 @@ struct ves1820_config
39 39
40 /* SELAGC control */ 40 /* SELAGC control */
41 u8 selagc:1; 41 u8 selagc:1;
42
43 /* PLL maintenance */
44 int (*pll_init)(struct dvb_frontend* fe);
45 int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
46}; 42};
47 43
48extern struct dvb_frontend* ves1820_attach(const struct ves1820_config* config, 44extern struct dvb_frontend* ves1820_attach(const struct ves1820_config* config,
diff --git a/drivers/media/dvb/frontends/ves1x93.c b/drivers/media/dvb/frontends/ves1x93.c
index 821df8e839d0..54d7b07571b8 100644
--- a/drivers/media/dvb/frontends/ves1x93.c
+++ b/drivers/media/dvb/frontends/ves1x93.c
@@ -36,7 +36,6 @@
36 36
37struct ves1x93_state { 37struct ves1x93_state {
38 struct i2c_adapter* i2c; 38 struct i2c_adapter* i2c;
39 struct dvb_frontend_ops ops;
40 /* configuration settings */ 39 /* configuration settings */
41 const struct ves1x93_config* config; 40 const struct ves1x93_config* config;
42 struct dvb_frontend frontend; 41 struct dvb_frontend frontend;
@@ -278,12 +277,6 @@ static int ves1x93_init (struct dvb_frontend* fe)
278 } 277 }
279 } 278 }
280 279
281 if (state->config->pll_init) {
282 ves1x93_writereg(state, 0x00, 0x11);
283 state->config->pll_init(fe);
284 ves1x93_writereg(state, 0x00, 0x01);
285 }
286
287 return 0; 280 return 0;
288} 281}
289 282
@@ -395,9 +388,10 @@ static int ves1x93_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_par
395{ 388{
396 struct ves1x93_state* state = fe->demodulator_priv; 389 struct ves1x93_state* state = fe->demodulator_priv;
397 390
398 ves1x93_writereg(state, 0x00, 0x11); 391 if (fe->ops.tuner_ops.set_params) {
399 state->config->pll_set(fe, p); 392 fe->ops.tuner_ops.set_params(fe, p);
400 ves1x93_writereg(state, 0x00, 0x01); 393 if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
394 }
401 ves1x93_set_inversion (state, p->inversion); 395 ves1x93_set_inversion (state, p->inversion);
402 ves1x93_set_fec (state, p->u.qpsk.fec_inner); 396 ves1x93_set_fec (state, p->u.qpsk.fec_inner);
403 ves1x93_set_symbolrate (state, p->u.qpsk.symbol_rate); 397 ves1x93_set_symbolrate (state, p->u.qpsk.symbol_rate);
@@ -442,6 +436,17 @@ static void ves1x93_release(struct dvb_frontend* fe)
442 kfree(state); 436 kfree(state);
443} 437}
444 438
439static int ves1x93_i2c_gate_ctrl(struct dvb_frontend* fe, int enable)
440{
441 struct ves1x93_state* state = fe->demodulator_priv;
442
443 if (enable) {
444 return ves1x93_writereg(state, 0x00, 0x11);
445 } else {
446 return ves1x93_writereg(state, 0x00, 0x01);
447 }
448}
449
445static struct dvb_frontend_ops ves1x93_ops; 450static struct dvb_frontend_ops ves1x93_ops;
446 451
447struct dvb_frontend* ves1x93_attach(const struct ves1x93_config* config, 452struct dvb_frontend* ves1x93_attach(const struct ves1x93_config* config,
@@ -457,7 +462,6 @@ struct dvb_frontend* ves1x93_attach(const struct ves1x93_config* config,
457 /* setup the state */ 462 /* setup the state */
458 state->config = config; 463 state->config = config;
459 state->i2c = i2c; 464 state->i2c = i2c;
460 memcpy(&state->ops, &ves1x93_ops, sizeof(struct dvb_frontend_ops));
461 state->inversion = INVERSION_OFF; 465 state->inversion = INVERSION_OFF;
462 466
463 /* check if the demod is there + identify it */ 467 /* check if the demod is there + identify it */
@@ -492,7 +496,7 @@ struct dvb_frontend* ves1x93_attach(const struct ves1x93_config* config,
492 } 496 }
493 497
494 /* create dvb_frontend */ 498 /* create dvb_frontend */
495 state->frontend.ops = &state->ops; 499 memcpy(&state->frontend.ops, &ves1x93_ops, sizeof(struct dvb_frontend_ops));
496 state->frontend.demodulator_priv = state; 500 state->frontend.demodulator_priv = state;
497 return &state->frontend; 501 return &state->frontend;
498 502
@@ -523,6 +527,7 @@ static struct dvb_frontend_ops ves1x93_ops = {
523 527
524 .init = ves1x93_init, 528 .init = ves1x93_init,
525 .sleep = ves1x93_sleep, 529 .sleep = ves1x93_sleep,
530 .i2c_gate_ctrl = ves1x93_i2c_gate_ctrl,
526 531
527 .set_frontend = ves1x93_set_frontend, 532 .set_frontend = ves1x93_set_frontend,
528 .get_frontend = ves1x93_get_frontend, 533 .get_frontend = ves1x93_get_frontend,
diff --git a/drivers/media/dvb/frontends/ves1x93.h b/drivers/media/dvb/frontends/ves1x93.h
index 1627e37c57a4..ba88ae0855c9 100644
--- a/drivers/media/dvb/frontends/ves1x93.h
+++ b/drivers/media/dvb/frontends/ves1x93.h
@@ -38,10 +38,6 @@ struct ves1x93_config
38 38
39 /* should PWM be inverted? */ 39 /* should PWM be inverted? */
40 u8 invert_pwm:1; 40 u8 invert_pwm:1;
41
42 /* PLL maintenance */
43 int (*pll_init)(struct dvb_frontend* fe);
44 int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
45}; 41};
46 42
47extern struct dvb_frontend* ves1x93_attach(const struct ves1x93_config* config, 43extern struct dvb_frontend* ves1x93_attach(const struct ves1x93_config* config,
diff --git a/drivers/media/dvb/frontends/zl10353.c b/drivers/media/dvb/frontends/zl10353.c
index d7d9f59d76d2..2b95e8b6cd39 100644
--- a/drivers/media/dvb/frontends/zl10353.c
+++ b/drivers/media/dvb/frontends/zl10353.c
@@ -34,7 +34,6 @@
34struct zl10353_state { 34struct zl10353_state {
35 struct i2c_adapter *i2c; 35 struct i2c_adapter *i2c;
36 struct dvb_frontend frontend; 36 struct dvb_frontend frontend;
37 struct dvb_frontend_ops ops;
38 37
39 struct zl10353_config config; 38 struct zl10353_config config;
40}; 39};
@@ -126,6 +125,7 @@ static int zl10353_set_parameters(struct dvb_frontend *fe,
126 struct dvb_frontend_parameters *param) 125 struct dvb_frontend_parameters *param)
127{ 126{
128 struct zl10353_state *state = fe->demodulator_priv; 127 struct zl10353_state *state = fe->demodulator_priv;
128
129 u8 pllbuf[6] = { 0x67 }; 129 u8 pllbuf[6] = { 0x67 };
130 130
131 /* These settings set "auto-everything" and start the FSM. */ 131 /* These settings set "auto-everything" and start the FSM. */
@@ -142,7 +142,30 @@ static int zl10353_set_parameters(struct dvb_frontend *fe,
142 zl10353_single_write(fe, 0x66, 0xE9); 142 zl10353_single_write(fe, 0x66, 0xE9);
143 zl10353_single_write(fe, 0x62, 0x0A); 143 zl10353_single_write(fe, 0x62, 0x0A);
144 144
145 state->config.pll_set(fe, param, pllbuf + 1); 145 // if there is no attached secondary tuner, we call set_params to program
146 // a potential tuner attached somewhere else
147 if (state->config.no_tuner) {
148 if (fe->ops.tuner_ops.set_params) {
149 fe->ops.tuner_ops.set_params(fe, param);
150 if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
151 }
152 }
153
154 // if pllbuf is defined, retrieve the settings
155 if (fe->ops.tuner_ops.calc_regs) {
156 fe->ops.tuner_ops.calc_regs(fe, param, pllbuf+1, 5);
157 pllbuf[1] <<= 1;
158 } else {
159 // fake pllbuf settings
160 pllbuf[1] = 0x61 << 1;
161 pllbuf[2] = 0;
162 pllbuf[3] = 0;
163 pllbuf[3] = 0;
164 pllbuf[4] = 0;
165 }
166
167 // there is no call to _just_ start decoding, so we send the pllbuf anyway
168 // even if there isn't a PLL attached to the secondary bus
146 zl10353_write(fe, pllbuf, sizeof(pllbuf)); 169 zl10353_write(fe, pllbuf, sizeof(pllbuf));
147 170
148 zl10353_single_write(fe, 0x70, 0x01); 171 zl10353_single_write(fe, 0x70, 0x01);
@@ -254,14 +277,13 @@ struct dvb_frontend *zl10353_attach(const struct zl10353_config *config,
254 /* setup the state */ 277 /* setup the state */
255 state->i2c = i2c; 278 state->i2c = i2c;
256 memcpy(&state->config, config, sizeof(struct zl10353_config)); 279 memcpy(&state->config, config, sizeof(struct zl10353_config));
257 memcpy(&state->ops, &zl10353_ops, sizeof(struct dvb_frontend_ops));
258 280
259 /* check if the demod is there */ 281 /* check if the demod is there */
260 if (zl10353_read_register(state, CHIP_ID) != ID_ZL10353) 282 if (zl10353_read_register(state, CHIP_ID) != ID_ZL10353)
261 goto error; 283 goto error;
262 284
263 /* create dvb_frontend */ 285 /* create dvb_frontend */
264 state->frontend.ops = &state->ops; 286 memcpy(&state->frontend.ops, &zl10353_ops, sizeof(struct dvb_frontend_ops));
265 state->frontend.demodulator_priv = state; 287 state->frontend.demodulator_priv = state;
266 288
267 return &state->frontend; 289 return &state->frontend;
diff --git a/drivers/media/dvb/frontends/zl10353.h b/drivers/media/dvb/frontends/zl10353.h
index 5cc4ae718d8c..9770cb840cfc 100644
--- a/drivers/media/dvb/frontends/zl10353.h
+++ b/drivers/media/dvb/frontends/zl10353.h
@@ -29,10 +29,8 @@ struct zl10353_config
29 /* demodulator's I2C address */ 29 /* demodulator's I2C address */
30 u8 demod_address; 30 u8 demod_address;
31 31
32 /* function which configures the PLL buffer (for secondary I2C 32 /* set if no pll is connected to the secondary i2c bus */
33 * connected tuner) or tunes the PLL (for direct connected tuner) */ 33 int no_tuner;
34 int (*pll_set)(struct dvb_frontend *fe,
35 struct dvb_frontend_parameters *params, u8 *pllbuf);
36}; 34};
37 35
38extern struct dvb_frontend* zl10353_attach(const struct zl10353_config *config, 36extern struct dvb_frontend* zl10353_attach(const struct zl10353_config *config,
diff --git a/drivers/media/dvb/pluto2/pluto2.c b/drivers/media/dvb/pluto2/pluto2.c
index 1c5316e209ef..acabea0793b6 100644
--- a/drivers/media/dvb/pluto2/pluto2.c
+++ b/drivers/media/dvb/pluto2/pluto2.c
@@ -424,8 +424,8 @@ static inline u32 divide(u32 numerator, u32 denominator)
424} 424}
425 425
426/* LG Innotek TDTE-E001P (Infineon TUA6034) */ 426/* LG Innotek TDTE-E001P (Infineon TUA6034) */
427static int lg_tdtpe001p_pll_set(struct dvb_frontend *fe, 427static int lg_tdtpe001p_tuner_set_params(struct dvb_frontend *fe,
428 struct dvb_frontend_parameters *p) 428 struct dvb_frontend_parameters *p)
429{ 429{
430 struct pluto *pluto = frontend_to_pluto(fe); 430 struct pluto *pluto = frontend_to_pluto(fe);
431 struct i2c_msg msg; 431 struct i2c_msg msg;
@@ -473,6 +473,8 @@ static int lg_tdtpe001p_pll_set(struct dvb_frontend *fe,
473 msg.buf = buf; 473 msg.buf = buf;
474 msg.len = sizeof(buf); 474 msg.len = sizeof(buf);
475 475
476 if (fe->ops.i2c_gate_ctrl)
477 fe->ops.i2c_gate_ctrl(fe, 1);
476 ret = i2c_transfer(&pluto->i2c_adap, &msg, 1); 478 ret = i2c_transfer(&pluto->i2c_adap, &msg, 1);
477 if (ret < 0) 479 if (ret < 0)
478 return ret; 480 return ret;
@@ -497,8 +499,6 @@ static struct tda1004x_config pluto2_fe_config __devinitdata = {
497 .xtal_freq = TDA10046_XTAL_16M, 499 .xtal_freq = TDA10046_XTAL_16M,
498 .agc_config = TDA10046_AGC_DEFAULT, 500 .agc_config = TDA10046_AGC_DEFAULT,
499 .if_freq = TDA10046_FREQ_3617, 501 .if_freq = TDA10046_FREQ_3617,
500 .pll_set = lg_tdtpe001p_pll_set,
501 .pll_sleep = NULL,
502 .request_firmware = pluto2_request_firmware, 502 .request_firmware = pluto2_request_firmware,
503}; 503};
504 504
@@ -511,11 +511,12 @@ static int __devinit frontend_init(struct pluto *pluto)
511 dev_err(&pluto->pdev->dev, "could not attach frontend\n"); 511 dev_err(&pluto->pdev->dev, "could not attach frontend\n");
512 return -ENODEV; 512 return -ENODEV;
513 } 513 }
514 pluto->fe->ops.tuner_ops.set_params = lg_tdtpe001p_tuner_set_params;
514 515
515 ret = dvb_register_frontend(&pluto->dvb_adapter, pluto->fe); 516 ret = dvb_register_frontend(&pluto->dvb_adapter, pluto->fe);
516 if (ret < 0) { 517 if (ret < 0) {
517 if (pluto->fe->ops->release) 518 if (pluto->fe->ops.release)
518 pluto->fe->ops->release(pluto->fe); 519 pluto->fe->ops.release(pluto->fe);
519 return ret; 520 return ret;
520 } 521 }
521 522
@@ -647,7 +648,7 @@ static int __devinit pluto2_probe(struct pci_dev *pdev,
647 goto err_pluto_hw_exit; 648 goto err_pluto_hw_exit;
648 649
649 /* dvb */ 650 /* dvb */
650 ret = dvb_register_adapter(&pluto->dvb_adapter, DRIVER_NAME, THIS_MODULE); 651 ret = dvb_register_adapter(&pluto->dvb_adapter, DRIVER_NAME, THIS_MODULE, &pdev->dev);
651 if (ret < 0) 652 if (ret < 0)
652 goto err_i2c_bit_del_bus; 653 goto err_i2c_bit_del_bus;
653 654
diff --git a/drivers/media/dvb/ttpci/Kconfig b/drivers/media/dvb/ttpci/Kconfig
index b5ac7dfde52f..987881fa988c 100644
--- a/drivers/media/dvb/ttpci/Kconfig
+++ b/drivers/media/dvb/ttpci/Kconfig
@@ -10,6 +10,7 @@ config DVB_AV7110
10 select DVB_SP8870 10 select DVB_SP8870
11 select DVB_STV0297 11 select DVB_STV0297
12 select DVB_L64781 12 select DVB_L64781
13 select DVB_LNBP21
13 help 14 help
14 Support for SAA7146 and AV7110 based DVB cards as produced 15 Support for SAA7146 and AV7110 based DVB cards as produced
15 by Fujitsu-Siemens, Technotrend, Hauppauge and others. 16 by Fujitsu-Siemens, Technotrend, Hauppauge and others.
@@ -67,6 +68,7 @@ config DVB_BUDGET
67 select DVB_TDA8083 68 select DVB_TDA8083
68 select DVB_TDA10021 69 select DVB_TDA10021
69 select DVB_S5H1420 70 select DVB_S5H1420
71 select DVB_LNBP21
70 help 72 help
71 Support for simple SAA7146 based DVB cards 73 Support for simple SAA7146 based DVB cards
72 (so called Budget- or Nova-PCI cards) without onboard 74 (so called Budget- or Nova-PCI cards) without onboard
@@ -84,6 +86,7 @@ config DVB_BUDGET_CI
84 select DVB_STV0297 86 select DVB_STV0297
85 select DVB_STV0299 87 select DVB_STV0299
86 select DVB_TDA1004X 88 select DVB_TDA1004X
89 select DVB_LNBP21
87 help 90 help
88 Support for simple SAA7146 based DVB cards 91 Support for simple SAA7146 based DVB cards
89 (so called Budget- or Nova-PCI cards) without onboard 92 (so called Budget- or Nova-PCI cards) without onboard
diff --git a/drivers/media/dvb/ttpci/Makefile b/drivers/media/dvb/ttpci/Makefile
index a690730ac39d..aa85ecdc6c80 100644
--- a/drivers/media/dvb/ttpci/Makefile
+++ b/drivers/media/dvb/ttpci/Makefile
@@ -15,9 +15,9 @@ EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/
15 15
16hostprogs-y := fdump 16hostprogs-y := fdump
17 17
18ifdef CONFIG_DVB_AV7110_FIRMWARE 18ifeq ($(CONFIG_DVB_AV7110_FIRMWARE),y)
19$(obj)/av7110.o: $(obj)/fdump $(obj)/av7110_firm.h 19$(obj)/av7110.o: $(obj)/av7110_firm.h
20 20
21$(obj)/av7110_firm.h: 21$(obj)/av7110_firm.h: $(obj)/fdump
22 $(obj)/fdump $(CONFIG_DVB_AV7110_FIRMWARE_FILE) dvb_ttpci_fw $@ 22 $(obj)/fdump $(CONFIG_DVB_AV7110_FIRMWARE_FILE) dvb_ttpci_fw $@
23endif 23endif
diff --git a/drivers/media/dvb/ttpci/av7110.c b/drivers/media/dvb/ttpci/av7110.c
index d028245c8eed..8832f80c05f7 100644
--- a/drivers/media/dvb/ttpci/av7110.c
+++ b/drivers/media/dvb/ttpci/av7110.c
@@ -1552,7 +1552,7 @@ static int get_firmware(struct av7110* av7110)
1552#endif 1552#endif
1553 1553
1554 1554
1555static int alps_bsrv2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) 1555static int alps_bsrv2_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters *params)
1556{ 1556{
1557 struct av7110* av7110 = (struct av7110*) fe->dvb->priv; 1557 struct av7110* av7110 = (struct av7110*) fe->dvb->priv;
1558 u8 pwr = 0; 1558 u8 pwr = 0;
@@ -1575,6 +1575,8 @@ static int alps_bsrv2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_param
1575 // NOTE: since we're using a prescaler of 2, we set the 1575 // NOTE: since we're using a prescaler of 2, we set the
1576 // divisor frequency to 62.5kHz and divide by 125 above 1576 // divisor frequency to 62.5kHz and divide by 125 above
1577 1577
1578 if (fe->ops.i2c_gate_ctrl)
1579 fe->ops.i2c_gate_ctrl(fe, 1);
1578 if (i2c_transfer (&av7110->i2c_adap, &msg, 1) != 1) 1580 if (i2c_transfer (&av7110->i2c_adap, &msg, 1) != 1)
1579 return -EIO; 1581 return -EIO;
1580 return 0; 1582 return 0;
@@ -1584,10 +1586,9 @@ static struct ves1x93_config alps_bsrv2_config = {
1584 .demod_address = 0x08, 1586 .demod_address = 0x08,
1585 .xin = 90100000UL, 1587 .xin = 90100000UL,
1586 .invert_pwm = 0, 1588 .invert_pwm = 0,
1587 .pll_set = alps_bsrv2_pll_set,
1588}; 1589};
1589 1590
1590static int alps_tdbe2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) 1591static int alps_tdbe2_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters *params)
1591{ 1592{
1592 struct av7110* av7110 = fe->dvb->priv; 1593 struct av7110* av7110 = fe->dvb->priv;
1593 u32 div; 1594 u32 div;
@@ -1601,6 +1602,8 @@ static int alps_tdbe2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_param
1601 data[2] = 0x85 | ((div >> 10) & 0x60); 1602 data[2] = 0x85 | ((div >> 10) & 0x60);
1602 data[3] = (params->frequency < 174000000 ? 0x88 : params->frequency < 470000000 ? 0x84 : 0x81); 1603 data[3] = (params->frequency < 174000000 ? 0x88 : params->frequency < 470000000 ? 0x84 : 0x81);
1603 1604
1605 if (fe->ops.i2c_gate_ctrl)
1606 fe->ops.i2c_gate_ctrl(fe, 1);
1604 if (i2c_transfer(&av7110->i2c_adap, &msg, 1) != 1) 1607 if (i2c_transfer(&av7110->i2c_adap, &msg, 1) != 1)
1605 return -EIO; 1608 return -EIO;
1606 return 0; 1609 return 0;
@@ -1611,14 +1614,12 @@ static struct ves1820_config alps_tdbe2_config = {
1611 .xin = 57840000UL, 1614 .xin = 57840000UL,
1612 .invert = 1, 1615 .invert = 1,
1613 .selagc = VES1820_SELAGC_SIGNAMPERR, 1616 .selagc = VES1820_SELAGC_SIGNAMPERR,
1614 .pll_set = alps_tdbe2_pll_set,
1615}; 1617};
1616 1618
1617 1619
1618 1620
1619 1621
1620static int grundig_29504_451_pll_set(struct dvb_frontend* fe, 1622static int grundig_29504_451_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters *params)
1621 struct dvb_frontend_parameters* params)
1622{ 1623{
1623 struct av7110* av7110 = fe->dvb->priv; 1624 struct av7110* av7110 = fe->dvb->priv;
1624 u32 div; 1625 u32 div;
@@ -1631,6 +1632,8 @@ static int grundig_29504_451_pll_set(struct dvb_frontend* fe,
1631 data[2] = 0x8e; 1632 data[2] = 0x8e;
1632 data[3] = 0x00; 1633 data[3] = 0x00;
1633 1634
1635 if (fe->ops.i2c_gate_ctrl)
1636 fe->ops.i2c_gate_ctrl(fe, 1);
1634 if (i2c_transfer(&av7110->i2c_adap, &msg, 1) != 1) 1637 if (i2c_transfer(&av7110->i2c_adap, &msg, 1) != 1)
1635 return -EIO; 1638 return -EIO;
1636 return 0; 1639 return 0;
@@ -1638,13 +1641,11 @@ static int grundig_29504_451_pll_set(struct dvb_frontend* fe,
1638 1641
1639static struct tda8083_config grundig_29504_451_config = { 1642static struct tda8083_config grundig_29504_451_config = {
1640 .demod_address = 0x68, 1643 .demod_address = 0x68,
1641 .pll_set = grundig_29504_451_pll_set,
1642}; 1644};
1643 1645
1644 1646
1645 1647
1646static int philips_cd1516_pll_set(struct dvb_frontend* fe, 1648static int philips_cd1516_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters *params)
1647 struct dvb_frontend_parameters* params)
1648{ 1649{
1649 struct av7110* av7110 = fe->dvb->priv; 1650 struct av7110* av7110 = fe->dvb->priv;
1650 u32 div; 1651 u32 div;
@@ -1659,6 +1660,8 @@ static int philips_cd1516_pll_set(struct dvb_frontend* fe,
1659 data[2] = 0x8e; 1660 data[2] = 0x8e;
1660 data[3] = (f < 174000000 ? 0xa1 : f < 470000000 ? 0x92 : 0x34); 1661 data[3] = (f < 174000000 ? 0xa1 : f < 470000000 ? 0x92 : 0x34);
1661 1662
1663 if (fe->ops.i2c_gate_ctrl)
1664 fe->ops.i2c_gate_ctrl(fe, 1);
1662 if (i2c_transfer(&av7110->i2c_adap, &msg, 1) != 1) 1665 if (i2c_transfer(&av7110->i2c_adap, &msg, 1) != 1)
1663 return -EIO; 1666 return -EIO;
1664 return 0; 1667 return 0;
@@ -1669,12 +1672,11 @@ static struct ves1820_config philips_cd1516_config = {
1669 .xin = 57840000UL, 1672 .xin = 57840000UL,
1670 .invert = 1, 1673 .invert = 1,
1671 .selagc = VES1820_SELAGC_SIGNAMPERR, 1674 .selagc = VES1820_SELAGC_SIGNAMPERR,
1672 .pll_set = philips_cd1516_pll_set,
1673}; 1675};
1674 1676
1675 1677
1676 1678
1677static int alps_tdlb7_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) 1679static int alps_tdlb7_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters *params)
1678{ 1680{
1679 struct av7110* av7110 = fe->dvb->priv; 1681 struct av7110* av7110 = fe->dvb->priv;
1680 u32 div, pwr; 1682 u32 div, pwr;
@@ -1693,6 +1695,8 @@ static int alps_tdlb7_pll_set(struct dvb_frontend* fe, struct dvb_frontend_param
1693 data[2] = 0x85; 1695 data[2] = 0x85;
1694 data[3] = pwr << 6; 1696 data[3] = pwr << 6;
1695 1697
1698 if (fe->ops.i2c_gate_ctrl)
1699 fe->ops.i2c_gate_ctrl(fe, 1);
1696 if (i2c_transfer(&av7110->i2c_adap, &msg, 1) != 1) 1700 if (i2c_transfer(&av7110->i2c_adap, &msg, 1) != 1)
1697 return -EIO; 1701 return -EIO;
1698 return 0; 1702 return 0;
@@ -1708,7 +1712,6 @@ static int alps_tdlb7_request_firmware(struct dvb_frontend* fe, const struct fir
1708static struct sp8870_config alps_tdlb7_config = { 1712static struct sp8870_config alps_tdlb7_config = {
1709 1713
1710 .demod_address = 0x71, 1714 .demod_address = 0x71,
1711 .pll_set = alps_tdlb7_pll_set,
1712 .request_firmware = alps_tdlb7_request_firmware, 1715 .request_firmware = alps_tdlb7_request_firmware,
1713}; 1716};
1714 1717
@@ -1806,7 +1809,7 @@ static u8 nexusca_stv0297_inittab[] = {
1806 0xff, 0xff, 1809 0xff, 0xff,
1807}; 1810};
1808 1811
1809static int nexusca_stv0297_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) 1812static int nexusca_stv0297_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters *params)
1810{ 1813{
1811 struct av7110* av7110 = fe->dvb->priv; 1814 struct av7110* av7110 = fe->dvb->priv;
1812 u32 div; 1815 u32 div;
@@ -1832,7 +1835,8 @@ static int nexusca_stv0297_pll_set(struct dvb_frontend* fe, struct dvb_frontend_
1832 else 1835 else
1833 return -EINVAL; 1836 return -EINVAL;
1834 1837
1835 stv0297_enable_plli2c(fe); 1838 if (fe->ops.i2c_gate_ctrl)
1839 fe->ops.i2c_gate_ctrl(fe, 1);
1836 if (i2c_transfer(&av7110->i2c_adap, &msg, 1) != 1) { 1840 if (i2c_transfer(&av7110->i2c_adap, &msg, 1) != 1) {
1837 printk("nexusca: pll transfer failed!\n"); 1841 printk("nexusca: pll transfer failed!\n");
1838 return -EIO; 1842 return -EIO;
@@ -1840,8 +1844,8 @@ static int nexusca_stv0297_pll_set(struct dvb_frontend* fe, struct dvb_frontend_
1840 1844
1841 // wait for PLL lock 1845 // wait for PLL lock
1842 for(i = 0; i < 20; i++) { 1846 for(i = 0; i < 20; i++) {
1843 1847 if (fe->ops.i2c_gate_ctrl)
1844 stv0297_enable_plli2c(fe); 1848 fe->ops.i2c_gate_ctrl(fe, 1);
1845 if (i2c_transfer(&av7110->i2c_adap, &readmsg, 1) == 1) 1849 if (i2c_transfer(&av7110->i2c_adap, &readmsg, 1) == 1)
1846 if (data[0] & 0x40) break; 1850 if (data[0] & 0x40) break;
1847 msleep(10); 1851 msleep(10);
@@ -1855,12 +1859,12 @@ static struct stv0297_config nexusca_stv0297_config = {
1855 .demod_address = 0x1C, 1859 .demod_address = 0x1C,
1856 .inittab = nexusca_stv0297_inittab, 1860 .inittab = nexusca_stv0297_inittab,
1857 .invert = 1, 1861 .invert = 1,
1858 .pll_set = nexusca_stv0297_pll_set, 1862 .stop_during_read = 1,
1859}; 1863};
1860 1864
1861 1865
1862 1866
1863static int grundig_29504_401_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) 1867static int grundig_29504_401_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters *params)
1864{ 1868{
1865 struct av7110* av7110 = (struct av7110*) fe->dvb->priv; 1869 struct av7110* av7110 = (struct av7110*) fe->dvb->priv;
1866 u32 div; 1870 u32 div;
@@ -1887,13 +1891,14 @@ static int grundig_29504_401_pll_set(struct dvb_frontend* fe, struct dvb_fronten
1887 data[2] = ((div >> 10) & 0x60) | cfg; 1891 data[2] = ((div >> 10) & 0x60) | cfg;
1888 data[3] = (cpump << 6) | band_select; 1892 data[3] = (cpump << 6) | band_select;
1889 1893
1894 if (fe->ops.i2c_gate_ctrl)
1895 fe->ops.i2c_gate_ctrl(fe, 1);
1890 if (i2c_transfer (&av7110->i2c_adap, &msg, 1) != 1) return -EIO; 1896 if (i2c_transfer (&av7110->i2c_adap, &msg, 1) != 1) return -EIO;
1891 return 0; 1897 return 0;
1892} 1898}
1893 1899
1894static struct l64781_config grundig_29504_401_config = { 1900static struct l64781_config grundig_29504_401_config = {
1895 .demod_address = 0x55, 1901 .demod_address = 0x55,
1896 .pll_set = grundig_29504_401_pll_set,
1897}; 1902};
1898 1903
1899 1904
@@ -2079,6 +2084,9 @@ static int frontend_init(struct av7110 *av7110)
2079 case 0x0000: // Fujitsu/Siemens DVB-Cable (ves1820/Philips CD1516(??)) 2084 case 0x0000: // Fujitsu/Siemens DVB-Cable (ves1820/Philips CD1516(??))
2080 av7110->fe = ves1820_attach(&philips_cd1516_config, 2085 av7110->fe = ves1820_attach(&philips_cd1516_config,
2081 &av7110->i2c_adap, read_pwm(av7110)); 2086 &av7110->i2c_adap, read_pwm(av7110));
2087 if (av7110->fe) {
2088 av7110->fe->ops.tuner_ops.set_params = philips_cd1516_tuner_set_params;
2089 }
2082 break; 2090 break;
2083 } 2091 }
2084 2092
@@ -2091,9 +2099,10 @@ static int frontend_init(struct av7110 *av7110)
2091 // try the ALPS BSRV2 first of all 2099 // try the ALPS BSRV2 first of all
2092 av7110->fe = ves1x93_attach(&alps_bsrv2_config, &av7110->i2c_adap); 2100 av7110->fe = ves1x93_attach(&alps_bsrv2_config, &av7110->i2c_adap);
2093 if (av7110->fe) { 2101 if (av7110->fe) {
2094 av7110->fe->ops->diseqc_send_master_cmd = av7110_diseqc_send_master_cmd; 2102 av7110->fe->ops.tuner_ops.set_params = alps_bsrv2_tuner_set_params;
2095 av7110->fe->ops->diseqc_send_burst = av7110_diseqc_send_burst; 2103 av7110->fe->ops.diseqc_send_master_cmd = av7110_diseqc_send_master_cmd;
2096 av7110->fe->ops->set_tone = av7110_set_tone; 2104 av7110->fe->ops.diseqc_send_burst = av7110_diseqc_send_burst;
2105 av7110->fe->ops.set_tone = av7110_set_tone;
2097 av7110->recover = dvb_s_recover; 2106 av7110->recover = dvb_s_recover;
2098 break; 2107 break;
2099 } 2108 }
@@ -2101,9 +2110,12 @@ static int frontend_init(struct av7110 *av7110)
2101 // try the ALPS BSRU6 now 2110 // try the ALPS BSRU6 now
2102 av7110->fe = stv0299_attach(&alps_bsru6_config, &av7110->i2c_adap); 2111 av7110->fe = stv0299_attach(&alps_bsru6_config, &av7110->i2c_adap);
2103 if (av7110->fe) { 2112 if (av7110->fe) {
2104 av7110->fe->ops->diseqc_send_master_cmd = av7110_diseqc_send_master_cmd; 2113 av7110->fe->ops.tuner_ops.set_params = alps_bsru6_tuner_set_params;
2105 av7110->fe->ops->diseqc_send_burst = av7110_diseqc_send_burst; 2114 av7110->fe->tuner_priv = &av7110->i2c_adap;
2106 av7110->fe->ops->set_tone = av7110_set_tone; 2115
2116 av7110->fe->ops.diseqc_send_master_cmd = av7110_diseqc_send_master_cmd;
2117 av7110->fe->ops.diseqc_send_burst = av7110_diseqc_send_burst;
2118 av7110->fe->ops.set_tone = av7110_set_tone;
2107 av7110->recover = dvb_s_recover; 2119 av7110->recover = dvb_s_recover;
2108 break; 2120 break;
2109 } 2121 }
@@ -2111,9 +2123,10 @@ static int frontend_init(struct av7110 *av7110)
2111 // Try the grundig 29504-451 2123 // Try the grundig 29504-451
2112 av7110->fe = tda8083_attach(&grundig_29504_451_config, &av7110->i2c_adap); 2124 av7110->fe = tda8083_attach(&grundig_29504_451_config, &av7110->i2c_adap);
2113 if (av7110->fe) { 2125 if (av7110->fe) {
2114 av7110->fe->ops->diseqc_send_master_cmd = av7110_diseqc_send_master_cmd; 2126 av7110->fe->ops.tuner_ops.set_params = grundig_29504_451_tuner_set_params;
2115 av7110->fe->ops->diseqc_send_burst = av7110_diseqc_send_burst; 2127 av7110->fe->ops.diseqc_send_master_cmd = av7110_diseqc_send_master_cmd;
2116 av7110->fe->ops->set_tone = av7110_set_tone; 2128 av7110->fe->ops.diseqc_send_burst = av7110_diseqc_send_burst;
2129 av7110->fe->ops.set_tone = av7110_set_tone;
2117 av7110->recover = dvb_s_recover; 2130 av7110->recover = dvb_s_recover;
2118 break; 2131 break;
2119 } 2132 }
@@ -2124,11 +2137,17 @@ static int frontend_init(struct av7110 *av7110)
2124 /* Siemens DVB-C (full-length card) VES1820/Philips CD1516 */ 2137 /* Siemens DVB-C (full-length card) VES1820/Philips CD1516 */
2125 av7110->fe = ves1820_attach(&philips_cd1516_config, &av7110->i2c_adap, 2138 av7110->fe = ves1820_attach(&philips_cd1516_config, &av7110->i2c_adap,
2126 read_pwm(av7110)); 2139 read_pwm(av7110));
2140 if (av7110->fe) {
2141 av7110->fe->ops.tuner_ops.set_params = philips_cd1516_tuner_set_params;
2142 }
2127 break; 2143 break;
2128 case 0x0003: 2144 case 0x0003:
2129 /* Hauppauge DVB-C 2.1 VES1820/ALPS TDBE2 */ 2145 /* Hauppauge DVB-C 2.1 VES1820/ALPS TDBE2 */
2130 av7110->fe = ves1820_attach(&alps_tdbe2_config, &av7110->i2c_adap, 2146 av7110->fe = ves1820_attach(&alps_tdbe2_config, &av7110->i2c_adap,
2131 read_pwm(av7110)); 2147 read_pwm(av7110));
2148 if (av7110->fe) {
2149 av7110->fe->ops.tuner_ops.set_params = alps_tdbe2_tuner_set_params;
2150 }
2132 break; 2151 break;
2133 } 2152 }
2134 break; 2153 break;
@@ -2137,20 +2156,27 @@ static int frontend_init(struct av7110 *av7110)
2137 2156
2138 // ALPS TDLB7 2157 // ALPS TDLB7
2139 av7110->fe = sp8870_attach(&alps_tdlb7_config, &av7110->i2c_adap); 2158 av7110->fe = sp8870_attach(&alps_tdlb7_config, &av7110->i2c_adap);
2159 if (av7110->fe) {
2160 av7110->fe->ops.tuner_ops.set_params = alps_tdlb7_tuner_set_params;
2161 }
2140 break; 2162 break;
2141 2163
2142 case 0x0002: // Hauppauge/TT DVB-C premium rev2.X 2164 case 0x0002: // Hauppauge/TT DVB-C premium rev2.X
2143 2165
2144 av7110->fe = ves1820_attach(&alps_tdbe2_config, &av7110->i2c_adap, read_pwm(av7110)); 2166 av7110->fe = ves1820_attach(&alps_tdbe2_config, &av7110->i2c_adap, read_pwm(av7110));
2167 if (av7110->fe) {
2168 av7110->fe->ops.tuner_ops.set_params = alps_tdbe2_tuner_set_params;
2169 }
2145 break; 2170 break;
2146 2171
2147 case 0x0004: // Galaxis DVB-S rev1.3 2172 case 0x0004: // Galaxis DVB-S rev1.3
2148 /* ALPS BSRV2 */ 2173 /* ALPS BSRV2 */
2149 av7110->fe = ves1x93_attach(&alps_bsrv2_config, &av7110->i2c_adap); 2174 av7110->fe = ves1x93_attach(&alps_bsrv2_config, &av7110->i2c_adap);
2150 if (av7110->fe) { 2175 if (av7110->fe) {
2151 av7110->fe->ops->diseqc_send_master_cmd = av7110_diseqc_send_master_cmd; 2176 av7110->fe->ops.tuner_ops.set_params = alps_bsrv2_tuner_set_params;
2152 av7110->fe->ops->diseqc_send_burst = av7110_diseqc_send_burst; 2177 av7110->fe->ops.diseqc_send_master_cmd = av7110_diseqc_send_master_cmd;
2153 av7110->fe->ops->set_tone = av7110_set_tone; 2178 av7110->fe->ops.diseqc_send_burst = av7110_diseqc_send_burst;
2179 av7110->fe->ops.set_tone = av7110_set_tone;
2154 av7110->recover = dvb_s_recover; 2180 av7110->recover = dvb_s_recover;
2155 } 2181 }
2156 break; 2182 break;
@@ -2159,9 +2185,10 @@ static int frontend_init(struct av7110 *av7110)
2159 /* Grundig 29504-451 */ 2185 /* Grundig 29504-451 */
2160 av7110->fe = tda8083_attach(&grundig_29504_451_config, &av7110->i2c_adap); 2186 av7110->fe = tda8083_attach(&grundig_29504_451_config, &av7110->i2c_adap);
2161 if (av7110->fe) { 2187 if (av7110->fe) {
2162 av7110->fe->ops->diseqc_send_master_cmd = av7110_diseqc_send_master_cmd; 2188 av7110->fe->ops.tuner_ops.set_params = grundig_29504_451_tuner_set_params;
2163 av7110->fe->ops->diseqc_send_burst = av7110_diseqc_send_burst; 2189 av7110->fe->ops.diseqc_send_master_cmd = av7110_diseqc_send_master_cmd;
2164 av7110->fe->ops->set_tone = av7110_set_tone; 2190 av7110->fe->ops.diseqc_send_burst = av7110_diseqc_send_burst;
2191 av7110->fe->ops.set_tone = av7110_set_tone;
2165 av7110->recover = dvb_s_recover; 2192 av7110->recover = dvb_s_recover;
2166 } 2193 }
2167 break; 2194 break;
@@ -2169,12 +2196,17 @@ static int frontend_init(struct av7110 *av7110)
2169 case 0x0008: // Hauppauge/TT DVB-T 2196 case 0x0008: // Hauppauge/TT DVB-T
2170 2197
2171 av7110->fe = l64781_attach(&grundig_29504_401_config, &av7110->i2c_adap); 2198 av7110->fe = l64781_attach(&grundig_29504_401_config, &av7110->i2c_adap);
2199 if (av7110->fe) {
2200 av7110->fe->ops.tuner_ops.set_params = grundig_29504_401_tuner_set_params;
2201 }
2172 break; 2202 break;
2173 2203
2174 case 0x000A: // Hauppauge/TT Nexus-CA rev1.X 2204 case 0x000A: // Hauppauge/TT Nexus-CA rev1.X
2175 2205
2176 av7110->fe = stv0297_attach(&nexusca_stv0297_config, &av7110->i2c_adap); 2206 av7110->fe = stv0297_attach(&nexusca_stv0297_config, &av7110->i2c_adap);
2177 if (av7110->fe) { 2207 if (av7110->fe) {
2208 av7110->fe->ops.tuner_ops.set_params = nexusca_stv0297_tuner_set_params;
2209
2178 /* set TDA9819 into DVB mode */ 2210 /* set TDA9819 into DVB mode */
2179 saa7146_setgpio(av7110->dev, 1, SAA7146_GPIO_OUTLO); // TDA9198 pin9(STD) 2211 saa7146_setgpio(av7110->dev, 1, SAA7146_GPIO_OUTLO); // TDA9198 pin9(STD)
2180 saa7146_setgpio(av7110->dev, 3, SAA7146_GPIO_OUTLO); // TDA9198 pin30(VIF) 2212 saa7146_setgpio(av7110->dev, 3, SAA7146_GPIO_OUTLO); // TDA9198 pin30(VIF)
@@ -2189,13 +2221,16 @@ static int frontend_init(struct av7110 *av7110)
2189 /* ALPS BSBE1 */ 2221 /* ALPS BSBE1 */
2190 av7110->fe = stv0299_attach(&alps_bsbe1_config, &av7110->i2c_adap); 2222 av7110->fe = stv0299_attach(&alps_bsbe1_config, &av7110->i2c_adap);
2191 if (av7110->fe) { 2223 if (av7110->fe) {
2192 if (lnbp21_init(av7110->fe, &av7110->i2c_adap, 0, 0)) { 2224 av7110->fe->ops.tuner_ops.set_params = alps_bsbe1_tuner_set_params;
2225 av7110->fe->tuner_priv = &av7110->i2c_adap;
2226
2227 if (lnbp21_attach(av7110->fe, &av7110->i2c_adap, 0, 0)) {
2193 printk("dvb-ttpci: LNBP21 not found!\n"); 2228 printk("dvb-ttpci: LNBP21 not found!\n");
2194 if (av7110->fe->ops->release) 2229 if (av7110->fe->ops.release)
2195 av7110->fe->ops->release(av7110->fe); 2230 av7110->fe->ops.release(av7110->fe);
2196 av7110->fe = NULL; 2231 av7110->fe = NULL;
2197 } else { 2232 } else {
2198 av7110->fe->ops->dishnetwork_send_legacy_command = NULL; 2233 av7110->fe->ops.dishnetwork_send_legacy_command = NULL;
2199 av7110->recover = dvb_s_recover; 2234 av7110->recover = dvb_s_recover;
2200 } 2235 }
2201 } 2236 }
@@ -2212,21 +2247,21 @@ static int frontend_init(struct av7110 *av7110)
2212 av7110->dev->pci->subsystem_vendor, 2247 av7110->dev->pci->subsystem_vendor,
2213 av7110->dev->pci->subsystem_device); 2248 av7110->dev->pci->subsystem_device);
2214 } else { 2249 } else {
2215 FE_FUNC_OVERRIDE(av7110->fe->ops->init, av7110->fe_init, av7110_fe_init); 2250 FE_FUNC_OVERRIDE(av7110->fe->ops.init, av7110->fe_init, av7110_fe_init);
2216 FE_FUNC_OVERRIDE(av7110->fe->ops->read_status, av7110->fe_read_status, av7110_fe_read_status); 2251 FE_FUNC_OVERRIDE(av7110->fe->ops.read_status, av7110->fe_read_status, av7110_fe_read_status);
2217 FE_FUNC_OVERRIDE(av7110->fe->ops->diseqc_reset_overload, av7110->fe_diseqc_reset_overload, av7110_fe_diseqc_reset_overload); 2252 FE_FUNC_OVERRIDE(av7110->fe->ops.diseqc_reset_overload, av7110->fe_diseqc_reset_overload, av7110_fe_diseqc_reset_overload);
2218 FE_FUNC_OVERRIDE(av7110->fe->ops->diseqc_send_master_cmd, av7110->fe_diseqc_send_master_cmd, av7110_fe_diseqc_send_master_cmd); 2253 FE_FUNC_OVERRIDE(av7110->fe->ops.diseqc_send_master_cmd, av7110->fe_diseqc_send_master_cmd, av7110_fe_diseqc_send_master_cmd);
2219 FE_FUNC_OVERRIDE(av7110->fe->ops->diseqc_send_burst, av7110->fe_diseqc_send_burst, av7110_fe_diseqc_send_burst); 2254 FE_FUNC_OVERRIDE(av7110->fe->ops.diseqc_send_burst, av7110->fe_diseqc_send_burst, av7110_fe_diseqc_send_burst);
2220 FE_FUNC_OVERRIDE(av7110->fe->ops->set_tone, av7110->fe_set_tone, av7110_fe_set_tone); 2255 FE_FUNC_OVERRIDE(av7110->fe->ops.set_tone, av7110->fe_set_tone, av7110_fe_set_tone);
2221 FE_FUNC_OVERRIDE(av7110->fe->ops->set_voltage, av7110->fe_set_voltage, av7110_fe_set_voltage;) 2256 FE_FUNC_OVERRIDE(av7110->fe->ops.set_voltage, av7110->fe_set_voltage, av7110_fe_set_voltage;)
2222 FE_FUNC_OVERRIDE(av7110->fe->ops->dishnetwork_send_legacy_command, av7110->fe_dishnetwork_send_legacy_command, av7110_fe_dishnetwork_send_legacy_command); 2257 FE_FUNC_OVERRIDE(av7110->fe->ops.dishnetwork_send_legacy_command, av7110->fe_dishnetwork_send_legacy_command, av7110_fe_dishnetwork_send_legacy_command);
2223 FE_FUNC_OVERRIDE(av7110->fe->ops->set_frontend, av7110->fe_set_frontend, av7110_fe_set_frontend); 2258 FE_FUNC_OVERRIDE(av7110->fe->ops.set_frontend, av7110->fe_set_frontend, av7110_fe_set_frontend);
2224 2259
2225 ret = dvb_register_frontend(&av7110->dvb_adapter, av7110->fe); 2260 ret = dvb_register_frontend(&av7110->dvb_adapter, av7110->fe);
2226 if (ret < 0) { 2261 if (ret < 0) {
2227 printk("av7110: Frontend registration failed!\n"); 2262 printk("av7110: Frontend registration failed!\n");
2228 if (av7110->fe->ops->release) 2263 if (av7110->fe->ops.release)
2229 av7110->fe->ops->release(av7110->fe); 2264 av7110->fe->ops.release(av7110->fe);
2230 av7110->fe = NULL; 2265 av7110->fe = NULL;
2231 } 2266 }
2232 } 2267 }
@@ -2413,7 +2448,7 @@ static int __devinit av7110_attach(struct saa7146_dev* dev,
2413 goto err_kfree_0; 2448 goto err_kfree_0;
2414 2449
2415 ret = dvb_register_adapter(&av7110->dvb_adapter, av7110->card_name, 2450 ret = dvb_register_adapter(&av7110->dvb_adapter, av7110->card_name,
2416 THIS_MODULE); 2451 THIS_MODULE, &dev->pci->dev);
2417 if (ret < 0) 2452 if (ret < 0)
2418 goto err_put_firmware_1; 2453 goto err_put_firmware_1;
2419 2454
diff --git a/drivers/media/dvb/ttpci/budget-av.c b/drivers/media/dvb/ttpci/budget-av.c
index 8a7cd7d505cf..6163cb03b8f4 100644
--- a/drivers/media/dvb/ttpci/budget-av.c
+++ b/drivers/media/dvb/ttpci/budget-av.c
@@ -50,6 +50,12 @@
50 50
51#define DEBICICAM 0x02420000 51#define DEBICICAM 0x02420000
52 52
53#define SLOTSTATUS_NONE 1
54#define SLOTSTATUS_PRESENT 2
55#define SLOTSTATUS_RESET 4
56#define SLOTSTATUS_READY 8
57#define SLOTSTATUS_OCCUPIED (SLOTSTATUS_PRESENT|SLOTSTATUS_RESET|SLOTSTATUS_READY)
58
53struct budget_av { 59struct budget_av {
54 struct budget budget; 60 struct budget budget;
55 struct video_device *vd; 61 struct video_device *vd;
@@ -58,8 +64,15 @@ struct budget_av {
58 struct tasklet_struct ciintf_irq_tasklet; 64 struct tasklet_struct ciintf_irq_tasklet;
59 int slot_status; 65 int slot_status;
60 struct dvb_ca_en50221 ca; 66 struct dvb_ca_en50221 ca;
67 u8 reinitialise_demod:1;
68 u8 tda10021_poclkp:1;
69 u8 tda10021_ts_enabled;
70 int (*tda10021_set_frontend)(struct dvb_frontend *fe, struct dvb_frontend_parameters *p);
61}; 71};
62 72
73static int ciintf_slot_shutdown(struct dvb_ca_en50221 *ca, int slot);
74
75
63/* GPIO Connections: 76/* GPIO Connections:
64 * 0 - Vcc/Reset (Reset is controlled by capacitor). Resets the frontend *AS WELL*! 77 * 0 - Vcc/Reset (Reset is controlled by capacitor). Resets the frontend *AS WELL*!
65 * 1 - CI memory select 0=>IO memory, 1=>Attribute Memory 78 * 1 - CI memory select 0=>IO memory, 1=>Attribute Memory
@@ -129,9 +142,10 @@ static int ciintf_read_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int ad
129 udelay(1); 142 udelay(1);
130 143
131 result = ttpci_budget_debiread(&budget_av->budget, DEBICICAM, address & 0xfff, 1, 0, 1); 144 result = ttpci_budget_debiread(&budget_av->budget, DEBICICAM, address & 0xfff, 1, 0, 1);
132 145 if (result == -ETIMEDOUT) {
133 if (result == -ETIMEDOUT) 146 ciintf_slot_shutdown(ca, slot);
134 budget_av->slot_status = 0; 147 printk(KERN_INFO "budget-av: cam ejected 1\n");
148 }
135 return result; 149 return result;
136} 150}
137 151
@@ -147,9 +161,10 @@ static int ciintf_write_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int a
147 udelay(1); 161 udelay(1);
148 162
149 result = ttpci_budget_debiwrite(&budget_av->budget, DEBICICAM, address & 0xfff, 1, value, 0, 1); 163 result = ttpci_budget_debiwrite(&budget_av->budget, DEBICICAM, address & 0xfff, 1, value, 0, 1);
150 164 if (result == -ETIMEDOUT) {
151 if (result == -ETIMEDOUT) 165 ciintf_slot_shutdown(ca, slot);
152 budget_av->slot_status = 0; 166 printk(KERN_INFO "budget-av: cam ejected 2\n");
167 }
153 return result; 168 return result;
154} 169}
155 170
@@ -165,9 +180,11 @@ static int ciintf_read_cam_control(struct dvb_ca_en50221 *ca, int slot, u8 addre
165 udelay(1); 180 udelay(1);
166 181
167 result = ttpci_budget_debiread(&budget_av->budget, DEBICICAM, address & 3, 1, 0, 0); 182 result = ttpci_budget_debiread(&budget_av->budget, DEBICICAM, address & 3, 1, 0, 0);
168 183 if ((result == -ETIMEDOUT) || ((result == 0xff) && ((address & 3) < 2))) {
169 if (result == -ETIMEDOUT) 184 ciintf_slot_shutdown(ca, slot);
170 budget_av->slot_status = 0; 185 printk(KERN_INFO "budget-av: cam ejected 3\n");
186 return -ETIMEDOUT;
187 }
171 return result; 188 return result;
172} 189}
173 190
@@ -183,9 +200,10 @@ static int ciintf_write_cam_control(struct dvb_ca_en50221 *ca, int slot, u8 addr
183 udelay(1); 200 udelay(1);
184 201
185 result = ttpci_budget_debiwrite(&budget_av->budget, DEBICICAM, address & 3, 1, value, 0, 0); 202 result = ttpci_budget_debiwrite(&budget_av->budget, DEBICICAM, address & 3, 1, value, 0, 0);
186 203 if (result == -ETIMEDOUT) {
187 if (result == -ETIMEDOUT) 204 ciintf_slot_shutdown(ca, slot);
188 budget_av->slot_status = 0; 205 printk(KERN_INFO "budget-av: cam ejected 5\n");
206 }
189 return result; 207 return result;
190} 208}
191 209
@@ -193,12 +211,12 @@ static int ciintf_slot_reset(struct dvb_ca_en50221 *ca, int slot)
193{ 211{
194 struct budget_av *budget_av = (struct budget_av *) ca->data; 212 struct budget_av *budget_av = (struct budget_av *) ca->data;
195 struct saa7146_dev *saa = budget_av->budget.dev; 213 struct saa7146_dev *saa = budget_av->budget.dev;
196 int timeout = 50; // 5 seconds (4.4.6 Ready)
197 214
198 if (slot != 0) 215 if (slot != 0)
199 return -EINVAL; 216 return -EINVAL;
200 217
201 dprintk(1, "ciintf_slot_reset\n"); 218 dprintk(1, "ciintf_slot_reset\n");
219 budget_av->slot_status = SLOTSTATUS_RESET;
202 220
203 saa7146_setgpio(saa, 2, SAA7146_GPIO_OUTHI); /* disable card */ 221 saa7146_setgpio(saa, 2, SAA7146_GPIO_OUTHI); /* disable card */
204 222
@@ -208,20 +226,17 @@ static int ciintf_slot_reset(struct dvb_ca_en50221 *ca, int slot)
208 msleep(20); /* 20 ms Vcc settling time */ 226 msleep(20); /* 20 ms Vcc settling time */
209 227
210 saa7146_setgpio(saa, 2, SAA7146_GPIO_OUTLO); /* enable card */ 228 saa7146_setgpio(saa, 2, SAA7146_GPIO_OUTLO); /* enable card */
229 ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTB);
230 msleep(20);
211 231
212 /* This should have been based on pin 16 READY of the pcmcia port, 232 /* reinitialise the frontend if necessary */
213 * but AFAICS it is not routed to the saa7146 */ 233 if (budget_av->reinitialise_demod)
214 while (--timeout > 0 && ciintf_read_attribute_mem(ca, slot, 0) != 0x1d) 234 dvb_frontend_reinitialise(budget_av->budget.dvb_frontend);
215 msleep(100);
216
217 /* reinitialise the frontend */
218 dvb_frontend_reinitialise(budget_av->budget.dvb_frontend);
219 235
220 if (timeout <= 0) 236 /* set tda10021 back to original clock configuration on reset */
221 { 237 if (budget_av->tda10021_poclkp) {
222 printk(KERN_ERR "budget-av: cam reset failed (timeout).\n"); 238 tda10021_write_byte(budget_av->budget.dvb_frontend, 0x12, 0xa0);
223 saa7146_setgpio(saa, 2, SAA7146_GPIO_OUTHI); /* disable card */ 239 budget_av->tda10021_ts_enabled = 0;
224 return -ETIMEDOUT;
225 } 240 }
226 241
227 return 0; 242 return 0;
@@ -238,7 +253,13 @@ static int ciintf_slot_shutdown(struct dvb_ca_en50221 *ca, int slot)
238 dprintk(1, "ciintf_slot_shutdown\n"); 253 dprintk(1, "ciintf_slot_shutdown\n");
239 254
240 ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTB); 255 ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTB);
241 budget_av->slot_status = 0; 256 budget_av->slot_status = SLOTSTATUS_NONE;
257
258 /* set tda10021 back to original clock configuration when cam removed */
259 if (budget_av->tda10021_poclkp) {
260 tda10021_write_byte(budget_av->budget.dvb_frontend, 0x12, 0xa0);
261 budget_av->tda10021_ts_enabled = 0;
262 }
242 return 0; 263 return 0;
243} 264}
244 265
@@ -253,6 +274,13 @@ static int ciintf_slot_ts_enable(struct dvb_ca_en50221 *ca, int slot)
253 dprintk(1, "ciintf_slot_ts_enable: %d\n", budget_av->slot_status); 274 dprintk(1, "ciintf_slot_ts_enable: %d\n", budget_av->slot_status);
254 275
255 ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTA); 276 ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTA);
277
278 /* tda10021 seems to need a different TS clock config when data is routed to the CAM */
279 if (budget_av->tda10021_poclkp) {
280 tda10021_write_byte(budget_av->budget.dvb_frontend, 0x12, 0xa1);
281 budget_av->tda10021_ts_enabled = 1;
282 }
283
256 return 0; 284 return 0;
257} 285}
258 286
@@ -260,50 +288,61 @@ static int ciintf_poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int open
260{ 288{
261 struct budget_av *budget_av = (struct budget_av *) ca->data; 289 struct budget_av *budget_av = (struct budget_av *) ca->data;
262 struct saa7146_dev *saa = budget_av->budget.dev; 290 struct saa7146_dev *saa = budget_av->budget.dev;
263 int cam_present = 0; 291 int result;
264 292
265 if (slot != 0) 293 if (slot != 0)
266 return -EINVAL; 294 return -EINVAL;
267 295
268 if (!budget_av->slot_status) 296 /* test the card detect line - needs to be done carefully
269 { 297 * since it never goes high for some CAMs on this interface (e.g. topuptv) */
270 // first of all test the card detect line 298 if (budget_av->slot_status == SLOTSTATUS_NONE) {
271 saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT); 299 saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT);
272 udelay(1); 300 udelay(1);
273 if (saa7146_read(saa, PSR) & MASK_06) 301 if (saa7146_read(saa, PSR) & MASK_06) {
274 { 302 if (budget_av->slot_status == SLOTSTATUS_NONE) {
275 cam_present = 1; 303 budget_av->slot_status = SLOTSTATUS_PRESENT;
304 printk(KERN_INFO "budget-av: cam inserted A\n");
305 }
276 } 306 }
277 saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTLO); 307 saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTLO);
308 }
278 309
279 // that is unreliable however, so try and read from IO memory 310 /* We also try and read from IO memory to work round the above detection bug. If
280 if (!cam_present) 311 * there is no CAM, we will get a timeout. Only done if there is no cam
281 { 312 * present, since this test actually breaks some cams :(
282 saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTLO); 313 *
283 if (ttpci_budget_debiread(&budget_av->budget, DEBICICAM, 0, 1, 0, 1) != -ETIMEDOUT) 314 * if the CI interface is not open, we also do the above test since we
284 { 315 * don't care if the cam has problems - we'll be resetting it on open() anyway */
285 cam_present = 1; 316 if ((budget_av->slot_status == SLOTSTATUS_NONE) || (!open)) {
317 saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTLO);
318 result = ttpci_budget_debiread(&budget_av->budget, DEBICICAM, 0, 1, 0, 1);
319 if ((result >= 0) && (budget_av->slot_status == SLOTSTATUS_NONE)) {
320 budget_av->slot_status = SLOTSTATUS_PRESENT;
321 printk(KERN_INFO "budget-av: cam inserted B\n");
322 } else if (result < 0) {
323 if (budget_av->slot_status != SLOTSTATUS_NONE) {
324 ciintf_slot_shutdown(ca, slot);
325 printk(KERN_INFO "budget-av: cam ejected 5\n");
326 return 0;
286 } 327 }
287 } 328 }
329 }
288 330
289 // did we find something? 331 /* read from attribute memory in reset/ready state to know when the CAM is ready */
290 if (cam_present) { 332 if (budget_av->slot_status == SLOTSTATUS_RESET) {
291 printk(KERN_INFO "budget-av: cam inserted\n"); 333 result = ciintf_read_attribute_mem(ca, slot, 0);
292 budget_av->slot_status = 1; 334 if (result == 0x1d) {
293 } 335 budget_av->slot_status = SLOTSTATUS_READY;
294 } else if (!open) {
295 saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTLO);
296 if (ttpci_budget_debiread(&budget_av->budget, DEBICICAM, 0, 1, 0, 1) == -ETIMEDOUT)
297 {
298 printk(KERN_INFO "budget-av: cam ejected\n");
299 saa7146_setgpio(saa, 2, SAA7146_GPIO_OUTHI); /* disable card */
300 budget_av->slot_status = 0;
301 } 336 }
302 } 337 }
303 338
304 if (budget_av->slot_status == 1) 339 /* work out correct return code */
305 return DVB_CA_EN50221_POLL_CAM_PRESENT | DVB_CA_EN50221_POLL_CAM_READY; 340 if (budget_av->slot_status != SLOTSTATUS_NONE) {
306 341 if (budget_av->slot_status & SLOTSTATUS_READY) {
342 return DVB_CA_EN50221_POLL_CAM_PRESENT | DVB_CA_EN50221_POLL_CAM_READY;
343 }
344 return DVB_CA_EN50221_POLL_CAM_PRESENT;
345 }
307 return 0; 346 return 0;
308} 347}
309 348
@@ -333,6 +372,8 @@ static int ciintf_init(struct budget_av *budget_av)
333 budget_av->ca.slot_ts_enable = ciintf_slot_ts_enable; 372 budget_av->ca.slot_ts_enable = ciintf_slot_ts_enable;
334 budget_av->ca.poll_slot_status = ciintf_poll_slot_status; 373 budget_av->ca.poll_slot_status = ciintf_poll_slot_status;
335 budget_av->ca.data = budget_av; 374 budget_av->ca.data = budget_av;
375 budget_av->budget.ci_present = 1;
376 budget_av->slot_status = SLOTSTATUS_NONE;
336 377
337 if ((result = dvb_ca_en50221_init(&budget_av->budget.dvb_adapter, 378 if ((result = dvb_ca_en50221_init(&budget_av->budget.dvb_adapter,
338 &budget_av->ca, 0, 1)) != 0) { 379 &budget_av->ca, 0, 1)) != 0) {
@@ -341,7 +382,6 @@ static int ciintf_init(struct budget_av *budget_av)
341 } 382 }
342 383
343 printk(KERN_INFO "budget-av: ci interface initialised.\n"); 384 printk(KERN_INFO "budget-av: ci interface initialised.\n");
344 budget_av->budget.ci_present = 1;
345 return 0; 385 return 0;
346 386
347error: 387error:
@@ -472,12 +512,12 @@ static int philips_su1278_ty_ci_set_symbol_rate(struct dvb_frontend *fe, u32 sra
472 return 0; 512 return 0;
473} 513}
474 514
475static int philips_su1278_ty_ci_pll_set(struct dvb_frontend *fe, 515static int philips_su1278_ty_ci_tuner_set_params(struct dvb_frontend *fe,
476 struct i2c_adapter *i2c, 516 struct dvb_frontend_parameters *params)
477 struct dvb_frontend_parameters *params)
478{ 517{
479 u32 div; 518 u32 div;
480 u8 buf[4]; 519 u8 buf[4];
520 struct budget *budget = (struct budget *) fe->dvb->priv;
481 struct i2c_msg msg = {.addr = 0x61,.flags = 0,.buf = buf,.len = sizeof(buf) }; 521 struct i2c_msg msg = {.addr = 0x61,.flags = 0,.buf = buf,.len = sizeof(buf) };
482 522
483 if ((params->frequency < 950000) || (params->frequency > 2150000)) 523 if ((params->frequency < 950000) || (params->frequency > 2150000))
@@ -501,7 +541,9 @@ static int philips_su1278_ty_ci_pll_set(struct dvb_frontend *fe,
501 else if (params->frequency < 2150000) 541 else if (params->frequency < 2150000)
502 buf[3] |= 0xC0; 542 buf[3] |= 0xC0;
503 543
504 if (i2c_transfer(i2c, &msg, 1) != 1) 544 if (fe->ops.i2c_gate_ctrl)
545 fe->ops.i2c_gate_ctrl(fe, 1);
546 if (i2c_transfer(&budget->i2c_adap, &msg, 1) != 1)
505 return -EIO; 547 return -EIO;
506 return 0; 548 return 0;
507} 549}
@@ -509,9 +551,8 @@ static int philips_su1278_ty_ci_pll_set(struct dvb_frontend *fe,
509#define MIN2(a,b) ((a) < (b) ? (a) : (b)) 551#define MIN2(a,b) ((a) < (b) ? (a) : (b))
510#define MIN3(a,b,c) MIN2(MIN2(a,b),c) 552#define MIN3(a,b,c) MIN2(MIN2(a,b),c)
511 553
512static int philips_su1278sh2_tua6100_pll_set(struct dvb_frontend *fe, 554static int philips_su1278sh2_tua6100_tuner_set_params(struct dvb_frontend *fe,
513 struct i2c_adapter *i2c, 555 struct dvb_frontend_parameters *params)
514 struct dvb_frontend_parameters *params)
515{ 556{
516 u8 reg0 [2] = { 0x00, 0x00 }; 557 u8 reg0 [2] = { 0x00, 0x00 };
517 u8 reg1 [4] = { 0x01, 0x00, 0x00, 0x00 }; 558 u8 reg1 [4] = { 0x01, 0x00, 0x00, 0x00 };
@@ -521,6 +562,7 @@ static int philips_su1278sh2_tua6100_pll_set(struct dvb_frontend *fe,
521 int R, A, N, P, M; 562 int R, A, N, P, M;
522 struct i2c_msg msg = {.addr = 0x60,.flags = 0,.buf = NULL,.len = 0 }; 563 struct i2c_msg msg = {.addr = 0x60,.flags = 0,.buf = NULL,.len = 0 };
523 int freq = params->frequency; 564 int freq = params->frequency;
565 struct budget *budget = (struct budget *) fe->dvb->priv;
524 566
525 first_ZF = (freq) / 1000; 567 first_ZF = (freq) / 1000;
526 568
@@ -620,21 +662,25 @@ static int philips_su1278sh2_tua6100_pll_set(struct dvb_frontend *fe,
620 reg0[1] |= 0x03; 662 reg0[1] |= 0x03;
621 663
622 /* already enabled - do not reenable i2c repeater or TX fails */ 664 /* already enabled - do not reenable i2c repeater or TX fails */
665 if (fe->ops.i2c_gate_ctrl)
666 fe->ops.i2c_gate_ctrl(fe, 1);
623 msg.buf = reg0; 667 msg.buf = reg0;
624 msg.len = sizeof(reg0); 668 msg.len = sizeof(reg0);
625 if (i2c_transfer(i2c, &msg, 1) != 1) 669 if (i2c_transfer(&budget->i2c_adap, &msg, 1) != 1)
626 return -EIO; 670 return -EIO;
627 671
628 stv0299_enable_plli2c(fe); 672 if (fe->ops.i2c_gate_ctrl)
673 fe->ops.i2c_gate_ctrl(fe, 1);
629 msg.buf = reg1; 674 msg.buf = reg1;
630 msg.len = sizeof(reg1); 675 msg.len = sizeof(reg1);
631 if (i2c_transfer(i2c, &msg, 1) != 1) 676 if (i2c_transfer(&budget->i2c_adap, &msg, 1) != 1)
632 return -EIO; 677 return -EIO;
633 678
634 stv0299_enable_plli2c(fe); 679 if (fe->ops.i2c_gate_ctrl)
680 fe->ops.i2c_gate_ctrl(fe, 1);
635 msg.buf = reg2; 681 msg.buf = reg2;
636 msg.len = sizeof(reg2); 682 msg.len = sizeof(reg2);
637 if (i2c_transfer(i2c, &msg, 1) != 1) 683 if (i2c_transfer(&budget->i2c_adap, &msg, 1) != 1)
638 return -EIO; 684 return -EIO;
639 685
640 return 0; 686 return 0;
@@ -692,7 +738,6 @@ static struct stv0299_config typhoon_config = {
692 .volt13_op0_op1 = STV0299_VOLT13_OP0, 738 .volt13_op0_op1 = STV0299_VOLT13_OP0,
693 .min_delay_ms = 100, 739 .min_delay_ms = 100,
694 .set_symbol_rate = philips_su1278_ty_ci_set_symbol_rate, 740 .set_symbol_rate = philips_su1278_ty_ci_set_symbol_rate,
695 .pll_set = philips_su1278_ty_ci_pll_set,
696}; 741};
697 742
698 743
@@ -706,7 +751,6 @@ static struct stv0299_config cinergy_1200s_config = {
706 .volt13_op0_op1 = STV0299_VOLT13_OP0, 751 .volt13_op0_op1 = STV0299_VOLT13_OP0,
707 .min_delay_ms = 100, 752 .min_delay_ms = 100,
708 .set_symbol_rate = philips_su1278_ty_ci_set_symbol_rate, 753 .set_symbol_rate = philips_su1278_ty_ci_set_symbol_rate,
709 .pll_set = philips_su1278_ty_ci_pll_set,
710}; 754};
711 755
712static struct stv0299_config cinergy_1200s_1894_0010_config = { 756static struct stv0299_config cinergy_1200s_1894_0010_config = {
@@ -719,10 +763,9 @@ static struct stv0299_config cinergy_1200s_1894_0010_config = {
719 .volt13_op0_op1 = STV0299_VOLT13_OP0, 763 .volt13_op0_op1 = STV0299_VOLT13_OP0,
720 .min_delay_ms = 100, 764 .min_delay_ms = 100,
721 .set_symbol_rate = philips_su1278_ty_ci_set_symbol_rate, 765 .set_symbol_rate = philips_su1278_ty_ci_set_symbol_rate,
722 .pll_set = philips_su1278sh2_tua6100_pll_set,
723}; 766};
724 767
725static int philips_cu1216_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) 768static int philips_cu1216_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
726{ 769{
727 struct budget *budget = (struct budget *) fe->dvb->priv; 770 struct budget *budget = (struct budget *) fe->dvb->priv;
728 u8 buf[4]; 771 u8 buf[4];
@@ -738,6 +781,8 @@ static int philips_cu1216_pll_set(struct dvb_frontend *fe, struct dvb_frontend_p
738 buf[3] = (params->frequency < 150000000 ? 0x01 : 781 buf[3] = (params->frequency < 150000000 ? 0x01 :
739 params->frequency < 445000000 ? 0x02 : 0x04); 782 params->frequency < 445000000 ? 0x02 : 0x04);
740 783
784 if (fe->ops.i2c_gate_ctrl)
785 fe->ops.i2c_gate_ctrl(fe, 1);
741 if (i2c_transfer(&budget->i2c_adap, &msg, 1) != 1) 786 if (i2c_transfer(&budget->i2c_adap, &msg, 1) != 1)
742 return -EIO; 787 return -EIO;
743 return 0; 788 return 0;
@@ -745,19 +790,20 @@ static int philips_cu1216_pll_set(struct dvb_frontend *fe, struct dvb_frontend_p
745 790
746static struct tda10021_config philips_cu1216_config = { 791static struct tda10021_config philips_cu1216_config = {
747 .demod_address = 0x0c, 792 .demod_address = 0x0c,
748 .pll_set = philips_cu1216_pll_set,
749}; 793};
750 794
751 795
752 796
753 797
754static int philips_tu1216_pll_init(struct dvb_frontend *fe) 798static int philips_tu1216_tuner_init(struct dvb_frontend *fe)
755{ 799{
756 struct budget *budget = (struct budget *) fe->dvb->priv; 800 struct budget *budget = (struct budget *) fe->dvb->priv;
757 static u8 tu1216_init[] = { 0x0b, 0xf5, 0x85, 0xab }; 801 static u8 tu1216_init[] = { 0x0b, 0xf5, 0x85, 0xab };
758 struct i2c_msg tuner_msg = {.addr = 0x60,.flags = 0,.buf = tu1216_init,.len = sizeof(tu1216_init) }; 802 struct i2c_msg tuner_msg = {.addr = 0x60,.flags = 0,.buf = tu1216_init,.len = sizeof(tu1216_init) };
759 803
760 // setup PLL configuration 804 // setup PLL configuration
805 if (fe->ops.i2c_gate_ctrl)
806 fe->ops.i2c_gate_ctrl(fe, 1);
761 if (i2c_transfer(&budget->i2c_adap, &tuner_msg, 1) != 1) 807 if (i2c_transfer(&budget->i2c_adap, &tuner_msg, 1) != 1)
762 return -EIO; 808 return -EIO;
763 msleep(1); 809 msleep(1);
@@ -765,7 +811,7 @@ static int philips_tu1216_pll_init(struct dvb_frontend *fe)
765 return 0; 811 return 0;
766} 812}
767 813
768static int philips_tu1216_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) 814static int philips_tu1216_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
769{ 815{
770 struct budget *budget = (struct budget *) fe->dvb->priv; 816 struct budget *budget = (struct budget *) fe->dvb->priv;
771 u8 tuner_buf[4]; 817 u8 tuner_buf[4];
@@ -839,6 +885,8 @@ static int philips_tu1216_pll_set(struct dvb_frontend *fe, struct dvb_frontend_p
839 tuner_buf[2] = 0xca; 885 tuner_buf[2] = 0xca;
840 tuner_buf[3] = (cp << 5) | (filter << 3) | band; 886 tuner_buf[3] = (cp << 5) | (filter << 3) | band;
841 887
888 if (fe->ops.i2c_gate_ctrl)
889 fe->ops.i2c_gate_ctrl(fe, 1);
842 if (i2c_transfer(&budget->i2c_adap, &tuner_msg, 1) != 1) 890 if (i2c_transfer(&budget->i2c_adap, &tuner_msg, 1) != 1)
843 return -EIO; 891 return -EIO;
844 892
@@ -862,9 +910,6 @@ static struct tda1004x_config philips_tu1216_config = {
862 .xtal_freq = TDA10046_XTAL_4M, 910 .xtal_freq = TDA10046_XTAL_4M,
863 .agc_config = TDA10046_AGC_DEFAULT, 911 .agc_config = TDA10046_AGC_DEFAULT,
864 .if_freq = TDA10046_FREQ_3617, 912 .if_freq = TDA10046_FREQ_3617,
865 .pll_init = philips_tu1216_pll_init,
866 .pll_set = philips_tu1216_pll_set,
867 .pll_sleep = NULL,
868 .request_firmware = philips_tu1216_request_firmware, 913 .request_firmware = philips_tu1216_request_firmware,
869}; 914};
870 915
@@ -911,13 +956,13 @@ static u8 philips_sd1878_inittab[] = {
911 0xff, 0xff 956 0xff, 0xff
912}; 957};
913 958
914static int philips_sd1878_tda8261_pll_set(struct dvb_frontend *fe, 959static int philips_sd1878_tda8261_tuner_set_params(struct dvb_frontend *fe,
915 struct i2c_adapter *i2c, 960 struct dvb_frontend_parameters *params)
916 struct dvb_frontend_parameters *params)
917{ 961{
918 u8 buf[4]; 962 u8 buf[4];
919 int rc; 963 int rc;
920 struct i2c_msg tuner_msg = {.addr=0x60,.flags=0,.buf=buf,.len=sizeof(buf)}; 964 struct i2c_msg tuner_msg = {.addr=0x60,.flags=0,.buf=buf,.len=sizeof(buf)};
965 struct budget *budget = (struct budget *) fe->dvb->priv;
921 966
922 if((params->frequency < 950000) || (params->frequency > 2150000)) 967 if((params->frequency < 950000) || (params->frequency > 2150000))
923 return -EINVAL; 968 return -EINVAL;
@@ -926,7 +971,9 @@ static int philips_sd1878_tda8261_pll_set(struct dvb_frontend *fe,
926 params->frequency, 0); 971 params->frequency, 0);
927 if(rc < 0) return rc; 972 if(rc < 0) return rc;
928 973
929 if(i2c_transfer(i2c, &tuner_msg, 1) != 1) 974 if (fe->ops.i2c_gate_ctrl)
975 fe->ops.i2c_gate_ctrl(fe, 1);
976 if(i2c_transfer(&budget->i2c_adap, &tuner_msg, 1) != 1)
930 return -EIO; 977 return -EIO;
931 978
932 return 0; 979 return 0;
@@ -969,7 +1016,7 @@ static int philips_sd1878_ci_set_symbol_rate(struct dvb_frontend *fe,
969 1016
970static struct stv0299_config philips_sd1878_config = { 1017static struct stv0299_config philips_sd1878_config = {
971 .demod_address = 0x68, 1018 .demod_address = 0x68,
972 .inittab = philips_sd1878_inittab, 1019 .inittab = philips_sd1878_inittab,
973 .mclk = 88000000UL, 1020 .mclk = 88000000UL,
974 .invert = 0, 1021 .invert = 0,
975 .skip_reinit = 0, 1022 .skip_reinit = 0,
@@ -977,7 +1024,6 @@ static struct stv0299_config philips_sd1878_config = {
977 .volt13_op0_op1 = STV0299_VOLT13_OP0, 1024 .volt13_op0_op1 = STV0299_VOLT13_OP0,
978 .min_delay_ms = 100, 1025 .min_delay_ms = 100,
979 .set_symbol_rate = philips_sd1878_ci_set_symbol_rate, 1026 .set_symbol_rate = philips_sd1878_ci_set_symbol_rate,
980 .pll_set = philips_sd1878_tda8261_pll_set,
981}; 1027};
982 1028
983static u8 read_pwm(struct budget_av *budget_av) 1029static u8 read_pwm(struct budget_av *budget_av)
@@ -1003,6 +1049,7 @@ static u8 read_pwm(struct budget_av *budget_av)
1003 1049
1004#define SUBID_DVBS_TV_STAR 0x0014 1050#define SUBID_DVBS_TV_STAR 0x0014
1005#define SUBID_DVBS_TV_STAR_CI 0x0016 1051#define SUBID_DVBS_TV_STAR_CI 0x0016
1052#define SUBID_DVBS_EASYWATCH_1 0x001a
1006#define SUBID_DVBS_EASYWATCH 0x001e 1053#define SUBID_DVBS_EASYWATCH 0x001e
1007#define SUBID_DVBC_KNC1 0x0020 1054#define SUBID_DVBC_KNC1 0x0020
1008#define SUBID_DVBC_KNC1_PLUS 0x0021 1055#define SUBID_DVBC_KNC1_PLUS 0x0021
@@ -1012,17 +1059,36 @@ static u8 read_pwm(struct budget_av *budget_av)
1012#define SUBID_DVBT_KNC1 0x0030 1059#define SUBID_DVBT_KNC1 0x0030
1013#define SUBID_DVBT_CINERGY1200 0x1157 1060#define SUBID_DVBT_CINERGY1200 0x1157
1014 1061
1062
1063static int tda10021_set_frontend(struct dvb_frontend *fe,
1064 struct dvb_frontend_parameters *p)
1065{
1066 struct budget_av* budget_av = fe->dvb->priv;
1067 int result;
1068
1069 result = budget_av->tda10021_set_frontend(fe, p);
1070 if (budget_av->tda10021_ts_enabled) {
1071 tda10021_write_byte(budget_av->budget.dvb_frontend, 0x12, 0xa1);
1072 } else {
1073 tda10021_write_byte(budget_av->budget.dvb_frontend, 0x12, 0xa0);
1074 }
1075
1076 return result;
1077}
1078
1015static void frontend_init(struct budget_av *budget_av) 1079static void frontend_init(struct budget_av *budget_av)
1016{ 1080{
1017 struct saa7146_dev * saa = budget_av->budget.dev; 1081 struct saa7146_dev * saa = budget_av->budget.dev;
1018 struct dvb_frontend * fe = NULL; 1082 struct dvb_frontend * fe = NULL;
1019 1083
1084 /* Enable / PowerON Frontend */
1085 saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTLO);
1086
1087 /* additional setup necessary for the PLUS cards */
1020 switch (saa->pci->subsystem_device) { 1088 switch (saa->pci->subsystem_device) {
1021 case SUBID_DVBS_KNC1_PLUS: 1089 case SUBID_DVBS_KNC1_PLUS:
1022 case SUBID_DVBC_KNC1_PLUS: 1090 case SUBID_DVBC_KNC1_PLUS:
1023 case SUBID_DVBT_KNC1_PLUS: 1091 case SUBID_DVBT_KNC1_PLUS:
1024 // Enable / PowerON Frontend
1025 saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTLO);
1026 saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTHI); 1092 saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTHI);
1027 break; 1093 break;
1028 } 1094 }
@@ -1030,12 +1096,19 @@ static void frontend_init(struct budget_av *budget_av)
1030 switch (saa->pci->subsystem_device) { 1096 switch (saa->pci->subsystem_device) {
1031 1097
1032 case SUBID_DVBS_KNC1: 1098 case SUBID_DVBS_KNC1:
1099 case SUBID_DVBS_EASYWATCH_1:
1033 if (saa->pci->subsystem_vendor == 0x1894) { 1100 if (saa->pci->subsystem_vendor == 0x1894) {
1034 fe = stv0299_attach(&cinergy_1200s_1894_0010_config, 1101 fe = stv0299_attach(&cinergy_1200s_1894_0010_config,
1035 &budget_av->budget.i2c_adap); 1102 &budget_av->budget.i2c_adap);
1103 if (fe) {
1104 fe->ops.tuner_ops.set_params = philips_su1278sh2_tua6100_tuner_set_params;
1105 }
1036 } else { 1106 } else {
1037 fe = stv0299_attach(&typhoon_config, 1107 fe = stv0299_attach(&typhoon_config,
1038 &budget_av->budget.i2c_adap); 1108 &budget_av->budget.i2c_adap);
1109 if (fe) {
1110 fe->ops.tuner_ops.set_params = philips_su1278_ty_ci_tuner_set_params;
1111 }
1039 } 1112 }
1040 break; 1113 break;
1041 1114
@@ -1045,41 +1118,53 @@ static void frontend_init(struct budget_av *budget_av)
1045 case SUBID_DVBS_EASYWATCH: 1118 case SUBID_DVBS_EASYWATCH:
1046 fe = stv0299_attach(&philips_sd1878_config, 1119 fe = stv0299_attach(&philips_sd1878_config,
1047 &budget_av->budget.i2c_adap); 1120 &budget_av->budget.i2c_adap);
1121 if (fe) {
1122 fe->ops.tuner_ops.set_params = philips_sd1878_tda8261_tuner_set_params;
1123 }
1048 break; 1124 break;
1049 1125
1050 case SUBID_DVBS_KNC1_PLUS: 1126 case SUBID_DVBS_KNC1_PLUS:
1051 case SUBID_DVBS_TYPHOON: 1127 case SUBID_DVBS_TYPHOON:
1052 fe = stv0299_attach(&typhoon_config, 1128 fe = stv0299_attach(&typhoon_config,
1053 &budget_av->budget.i2c_adap); 1129 &budget_av->budget.i2c_adap);
1130 if (fe) {
1131 fe->ops.tuner_ops.set_params = philips_su1278_ty_ci_tuner_set_params;
1132 }
1054 break; 1133 break;
1055 1134
1056 case SUBID_DVBS_CINERGY1200: 1135 case SUBID_DVBS_CINERGY1200:
1057 fe = stv0299_attach(&cinergy_1200s_config, 1136 fe = stv0299_attach(&cinergy_1200s_config,
1058 &budget_av->budget.i2c_adap); 1137 &budget_av->budget.i2c_adap);
1138 if (fe) {
1139 fe->ops.tuner_ops.set_params = philips_su1278_ty_ci_tuner_set_params;
1140 }
1059 break; 1141 break;
1060 1142
1061 case SUBID_DVBC_KNC1: 1143 case SUBID_DVBC_KNC1:
1062 case SUBID_DVBC_KNC1_PLUS: 1144 case SUBID_DVBC_KNC1_PLUS:
1145 case SUBID_DVBC_CINERGY1200:
1146 budget_av->reinitialise_demod = 1;
1063 fe = tda10021_attach(&philips_cu1216_config, 1147 fe = tda10021_attach(&philips_cu1216_config,
1064 &budget_av->budget.i2c_adap, 1148 &budget_av->budget.i2c_adap,
1065 read_pwm(budget_av)); 1149 read_pwm(budget_av));
1150 if (fe) {
1151 budget_av->tda10021_poclkp = 1;
1152 budget_av->tda10021_set_frontend = fe->ops.set_frontend;
1153 fe->ops.set_frontend = tda10021_set_frontend;
1154 fe->ops.tuner_ops.set_params = philips_cu1216_tuner_set_params;
1155 }
1066 break; 1156 break;
1067 1157
1068 case SUBID_DVBT_KNC1: 1158 case SUBID_DVBT_KNC1:
1069 case SUBID_DVBT_KNC1_PLUS: 1159 case SUBID_DVBT_KNC1_PLUS:
1070 fe = tda10046_attach(&philips_tu1216_config,
1071 &budget_av->budget.i2c_adap);
1072 break;
1073
1074 case SUBID_DVBC_CINERGY1200:
1075 fe = tda10021_attach(&philips_cu1216_config,
1076 &budget_av->budget.i2c_adap,
1077 read_pwm(budget_av));
1078 break;
1079
1080 case SUBID_DVBT_CINERGY1200: 1160 case SUBID_DVBT_CINERGY1200:
1161 budget_av->reinitialise_demod = 1;
1081 fe = tda10046_attach(&philips_tu1216_config, 1162 fe = tda10046_attach(&philips_tu1216_config,
1082 &budget_av->budget.i2c_adap); 1163 &budget_av->budget.i2c_adap);
1164 if (fe) {
1165 fe->ops.tuner_ops.init = philips_tu1216_tuner_init;
1166 fe->ops.tuner_ops.set_params = philips_tu1216_tuner_set_params;
1167 }
1083 break; 1168 break;
1084 } 1169 }
1085 1170
@@ -1098,8 +1183,8 @@ static void frontend_init(struct budget_av *budget_av)
1098 if (dvb_register_frontend(&budget_av->budget.dvb_adapter, 1183 if (dvb_register_frontend(&budget_av->budget.dvb_adapter,
1099 budget_av->budget.dvb_frontend)) { 1184 budget_av->budget.dvb_frontend)) {
1100 printk(KERN_ERR "budget-av: Frontend registration failed!\n"); 1185 printk(KERN_ERR "budget-av: Frontend registration failed!\n");
1101 if (budget_av->budget.dvb_frontend->ops->release) 1186 if (budget_av->budget.dvb_frontend->ops.release)
1102 budget_av->budget.dvb_frontend->ops->release(budget_av->budget.dvb_frontend); 1187 budget_av->budget.dvb_frontend->ops.release(budget_av->budget.dvb_frontend);
1103 budget_av->budget.dvb_frontend = NULL; 1188 budget_av->budget.dvb_frontend = NULL;
1104 } 1189 }
1105} 1190}
@@ -1293,6 +1378,7 @@ MAKE_BUDGET_INFO(knc1c, "KNC1 DVB-C", BUDGET_KNC1C);
1293MAKE_BUDGET_INFO(knc1t, "KNC1 DVB-T", BUDGET_KNC1T); 1378MAKE_BUDGET_INFO(knc1t, "KNC1 DVB-T", BUDGET_KNC1T);
1294MAKE_BUDGET_INFO(kncxs, "KNC TV STAR DVB-S", BUDGET_TVSTAR); 1379MAKE_BUDGET_INFO(kncxs, "KNC TV STAR DVB-S", BUDGET_TVSTAR);
1295MAKE_BUDGET_INFO(satewpls, "Satelco EasyWatch DVB-S light", BUDGET_TVSTAR); 1380MAKE_BUDGET_INFO(satewpls, "Satelco EasyWatch DVB-S light", BUDGET_TVSTAR);
1381MAKE_BUDGET_INFO(satewpls1, "Satelco EasyWatch DVB-S light", BUDGET_KNC1S);
1296MAKE_BUDGET_INFO(knc1sp, "KNC1 DVB-S Plus", BUDGET_KNC1SP); 1382MAKE_BUDGET_INFO(knc1sp, "KNC1 DVB-S Plus", BUDGET_KNC1SP);
1297MAKE_BUDGET_INFO(knc1cp, "KNC1 DVB-C Plus", BUDGET_KNC1CP); 1383MAKE_BUDGET_INFO(knc1cp, "KNC1 DVB-C Plus", BUDGET_KNC1CP);
1298MAKE_BUDGET_INFO(knc1tp, "KNC1 DVB-T Plus", BUDGET_KNC1TP); 1384MAKE_BUDGET_INFO(knc1tp, "KNC1 DVB-T Plus", BUDGET_KNC1TP);
@@ -1309,6 +1395,7 @@ static struct pci_device_id pci_tbl[] = {
1309 MAKE_EXTENSION_PCI(kncxs, 0x1894, 0x0014), 1395 MAKE_EXTENSION_PCI(kncxs, 0x1894, 0x0014),
1310 MAKE_EXTENSION_PCI(kncxs, 0x1894, 0x0016), 1396 MAKE_EXTENSION_PCI(kncxs, 0x1894, 0x0016),
1311 MAKE_EXTENSION_PCI(satewpls, 0x1894, 0x001e), 1397 MAKE_EXTENSION_PCI(satewpls, 0x1894, 0x001e),
1398 MAKE_EXTENSION_PCI(satewpls1, 0x1894, 0x001a),
1312 MAKE_EXTENSION_PCI(knc1c, 0x1894, 0x0020), 1399 MAKE_EXTENSION_PCI(knc1c, 0x1894, 0x0020),
1313 MAKE_EXTENSION_PCI(knc1cp, 0x1894, 0x0021), 1400 MAKE_EXTENSION_PCI(knc1cp, 0x1894, 0x0021),
1314 MAKE_EXTENSION_PCI(knc1t, 0x1894, 0x0030), 1401 MAKE_EXTENSION_PCI(knc1t, 0x1894, 0x0030),
diff --git a/drivers/media/dvb/ttpci/budget-ci.c b/drivers/media/dvb/ttpci/budget-ci.c
index e64a609cf4ff..4b966eea3834 100644
--- a/drivers/media/dvb/ttpci/budget-ci.c
+++ b/drivers/media/dvb/ttpci/budget-ci.c
@@ -620,10 +620,10 @@ static int philips_su1278_tt_set_symbol_rate(struct dvb_frontend *fe, u32 srate,
620 return 0; 620 return 0;
621} 621}
622 622
623static int philips_su1278_tt_pll_set(struct dvb_frontend *fe, 623static int philips_su1278_tt_tuner_set_params(struct dvb_frontend *fe,
624 struct i2c_adapter *i2c, 624 struct dvb_frontend_parameters *params)
625 struct dvb_frontend_parameters *params)
626{ 625{
626 struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv;
627 u32 div; 627 u32 div;
628 u8 buf[4]; 628 u8 buf[4];
629 struct i2c_msg msg = {.addr = 0x60,.flags = 0,.buf = buf,.len = sizeof(buf) }; 629 struct i2c_msg msg = {.addr = 0x60,.flags = 0,.buf = buf,.len = sizeof(buf) };
@@ -649,7 +649,9 @@ static int philips_su1278_tt_pll_set(struct dvb_frontend *fe,
649 else if (params->frequency < 2150000) 649 else if (params->frequency < 2150000)
650 buf[3] |= 0xC0; 650 buf[3] |= 0xC0;
651 651
652 if (i2c_transfer(i2c, &msg, 1) != 1) 652 if (fe->ops.i2c_gate_ctrl)
653 fe->ops.i2c_gate_ctrl(fe, 1);
654 if (i2c_transfer(&budget_ci->budget.i2c_adap, &msg, 1) != 1)
653 return -EIO; 655 return -EIO;
654 return 0; 656 return 0;
655} 657}
@@ -665,12 +667,11 @@ static struct stv0299_config philips_su1278_tt_config = {
665 .volt13_op0_op1 = STV0299_VOLT13_OP1, 667 .volt13_op0_op1 = STV0299_VOLT13_OP1,
666 .min_delay_ms = 50, 668 .min_delay_ms = 50,
667 .set_symbol_rate = philips_su1278_tt_set_symbol_rate, 669 .set_symbol_rate = philips_su1278_tt_set_symbol_rate,
668 .pll_set = philips_su1278_tt_pll_set,
669}; 670};
670 671
671 672
672 673
673static int philips_tdm1316l_pll_init(struct dvb_frontend *fe) 674static int philips_tdm1316l_tuner_init(struct dvb_frontend *fe)
674{ 675{
675 struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv; 676 struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv;
676 static u8 td1316_init[] = { 0x0b, 0xf5, 0x85, 0xab }; 677 static u8 td1316_init[] = { 0x0b, 0xf5, 0x85, 0xab };
@@ -679,6 +680,8 @@ static int philips_tdm1316l_pll_init(struct dvb_frontend *fe)
679 sizeof(td1316_init) }; 680 sizeof(td1316_init) };
680 681
681 // setup PLL configuration 682 // setup PLL configuration
683 if (fe->ops.i2c_gate_ctrl)
684 fe->ops.i2c_gate_ctrl(fe, 1);
682 if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1) 685 if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1)
683 return -EIO; 686 return -EIO;
684 msleep(1); 687 msleep(1);
@@ -687,14 +690,18 @@ static int philips_tdm1316l_pll_init(struct dvb_frontend *fe)
687 tuner_msg.addr = 0x65; 690 tuner_msg.addr = 0x65;
688 tuner_msg.buf = disable_mc44BC374c; 691 tuner_msg.buf = disable_mc44BC374c;
689 tuner_msg.len = sizeof(disable_mc44BC374c); 692 tuner_msg.len = sizeof(disable_mc44BC374c);
693 if (fe->ops.i2c_gate_ctrl)
694 fe->ops.i2c_gate_ctrl(fe, 1);
690 if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1) { 695 if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1) {
696 if (fe->ops.i2c_gate_ctrl)
697 fe->ops.i2c_gate_ctrl(fe, 1);
691 i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1); 698 i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1);
692 } 699 }
693 700
694 return 0; 701 return 0;
695} 702}
696 703
697static int philips_tdm1316l_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) 704static int philips_tdm1316l_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
698{ 705{
699 struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv; 706 struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv;
700 u8 tuner_buf[4]; 707 u8 tuner_buf[4];
@@ -770,6 +777,8 @@ static int philips_tdm1316l_pll_set(struct dvb_frontend *fe, struct dvb_frontend
770 tuner_buf[2] = 0xca; 777 tuner_buf[2] = 0xca;
771 tuner_buf[3] = (cp << 5) | (filter << 3) | band; 778 tuner_buf[3] = (cp << 5) | (filter << 3) | band;
772 779
780 if (fe->ops.i2c_gate_ctrl)
781 fe->ops.i2c_gate_ctrl(fe, 1);
773 if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1) 782 if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1)
774 return -EIO; 783 return -EIO;
775 784
@@ -793,13 +802,10 @@ static struct tda1004x_config philips_tdm1316l_config = {
793 .xtal_freq = TDA10046_XTAL_4M, 802 .xtal_freq = TDA10046_XTAL_4M,
794 .agc_config = TDA10046_AGC_DEFAULT, 803 .agc_config = TDA10046_AGC_DEFAULT,
795 .if_freq = TDA10046_FREQ_3617, 804 .if_freq = TDA10046_FREQ_3617,
796 .pll_init = philips_tdm1316l_pll_init,
797 .pll_set = philips_tdm1316l_pll_set,
798 .pll_sleep = NULL,
799 .request_firmware = philips_tdm1316l_request_firmware, 805 .request_firmware = philips_tdm1316l_request_firmware,
800}; 806};
801 807
802static int dvbc_philips_tdm1316l_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) 808static int dvbc_philips_tdm1316l_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
803{ 809{
804 struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv; 810 struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv;
805 u8 tuner_buf[5]; 811 u8 tuner_buf[5];
@@ -857,13 +863,15 @@ static int dvbc_philips_tdm1316l_pll_set(struct dvb_frontend *fe, struct dvb_fro
857 tuner_buf[3] = (cp << 5) | (filter << 3) | band; 863 tuner_buf[3] = (cp << 5) | (filter << 3) | band;
858 tuner_buf[4] = 0x80; 864 tuner_buf[4] = 0x80;
859 865
860 stv0297_enable_plli2c(fe); 866 if (fe->ops.i2c_gate_ctrl)
867 fe->ops.i2c_gate_ctrl(fe, 1);
861 if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1) 868 if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1)
862 return -EIO; 869 return -EIO;
863 870
864 msleep(50); 871 msleep(50);
865 872
866 stv0297_enable_plli2c(fe); 873 if (fe->ops.i2c_gate_ctrl)
874 fe->ops.i2c_gate_ctrl(fe, 1);
867 if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1) 875 if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1)
868 return -EIO; 876 return -EIO;
869 877
@@ -969,7 +977,7 @@ static struct stv0297_config dvbc_philips_tdm1316l_config = {
969 .demod_address = 0x1c, 977 .demod_address = 0x1c,
970 .inittab = dvbc_philips_tdm1316l_inittab, 978 .inittab = dvbc_philips_tdm1316l_inittab,
971 .invert = 0, 979 .invert = 0,
972 .pll_set = dvbc_philips_tdm1316l_pll_set, 980 .stop_during_read = 1,
973}; 981};
974 982
975 983
@@ -982,6 +990,8 @@ static void frontend_init(struct budget_ci *budget_ci)
982 budget_ci->budget.dvb_frontend = 990 budget_ci->budget.dvb_frontend =
983 stv0299_attach(&alps_bsru6_config, &budget_ci->budget.i2c_adap); 991 stv0299_attach(&alps_bsru6_config, &budget_ci->budget.i2c_adap);
984 if (budget_ci->budget.dvb_frontend) { 992 if (budget_ci->budget.dvb_frontend) {
993 budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = alps_bsru6_tuner_set_params;
994 budget_ci->budget.dvb_frontend->tuner_priv = &budget_ci->budget.i2c_adap;
985 break; 995 break;
986 } 996 }
987 break; 997 break;
@@ -990,6 +1000,7 @@ static void frontend_init(struct budget_ci *budget_ci)
990 budget_ci->budget.dvb_frontend = 1000 budget_ci->budget.dvb_frontend =
991 stv0299_attach(&philips_su1278_tt_config, &budget_ci->budget.i2c_adap); 1001 stv0299_attach(&philips_su1278_tt_config, &budget_ci->budget.i2c_adap);
992 if (budget_ci->budget.dvb_frontend) { 1002 if (budget_ci->budget.dvb_frontend) {
1003 budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = philips_su1278_tt_tuner_set_params;
993 break; 1004 break;
994 } 1005 }
995 break; 1006 break;
@@ -999,6 +1010,7 @@ static void frontend_init(struct budget_ci *budget_ci)
999 budget_ci->budget.dvb_frontend = 1010 budget_ci->budget.dvb_frontend =
1000 stv0297_attach(&dvbc_philips_tdm1316l_config, &budget_ci->budget.i2c_adap); 1011 stv0297_attach(&dvbc_philips_tdm1316l_config, &budget_ci->budget.i2c_adap);
1001 if (budget_ci->budget.dvb_frontend) { 1012 if (budget_ci->budget.dvb_frontend) {
1013 budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = dvbc_philips_tdm1316l_tuner_set_params;
1002 break; 1014 break;
1003 } 1015 }
1004 break; 1016 break;
@@ -1008,6 +1020,8 @@ static void frontend_init(struct budget_ci *budget_ci)
1008 budget_ci->budget.dvb_frontend = 1020 budget_ci->budget.dvb_frontend =
1009 tda10045_attach(&philips_tdm1316l_config, &budget_ci->budget.i2c_adap); 1021 tda10045_attach(&philips_tdm1316l_config, &budget_ci->budget.i2c_adap);
1010 if (budget_ci->budget.dvb_frontend) { 1022 if (budget_ci->budget.dvb_frontend) {
1023 budget_ci->budget.dvb_frontend->ops.tuner_ops.init = philips_tdm1316l_tuner_init;
1024 budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = philips_tdm1316l_tuner_set_params;
1011 break; 1025 break;
1012 } 1026 }
1013 break; 1027 break;
@@ -1017,6 +1031,8 @@ static void frontend_init(struct budget_ci *budget_ci)
1017 budget_ci->budget.dvb_frontend = 1031 budget_ci->budget.dvb_frontend =
1018 tda10046_attach(&philips_tdm1316l_config, &budget_ci->budget.i2c_adap); 1032 tda10046_attach(&philips_tdm1316l_config, &budget_ci->budget.i2c_adap);
1019 if (budget_ci->budget.dvb_frontend) { 1033 if (budget_ci->budget.dvb_frontend) {
1034 budget_ci->budget.dvb_frontend->ops.tuner_ops.init = philips_tdm1316l_tuner_init;
1035 budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = philips_tdm1316l_tuner_set_params;
1020 break; 1036 break;
1021 } 1037 }
1022 break; 1038 break;
@@ -1024,11 +1040,14 @@ static void frontend_init(struct budget_ci *budget_ci)
1024 case 0x1017: // TT S-1500 PCI 1040 case 0x1017: // TT S-1500 PCI
1025 budget_ci->budget.dvb_frontend = stv0299_attach(&alps_bsbe1_config, &budget_ci->budget.i2c_adap); 1041 budget_ci->budget.dvb_frontend = stv0299_attach(&alps_bsbe1_config, &budget_ci->budget.i2c_adap);
1026 if (budget_ci->budget.dvb_frontend) { 1042 if (budget_ci->budget.dvb_frontend) {
1027 budget_ci->budget.dvb_frontend->ops->dishnetwork_send_legacy_command = NULL; 1043 budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = alps_bsbe1_tuner_set_params;
1028 if (lnbp21_init(budget_ci->budget.dvb_frontend, &budget_ci->budget.i2c_adap, LNBP21_LLC, 0)) { 1044 budget_ci->budget.dvb_frontend->tuner_priv = &budget_ci->budget.i2c_adap;
1045
1046 budget_ci->budget.dvb_frontend->ops.dishnetwork_send_legacy_command = NULL;
1047 if (lnbp21_attach(budget_ci->budget.dvb_frontend, &budget_ci->budget.i2c_adap, LNBP21_LLC, 0)) {
1029 printk("%s: No LNBP21 found!\n", __FUNCTION__); 1048 printk("%s: No LNBP21 found!\n", __FUNCTION__);
1030 if (budget_ci->budget.dvb_frontend->ops->release) 1049 if (budget_ci->budget.dvb_frontend->ops.release)
1031 budget_ci->budget.dvb_frontend->ops->release(budget_ci->budget.dvb_frontend); 1050 budget_ci->budget.dvb_frontend->ops.release(budget_ci->budget.dvb_frontend);
1032 budget_ci->budget.dvb_frontend = NULL; 1051 budget_ci->budget.dvb_frontend = NULL;
1033 } 1052 }
1034 } 1053 }
@@ -1046,8 +1065,8 @@ static void frontend_init(struct budget_ci *budget_ci)
1046 if (dvb_register_frontend 1065 if (dvb_register_frontend
1047 (&budget_ci->budget.dvb_adapter, budget_ci->budget.dvb_frontend)) { 1066 (&budget_ci->budget.dvb_adapter, budget_ci->budget.dvb_frontend)) {
1048 printk("budget-ci: Frontend registration failed!\n"); 1067 printk("budget-ci: Frontend registration failed!\n");
1049 if (budget_ci->budget.dvb_frontend->ops->release) 1068 if (budget_ci->budget.dvb_frontend->ops.release)
1050 budget_ci->budget.dvb_frontend->ops->release(budget_ci->budget.dvb_frontend); 1069 budget_ci->budget.dvb_frontend->ops.release(budget_ci->budget.dvb_frontend);
1051 budget_ci->budget.dvb_frontend = NULL; 1070 budget_ci->budget.dvb_frontend = NULL;
1052 } 1071 }
1053 } 1072 }
diff --git a/drivers/media/dvb/ttpci/budget-core.c b/drivers/media/dvb/ttpci/budget-core.c
index ea2066d461fc..e4cf7775e07f 100644
--- a/drivers/media/dvb/ttpci/budget-core.c
+++ b/drivers/media/dvb/ttpci/budget-core.c
@@ -400,7 +400,9 @@ int ttpci_budget_init(struct budget *budget, struct saa7146_dev *dev,
400 budget->dev->name, budget->buffer_width, budget->buffer_height); 400 budget->dev->name, budget->buffer_width, budget->buffer_height);
401 printk("%s: dma buffer size %u\n", budget->dev->name, budget->buffer_size); 401 printk("%s: dma buffer size %u\n", budget->dev->name, budget->buffer_size);
402 402
403 dvb_register_adapter(&budget->dvb_adapter, budget->card->name, owner); 403 if ((ret = dvb_register_adapter(&budget->dvb_adapter, budget->card->name, owner, &budget->dev->pci->dev)) < 0) {
404 return ret;
405 }
404 406
405 /* set dd1 stream a & b */ 407 /* set dd1 stream a & b */
406 saa7146_write(dev, DD1_STREAM_B, 0x00000000); 408 saa7146_write(dev, DD1_STREAM_B, 0x00000000);
diff --git a/drivers/media/dvb/ttpci/budget-patch.c b/drivers/media/dvb/ttpci/budget-patch.c
index 1b3aaac5e763..ee60ce90a400 100644
--- a/drivers/media/dvb/ttpci/budget-patch.c
+++ b/drivers/media/dvb/ttpci/budget-patch.c
@@ -258,7 +258,7 @@ static int budget_patch_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_c
258 return 0; 258 return 0;
259} 259}
260 260
261static int alps_bsrv2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) 261static int alps_bsrv2_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
262{ 262{
263 struct budget_patch* budget = (struct budget_patch*) fe->dvb->priv; 263 struct budget_patch* budget = (struct budget_patch*) fe->dvb->priv;
264 u8 pwr = 0; 264 u8 pwr = 0;
@@ -281,7 +281,10 @@ static int alps_bsrv2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_param
281 // NOTE: since we're using a prescaler of 2, we set the 281 // NOTE: since we're using a prescaler of 2, we set the
282 // divisor frequency to 62.5kHz and divide by 125 above 282 // divisor frequency to 62.5kHz and divide by 125 above
283 283
284 if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO; 284 if (fe->ops.i2c_gate_ctrl)
285 fe->ops.i2c_gate_ctrl(fe, 1);
286 if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1)
287 return -EIO;
285 return 0; 288 return 0;
286} 289}
287 290
@@ -289,10 +292,9 @@ static struct ves1x93_config alps_bsrv2_config = {
289 .demod_address = 0x08, 292 .demod_address = 0x08,
290 .xin = 90100000UL, 293 .xin = 90100000UL,
291 .invert_pwm = 0, 294 .invert_pwm = 0,
292 .pll_set = alps_bsrv2_pll_set,
293}; 295};
294 296
295static int grundig_29504_451_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) 297static int grundig_29504_451_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
296{ 298{
297 struct budget_patch* budget = (struct budget_patch*) fe->dvb->priv; 299 struct budget_patch* budget = (struct budget_patch*) fe->dvb->priv;
298 u32 div; 300 u32 div;
@@ -305,13 +307,15 @@ static int grundig_29504_451_pll_set(struct dvb_frontend* fe, struct dvb_fronten
305 data[2] = 0x8e; 307 data[2] = 0x8e;
306 data[3] = 0x00; 308 data[3] = 0x00;
307 309
308 if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO; 310 if (fe->ops.i2c_gate_ctrl)
311 fe->ops.i2c_gate_ctrl(fe, 1);
312 if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1)
313 return -EIO;
309 return 0; 314 return 0;
310} 315}
311 316
312static struct tda8083_config grundig_29504_451_config = { 317static struct tda8083_config grundig_29504_451_config = {
313 .demod_address = 0x68, 318 .demod_address = 0x68,
314 .pll_set = grundig_29504_451_pll_set,
315}; 319};
316 320
317static void frontend_init(struct budget_patch* budget) 321static void frontend_init(struct budget_patch* budget)
@@ -323,27 +327,32 @@ static void frontend_init(struct budget_patch* budget)
323 // try the ALPS BSRV2 first of all 327 // try the ALPS BSRV2 first of all
324 budget->dvb_frontend = ves1x93_attach(&alps_bsrv2_config, &budget->i2c_adap); 328 budget->dvb_frontend = ves1x93_attach(&alps_bsrv2_config, &budget->i2c_adap);
325 if (budget->dvb_frontend) { 329 if (budget->dvb_frontend) {
326 budget->dvb_frontend->ops->diseqc_send_master_cmd = budget_patch_diseqc_send_master_cmd; 330 budget->dvb_frontend->ops.tuner_ops.set_params = alps_bsrv2_tuner_set_params;
327 budget->dvb_frontend->ops->diseqc_send_burst = budget_patch_diseqc_send_burst; 331 budget->dvb_frontend->ops.diseqc_send_master_cmd = budget_patch_diseqc_send_master_cmd;
328 budget->dvb_frontend->ops->set_tone = budget_patch_set_tone; 332 budget->dvb_frontend->ops.diseqc_send_burst = budget_patch_diseqc_send_burst;
333 budget->dvb_frontend->ops.set_tone = budget_patch_set_tone;
329 break; 334 break;
330 } 335 }
331 336
332 // try the ALPS BSRU6 now 337 // try the ALPS BSRU6 now
333 budget->dvb_frontend = stv0299_attach(&alps_bsru6_config, &budget->i2c_adap); 338 budget->dvb_frontend = stv0299_attach(&alps_bsru6_config, &budget->i2c_adap);
334 if (budget->dvb_frontend) { 339 if (budget->dvb_frontend) {
335 budget->dvb_frontend->ops->diseqc_send_master_cmd = budget_diseqc_send_master_cmd; 340 budget->dvb_frontend->ops.tuner_ops.set_params = alps_bsru6_tuner_set_params;
336 budget->dvb_frontend->ops->diseqc_send_burst = budget_diseqc_send_burst; 341 budget->dvb_frontend->tuner_priv = &budget->i2c_adap;
337 budget->dvb_frontend->ops->set_tone = budget_set_tone; 342
343 budget->dvb_frontend->ops.diseqc_send_master_cmd = budget_diseqc_send_master_cmd;
344 budget->dvb_frontend->ops.diseqc_send_burst = budget_diseqc_send_burst;
345 budget->dvb_frontend->ops.set_tone = budget_set_tone;
338 break; 346 break;
339 } 347 }
340 348
341 // Try the grundig 29504-451 349 // Try the grundig 29504-451
342 budget->dvb_frontend = tda8083_attach(&grundig_29504_451_config, &budget->i2c_adap); 350 budget->dvb_frontend = tda8083_attach(&grundig_29504_451_config, &budget->i2c_adap);
343 if (budget->dvb_frontend) { 351 if (budget->dvb_frontend) {
344 budget->dvb_frontend->ops->diseqc_send_master_cmd = budget_diseqc_send_master_cmd; 352 budget->dvb_frontend->ops.tuner_ops.set_params = grundig_29504_451_tuner_set_params;
345 budget->dvb_frontend->ops->diseqc_send_burst = budget_diseqc_send_burst; 353 budget->dvb_frontend->ops.diseqc_send_master_cmd = budget_diseqc_send_master_cmd;
346 budget->dvb_frontend->ops->set_tone = budget_set_tone; 354 budget->dvb_frontend->ops.diseqc_send_burst = budget_diseqc_send_burst;
355 budget->dvb_frontend->ops.set_tone = budget_set_tone;
347 break; 356 break;
348 } 357 }
349 break; 358 break;
@@ -358,8 +367,8 @@ static void frontend_init(struct budget_patch* budget)
358 } else { 367 } else {
359 if (dvb_register_frontend(&budget->dvb_adapter, budget->dvb_frontend)) { 368 if (dvb_register_frontend(&budget->dvb_adapter, budget->dvb_frontend)) {
360 printk("budget-av: Frontend registration failed!\n"); 369 printk("budget-av: Frontend registration failed!\n");
361 if (budget->dvb_frontend->ops->release) 370 if (budget->dvb_frontend->ops.release)
362 budget->dvb_frontend->ops->release(budget->dvb_frontend); 371 budget->dvb_frontend->ops.release(budget->dvb_frontend);
363 budget->dvb_frontend = NULL; 372 budget->dvb_frontend = NULL;
364 } 373 }
365 } 374 }
diff --git a/drivers/media/dvb/ttpci/budget.c b/drivers/media/dvb/ttpci/budget.c
index c23c02d95641..35761f13c12b 100644
--- a/drivers/media/dvb/ttpci/budget.c
+++ b/drivers/media/dvb/ttpci/budget.c
@@ -186,7 +186,7 @@ static int budget_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t m
186 return 0; 186 return 0;
187} 187}
188 188
189static int alps_bsrv2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) 189static int alps_bsrv2_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
190{ 190{
191 struct budget* budget = (struct budget*) fe->dvb->priv; 191 struct budget* budget = (struct budget*) fe->dvb->priv;
192 u8 pwr = 0; 192 u8 pwr = 0;
@@ -209,6 +209,8 @@ static int alps_bsrv2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_param
209 // NOTE: since we're using a prescaler of 2, we set the 209 // NOTE: since we're using a prescaler of 2, we set the
210 // divisor frequency to 62.5kHz and divide by 125 above 210 // divisor frequency to 62.5kHz and divide by 125 above
211 211
212 if (fe->ops.i2c_gate_ctrl)
213 fe->ops.i2c_gate_ctrl(fe, 1);
212 if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO; 214 if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO;
213 return 0; 215 return 0;
214} 216}
@@ -218,10 +220,9 @@ static struct ves1x93_config alps_bsrv2_config =
218 .demod_address = 0x08, 220 .demod_address = 0x08,
219 .xin = 90100000UL, 221 .xin = 90100000UL,
220 .invert_pwm = 0, 222 .invert_pwm = 0,
221 .pll_set = alps_bsrv2_pll_set,
222}; 223};
223 224
224static int alps_tdbe2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) 225static int alps_tdbe2_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
225{ 226{
226 struct budget* budget = (struct budget*) fe->dvb->priv; 227 struct budget* budget = (struct budget*) fe->dvb->priv;
227 u32 div; 228 u32 div;
@@ -235,6 +236,8 @@ static int alps_tdbe2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_param
235 data[2] = 0x85 | ((div >> 10) & 0x60); 236 data[2] = 0x85 | ((div >> 10) & 0x60);
236 data[3] = (params->frequency < 174000000 ? 0x88 : params->frequency < 470000000 ? 0x84 : 0x81); 237 data[3] = (params->frequency < 174000000 ? 0x88 : params->frequency < 470000000 ? 0x84 : 0x81);
237 238
239 if (fe->ops.i2c_gate_ctrl)
240 fe->ops.i2c_gate_ctrl(fe, 1);
238 if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO; 241 if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO;
239 return 0; 242 return 0;
240} 243}
@@ -244,10 +247,9 @@ static struct ves1820_config alps_tdbe2_config = {
244 .xin = 57840000UL, 247 .xin = 57840000UL,
245 .invert = 1, 248 .invert = 1,
246 .selagc = VES1820_SELAGC_SIGNAMPERR, 249 .selagc = VES1820_SELAGC_SIGNAMPERR,
247 .pll_set = alps_tdbe2_pll_set,
248}; 250};
249 251
250static int grundig_29504_401_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) 252static int grundig_29504_401_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
251{ 253{
252 struct budget* budget = (struct budget*) fe->dvb->priv; 254 struct budget* budget = (struct budget*) fe->dvb->priv;
253 u32 div; 255 u32 div;
@@ -274,16 +276,17 @@ static int grundig_29504_401_pll_set(struct dvb_frontend* fe, struct dvb_fronten
274 data[2] = ((div >> 10) & 0x60) | cfg; 276 data[2] = ((div >> 10) & 0x60) | cfg;
275 data[3] = (cpump << 6) | band_select; 277 data[3] = (cpump << 6) | band_select;
276 278
279 if (fe->ops.i2c_gate_ctrl)
280 fe->ops.i2c_gate_ctrl(fe, 1);
277 if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO; 281 if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO;
278 return 0; 282 return 0;
279} 283}
280 284
281static struct l64781_config grundig_29504_401_config = { 285static struct l64781_config grundig_29504_401_config = {
282 .demod_address = 0x55, 286 .demod_address = 0x55,
283 .pll_set = grundig_29504_401_pll_set,
284}; 287};
285 288
286static int grundig_29504_451_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) 289static int grundig_29504_451_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
287{ 290{
288 struct budget* budget = (struct budget*) fe->dvb->priv; 291 struct budget* budget = (struct budget*) fe->dvb->priv;
289 u32 div; 292 u32 div;
@@ -296,16 +299,17 @@ static int grundig_29504_451_pll_set(struct dvb_frontend* fe, struct dvb_fronten
296 data[2] = 0x8e; 299 data[2] = 0x8e;
297 data[3] = 0x00; 300 data[3] = 0x00;
298 301
302 if (fe->ops.i2c_gate_ctrl)
303 fe->ops.i2c_gate_ctrl(fe, 1);
299 if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO; 304 if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO;
300 return 0; 305 return 0;
301} 306}
302 307
303static struct tda8083_config grundig_29504_451_config = { 308static struct tda8083_config grundig_29504_451_config = {
304 .demod_address = 0x68, 309 .demod_address = 0x68,
305 .pll_set = grundig_29504_451_pll_set,
306}; 310};
307 311
308static int s5h1420_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params, u32* freqout) 312static int s5h1420_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
309{ 313{
310 struct budget* budget = (struct budget*) fe->dvb->priv; 314 struct budget* budget = (struct budget*) fe->dvb->priv;
311 u32 div; 315 u32 div;
@@ -326,16 +330,16 @@ static int s5h1420_pll_set(struct dvb_frontend* fe, struct dvb_frontend_paramete
326 else 330 else
327 data[3] = 0xc0; 331 data[3] = 0xc0;
328 332
333 if (fe->ops.i2c_gate_ctrl)
334 fe->ops.i2c_gate_ctrl(fe, 1);
329 if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO; 335 if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO;
330 336
331 *freqout = div * 1000;
332 return 0; 337 return 0;
333} 338}
334 339
335static struct s5h1420_config s5h1420_config = { 340static struct s5h1420_config s5h1420_config = {
336 .demod_address = 0x53, 341 .demod_address = 0x53,
337 .invert = 1, 342 .invert = 1,
338 .pll_set = s5h1420_pll_set,
339}; 343};
340 344
341static u8 read_pwm(struct budget* budget) 345static u8 read_pwm(struct budget* budget)
@@ -359,18 +363,21 @@ static void frontend_init(struct budget *budget)
359 // try the ALPS BSRV2 first of all 363 // try the ALPS BSRV2 first of all
360 budget->dvb_frontend = ves1x93_attach(&alps_bsrv2_config, &budget->i2c_adap); 364 budget->dvb_frontend = ves1x93_attach(&alps_bsrv2_config, &budget->i2c_adap);
361 if (budget->dvb_frontend) { 365 if (budget->dvb_frontend) {
362 budget->dvb_frontend->ops->diseqc_send_master_cmd = budget_diseqc_send_master_cmd; 366 budget->dvb_frontend->ops.tuner_ops.set_params = alps_bsrv2_tuner_set_params;
363 budget->dvb_frontend->ops->diseqc_send_burst = budget_diseqc_send_burst; 367 budget->dvb_frontend->ops.diseqc_send_master_cmd = budget_diseqc_send_master_cmd;
364 budget->dvb_frontend->ops->set_tone = budget_set_tone; 368 budget->dvb_frontend->ops.diseqc_send_burst = budget_diseqc_send_burst;
369 budget->dvb_frontend->ops.set_tone = budget_set_tone;
365 break; 370 break;
366 } 371 }
367 372
368 // try the ALPS BSRU6 now 373 // try the ALPS BSRU6 now
369 budget->dvb_frontend = stv0299_attach(&alps_bsru6_config, &budget->i2c_adap); 374 budget->dvb_frontend = stv0299_attach(&alps_bsru6_config, &budget->i2c_adap);
370 if (budget->dvb_frontend) { 375 if (budget->dvb_frontend) {
371 budget->dvb_frontend->ops->diseqc_send_master_cmd = budget_diseqc_send_master_cmd; 376 budget->dvb_frontend->ops.tuner_ops.set_params = alps_bsru6_tuner_set_params;
372 budget->dvb_frontend->ops->diseqc_send_burst = budget_diseqc_send_burst; 377 budget->dvb_frontend->tuner_priv = &budget->i2c_adap;
373 budget->dvb_frontend->ops->set_tone = budget_set_tone; 378 budget->dvb_frontend->ops.diseqc_send_master_cmd = budget_diseqc_send_master_cmd;
379 budget->dvb_frontend->ops.diseqc_send_burst = budget_diseqc_send_burst;
380 budget->dvb_frontend->ops.set_tone = budget_set_tone;
374 break; 381 break;
375 } 382 }
376 break; 383 break;
@@ -378,35 +385,45 @@ static void frontend_init(struct budget *budget)
378 case 0x1004: // Hauppauge/TT DVB-C budget (ves1820/ALPS TDBE2(sp5659)) 385 case 0x1004: // Hauppauge/TT DVB-C budget (ves1820/ALPS TDBE2(sp5659))
379 386
380 budget->dvb_frontend = ves1820_attach(&alps_tdbe2_config, &budget->i2c_adap, read_pwm(budget)); 387 budget->dvb_frontend = ves1820_attach(&alps_tdbe2_config, &budget->i2c_adap, read_pwm(budget));
381 if (budget->dvb_frontend) break; 388 if (budget->dvb_frontend) {
389 budget->dvb_frontend->ops.tuner_ops.set_params = alps_tdbe2_tuner_set_params;
390 break;
391 }
382 break; 392 break;
383 393
384 case 0x1005: // Hauppauge/TT Nova-T budget (L64781/Grundig 29504-401(tsa5060)) 394 case 0x1005: // Hauppauge/TT Nova-T budget (L64781/Grundig 29504-401(tsa5060))
385 395
386 budget->dvb_frontend = l64781_attach(&grundig_29504_401_config, &budget->i2c_adap); 396 budget->dvb_frontend = l64781_attach(&grundig_29504_401_config, &budget->i2c_adap);
387 if (budget->dvb_frontend) break; 397 if (budget->dvb_frontend) {
398 budget->dvb_frontend->ops.tuner_ops.set_params = grundig_29504_401_tuner_set_params;
399 break;
400 }
388 break; 401 break;
389 402
390 case 0x4f60: // Fujitsu Siemens Activy Budget-S PCI rev AL (stv0299/ALPS BSRU6(tsa5059)) 403 case 0x4f60: // Fujitsu Siemens Activy Budget-S PCI rev AL (stv0299/ALPS BSRU6(tsa5059))
391 budget->dvb_frontend = stv0299_attach(&alps_bsru6_config, &budget->i2c_adap); 404 budget->dvb_frontend = stv0299_attach(&alps_bsru6_config, &budget->i2c_adap);
392 if (budget->dvb_frontend) { 405 if (budget->dvb_frontend) {
393 budget->dvb_frontend->ops->set_voltage = siemens_budget_set_voltage; 406 budget->dvb_frontend->ops.tuner_ops.set_params = alps_bsru6_tuner_set_params;
394 budget->dvb_frontend->ops->dishnetwork_send_legacy_command = NULL; 407 budget->dvb_frontend->tuner_priv = &budget->i2c_adap;
408 budget->dvb_frontend->ops.set_voltage = siemens_budget_set_voltage;
409 budget->dvb_frontend->ops.dishnetwork_send_legacy_command = NULL;
395 } 410 }
396 break; 411 break;
397 412
398 case 0x4f61: // Fujitsu Siemens Activy Budget-S PCI rev GR (tda8083/Grundig 29504-451(tsa5522)) 413 case 0x4f61: // Fujitsu Siemens Activy Budget-S PCI rev GR (tda8083/Grundig 29504-451(tsa5522))
399 budget->dvb_frontend = tda8083_attach(&grundig_29504_451_config, &budget->i2c_adap); 414 budget->dvb_frontend = tda8083_attach(&grundig_29504_451_config, &budget->i2c_adap);
400 if (budget->dvb_frontend) { 415 if (budget->dvb_frontend) {
401 budget->dvb_frontend->ops->set_voltage = siemens_budget_set_voltage; 416 budget->dvb_frontend->ops.tuner_ops.set_params = grundig_29504_451_tuner_set_params;
402 budget->dvb_frontend->ops->dishnetwork_send_legacy_command = NULL; 417 budget->dvb_frontend->ops.set_voltage = siemens_budget_set_voltage;
418 budget->dvb_frontend->ops.dishnetwork_send_legacy_command = NULL;
403 } 419 }
404 break; 420 break;
405 421
406 case 0x1016: // Hauppauge/TT Nova-S SE (samsung s5h1420/????(tda8260)) 422 case 0x1016: // Hauppauge/TT Nova-S SE (samsung s5h1420/????(tda8260))
407 budget->dvb_frontend = s5h1420_attach(&s5h1420_config, &budget->i2c_adap); 423 budget->dvb_frontend = s5h1420_attach(&s5h1420_config, &budget->i2c_adap);
408 if (budget->dvb_frontend) { 424 if (budget->dvb_frontend) {
409 if (lnbp21_init(budget->dvb_frontend, &budget->i2c_adap, 0, 0)) { 425 budget->dvb_frontend->ops.tuner_ops.set_params = s5h1420_tuner_set_params;
426 if (lnbp21_attach(budget->dvb_frontend, &budget->i2c_adap, 0, 0)) {
410 printk("%s: No LNBP21 found!\n", __FUNCTION__); 427 printk("%s: No LNBP21 found!\n", __FUNCTION__);
411 goto error_out; 428 goto error_out;
412 } 429 }
@@ -428,8 +445,8 @@ static void frontend_init(struct budget *budget)
428 445
429error_out: 446error_out:
430 printk("budget: Frontend registration failed!\n"); 447 printk("budget: Frontend registration failed!\n");
431 if (budget->dvb_frontend->ops->release) 448 if (budget->dvb_frontend->ops.release)
432 budget->dvb_frontend->ops->release(budget->dvb_frontend); 449 budget->dvb_frontend->ops.release(budget->dvb_frontend);
433 budget->dvb_frontend = NULL; 450 budget->dvb_frontend = NULL;
434 return; 451 return;
435} 452}
diff --git a/drivers/media/dvb/ttusb-budget/Kconfig b/drivers/media/dvb/ttusb-budget/Kconfig
index 914587d52b57..92c7cdcf8981 100644
--- a/drivers/media/dvb/ttusb-budget/Kconfig
+++ b/drivers/media/dvb/ttusb-budget/Kconfig
@@ -6,6 +6,8 @@ config DVB_TTUSB_BUDGET
6 select DVB_VES1820 6 select DVB_VES1820
7 select DVB_TDA8083 7 select DVB_TDA8083
8 select DVB_STV0299 8 select DVB_STV0299
9 select DVB_STV0297
10 select DVB_LNBP21
9 help 11 help
10 Support for external USB adapters designed by Technotrend and 12 Support for external USB adapters designed by Technotrend and
11 produced by Hauppauge, shipped under the brand name 'Nova-USB'. 13 produced by Hauppauge, shipped under the brand name 'Nova-USB'.
diff --git a/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c b/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
index 6ceae38125c7..14559ef6153c 100644
--- a/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
+++ b/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
@@ -30,6 +30,8 @@
30#include "tda1004x.h" 30#include "tda1004x.h"
31#include "stv0299.h" 31#include "stv0299.h"
32#include "tda8083.h" 32#include "tda8083.h"
33#include "stv0297.h"
34#include "lnbp21.h"
33 35
34#include <linux/dvb/frontend.h> 36#include <linux/dvb/frontend.h>
35#include <linux/dvb/dmx.h> 37#include <linux/dvb/dmx.h>
@@ -486,31 +488,6 @@ static int ttusb_send_diseqc(struct dvb_frontend* fe,
486} 488}
487#endif 489#endif
488 490
489static int lnbp21_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage)
490{
491 struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
492 int ret;
493 u8 data[1];
494 struct i2c_msg msg = { .addr = 0x08, .flags = 0, .buf = data, .len = sizeof(data) };
495
496 switch(voltage) {
497 case SEC_VOLTAGE_OFF:
498 data[0] = 0x00;
499 break;
500 case SEC_VOLTAGE_13:
501 data[0] = 0x44;
502 break;
503 case SEC_VOLTAGE_18:
504 data[0] = 0x4c;
505 break;
506 default:
507 return -EINVAL;
508 };
509
510 ret = i2c_transfer(&ttusb->i2c_adap, &msg, 1);
511 return (ret != 1) ? -EIO : 0;
512}
513
514static int ttusb_update_lnb(struct ttusb *ttusb) 491static int ttusb_update_lnb(struct ttusb *ttusb)
515{ 492{
516 u8 b[] = { 0xaa, ++ttusb->c, 0x16, 5, /*power: */ 1, 493 u8 b[] = { 0xaa, ++ttusb->c, 0x16, 5, /*power: */ 1,
@@ -1048,7 +1025,7 @@ static u32 functionality(struct i2c_adapter *adapter)
1048 1025
1049 1026
1050 1027
1051static int alps_tdmb7_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) 1028static int alps_tdmb7_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
1052{ 1029{
1053 struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv; 1030 struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
1054 u8 data[4]; 1031 u8 data[4];
@@ -1062,20 +1039,21 @@ static int alps_tdmb7_pll_set(struct dvb_frontend* fe, struct dvb_frontend_param
1062 data[2] = ((div >> 10) & 0x60) | 0x85; 1039 data[2] = ((div >> 10) & 0x60) | 0x85;
1063 data[3] = params->frequency < 592000000 ? 0x40 : 0x80; 1040 data[3] = params->frequency < 592000000 ? 0x40 : 0x80;
1064 1041
1042 if (fe->ops.i2c_gate_ctrl)
1043 fe->ops.i2c_gate_ctrl(fe, 1);
1065 if (i2c_transfer(&ttusb->i2c_adap, &msg, 1) != 1) return -EIO; 1044 if (i2c_transfer(&ttusb->i2c_adap, &msg, 1) != 1) return -EIO;
1066 return 0; 1045 return 0;
1067} 1046}
1068 1047
1069static struct cx22700_config alps_tdmb7_config = { 1048static struct cx22700_config alps_tdmb7_config = {
1070 .demod_address = 0x43, 1049 .demod_address = 0x43,
1071 .pll_set = alps_tdmb7_pll_set,
1072}; 1050};
1073 1051
1074 1052
1075 1053
1076 1054
1077 1055
1078static int philips_tdm1316l_pll_init(struct dvb_frontend* fe) 1056static int philips_tdm1316l_tuner_init(struct dvb_frontend* fe)
1079{ 1057{
1080 struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv; 1058 struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
1081 static u8 td1316_init[] = { 0x0b, 0xf5, 0x85, 0xab }; 1059 static u8 td1316_init[] = { 0x0b, 0xf5, 0x85, 0xab };
@@ -1083,6 +1061,8 @@ static int philips_tdm1316l_pll_init(struct dvb_frontend* fe)
1083 struct i2c_msg tuner_msg = { .addr=0x60, .flags=0, .buf=td1316_init, .len=sizeof(td1316_init) }; 1061 struct i2c_msg tuner_msg = { .addr=0x60, .flags=0, .buf=td1316_init, .len=sizeof(td1316_init) };
1084 1062
1085 // setup PLL configuration 1063 // setup PLL configuration
1064 if (fe->ops.i2c_gate_ctrl)
1065 fe->ops.i2c_gate_ctrl(fe, 1);
1086 if (i2c_transfer(&ttusb->i2c_adap, &tuner_msg, 1) != 1) return -EIO; 1066 if (i2c_transfer(&ttusb->i2c_adap, &tuner_msg, 1) != 1) return -EIO;
1087 msleep(1); 1067 msleep(1);
1088 1068
@@ -1090,6 +1070,8 @@ static int philips_tdm1316l_pll_init(struct dvb_frontend* fe)
1090 tuner_msg.addr = 0x65; 1070 tuner_msg.addr = 0x65;
1091 tuner_msg.buf = disable_mc44BC374c; 1071 tuner_msg.buf = disable_mc44BC374c;
1092 tuner_msg.len = sizeof(disable_mc44BC374c); 1072 tuner_msg.len = sizeof(disable_mc44BC374c);
1073 if (fe->ops.i2c_gate_ctrl)
1074 fe->ops.i2c_gate_ctrl(fe, 1);
1093 if (i2c_transfer(&ttusb->i2c_adap, &tuner_msg, 1) != 1) { 1075 if (i2c_transfer(&ttusb->i2c_adap, &tuner_msg, 1) != 1) {
1094 i2c_transfer(&ttusb->i2c_adap, &tuner_msg, 1); 1076 i2c_transfer(&ttusb->i2c_adap, &tuner_msg, 1);
1095 } 1077 }
@@ -1097,7 +1079,7 @@ static int philips_tdm1316l_pll_init(struct dvb_frontend* fe)
1097 return 0; 1079 return 0;
1098} 1080}
1099 1081
1100static int philips_tdm1316l_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) 1082static int philips_tdm1316l_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
1101{ 1083{
1102 struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv; 1084 struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
1103 u8 tuner_buf[4]; 1085 u8 tuner_buf[4];
@@ -1157,6 +1139,8 @@ static int philips_tdm1316l_pll_set(struct dvb_frontend* fe, struct dvb_frontend
1157 tuner_buf[2] = 0xca; 1139 tuner_buf[2] = 0xca;
1158 tuner_buf[3] = (cp << 5) | (filter << 3) | band; 1140 tuner_buf[3] = (cp << 5) | (filter << 3) | band;
1159 1141
1142 if (fe->ops.i2c_gate_ctrl)
1143 fe->ops.i2c_gate_ctrl(fe, 1);
1160 if (i2c_transfer(&ttusb->i2c_adap, &tuner_msg, 1) != 1) 1144 if (i2c_transfer(&ttusb->i2c_adap, &tuner_msg, 1) != 1)
1161 return -EIO; 1145 return -EIO;
1162 1146
@@ -1176,8 +1160,6 @@ static struct tda1004x_config philips_tdm1316l_config = {
1176 .demod_address = 0x8, 1160 .demod_address = 0x8,
1177 .invert = 1, 1161 .invert = 1,
1178 .invert_oclk = 0, 1162 .invert_oclk = 0,
1179 .pll_init = philips_tdm1316l_pll_init,
1180 .pll_set = philips_tdm1316l_pll_set,
1181 .request_firmware = philips_tdm1316l_request_firmware, 1163 .request_firmware = philips_tdm1316l_request_firmware,
1182}; 1164};
1183 1165
@@ -1299,7 +1281,7 @@ static int alps_stv0299_set_symbol_rate(struct dvb_frontend *fe, u32 srate, u32
1299 return 0; 1281 return 0;
1300} 1282}
1301 1283
1302static int philips_tsa5059_pll_set(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct dvb_frontend_parameters *params) 1284static int philips_tsa5059_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
1303{ 1285{
1304 struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv; 1286 struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
1305 u8 buf[4]; 1287 u8 buf[4];
@@ -1322,7 +1304,9 @@ static int philips_tsa5059_pll_set(struct dvb_frontend *fe, struct i2c_adapter *
1322 if (ttusb->revision == TTUSB_REV_2_2) 1304 if (ttusb->revision == TTUSB_REV_2_2)
1323 buf[3] |= 0x20; 1305 buf[3] |= 0x20;
1324 1306
1325 if (i2c_transfer(i2c, &msg, 1) != 1) 1307 if (fe->ops.i2c_gate_ctrl)
1308 fe->ops.i2c_gate_ctrl(fe, 1);
1309 if (i2c_transfer(&ttusb->i2c_adap, &msg, 1) != 1)
1326 return -EIO; 1310 return -EIO;
1327 1311
1328 return 0; 1312 return 0;
@@ -1338,10 +1322,9 @@ static struct stv0299_config alps_stv0299_config = {
1338 .volt13_op0_op1 = STV0299_VOLT13_OP1, 1322 .volt13_op0_op1 = STV0299_VOLT13_OP1,
1339 .min_delay_ms = 100, 1323 .min_delay_ms = 100,
1340 .set_symbol_rate = alps_stv0299_set_symbol_rate, 1324 .set_symbol_rate = alps_stv0299_set_symbol_rate,
1341 .pll_set = philips_tsa5059_pll_set,
1342}; 1325};
1343 1326
1344static int ttusb_novas_grundig_29504_491_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) 1327static int ttusb_novas_grundig_29504_491_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
1345{ 1328{
1346 struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv; 1329 struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
1347 u8 buf[4]; 1330 u8 buf[4];
@@ -1355,6 +1338,8 @@ static int ttusb_novas_grundig_29504_491_pll_set(struct dvb_frontend *fe, struct
1355 buf[2] = 0x8e; 1338 buf[2] = 0x8e;
1356 buf[3] = 0x00; 1339 buf[3] = 0x00;
1357 1340
1341 if (fe->ops.i2c_gate_ctrl)
1342 fe->ops.i2c_gate_ctrl(fe, 1);
1358 if (i2c_transfer(&ttusb->i2c_adap, &msg, 1) != 1) 1343 if (i2c_transfer(&ttusb->i2c_adap, &msg, 1) != 1)
1359 return -EIO; 1344 return -EIO;
1360 1345
@@ -1364,10 +1349,9 @@ static int ttusb_novas_grundig_29504_491_pll_set(struct dvb_frontend *fe, struct
1364static struct tda8083_config ttusb_novas_grundig_29504_491_config = { 1349static struct tda8083_config ttusb_novas_grundig_29504_491_config = {
1365 1350
1366 .demod_address = 0x68, 1351 .demod_address = 0x68,
1367 .pll_set = ttusb_novas_grundig_29504_491_pll_set,
1368}; 1352};
1369 1353
1370static int alps_tdbe2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) 1354static int alps_tdbe2_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
1371{ 1355{
1372 struct ttusb* ttusb = fe->dvb->priv; 1356 struct ttusb* ttusb = fe->dvb->priv;
1373 u32 div; 1357 u32 div;
@@ -1381,6 +1365,8 @@ static int alps_tdbe2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_param
1381 data[2] = 0x85 | ((div >> 10) & 0x60); 1365 data[2] = 0x85 | ((div >> 10) & 0x60);
1382 data[3] = (params->frequency < 174000000 ? 0x88 : params->frequency < 470000000 ? 0x84 : 0x81); 1366 data[3] = (params->frequency < 174000000 ? 0x88 : params->frequency < 470000000 ? 0x84 : 0x81);
1383 1367
1368 if (fe->ops.i2c_gate_ctrl)
1369 fe->ops.i2c_gate_ctrl(fe, 1);
1384 if (i2c_transfer (&ttusb->i2c_adap, &msg, 1) != 1) 1370 if (i2c_transfer (&ttusb->i2c_adap, &msg, 1) != 1)
1385 return -EIO; 1371 return -EIO;
1386 1372
@@ -1393,7 +1379,6 @@ static struct ves1820_config alps_tdbe2_config = {
1393 .xin = 57840000UL, 1379 .xin = 57840000UL,
1394 .invert = 1, 1380 .invert = 1,
1395 .selagc = VES1820_SELAGC_SIGNAMPERR, 1381 .selagc = VES1820_SELAGC_SIGNAMPERR,
1396 .pll_set = alps_tdbe2_pll_set,
1397}; 1382};
1398 1383
1399static u8 read_pwm(struct ttusb* ttusb) 1384static u8 read_pwm(struct ttusb* ttusb)
@@ -1410,6 +1395,174 @@ static u8 read_pwm(struct ttusb* ttusb)
1410} 1395}
1411 1396
1412 1397
1398static int dvbc_philips_tdm1316l_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
1399{
1400 struct ttusb *ttusb = (struct ttusb *) fe->dvb->priv;
1401 u8 tuner_buf[5];
1402 struct i2c_msg tuner_msg = {.addr = 0x60,
1403 .flags = 0,
1404 .buf = tuner_buf,
1405 .len = sizeof(tuner_buf) };
1406 int tuner_frequency = 0;
1407 u8 band, cp, filter;
1408
1409 // determine charge pump
1410 tuner_frequency = params->frequency;
1411 if (tuner_frequency < 87000000) {return -EINVAL;}
1412 else if (tuner_frequency < 130000000) {cp = 3; band = 1;}
1413 else if (tuner_frequency < 160000000) {cp = 5; band = 1;}
1414 else if (tuner_frequency < 200000000) {cp = 6; band = 1;}
1415 else if (tuner_frequency < 290000000) {cp = 3; band = 2;}
1416 else if (tuner_frequency < 420000000) {cp = 5; band = 2;}
1417 else if (tuner_frequency < 480000000) {cp = 6; band = 2;}
1418 else if (tuner_frequency < 620000000) {cp = 3; band = 4;}
1419 else if (tuner_frequency < 830000000) {cp = 5; band = 4;}
1420 else if (tuner_frequency < 895000000) {cp = 7; band = 4;}
1421 else {return -EINVAL;}
1422
1423 // assume PLL filter should always be 8MHz for the moment.
1424 filter = 1;
1425
1426 // calculate divisor
1427 // (Finput + Fif)/Fref; Fif = 36125000 Hz, Fref = 62500 Hz
1428 tuner_frequency = ((params->frequency + 36125000) / 62500);
1429
1430 // setup tuner buffer
1431 tuner_buf[0] = tuner_frequency >> 8;
1432 tuner_buf[1] = tuner_frequency & 0xff;
1433 tuner_buf[2] = 0xc8;
1434 tuner_buf[3] = (cp << 5) | (filter << 3) | band;
1435 tuner_buf[4] = 0x80;
1436
1437 if (fe->ops.i2c_gate_ctrl)
1438 fe->ops.i2c_gate_ctrl(fe, 1);
1439 if (i2c_transfer(&ttusb->i2c_adap, &tuner_msg, 1) != 1) {
1440 printk("dvb-ttusb-budget: dvbc_philips_tdm1316l_pll_set Error 1\n");
1441 return -EIO;
1442 }
1443
1444 msleep(50);
1445
1446 if (fe->ops.i2c_gate_ctrl)
1447 fe->ops.i2c_gate_ctrl(fe, 1);
1448 if (i2c_transfer(&ttusb->i2c_adap, &tuner_msg, 1) != 1) {
1449 printk("dvb-ttusb-budget: dvbc_philips_tdm1316l_pll_set Error 2\n");
1450 return -EIO;
1451 }
1452
1453 msleep(1);
1454
1455 return 0;
1456}
1457
1458static u8 dvbc_philips_tdm1316l_inittab[] = {
1459 0x80, 0x21,
1460 0x80, 0x20,
1461 0x81, 0x01,
1462 0x81, 0x00,
1463 0x00, 0x09,
1464 0x01, 0x69,
1465 0x03, 0x00,
1466 0x04, 0x00,
1467 0x07, 0x00,
1468 0x08, 0x00,
1469 0x20, 0x00,
1470 0x21, 0x40,
1471 0x22, 0x00,
1472 0x23, 0x00,
1473 0x24, 0x40,
1474 0x25, 0x88,
1475 0x30, 0xff,
1476 0x31, 0x00,
1477 0x32, 0xff,
1478 0x33, 0x00,
1479 0x34, 0x50,
1480 0x35, 0x7f,
1481 0x36, 0x00,
1482 0x37, 0x20,
1483 0x38, 0x00,
1484 0x40, 0x1c,
1485 0x41, 0xff,
1486 0x42, 0x29,
1487 0x43, 0x20,
1488 0x44, 0xff,
1489 0x45, 0x00,
1490 0x46, 0x00,
1491 0x49, 0x04,
1492 0x4a, 0xff,
1493 0x4b, 0x7f,
1494 0x52, 0x30,
1495 0x55, 0xae,
1496 0x56, 0x47,
1497 0x57, 0xe1,
1498 0x58, 0x3a,
1499 0x5a, 0x1e,
1500 0x5b, 0x34,
1501 0x60, 0x00,
1502 0x63, 0x00,
1503 0x64, 0x00,
1504 0x65, 0x00,
1505 0x66, 0x00,
1506 0x67, 0x00,
1507 0x68, 0x00,
1508 0x69, 0x00,
1509 0x6a, 0x02,
1510 0x6b, 0x00,
1511 0x70, 0xff,
1512 0x71, 0x00,
1513 0x72, 0x00,
1514 0x73, 0x00,
1515 0x74, 0x0c,
1516 0x80, 0x00,
1517 0x81, 0x00,
1518 0x82, 0x00,
1519 0x83, 0x00,
1520 0x84, 0x04,
1521 0x85, 0x80,
1522 0x86, 0x24,
1523 0x87, 0x78,
1524 0x88, 0x00,
1525 0x89, 0x00,
1526 0x90, 0x01,
1527 0x91, 0x01,
1528 0xa0, 0x00,
1529 0xa1, 0x00,
1530 0xa2, 0x00,
1531 0xb0, 0x91,
1532 0xb1, 0x0b,
1533 0xc0, 0x4b,
1534 0xc1, 0x00,
1535 0xc2, 0x00,
1536 0xd0, 0x00,
1537 0xd1, 0x00,
1538 0xd2, 0x00,
1539 0xd3, 0x00,
1540 0xd4, 0x00,
1541 0xd5, 0x00,
1542 0xde, 0x00,
1543 0xdf, 0x00,
1544 0x61, 0x38,
1545 0x62, 0x0a,
1546 0x53, 0x13,
1547 0x59, 0x08,
1548 0x55, 0x00,
1549 0x56, 0x40,
1550 0x57, 0x08,
1551 0x58, 0x3d,
1552 0x88, 0x10,
1553 0xa0, 0x00,
1554 0xa0, 0x00,
1555 0xa0, 0x00,
1556 0xa0, 0x04,
1557 0xff, 0xff,
1558};
1559
1560static struct stv0297_config dvbc_philips_tdm1316l_config = {
1561 .demod_address = 0x1c,
1562 .inittab = dvbc_philips_tdm1316l_inittab,
1563 .invert = 0,
1564};
1565
1413static void frontend_init(struct ttusb* ttusb) 1566static void frontend_init(struct ttusb* ttusb)
1414{ 1567{
1415 switch(le16_to_cpu(ttusb->dev->descriptor.idProduct)) { 1568 switch(le16_to_cpu(ttusb->dev->descriptor.idProduct)) {
@@ -1417,11 +1570,13 @@ static void frontend_init(struct ttusb* ttusb)
1417 // try the stv0299 based first 1570 // try the stv0299 based first
1418 ttusb->fe = stv0299_attach(&alps_stv0299_config, &ttusb->i2c_adap); 1571 ttusb->fe = stv0299_attach(&alps_stv0299_config, &ttusb->i2c_adap);
1419 if (ttusb->fe != NULL) { 1572 if (ttusb->fe != NULL) {
1573 ttusb->fe->ops.tuner_ops.set_params = philips_tsa5059_tuner_set_params;
1574
1420 if(ttusb->revision == TTUSB_REV_2_2) { // ALPS BSBE1 1575 if(ttusb->revision == TTUSB_REV_2_2) { // ALPS BSBE1
1421 alps_stv0299_config.inittab = alps_bsbe1_inittab; 1576 alps_stv0299_config.inittab = alps_bsbe1_inittab;
1422 ttusb->fe->ops->set_voltage = lnbp21_set_voltage; 1577 lnbp21_attach(ttusb->fe, &ttusb->i2c_adap, 0, 0);
1423 } else { // ALPS BSRU6 1578 } else { // ALPS BSRU6
1424 ttusb->fe->ops->set_voltage = ttusb_set_voltage; 1579 ttusb->fe->ops.set_voltage = ttusb_set_voltage;
1425 } 1580 }
1426 break; 1581 break;
1427 } 1582 }
@@ -1429,28 +1584,41 @@ static void frontend_init(struct ttusb* ttusb)
1429 // Grundig 29504-491 1584 // Grundig 29504-491
1430 ttusb->fe = tda8083_attach(&ttusb_novas_grundig_29504_491_config, &ttusb->i2c_adap); 1585 ttusb->fe = tda8083_attach(&ttusb_novas_grundig_29504_491_config, &ttusb->i2c_adap);
1431 if (ttusb->fe != NULL) { 1586 if (ttusb->fe != NULL) {
1432 ttusb->fe->ops->set_voltage = ttusb_set_voltage; 1587 ttusb->fe->ops.tuner_ops.set_params = ttusb_novas_grundig_29504_491_tuner_set_params;
1588 ttusb->fe->ops.set_voltage = ttusb_set_voltage;
1433 break; 1589 break;
1434 } 1590 }
1435
1436 break; 1591 break;
1437 1592
1438 case 0x1004: // Hauppauge/TT DVB-C budget (ves1820/ALPS TDBE2(sp5659)) 1593 case 0x1004: // Hauppauge/TT DVB-C budget (ves1820/ALPS TDBE2(sp5659))
1439 ttusb->fe = ves1820_attach(&alps_tdbe2_config, &ttusb->i2c_adap, read_pwm(ttusb)); 1594 ttusb->fe = ves1820_attach(&alps_tdbe2_config, &ttusb->i2c_adap, read_pwm(ttusb));
1440 if (ttusb->fe != NULL) 1595 if (ttusb->fe != NULL) {
1596 ttusb->fe->ops.tuner_ops.set_params = alps_tdbe2_tuner_set_params;
1597 break;
1598 }
1599
1600 ttusb->fe = stv0297_attach(&dvbc_philips_tdm1316l_config, &ttusb->i2c_adap);
1601 if (ttusb->fe != NULL) {
1602 ttusb->fe->ops.tuner_ops.set_params = dvbc_philips_tdm1316l_tuner_set_params;
1441 break; 1603 break;
1604 }
1442 break; 1605 break;
1443 1606
1444 case 0x1005: // Hauppauge/TT Nova-USB-t budget (tda10046/Philips td1316(tda6651tt) OR cx22700/ALPS TDMB7(??)) 1607 case 0x1005: // Hauppauge/TT Nova-USB-t budget (tda10046/Philips td1316(tda6651tt) OR cx22700/ALPS TDMB7(??))
1445 // try the ALPS TDMB7 first 1608 // try the ALPS TDMB7 first
1446 ttusb->fe = cx22700_attach(&alps_tdmb7_config, &ttusb->i2c_adap); 1609 ttusb->fe = cx22700_attach(&alps_tdmb7_config, &ttusb->i2c_adap);
1447 if (ttusb->fe != NULL) 1610 if (ttusb->fe != NULL) {
1611 ttusb->fe->ops.tuner_ops.set_params = alps_tdmb7_tuner_set_params;
1448 break; 1612 break;
1613 }
1449 1614
1450 // Philips td1316 1615 // Philips td1316
1451 ttusb->fe = tda10046_attach(&philips_tdm1316l_config, &ttusb->i2c_adap); 1616 ttusb->fe = tda10046_attach(&philips_tdm1316l_config, &ttusb->i2c_adap);
1452 if (ttusb->fe != NULL) 1617 if (ttusb->fe != NULL) {
1618 ttusb->fe->ops.tuner_ops.init = philips_tdm1316l_tuner_init;
1619 ttusb->fe->ops.tuner_ops.set_params = philips_tdm1316l_tuner_set_params;
1453 break; 1620 break;
1621 }
1454 break; 1622 break;
1455 } 1623 }
1456 1624
@@ -1461,8 +1629,8 @@ static void frontend_init(struct ttusb* ttusb)
1461 } else { 1629 } else {
1462 if (dvb_register_frontend(&ttusb->adapter, ttusb->fe)) { 1630 if (dvb_register_frontend(&ttusb->adapter, ttusb->fe)) {
1463 printk("dvb-ttusb-budget: Frontend registration failed!\n"); 1631 printk("dvb-ttusb-budget: Frontend registration failed!\n");
1464 if (ttusb->fe->ops->release) 1632 if (ttusb->fe->ops.release)
1465 ttusb->fe->ops->release(ttusb->fe); 1633 ttusb->fe->ops.release(ttusb->fe);
1466 ttusb->fe = NULL; 1634 ttusb->fe = NULL;
1467 } 1635 }
1468 } 1636 }
@@ -1507,7 +1675,7 @@ static int ttusb_probe(struct usb_interface *intf, const struct usb_device_id *i
1507 1675
1508 mutex_unlock(&ttusb->semi2c); 1676 mutex_unlock(&ttusb->semi2c);
1509 1677
1510 if ((result = dvb_register_adapter(&ttusb->adapter, "Technotrend/Hauppauge Nova-USB", THIS_MODULE)) < 0) { 1678 if ((result = dvb_register_adapter(&ttusb->adapter, "Technotrend/Hauppauge Nova-USB", THIS_MODULE, &udev->dev)) < 0) {
1511 ttusb_free_iso_urbs(ttusb); 1679 ttusb_free_iso_urbs(ttusb);
1512 kfree(ttusb); 1680 kfree(ttusb);
1513 return result; 1681 return result;
diff --git a/drivers/media/dvb/ttusb-dec/ttusb_dec.c b/drivers/media/dvb/ttusb-dec/ttusb_dec.c
index 44dea3211848..6c1cb770bcf5 100644
--- a/drivers/media/dvb/ttusb-dec/ttusb_dec.c
+++ b/drivers/media/dvb/ttusb-dec/ttusb_dec.c
@@ -1432,7 +1432,7 @@ static int ttusb_dec_init_dvb(struct ttusb_dec *dec)
1432 dprintk("%s\n", __FUNCTION__); 1432 dprintk("%s\n", __FUNCTION__);
1433 1433
1434 if ((result = dvb_register_adapter(&dec->adapter, 1434 if ((result = dvb_register_adapter(&dec->adapter,
1435 dec->model_name, THIS_MODULE)) < 0) { 1435 dec->model_name, THIS_MODULE, &dec->udev->dev)) < 0) {
1436 printk("%s: dvb_register_adapter failed: error %d\n", 1436 printk("%s: dvb_register_adapter failed: error %d\n",
1437 __FUNCTION__, result); 1437 __FUNCTION__, result);
1438 1438
@@ -1657,8 +1657,8 @@ static int ttusb_dec_probe(struct usb_interface *intf,
1657 } else { 1657 } else {
1658 if (dvb_register_frontend(&dec->adapter, dec->fe)) { 1658 if (dvb_register_frontend(&dec->adapter, dec->fe)) {
1659 printk("budget-ci: Frontend registration failed!\n"); 1659 printk("budget-ci: Frontend registration failed!\n");
1660 if (dec->fe->ops->release) 1660 if (dec->fe->ops.release)
1661 dec->fe->ops->release(dec->fe); 1661 dec->fe->ops.release(dec->fe);
1662 dec->fe = NULL; 1662 dec->fe = NULL;
1663 } 1663 }
1664 } 1664 }
diff --git a/drivers/media/dvb/ttusb-dec/ttusbdecfe.c b/drivers/media/dvb/ttusb-dec/ttusbdecfe.c
index a5a46175fa09..42f39a89bc4d 100644
--- a/drivers/media/dvb/ttusb-dec/ttusbdecfe.c
+++ b/drivers/media/dvb/ttusb-dec/ttusbdecfe.c
@@ -28,8 +28,6 @@
28 28
29struct ttusbdecfe_state { 29struct ttusbdecfe_state {
30 30
31 struct dvb_frontend_ops ops;
32
33 /* configuration settings */ 31 /* configuration settings */
34 const struct ttusbdecfe_config* config; 32 const struct ttusbdecfe_config* config;
35 33
@@ -203,10 +201,9 @@ struct dvb_frontend* ttusbdecfe_dvbt_attach(const struct ttusbdecfe_config* conf
203 201
204 /* setup the state */ 202 /* setup the state */
205 state->config = config; 203 state->config = config;
206 memcpy(&state->ops, &ttusbdecfe_dvbt_ops, sizeof(struct dvb_frontend_ops));
207 204
208 /* create dvb_frontend */ 205 /* create dvb_frontend */
209 state->frontend.ops = &state->ops; 206 memcpy(&state->frontend.ops, &ttusbdecfe_dvbt_ops, sizeof(struct dvb_frontend_ops));
210 state->frontend.demodulator_priv = state; 207 state->frontend.demodulator_priv = state;
211 return &state->frontend; 208 return &state->frontend;
212} 209}
@@ -226,10 +223,9 @@ struct dvb_frontend* ttusbdecfe_dvbs_attach(const struct ttusbdecfe_config* conf
226 state->config = config; 223 state->config = config;
227 state->voltage = 0; 224 state->voltage = 0;
228 state->hi_band = 0; 225 state->hi_band = 0;
229 memcpy(&state->ops, &ttusbdecfe_dvbs_ops, sizeof(struct dvb_frontend_ops));
230 226
231 /* create dvb_frontend */ 227 /* create dvb_frontend */
232 state->frontend.ops = &state->ops; 228 memcpy(&state->frontend.ops, &ttusbdecfe_dvbs_ops, sizeof(struct dvb_frontend_ops));
233 state->frontend.demodulator_priv = state; 229 state->frontend.demodulator_priv = state;
234 return &state->frontend; 230 return &state->frontend;
235} 231}
diff --git a/drivers/media/radio/Kconfig b/drivers/media/radio/Kconfig
index 3fff75763693..de3128a31de8 100644
--- a/drivers/media/radio/Kconfig
+++ b/drivers/media/radio/Kconfig
@@ -136,7 +136,7 @@ config RADIO_GEMTEK_PCI
136 Choose Y here if you have this PCI FM radio card. 136 Choose Y here if you have this PCI FM radio card.
137 137
138 In order to control your radio card, you will need to use programs 138 In order to control your radio card, you will need to use programs
139 that are compatible with the Video for Linux API. Information on 139 that are compatible with the Video for Linux API. Information on
140 this API and pointers to "v4l" programs may be found at 140 this API and pointers to "v4l" programs may be found at
141 <file:Documentation/video4linux/API.html>. 141 <file:Documentation/video4linux/API.html>.
142 142
diff --git a/drivers/media/radio/Makefile b/drivers/media/radio/Makefile
index 8b351945d066..e95b6805e002 100644
--- a/drivers/media/radio/Makefile
+++ b/drivers/media/radio/Makefile
@@ -20,3 +20,5 @@ obj-$(CONFIG_RADIO_GEMTEK) += radio-gemtek.o
20obj-$(CONFIG_RADIO_GEMTEK_PCI) += radio-gemtek-pci.o 20obj-$(CONFIG_RADIO_GEMTEK_PCI) += radio-gemtek-pci.o
21obj-$(CONFIG_RADIO_TRUST) += radio-trust.o 21obj-$(CONFIG_RADIO_TRUST) += radio-trust.o
22obj-$(CONFIG_RADIO_MAESTRO) += radio-maestro.o 22obj-$(CONFIG_RADIO_MAESTRO) += radio-maestro.o
23
24EXTRA_CFLAGS += -Isound
diff --git a/drivers/media/radio/miropcm20-radio.c b/drivers/media/radio/miropcm20-radio.c
index dc292da2605f..c4312fa0e2f5 100644
--- a/drivers/media/radio/miropcm20-radio.c
+++ b/drivers/media/radio/miropcm20-radio.c
@@ -16,13 +16,14 @@
16 16
17/* What ever you think about the ACI, version 0x07 is not very well! 17/* What ever you think about the ACI, version 0x07 is not very well!
18 * I can't get frequency, 'tuner status', 'tuner flags' or mute/mono 18 * I can't get frequency, 'tuner status', 'tuner flags' or mute/mono
19 * conditions... Robert 19 * conditions... Robert
20 */ 20 */
21 21
22#include <linux/module.h> 22#include <linux/module.h>
23#include <linux/init.h> 23#include <linux/init.h>
24#include <linux/videodev.h> 24#include <linux/videodev.h>
25#include "../../../sound/oss/aci.h" 25#include <media/v4l2-common.h>
26#include "oss/aci.h"
26#include "miropcm20-rds-core.h" 27#include "miropcm20-rds-core.h"
27 28
28static int radio_nr = -1; 29static int radio_nr = -1;
@@ -123,7 +124,7 @@ static int pcm20_do_ioctl(struct inode *inode, struct file *file,
123 struct video_device *dev = video_devdata(file); 124 struct video_device *dev = video_devdata(file);
124 struct pcm20_device *pcm20 = dev->priv; 125 struct pcm20_device *pcm20 = dev->priv;
125 int i; 126 int i;
126 127
127 switch(cmd) 128 switch(cmd)
128 { 129 {
129 case VIDIOCGCAP: 130 case VIDIOCGCAP:
@@ -139,7 +140,7 @@ static int pcm20_do_ioctl(struct inode *inode, struct file *file,
139 case VIDIOCGTUNER: 140 case VIDIOCGTUNER:
140 { 141 {
141 struct video_tuner *v = arg; 142 struct video_tuner *v = arg;
142 if(v->tuner) /* Only 1 tuner */ 143 if(v->tuner) /* Only 1 tuner */
143 return -EINVAL; 144 return -EINVAL;
144 v->rangelow=87*16000; 145 v->rangelow=87*16000;
145 v->rangehigh=108*16000; 146 v->rangehigh=108*16000;
@@ -172,7 +173,7 @@ static int pcm20_do_ioctl(struct inode *inode, struct file *file,
172 return i; 173 return i;
173 } 174 }
174 case VIDIOCGAUDIO: 175 case VIDIOCGAUDIO:
175 { 176 {
176 struct video_audio *v = arg; 177 struct video_audio *v = arg;
177 memset(v,0, sizeof(*v)); 178 memset(v,0, sizeof(*v));
178 v->flags=VIDEO_AUDIO_MUTABLE; 179 v->flags=VIDEO_AUDIO_MUTABLE;
@@ -183,12 +184,12 @@ static int pcm20_do_ioctl(struct inode *inode, struct file *file,
183 v->mode|=VIDEO_SOUND_MONO; 184 v->mode|=VIDEO_SOUND_MONO;
184 /* v->step=2048; */ 185 /* v->step=2048; */
185 strcpy(v->name, "Radio"); 186 strcpy(v->name, "Radio");
186 return 0; 187 return 0;
187 } 188 }
188 case VIDIOCSAUDIO: 189 case VIDIOCSAUDIO:
189 { 190 {
190 struct video_audio *v = arg; 191 struct video_audio *v = arg;
191 if(v->audio) 192 if(v->audio)
192 return -EINVAL; 193 return -EINVAL;
193 194
194 pcm20_mute(pcm20, !!(v->flags&VIDEO_AUDIO_MUTE)); 195 pcm20_mute(pcm20, !!(v->flags&VIDEO_AUDIO_MUTE));
@@ -237,7 +238,7 @@ static int __init pcm20_init(void)
237{ 238{
238 if(video_register_device(&pcm20_radio, VFL_TYPE_RADIO, radio_nr)==-1) 239 if(video_register_device(&pcm20_radio, VFL_TYPE_RADIO, radio_nr)==-1)
239 goto video_register_device; 240 goto video_register_device;
240 241
241 if(attach_aci_rds()<0) 242 if(attach_aci_rds()<0)
242 goto attach_aci_rds; 243 goto attach_aci_rds;
243 244
diff --git a/drivers/media/radio/miropcm20-rds-core.c b/drivers/media/radio/miropcm20-rds-core.c
index b602c73e2309..9428d8b2642c 100644
--- a/drivers/media/radio/miropcm20-rds-core.c
+++ b/drivers/media/radio/miropcm20-rds-core.c
@@ -21,7 +21,7 @@
21#include <linux/mutex.h> 21#include <linux/mutex.h>
22 22
23#include <asm/io.h> 23#include <asm/io.h>
24#include "../../../sound/oss/aci.h" 24#include "oss/aci.h"
25#include "miropcm20-rds-core.h" 25#include "miropcm20-rds-core.h"
26 26
27#define DEBUG 0 27#define DEBUG 0
@@ -33,24 +33,24 @@ static struct mutex aci_rds_mutex;
33#define RDS_BUSYMASK 0x10 /* Bit 4 */ 33#define RDS_BUSYMASK 0x10 /* Bit 4 */
34#define RDS_CLOCKMASK 0x08 /* Bit 3 */ 34#define RDS_CLOCKMASK 0x08 /* Bit 3 */
35 35
36#define RDS_DATA(x) (((x) >> RDS_DATASHIFT) & 1) 36#define RDS_DATA(x) (((x) >> RDS_DATASHIFT) & 1)
37 37
38 38
39#if DEBUG 39#if DEBUG
40static void print_matrix(char array[], unsigned int length) 40static void print_matrix(char array[], unsigned int length)
41{ 41{
42 int i, j; 42 int i, j;
43 43
44 for (i=0; i<length; i++) { 44 for (i=0; i<length; i++) {
45 printk(KERN_DEBUG "aci-rds: "); 45 printk(KERN_DEBUG "aci-rds: ");
46 for (j=7; j>=0; j--) { 46 for (j=7; j>=0; j--) {
47 printk("%d", (array[i] >> j) & 0x1); 47 printk("%d", (array[i] >> j) & 0x1);
48 } 48 }
49 if (i%8 == 0) 49 if (i%8 == 0)
50 printk(" byte-border\n"); 50 printk(" byte-border\n");
51 else 51 else
52 printk("\n"); 52 printk("\n");
53 } 53 }
54} 54}
55#endif /* DEBUG */ 55#endif /* DEBUG */
56 56
@@ -114,7 +114,7 @@ static int rds_write(unsigned char cmd)
114{ 114{
115 unsigned char sendbuffer[8]; 115 unsigned char sendbuffer[8];
116 int i; 116 int i;
117 117
118 if (byte2trans(cmd, sendbuffer, 8) != 0){ 118 if (byte2trans(cmd, sendbuffer, 8) != 0){
119 return -1; 119 return -1;
120 } else { 120 } else {
@@ -151,7 +151,7 @@ static int rds_read(unsigned char databuffer[], int datasize)
151 I have to waitread() here */ 151 I have to waitread() here */
152 if (rds_waitread() < 0) 152 if (rds_waitread() < 0)
153 return -1; 153 return -1;
154 154
155 memset(databuffer, 0, datasize); 155 memset(databuffer, 0, datasize);
156 156
157 for (i=0; i< READSIZE; i++) 157 for (i=0; i< READSIZE; i++)
@@ -194,7 +194,7 @@ int aci_rds_cmd(unsigned char cmd, unsigned char databuffer[], int datasize)
194 ret = 0; 194 ret = 0;
195 195
196 mutex_unlock(&aci_rds_mutex); 196 mutex_unlock(&aci_rds_mutex);
197 197
198 return ret; 198 return ret;
199} 199}
200EXPORT_SYMBOL(aci_rds_cmd); 200EXPORT_SYMBOL(aci_rds_cmd);
diff --git a/drivers/media/radio/miropcm20-rds.c b/drivers/media/radio/miropcm20-rds.c
index e09214082e01..87b37b7691da 100644
--- a/drivers/media/radio/miropcm20-rds.c
+++ b/drivers/media/radio/miropcm20-rds.c
@@ -48,7 +48,7 @@ static int rds_f_release(struct inode *in, struct file *fi)
48 48
49static void print_matrix(char *ch, char out[]) 49static void print_matrix(char *ch, char out[])
50{ 50{
51 int j; 51 int j;
52 52
53 for (j=7; j>=0; j--) { 53 for (j=7; j>=0; j--) {
54 out[7-j] = ((*ch >> j) & 0x1) + '0'; 54 out[7-j] = ((*ch >> j) & 0x1) + '0';
diff --git a/drivers/media/radio/radio-aimslab.c b/drivers/media/radio/radio-aimslab.c
index 557fb5c4af38..df22a582e7a2 100644
--- a/drivers/media/radio/radio-aimslab.c
+++ b/drivers/media/radio/radio-aimslab.c
@@ -24,7 +24,7 @@
24 * out(port, start_increasing_volume); 24 * out(port, start_increasing_volume);
25 * wait(a_wee_while); 25 * wait(a_wee_while);
26 * out(port, stop_changing_the_volume); 26 * out(port, stop_changing_the_volume);
27 * 27 *
28 */ 28 */
29 29
30#include <linux/module.h> /* Modules */ 30#include <linux/module.h> /* Modules */
@@ -34,6 +34,7 @@
34#include <asm/io.h> /* outb, outb_p */ 34#include <asm/io.h> /* outb, outb_p */
35#include <asm/uaccess.h> /* copy to/from user */ 35#include <asm/uaccess.h> /* copy to/from user */
36#include <linux/videodev.h> /* kernel radio structs */ 36#include <linux/videodev.h> /* kernel radio structs */
37#include <media/v4l2-common.h>
37#include <linux/config.h> /* CONFIG_RADIO_RTRACK_PORT */ 38#include <linux/config.h> /* CONFIG_RADIO_RTRACK_PORT */
38#include <asm/semaphore.h> /* Lock for the I/O */ 39#include <asm/semaphore.h> /* Lock for the I/O */
39 40
@@ -41,7 +42,7 @@
41#define CONFIG_RADIO_RTRACK_PORT -1 42#define CONFIG_RADIO_RTRACK_PORT -1
42#endif 43#endif
43 44
44static int io = CONFIG_RADIO_RTRACK_PORT; 45static int io = CONFIG_RADIO_RTRACK_PORT;
45static int radio_nr = -1; 46static int radio_nr = -1;
46static struct mutex lock; 47static struct mutex lock;
47 48
@@ -93,12 +94,12 @@ static int rt_setvol(struct rt_device *dev, int vol)
93 int i; 94 int i;
94 95
95 mutex_lock(&lock); 96 mutex_lock(&lock);
96 97
97 if(vol == dev->curvol) { /* requested volume = current */ 98 if(vol == dev->curvol) { /* requested volume = current */
98 if (dev->muted) { /* user is unmuting the card */ 99 if (dev->muted) { /* user is unmuting the card */
99 dev->muted = 0; 100 dev->muted = 0;
100 outb (0xd8, io); /* enable card */ 101 outb (0xd8, io); /* enable card */
101 } 102 }
102 mutex_unlock(&lock); 103 mutex_unlock(&lock);
103 return 0; 104 return 0;
104 } 105 }
@@ -114,10 +115,10 @@ static int rt_setvol(struct rt_device *dev, int vol)
114 115
115 dev->muted = 0; 116 dev->muted = 0;
116 if(vol > dev->curvol) 117 if(vol > dev->curvol)
117 for(i = dev->curvol; i < vol; i++) 118 for(i = dev->curvol; i < vol; i++)
118 rt_incvol(); 119 rt_incvol();
119 else 120 else
120 for(i = dev->curvol; i > vol; i--) 121 for(i = dev->curvol; i > vol; i--)
121 rt_decvol(); 122 rt_decvol();
122 123
123 dev->curvol = vol; 124 dev->curvol = vol;
@@ -125,7 +126,7 @@ static int rt_setvol(struct rt_device *dev, int vol)
125 return 0; 126 return 0;
126} 127}
127 128
128/* the 128+64 on these outb's is to keep the volume stable while tuning 129/* the 128+64 on these outb's is to keep the volume stable while tuning
129 * without them, the volume _will_ creep up with each frequency change 130 * without them, the volume _will_ creep up with each frequency change
130 * and bit 4 (+16) is to keep the signal strength meter enabled 131 * and bit 4 (+16) is to keep the signal strength meter enabled
131 */ 132 */
@@ -140,7 +141,7 @@ static void send_0_byte(int port, struct rt_device *dev)
140 outb_p(128+64+16+8+ 1, port); /* on + wr-enable + data low */ 141 outb_p(128+64+16+8+ 1, port); /* on + wr-enable + data low */
141 outb_p(128+64+16+8+2+1, port); /* clock */ 142 outb_p(128+64+16+8+2+1, port); /* clock */
142 } 143 }
143 sleep_delay(1000); 144 sleep_delay(1000);
144} 145}
145 146
146static void send_1_byte(int port, struct rt_device *dev) 147static void send_1_byte(int port, struct rt_device *dev)
@@ -148,13 +149,13 @@ static void send_1_byte(int port, struct rt_device *dev)
148 if ((dev->curvol == 0) || (dev->muted)) { 149 if ((dev->curvol == 0) || (dev->muted)) {
149 outb_p(128+64+16+4 +1, port); /* wr-enable+data high */ 150 outb_p(128+64+16+4 +1, port); /* wr-enable+data high */
150 outb_p(128+64+16+4+2+1, port); /* clock */ 151 outb_p(128+64+16+4+2+1, port); /* clock */
151 } 152 }
152 else { 153 else {
153 outb_p(128+64+16+8+4 +1, port); /* on+wr-enable+data high */ 154 outb_p(128+64+16+8+4 +1, port); /* on+wr-enable+data high */
154 outb_p(128+64+16+8+4+2+1, port); /* clock */ 155 outb_p(128+64+16+8+4+2+1, port); /* clock */
155 } 156 }
156 157
157 sleep_delay(1000); 158 sleep_delay(1000);
158} 159}
159 160
160static int rt_setfreq(struct rt_device *dev, unsigned long freq) 161static int rt_setfreq(struct rt_device *dev, unsigned long freq)
@@ -167,9 +168,9 @@ static int rt_setfreq(struct rt_device *dev, unsigned long freq)
167 168
168 freq += 171200; /* Add 10.7 MHz IF */ 169 freq += 171200; /* Add 10.7 MHz IF */
169 freq /= 800; /* Convert to 50 kHz units */ 170 freq /= 800; /* Convert to 50 kHz units */
170 171
171 mutex_lock(&lock); /* Stop other ops interfering */ 172 mutex_lock(&lock); /* Stop other ops interfering */
172 173
173 send_0_byte (io, dev); /* 0: LSB of frequency */ 174 send_0_byte (io, dev); /* 0: LSB of frequency */
174 175
175 for (i = 0; i < 13; i++) /* : frequency bits (1-13) */ 176 for (i = 0; i < 13; i++) /* : frequency bits (1-13) */
@@ -195,7 +196,7 @@ static int rt_setfreq(struct rt_device *dev, unsigned long freq)
195 outb (0xd0, io); /* volume steady + sigstr */ 196 outb (0xd0, io); /* volume steady + sigstr */
196 else 197 else
197 outb (0xd8, io); /* volume steady + sigstr + on */ 198 outb (0xd8, io); /* volume steady + sigstr + on */
198 199
199 mutex_unlock(&lock); 200 mutex_unlock(&lock);
200 201
201 return 0; 202 return 0;
@@ -213,7 +214,7 @@ static int rt_do_ioctl(struct inode *inode, struct file *file,
213{ 214{
214 struct video_device *dev = video_devdata(file); 215 struct video_device *dev = video_devdata(file);
215 struct rt_device *rt=dev->priv; 216 struct rt_device *rt=dev->priv;
216 217
217 switch(cmd) 218 switch(cmd)
218 { 219 {
219 case VIDIOCGCAP: 220 case VIDIOCGCAP:
@@ -229,7 +230,7 @@ static int rt_do_ioctl(struct inode *inode, struct file *file,
229 case VIDIOCGTUNER: 230 case VIDIOCGTUNER:
230 { 231 {
231 struct video_tuner *v = arg; 232 struct video_tuner *v = arg;
232 if(v->tuner) /* Only 1 tuner */ 233 if(v->tuner) /* Only 1 tuner */
233 return -EINVAL; 234 return -EINVAL;
234 v->rangelow=(87*16000); 235 v->rangelow=(87*16000);
235 v->rangehigh=(108*16000); 236 v->rangehigh=(108*16000);
@@ -261,21 +262,21 @@ static int rt_do_ioctl(struct inode *inode, struct file *file,
261 return 0; 262 return 0;
262 } 263 }
263 case VIDIOCGAUDIO: 264 case VIDIOCGAUDIO:
264 { 265 {
265 struct video_audio *v = arg; 266 struct video_audio *v = arg;
266 memset(v,0, sizeof(*v)); 267 memset(v,0, sizeof(*v));
267 v->flags|=VIDEO_AUDIO_MUTABLE|VIDEO_AUDIO_VOLUME; 268 v->flags|=VIDEO_AUDIO_MUTABLE|VIDEO_AUDIO_VOLUME;
268 v->volume=rt->curvol * 6554; 269 v->volume=rt->curvol * 6554;
269 v->step=6554; 270 v->step=6554;
270 strcpy(v->name, "Radio"); 271 strcpy(v->name, "Radio");
271 return 0; 272 return 0;
272 } 273 }
273 case VIDIOCSAUDIO: 274 case VIDIOCSAUDIO:
274 { 275 {
275 struct video_audio *v = arg; 276 struct video_audio *v = arg;
276 if(v->audio) 277 if(v->audio)
277 return -EINVAL; 278 return -EINVAL;
278 if(v->flags&VIDEO_AUDIO_MUTE) 279 if(v->flags&VIDEO_AUDIO_MUTE)
279 rt_mute(rt); 280 rt_mute(rt);
280 else 281 else
281 rt_setvol(rt,v->volume/6554); 282 rt_setvol(rt,v->volume/6554);
@@ -298,7 +299,7 @@ static struct file_operations rtrack_fops = {
298 .owner = THIS_MODULE, 299 .owner = THIS_MODULE,
299 .open = video_exclusive_open, 300 .open = video_exclusive_open,
300 .release = video_exclusive_release, 301 .release = video_exclusive_release,
301 .ioctl = rt_ioctl, 302 .ioctl = rt_ioctl,
302 .compat_ioctl = v4l_compat_ioctl32, 303 .compat_ioctl = v4l_compat_ioctl32,
303 .llseek = no_llseek, 304 .llseek = no_llseek,
304}; 305};
@@ -320,14 +321,14 @@ static int __init rtrack_init(void)
320 return -EINVAL; 321 return -EINVAL;
321 } 322 }
322 323
323 if (!request_region(io, 2, "rtrack")) 324 if (!request_region(io, 2, "rtrack"))
324 { 325 {
325 printk(KERN_ERR "rtrack: port 0x%x already in use\n", io); 326 printk(KERN_ERR "rtrack: port 0x%x already in use\n", io);
326 return -EBUSY; 327 return -EBUSY;
327 } 328 }
328 329
329 rtrack_radio.priv=&rtrack_unit; 330 rtrack_radio.priv=&rtrack_unit;
330 331
331 if(video_register_device(&rtrack_radio, VFL_TYPE_RADIO, radio_nr)==-1) 332 if(video_register_device(&rtrack_radio, VFL_TYPE_RADIO, radio_nr)==-1)
332 { 333 {
333 release_region(io, 2); 334 release_region(io, 2);
@@ -336,10 +337,10 @@ static int __init rtrack_init(void)
336 printk(KERN_INFO "AIMSlab RadioTrack/RadioReveal card driver.\n"); 337 printk(KERN_INFO "AIMSlab RadioTrack/RadioReveal card driver.\n");
337 338
338 /* Set up the I/O locking */ 339 /* Set up the I/O locking */
339 340
340 mutex_init(&lock); 341 mutex_init(&lock);
341 342
342 /* mute card - prevents noisy bootups */ 343 /* mute card - prevents noisy bootups */
343 344
344 /* this ensures that the volume is all the way down */ 345 /* this ensures that the volume is all the way down */
345 outb(0x48, io); /* volume down but still "on" */ 346 outb(0x48, io); /* volume down but still "on" */
diff --git a/drivers/media/radio/radio-aztech.c b/drivers/media/radio/radio-aztech.c
index 83bdae23417d..95e6322133ee 100644
--- a/drivers/media/radio/radio-aztech.c
+++ b/drivers/media/radio/radio-aztech.c
@@ -1,11 +1,11 @@
1/* radio-aztech.c - Aztech radio card driver for Linux 2.2 1/* radio-aztech.c - Aztech radio card driver for Linux 2.2
2 * 2 *
3 * Adapted to support the Video for Linux API by 3 * Adapted to support the Video for Linux API by
4 * Russell Kroll <rkroll@exploits.org>. Based on original tuner code by: 4 * Russell Kroll <rkroll@exploits.org>. Based on original tuner code by:
5 * 5 *
6 * Quay Ly 6 * Quay Ly
7 * Donald Song 7 * Donald Song
8 * Jason Lewis (jlewis@twilight.vtc.vsc.edu) 8 * Jason Lewis (jlewis@twilight.vtc.vsc.edu)
9 * Scott McGrath (smcgrath@twilight.vtc.vsc.edu) 9 * Scott McGrath (smcgrath@twilight.vtc.vsc.edu)
10 * William McGrath (wmcgrath@twilight.vtc.vsc.edu) 10 * William McGrath (wmcgrath@twilight.vtc.vsc.edu)
11 * 11 *
@@ -31,6 +31,7 @@
31#include <asm/io.h> /* outb, outb_p */ 31#include <asm/io.h> /* outb, outb_p */
32#include <asm/uaccess.h> /* copy to/from user */ 32#include <asm/uaccess.h> /* copy to/from user */
33#include <linux/videodev.h> /* kernel radio structs */ 33#include <linux/videodev.h> /* kernel radio structs */
34#include <media/v4l2-common.h>
34#include <linux/config.h> /* CONFIG_RADIO_AZTECH_PORT */ 35#include <linux/config.h> /* CONFIG_RADIO_AZTECH_PORT */
35 36
36/* acceptable ports: 0x350 (JP3 shorted), 0x358 (JP3 open) */ 37/* acceptable ports: 0x350 (JP3 shorted), 0x358 (JP3 open) */
@@ -39,7 +40,7 @@
39#define CONFIG_RADIO_AZTECH_PORT -1 40#define CONFIG_RADIO_AZTECH_PORT -1
40#endif 41#endif
41 42
42static int io = CONFIG_RADIO_AZTECH_PORT; 43static int io = CONFIG_RADIO_AZTECH_PORT;
43static int radio_nr = -1; 44static int radio_nr = -1;
44static int radio_wait_time = 1000; 45static int radio_wait_time = 1000;
45static struct mutex lock; 46static struct mutex lock;
@@ -53,15 +54,15 @@ struct az_device
53 54
54static int volconvert(int level) 55static int volconvert(int level)
55{ 56{
56 level>>=14; /* Map 16bits down to 2 bit */ 57 level>>=14; /* Map 16bits down to 2 bit */
57 level&=3; 58 level&=3;
58 59
59 /* convert to card-friendly values */ 60 /* convert to card-friendly values */
60 switch (level) 61 switch (level)
61 { 62 {
62 case 0: 63 case 0:
63 return 0; 64 return 0;
64 case 1: 65 case 1:
65 return 1; 66 return 1;
66 case 2: 67 case 2:
67 return 4; 68 return 4;
@@ -121,9 +122,9 @@ static int az_setfreq(struct az_device *dev, unsigned long frequency)
121 122
122 frequency += 171200; /* Add 10.7 MHz IF */ 123 frequency += 171200; /* Add 10.7 MHz IF */
123 frequency /= 800; /* Convert to 50 kHz units */ 124 frequency /= 800; /* Convert to 50 kHz units */
124 125
125 mutex_lock(&lock); 126 mutex_lock(&lock);
126 127
127 send_0_byte (dev); /* 0: LSB of frequency */ 128 send_0_byte (dev); /* 0: LSB of frequency */
128 129
129 for (i = 0; i < 13; i++) /* : frequency bits (1-13) */ 130 for (i = 0; i < 13; i++) /* : frequency bits (1-13) */
@@ -151,7 +152,7 @@ static int az_setfreq(struct az_device *dev, unsigned long frequency)
151 152
152 udelay (radio_wait_time); 153 udelay (radio_wait_time);
153 outb_p(128+64+volconvert(dev->curvol), io); 154 outb_p(128+64+volconvert(dev->curvol), io);
154 155
155 mutex_unlock(&lock); 156 mutex_unlock(&lock);
156 157
157 return 0; 158 return 0;
@@ -162,7 +163,7 @@ static int az_do_ioctl(struct inode *inode, struct file *file,
162{ 163{
163 struct video_device *dev = video_devdata(file); 164 struct video_device *dev = video_devdata(file);
164 struct az_device *az = dev->priv; 165 struct az_device *az = dev->priv;
165 166
166 switch(cmd) 167 switch(cmd)
167 { 168 {
168 case VIDIOCGCAP: 169 case VIDIOCGCAP:
@@ -178,7 +179,7 @@ static int az_do_ioctl(struct inode *inode, struct file *file,
178 case VIDIOCGTUNER: 179 case VIDIOCGTUNER:
179 { 180 {
180 struct video_tuner *v = arg; 181 struct video_tuner *v = arg;
181 if(v->tuner) /* Only 1 tuner */ 182 if(v->tuner) /* Only 1 tuner */
182 return -EINVAL; 183 return -EINVAL;
183 v->rangelow=(87*16000); 184 v->rangelow=(87*16000);
184 v->rangehigh=(108*16000); 185 v->rangehigh=(108*16000);
@@ -211,7 +212,7 @@ static int az_do_ioctl(struct inode *inode, struct file *file,
211 return 0; 212 return 0;
212 } 213 }
213 case VIDIOCGAUDIO: 214 case VIDIOCGAUDIO:
214 { 215 {
215 struct video_audio *v = arg; 216 struct video_audio *v = arg;
216 memset(v,0, sizeof(*v)); 217 memset(v,0, sizeof(*v));
217 v->flags|=VIDEO_AUDIO_MUTABLE|VIDEO_AUDIO_VOLUME; 218 v->flags|=VIDEO_AUDIO_MUTABLE|VIDEO_AUDIO_VOLUME;
@@ -222,17 +223,17 @@ static int az_do_ioctl(struct inode *inode, struct file *file,
222 v->volume=az->curvol; 223 v->volume=az->curvol;
223 v->step=16384; 224 v->step=16384;
224 strcpy(v->name, "Radio"); 225 strcpy(v->name, "Radio");
225 return 0; 226 return 0;
226 } 227 }
227 case VIDIOCSAUDIO: 228 case VIDIOCSAUDIO:
228 { 229 {
229 struct video_audio *v = arg; 230 struct video_audio *v = arg;
230 if(v->audio) 231 if(v->audio)
231 return -EINVAL; 232 return -EINVAL;
232 az->curvol=v->volume; 233 az->curvol=v->volume;
233 234
234 az->stereo=(v->mode&VIDEO_SOUND_STEREO)?1:0; 235 az->stereo=(v->mode&VIDEO_SOUND_STEREO)?1:0;
235 if(v->flags&VIDEO_AUDIO_MUTE) 236 if(v->flags&VIDEO_AUDIO_MUTE)
236 az_setvol(az,0); 237 az_setvol(az,0);
237 else 238 else
238 az_setvol(az,az->curvol); 239 az_setvol(az,az->curvol);
@@ -277,7 +278,7 @@ static int __init aztech_init(void)
277 return -EINVAL; 278 return -EINVAL;
278 } 279 }
279 280
280 if (!request_region(io, 2, "aztech")) 281 if (!request_region(io, 2, "aztech"))
281 { 282 {
282 printk(KERN_ERR "aztech: port 0x%x already in use\n", io); 283 printk(KERN_ERR "aztech: port 0x%x already in use\n", io);
283 return -EBUSY; 284 return -EBUSY;
@@ -285,13 +286,13 @@ static int __init aztech_init(void)
285 286
286 mutex_init(&lock); 287 mutex_init(&lock);
287 aztech_radio.priv=&aztech_unit; 288 aztech_radio.priv=&aztech_unit;
288 289
289 if(video_register_device(&aztech_radio, VFL_TYPE_RADIO, radio_nr)==-1) 290 if(video_register_device(&aztech_radio, VFL_TYPE_RADIO, radio_nr)==-1)
290 { 291 {
291 release_region(io,2); 292 release_region(io,2);
292 return -EINVAL; 293 return -EINVAL;
293 } 294 }
294 295
295 printk(KERN_INFO "Aztech radio card driver v1.00/19990224 rkroll@exploits.org\n"); 296 printk(KERN_INFO "Aztech radio card driver v1.00/19990224 rkroll@exploits.org\n");
296 /* mute card - prevents noisy bootups */ 297 /* mute card - prevents noisy bootups */
297 outb (0, io); 298 outb (0, io);
diff --git a/drivers/media/radio/radio-cadet.c b/drivers/media/radio/radio-cadet.c
index f1b5ac81e9d2..8641aec7baf8 100644
--- a/drivers/media/radio/radio-cadet.c
+++ b/drivers/media/radio/radio-cadet.c
@@ -8,7 +8,7 @@
8 * Russell Kroll (rkroll@exploits.org) 8 * Russell Kroll (rkroll@exploits.org)
9 * Quay Ly 9 * Quay Ly
10 * Donald Song 10 * Donald Song
11 * Jason Lewis (jlewis@twilight.vtc.vsc.edu) 11 * Jason Lewis (jlewis@twilight.vtc.vsc.edu)
12 * Scott McGrath (smcgrath@twilight.vtc.vsc.edu) 12 * Scott McGrath (smcgrath@twilight.vtc.vsc.edu)
13 * William McGrath (wmcgrath@twilight.vtc.vsc.edu) 13 * William McGrath (wmcgrath@twilight.vtc.vsc.edu)
14 * 14 *
@@ -34,6 +34,7 @@
34#include <asm/io.h> /* outb, outb_p */ 34#include <asm/io.h> /* outb, outb_p */
35#include <asm/uaccess.h> /* copy to/from user */ 35#include <asm/uaccess.h> /* copy to/from user */
36#include <linux/videodev.h> /* kernel radio structs */ 36#include <linux/videodev.h> /* kernel radio structs */
37#include <media/v4l2-common.h>
37#include <linux/param.h> 38#include <linux/param.h>
38#include <linux/pnp.h> 39#include <linux/pnp.h>
39 40
@@ -55,29 +56,29 @@ static int cadet_probe(void);
55 56
56/* 57/*
57 * Signal Strength Threshold Values 58 * Signal Strength Threshold Values
58 * The V4L API spec does not define any particular unit for the signal 59 * The V4L API spec does not define any particular unit for the signal
59 * strength value. These values are in microvolts of RF at the tuner's input. 60 * strength value. These values are in microvolts of RF at the tuner's input.
60 */ 61 */
61static __u16 sigtable[2][4]={{5,10,30,150},{28,40,63,1000}}; 62static __u16 sigtable[2][4]={{5,10,30,150},{28,40,63,1000}};
62 63
63static int cadet_getrds(void) 64static int cadet_getrds(void)
64{ 65{
65 int rdsstat=0; 66 int rdsstat=0;
66 67
67 spin_lock(&cadet_io_lock); 68 spin_lock(&cadet_io_lock);
68 outb(3,io); /* Select Decoder Control/Status */ 69 outb(3,io); /* Select Decoder Control/Status */
69 outb(inb(io+1)&0x7f,io+1); /* Reset RDS detection */ 70 outb(inb(io+1)&0x7f,io+1); /* Reset RDS detection */
70 spin_unlock(&cadet_io_lock); 71 spin_unlock(&cadet_io_lock);
71 72
72 msleep(100); 73 msleep(100);
73 74
74 spin_lock(&cadet_io_lock); 75 spin_lock(&cadet_io_lock);
75 outb(3,io); /* Select Decoder Control/Status */ 76 outb(3,io); /* Select Decoder Control/Status */
76 if((inb(io+1)&0x80)!=0) { 77 if((inb(io+1)&0x80)!=0) {
77 rdsstat|=VIDEO_TUNER_RDS_ON; 78 rdsstat|=VIDEO_TUNER_RDS_ON;
78 } 79 }
79 if((inb(io+1)&0x10)!=0) { 80 if((inb(io+1)&0x10)!=0) {
80 rdsstat|=VIDEO_TUNER_MBS_ON; 81 rdsstat|=VIDEO_TUNER_MBS_ON;
81 } 82 }
82 spin_unlock(&cadet_io_lock); 83 spin_unlock(&cadet_io_lock);
83 return rdsstat; 84 return rdsstat;
@@ -86,49 +87,49 @@ static int cadet_getrds(void)
86static int cadet_getstereo(void) 87static int cadet_getstereo(void)
87{ 88{
88 int ret = 0; 89 int ret = 0;
89 if(curtuner != 0) /* Only FM has stereo capability! */ 90 if(curtuner != 0) /* Only FM has stereo capability! */
90 return 0; 91 return 0;
91 92
92 spin_lock(&cadet_io_lock); 93 spin_lock(&cadet_io_lock);
93 outb(7,io); /* Select tuner control */ 94 outb(7,io); /* Select tuner control */
94 if( (inb(io+1) & 0x40) == 0) 95 if( (inb(io+1) & 0x40) == 0)
95 ret = 1; 96 ret = 1;
96 spin_unlock(&cadet_io_lock); 97 spin_unlock(&cadet_io_lock);
97 return ret; 98 return ret;
98} 99}
99 100
100static unsigned cadet_gettune(void) 101static unsigned cadet_gettune(void)
101{ 102{
102 int curvol,i; 103 int curvol,i;
103 unsigned fifo=0; 104 unsigned fifo=0;
104 105
105 /* 106 /*
106 * Prepare for read 107 * Prepare for read
107 */ 108 */
108 109
109 spin_lock(&cadet_io_lock); 110 spin_lock(&cadet_io_lock);
110 111
111 outb(7,io); /* Select tuner control */ 112 outb(7,io); /* Select tuner control */
112 curvol=inb(io+1); /* Save current volume/mute setting */ 113 curvol=inb(io+1); /* Save current volume/mute setting */
113 outb(0x00,io+1); /* Ensure WRITE-ENABLE is LOW */ 114 outb(0x00,io+1); /* Ensure WRITE-ENABLE is LOW */
114 tunestat=0xffff; 115 tunestat=0xffff;
115 116
116 /* 117 /*
117 * Read the shift register 118 * Read the shift register
118 */ 119 */
119 for(i=0;i<25;i++) { 120 for(i=0;i<25;i++) {
120 fifo=(fifo<<1)|((inb(io+1)>>7)&0x01); 121 fifo=(fifo<<1)|((inb(io+1)>>7)&0x01);
121 if(i<24) { 122 if(i<24) {
122 outb(0x01,io+1); 123 outb(0x01,io+1);
123 tunestat&=inb(io+1); 124 tunestat&=inb(io+1);
124 outb(0x00,io+1); 125 outb(0x00,io+1);
125 } 126 }
126 } 127 }
127 128
128 /* 129 /*
129 * Restore volume/mute setting 130 * Restore volume/mute setting
130 */ 131 */
131 outb(curvol,io+1); 132 outb(curvol,io+1);
132 spin_unlock(&cadet_io_lock); 133 spin_unlock(&cadet_io_lock);
133 134
134 return fifo; 135 return fifo;
@@ -136,43 +137,43 @@ static unsigned cadet_gettune(void)
136 137
137static unsigned cadet_getfreq(void) 138static unsigned cadet_getfreq(void)
138{ 139{
139 int i; 140 int i;
140 unsigned freq=0,test,fifo=0; 141 unsigned freq=0,test,fifo=0;
141 142
142 /* 143 /*
143 * Read current tuning 144 * Read current tuning
144 */ 145 */
145 fifo=cadet_gettune(); 146 fifo=cadet_gettune();
146 147
147 /* 148 /*
148 * Convert to actual frequency 149 * Convert to actual frequency
149 */ 150 */
150 if(curtuner==0) { /* FM */ 151 if(curtuner==0) { /* FM */
151 test=12500; 152 test=12500;
152 for(i=0;i<14;i++) { 153 for(i=0;i<14;i++) {
153 if((fifo&0x01)!=0) { 154 if((fifo&0x01)!=0) {
154 freq+=test; 155 freq+=test;
155 } 156 }
156 test=test<<1; 157 test=test<<1;
157 fifo=fifo>>1; 158 fifo=fifo>>1;
158 } 159 }
159 freq-=10700000; /* IF frequency is 10.7 MHz */ 160 freq-=10700000; /* IF frequency is 10.7 MHz */
160 freq=(freq*16)/1000000; /* Make it 1/16 MHz */ 161 freq=(freq*16)/1000000; /* Make it 1/16 MHz */
161 } 162 }
162 if(curtuner==1) { /* AM */ 163 if(curtuner==1) { /* AM */
163 freq=((fifo&0x7fff)-2010)*16; 164 freq=((fifo&0x7fff)-2010)*16;
164 } 165 }
165 166
166 return freq; 167 return freq;
167} 168}
168 169
169static void cadet_settune(unsigned fifo) 170static void cadet_settune(unsigned fifo)
170{ 171{
171 int i; 172 int i;
172 unsigned test; 173 unsigned test;
173 174
174 spin_lock(&cadet_io_lock); 175 spin_lock(&cadet_io_lock);
175 176
176 outb(7,io); /* Select tuner control */ 177 outb(7,io); /* Select tuner control */
177 /* 178 /*
178 * Write the shift register 179 * Write the shift register
@@ -183,7 +184,7 @@ static void cadet_settune(unsigned fifo)
183 outb(7,io); /* Select tuner control */ 184 outb(7,io); /* Select tuner control */
184 outb(test,io+1); /* Initialize for write */ 185 outb(test,io+1); /* Initialize for write */
185 for(i=0;i<25;i++) { 186 for(i=0;i<25;i++) {
186 test|=0x01; /* Toggle SCK High */ 187 test|=0x01; /* Toggle SCK High */
187 outb(test,io+1); 188 outb(test,io+1);
188 test&=0xfe; /* Toggle SCK Low */ 189 test&=0xfe; /* Toggle SCK Low */
189 outb(test,io+1); 190 outb(test,io+1);
@@ -196,57 +197,57 @@ static void cadet_settune(unsigned fifo)
196 197
197static void cadet_setfreq(unsigned freq) 198static void cadet_setfreq(unsigned freq)
198{ 199{
199 unsigned fifo; 200 unsigned fifo;
200 int i,j,test; 201 int i,j,test;
201 int curvol; 202 int curvol;
202 203
203 /* 204 /*
204 * Formulate a fifo command 205 * Formulate a fifo command
205 */ 206 */
206 fifo=0; 207 fifo=0;
207 if(curtuner==0) { /* FM */ 208 if(curtuner==0) { /* FM */
208 test=102400; 209 test=102400;
209 freq=(freq*1000)/16; /* Make it kHz */ 210 freq=(freq*1000)/16; /* Make it kHz */
210 freq+=10700; /* IF is 10700 kHz */ 211 freq+=10700; /* IF is 10700 kHz */
211 for(i=0;i<14;i++) { 212 for(i=0;i<14;i++) {
212 fifo=fifo<<1; 213 fifo=fifo<<1;
213 if(freq>=test) { 214 if(freq>=test) {
214 fifo|=0x01; 215 fifo|=0x01;
215 freq-=test; 216 freq-=test;
216 } 217 }
217 test=test>>1; 218 test=test>>1;
218 } 219 }
219 } 220 }
220 if(curtuner==1) { /* AM */ 221 if(curtuner==1) { /* AM */
221 fifo=(freq/16)+2010; /* Make it kHz */ 222 fifo=(freq/16)+2010; /* Make it kHz */
222 fifo|=0x100000; /* Select AM Band */ 223 fifo|=0x100000; /* Select AM Band */
223 } 224 }
224 225
225 /* 226 /*
226 * Save current volume/mute setting 227 * Save current volume/mute setting
227 */ 228 */
228 229
229 spin_lock(&cadet_io_lock); 230 spin_lock(&cadet_io_lock);
230 outb(7,io); /* Select tuner control */ 231 outb(7,io); /* Select tuner control */
231 curvol=inb(io+1); 232 curvol=inb(io+1);
232 spin_unlock(&cadet_io_lock); 233 spin_unlock(&cadet_io_lock);
233 234
234 /* 235 /*
235 * Tune the card 236 * Tune the card
236 */ 237 */
237 for(j=3;j>-1;j--) { 238 for(j=3;j>-1;j--) {
238 cadet_settune(fifo|(j<<16)); 239 cadet_settune(fifo|(j<<16));
239 240
240 spin_lock(&cadet_io_lock); 241 spin_lock(&cadet_io_lock);
241 outb(7,io); /* Select tuner control */ 242 outb(7,io); /* Select tuner control */
242 outb(curvol,io+1); 243 outb(curvol,io+1);
243 spin_unlock(&cadet_io_lock); 244 spin_unlock(&cadet_io_lock);
244 245
245 msleep(100); 246 msleep(100);
246 247
247 cadet_gettune(); 248 cadet_gettune();
248 if((tunestat & 0x40) == 0) { /* Tuned */ 249 if((tunestat & 0x40) == 0) { /* Tuned */
249 sigstrength=sigtable[curtuner][j]; 250 sigstrength=sigtable[curtuner][j];
250 return; 251 return;
251 } 252 }
252 } 253 }
@@ -257,28 +258,28 @@ static void cadet_setfreq(unsigned freq)
257static int cadet_getvol(void) 258static int cadet_getvol(void)
258{ 259{
259 int ret = 0; 260 int ret = 0;
260 261
261 spin_lock(&cadet_io_lock); 262 spin_lock(&cadet_io_lock);
262 263
263 outb(7,io); /* Select tuner control */ 264 outb(7,io); /* Select tuner control */
264 if((inb(io + 1) & 0x20) != 0) 265 if((inb(io + 1) & 0x20) != 0)
265 ret = 0xffff; 266 ret = 0xffff;
266 267
267 spin_unlock(&cadet_io_lock); 268 spin_unlock(&cadet_io_lock);
268 return ret; 269 return ret;
269} 270}
270 271
271 272
272static void cadet_setvol(int vol) 273static void cadet_setvol(int vol)
273{ 274{
274 spin_lock(&cadet_io_lock); 275 spin_lock(&cadet_io_lock);
275 outb(7,io); /* Select tuner control */ 276 outb(7,io); /* Select tuner control */
276 if(vol>0) 277 if(vol>0)
277 outb(0x20,io+1); 278 outb(0x20,io+1);
278 else 279 else
279 outb(0x00,io+1); 280 outb(0x00,io+1);
280 spin_unlock(&cadet_io_lock); 281 spin_unlock(&cadet_io_lock);
281} 282}
282 283
283static void cadet_handler(unsigned long data) 284static void cadet_handler(unsigned long data)
284{ 285{
@@ -288,15 +289,15 @@ static void cadet_handler(unsigned long data)
288 289
289 if(spin_trylock(&cadet_io_lock)) 290 if(spin_trylock(&cadet_io_lock))
290 { 291 {
291 outb(0x3,io); /* Select RDS Decoder Control */ 292 outb(0x3,io); /* Select RDS Decoder Control */
292 if((inb(io+1)&0x20)!=0) { 293 if((inb(io+1)&0x20)!=0) {
293 printk(KERN_CRIT "cadet: RDS fifo overflow\n"); 294 printk(KERN_CRIT "cadet: RDS fifo overflow\n");
294 } 295 }
295 outb(0x80,io); /* Select RDS fifo */ 296 outb(0x80,io); /* Select RDS fifo */
296 while((inb(io)&0x80)!=0) { 297 while((inb(io)&0x80)!=0) {
297 rdsbuf[rdsin]=inb(io+1); 298 rdsbuf[rdsin]=inb(io+1);
298 if(rdsin==rdsout) 299 if(rdsin==rdsout)
299 printk(KERN_WARNING "cadet: RDS buffer overflow\n"); 300 printk(KERN_WARNING "cadet: RDS buffer overflow\n");
300 else 301 else
301 rdsin++; 302 rdsin++;
302 } 303 }
@@ -307,9 +308,9 @@ static void cadet_handler(unsigned long data)
307 * Service pending read 308 * Service pending read
308 */ 309 */
309 if( rdsin!=rdsout) 310 if( rdsin!=rdsout)
310 wake_up_interruptible(&read_queue); 311 wake_up_interruptible(&read_queue);
311 312
312 /* 313 /*
313 * Clean up and exit 314 * Clean up and exit
314 */ 315 */
315 init_timer(&readtimer); 316 init_timer(&readtimer);
@@ -324,12 +325,12 @@ static void cadet_handler(unsigned long data)
324static ssize_t cadet_read(struct file *file, char __user *data, 325static ssize_t cadet_read(struct file *file, char __user *data,
325 size_t count, loff_t *ppos) 326 size_t count, loff_t *ppos)
326{ 327{
327 int i=0; 328 int i=0;
328 unsigned char readbuf[RDS_BUFFER]; 329 unsigned char readbuf[RDS_BUFFER];
329 330
330 if(rdsstat==0) { 331 if(rdsstat==0) {
331 spin_lock(&cadet_io_lock); 332 spin_lock(&cadet_io_lock);
332 rdsstat=1; 333 rdsstat=1;
333 outb(0x80,io); /* Select RDS fifo */ 334 outb(0x80,io); /* Select RDS fifo */
334 spin_unlock(&cadet_io_lock); 335 spin_unlock(&cadet_io_lock);
335 init_timer(&readtimer); 336 init_timer(&readtimer);
@@ -339,15 +340,15 @@ static ssize_t cadet_read(struct file *file, char __user *data,
339 add_timer(&readtimer); 340 add_timer(&readtimer);
340 } 341 }
341 if(rdsin==rdsout) { 342 if(rdsin==rdsout) {
342 if (file->f_flags & O_NONBLOCK) 343 if (file->f_flags & O_NONBLOCK)
343 return -EWOULDBLOCK; 344 return -EWOULDBLOCK;
344 interruptible_sleep_on(&read_queue); 345 interruptible_sleep_on(&read_queue);
345 } 346 }
346 while( i<count && rdsin!=rdsout) 347 while( i<count && rdsin!=rdsout)
347 readbuf[i++]=rdsbuf[rdsout++]; 348 readbuf[i++]=rdsbuf[rdsout++];
348 349
349 if (copy_to_user(data,readbuf,i)) 350 if (copy_to_user(data,readbuf,i))
350 return -EFAULT; 351 return -EFAULT;
351 return i; 352 return i;
352} 353}
353 354
@@ -375,29 +376,29 @@ static int cadet_do_ioctl(struct inode *inode, struct file *file,
375 return -EINVAL; 376 return -EINVAL;
376 } 377 }
377 switch(v->tuner) { 378 switch(v->tuner) {
378 case 0: 379 case 0:
379 strcpy(v->name,"FM"); 380 strcpy(v->name,"FM");
380 v->rangelow=1400; /* 87.5 MHz */ 381 v->rangelow=1400; /* 87.5 MHz */
381 v->rangehigh=1728; /* 108.0 MHz */ 382 v->rangehigh=1728; /* 108.0 MHz */
382 v->flags=0; 383 v->flags=0;
383 v->mode=0; 384 v->mode=0;
384 v->mode|=VIDEO_MODE_AUTO; 385 v->mode|=VIDEO_MODE_AUTO;
385 v->signal=sigstrength; 386 v->signal=sigstrength;
386 if(cadet_getstereo()==1) { 387 if(cadet_getstereo()==1) {
387 v->flags|=VIDEO_TUNER_STEREO_ON; 388 v->flags|=VIDEO_TUNER_STEREO_ON;
388 } 389 }
389 v->flags|=cadet_getrds(); 390 v->flags|=cadet_getrds();
390 break; 391 break;
391 case 1: 392 case 1:
392 strcpy(v->name,"AM"); 393 strcpy(v->name,"AM");
393 v->rangelow=8320; /* 520 kHz */ 394 v->rangelow=8320; /* 520 kHz */
394 v->rangehigh=26400; /* 1650 kHz */ 395 v->rangehigh=26400; /* 1650 kHz */
395 v->flags=0; 396 v->flags=0;
396 v->flags|=VIDEO_TUNER_LOW; 397 v->flags|=VIDEO_TUNER_LOW;
397 v->mode=0; 398 v->mode=0;
398 v->mode|=VIDEO_MODE_AUTO; 399 v->mode|=VIDEO_MODE_AUTO;
399 v->signal=sigstrength; 400 v->signal=sigstrength;
400 break; 401 break;
401 } 402 }
402 return 0; 403 return 0;
403 } 404 }
@@ -407,49 +408,49 @@ static int cadet_do_ioctl(struct inode *inode, struct file *file,
407 if((v->tuner<0)||(v->tuner>1)) { 408 if((v->tuner<0)||(v->tuner>1)) {
408 return -EINVAL; 409 return -EINVAL;
409 } 410 }
410 curtuner=v->tuner; 411 curtuner=v->tuner;
411 return 0; 412 return 0;
412 } 413 }
413 case VIDIOCGFREQ: 414 case VIDIOCGFREQ:
414 { 415 {
415 unsigned long *freq = arg; 416 unsigned long *freq = arg;
416 *freq = cadet_getfreq(); 417 *freq = cadet_getfreq();
417 return 0; 418 return 0;
418 } 419 }
419 case VIDIOCSFREQ: 420 case VIDIOCSFREQ:
420 { 421 {
421 unsigned long *freq = arg; 422 unsigned long *freq = arg;
422 if((curtuner==0)&&((*freq<1400)||(*freq>1728))) { 423 if((curtuner==0)&&((*freq<1400)||(*freq>1728))) {
423 return -EINVAL; 424 return -EINVAL;
424 } 425 }
425 if((curtuner==1)&&((*freq<8320)||(*freq>26400))) { 426 if((curtuner==1)&&((*freq<8320)||(*freq>26400))) {
426 return -EINVAL; 427 return -EINVAL;
427 } 428 }
428 cadet_setfreq(*freq); 429 cadet_setfreq(*freq);
429 return 0; 430 return 0;
430 } 431 }
431 case VIDIOCGAUDIO: 432 case VIDIOCGAUDIO:
432 { 433 {
433 struct video_audio *v = arg; 434 struct video_audio *v = arg;
434 memset(v,0, sizeof(*v)); 435 memset(v,0, sizeof(*v));
435 v->flags=VIDEO_AUDIO_MUTABLE|VIDEO_AUDIO_VOLUME; 436 v->flags=VIDEO_AUDIO_MUTABLE|VIDEO_AUDIO_VOLUME;
436 if(cadet_getstereo()==0) { 437 if(cadet_getstereo()==0) {
437 v->mode=VIDEO_SOUND_MONO; 438 v->mode=VIDEO_SOUND_MONO;
438 } else { 439 } else {
439 v->mode=VIDEO_SOUND_STEREO; 440 v->mode=VIDEO_SOUND_STEREO;
440 } 441 }
441 v->volume=cadet_getvol(); 442 v->volume=cadet_getvol();
442 v->step=0xffff; 443 v->step=0xffff;
443 strcpy(v->name, "Radio"); 444 strcpy(v->name, "Radio");
444 return 0; 445 return 0;
445 } 446 }
446 case VIDIOCSAUDIO: 447 case VIDIOCSAUDIO:
447 { 448 {
448 struct video_audio *v = arg; 449 struct video_audio *v = arg;
449 if(v->audio) 450 if(v->audio)
450 return -EINVAL; 451 return -EINVAL;
451 cadet_setvol(v->volume); 452 cadet_setvol(v->volume);
452 if(v->flags&VIDEO_AUDIO_MUTE) 453 if(v->flags&VIDEO_AUDIO_MUTE)
453 cadet_setvol(0); 454 cadet_setvol(0);
454 else 455 else
455 cadet_setvol(0xffff); 456 cadet_setvol(0xffff);
@@ -539,16 +540,16 @@ static struct pnp_driver cadet_pnp_driver = {
539 540
540static int cadet_probe(void) 541static int cadet_probe(void)
541{ 542{
542 static int iovals[8]={0x330,0x332,0x334,0x336,0x338,0x33a,0x33c,0x33e}; 543 static int iovals[8]={0x330,0x332,0x334,0x336,0x338,0x33a,0x33c,0x33e};
543 int i; 544 int i;
544 545
545 for(i=0;i<8;i++) { 546 for(i=0;i<8;i++) {
546 io=iovals[i]; 547 io=iovals[i];
547 if (request_region(io, 2, "cadet-probe")) { 548 if (request_region(io, 2, "cadet-probe")) {
548 cadet_setfreq(1410); 549 cadet_setfreq(1410);
549 if(cadet_getfreq()==1410) { 550 if(cadet_getfreq()==1410) {
550 release_region(io, 2); 551 release_region(io, 2);
551 return io; 552 return io;
552 } 553 }
553 release_region(io, 2); 554 release_region(io, 2);
554 } 555 }
@@ -556,7 +557,7 @@ static int cadet_probe(void)
556 return -1; 557 return -1;
557} 558}
558 559
559/* 560/*
560 * io should only be set if the user has used something like 561 * io should only be set if the user has used something like
561 * isapnp (the userspace program) to initialize this card for us 562 * isapnp (the userspace program) to initialize this card for us
562 */ 563 */
@@ -564,7 +565,7 @@ static int cadet_probe(void)
564static int __init cadet_init(void) 565static int __init cadet_init(void)
565{ 566{
566 spin_lock_init(&cadet_io_lock); 567 spin_lock_init(&cadet_io_lock);
567 568
568 /* 569 /*
569 * If a probe was requested then probe ISAPnP first (safest) 570 * If a probe was requested then probe ISAPnP first (safest)
570 */ 571 */
@@ -579,12 +580,12 @@ static int __init cadet_init(void)
579 /* 580 /*
580 * Else we bail out 581 * Else we bail out
581 */ 582 */
582 583
583 if(io < 0) { 584 if(io < 0) {
584#ifdef MODULE 585#ifdef MODULE
585 printk(KERN_ERR "You must set an I/O address with io=0x???\n"); 586 printk(KERN_ERR "You must set an I/O address with io=0x???\n");
586#endif 587#endif
587 goto fail; 588 goto fail;
588 } 589 }
589 if (!request_region(io,2,"cadet")) 590 if (!request_region(io,2,"cadet"))
590 goto fail; 591 goto fail;
diff --git a/drivers/media/radio/radio-gemtek-pci.c b/drivers/media/radio/radio-gemtek-pci.c
index 8e499b8f64c7..9f249e7e60c9 100644
--- a/drivers/media/radio/radio-gemtek-pci.c
+++ b/drivers/media/radio/radio-gemtek-pci.c
@@ -1,6 +1,6 @@
1/* 1/*
2 *************************************************************************** 2 ***************************************************************************
3 * 3 *
4 * radio-gemtek-pci.c - Gemtek PCI Radio driver 4 * radio-gemtek-pci.c - Gemtek PCI Radio driver
5 * (C) 2001 Vladimir Shebordaev <vshebordaev@mail.ru> 5 * (C) 2001 Vladimir Shebordaev <vshebordaev@mail.ru>
6 * 6 *
@@ -31,7 +31,7 @@
31 * radio device driver. 31 * radio device driver.
32 * 32 *
33 * Please, let me know if this piece of code was useful :) 33 * Please, let me know if this piece of code was useful :)
34 * 34 *
35 * TODO: multiple device support and portability were not tested 35 * TODO: multiple device support and portability were not tested
36 * 36 *
37 *************************************************************************** 37 ***************************************************************************
@@ -44,6 +44,7 @@
44#include <linux/init.h> 44#include <linux/init.h>
45#include <linux/pci.h> 45#include <linux/pci.h>
46#include <linux/videodev.h> 46#include <linux/videodev.h>
47#include <media/v4l2-common.h>
47#include <linux/errno.h> 48#include <linux/errno.h>
48 49
49#include <asm/io.h> 50#include <asm/io.h>
@@ -69,18 +70,18 @@
69#define TRUE (1) 70#define TRUE (1)
70#endif 71#endif
71 72
72#ifndef FALSE 73#ifndef FALSE
73#define FALSE (0) 74#define FALSE (0)
74#endif 75#endif
75 76
76struct gemtek_pci_card { 77struct gemtek_pci_card {
77 struct video_device *videodev; 78 struct video_device *videodev;
78 79
79 u32 iobase; 80 u32 iobase;
80 u32 length; 81 u32 length;
81 u8 chiprev; 82 u8 chiprev;
82 u16 model; 83 u16 model;
83 84
84 u32 current_frequency; 85 u32 current_frequency;
85 u8 mute; 86 u8 mute;
86}; 87};
@@ -96,7 +97,7 @@ static inline u8 gemtek_pci_out( u16 value, u32 port )
96 return (u8)value; 97 return (u8)value;
97} 98}
98 99
99#define _b0( v ) *((u8 *)&v) 100#define _b0( v ) *((u8 *)&v)
100static void __gemtek_pci_cmd( u16 value, u32 port, u8 *last_byte, int keep ) 101static void __gemtek_pci_cmd( u16 value, u32 port, u8 *last_byte, int keep )
101{ 102{
102 register u8 byte = *last_byte; 103 register u8 byte = *last_byte;
@@ -104,7 +105,7 @@ static void __gemtek_pci_cmd( u16 value, u32 port, u8 *last_byte, int keep )
104 if ( !value ) { 105 if ( !value ) {
105 if ( !keep ) 106 if ( !keep )
106 value = (u16)port; 107 value = (u16)port;
107 byte &= 0xfd; 108 byte &= 0xfd;
108 } else 109 } else
109 byte |= 2; 110 byte |= 2;
110 111
@@ -116,7 +117,7 @@ static void __gemtek_pci_cmd( u16 value, u32 port, u8 *last_byte, int keep )
116 byte &= 0xfe; 117 byte &= 0xfe;
117 _b0( value ) = byte; 118 _b0( value ) = byte;
118 outw( value, port ); 119 outw( value, port );
119 120
120 *last_byte = byte; 121 *last_byte = byte;
121} 122}
122 123
@@ -193,13 +194,13 @@ static int gemtek_pci_do_ioctl(struct inode *inode, struct file *file,
193 c->audios = 1; 194 c->audios = 1;
194 strcpy( c->name, "Gemtek PCI Radio" ); 195 strcpy( c->name, "Gemtek PCI Radio" );
195 return 0; 196 return 0;
196 } 197 }
197 198
198 case VIDIOCGTUNER: 199 case VIDIOCGTUNER:
199 { 200 {
200 struct video_tuner *t = arg; 201 struct video_tuner *t = arg;
201 202
202 if ( t->tuner ) 203 if ( t->tuner )
203 return -EINVAL; 204 return -EINVAL;
204 205
205 t->rangelow = GEMTEK_PCI_RANGE_LOW; 206 t->rangelow = GEMTEK_PCI_RANGE_LOW;
@@ -228,7 +229,7 @@ static int gemtek_pci_do_ioctl(struct inode *inode, struct file *file,
228 case VIDIOCSFREQ: 229 case VIDIOCSFREQ:
229 { 230 {
230 unsigned long *freq = arg; 231 unsigned long *freq = arg;
231 232
232 if ( (*freq < GEMTEK_PCI_RANGE_LOW) || 233 if ( (*freq < GEMTEK_PCI_RANGE_LOW) ||
233 (*freq > GEMTEK_PCI_RANGE_HIGH) ) 234 (*freq > GEMTEK_PCI_RANGE_HIGH) )
234 return -EINVAL; 235 return -EINVAL;
@@ -239,9 +240,9 @@ static int gemtek_pci_do_ioctl(struct inode *inode, struct file *file,
239 240
240 return 0; 241 return 0;
241 } 242 }
242 243
243 case VIDIOCGAUDIO: 244 case VIDIOCGAUDIO:
244 { 245 {
245 struct video_audio *a = arg; 246 struct video_audio *a = arg;
246 247
247 memset( a, 0, sizeof( *a ) ); 248 memset( a, 0, sizeof( *a ) );
@@ -249,17 +250,17 @@ static int gemtek_pci_do_ioctl(struct inode *inode, struct file *file,
249 a->volume = 1; 250 a->volume = 1;
250 a->step = 65535; 251 a->step = 65535;
251 strcpy( a->name, "Radio" ); 252 strcpy( a->name, "Radio" );
252 return 0; 253 return 0;
253 } 254 }
254 255
255 case VIDIOCSAUDIO: 256 case VIDIOCSAUDIO:
256 { 257 {
257 struct video_audio *a = arg; 258 struct video_audio *a = arg;
258 259
259 if ( a->audio ) 260 if ( a->audio )
260 return -EINVAL; 261 return -EINVAL;
261 262
262 if ( a->flags & VIDEO_AUDIO_MUTE ) 263 if ( a->flags & VIDEO_AUDIO_MUTE )
263 gemtek_pci_mute( card ); 264 gemtek_pci_mute( card );
264 else 265 else
265 gemtek_pci_unmute( card ); 266 gemtek_pci_unmute( card );
@@ -323,9 +324,9 @@ static int __devinit gemtek_pci_probe( struct pci_dev *pci_dev, const struct pci
323 return -ENOMEM; 324 return -ENOMEM;
324 } 325 }
325 326
326 if ( pci_enable_device( pci_dev ) ) 327 if ( pci_enable_device( pci_dev ) )
327 goto err_pci; 328 goto err_pci;
328 329
329 card->iobase = pci_resource_start( pci_dev, 0 ); 330 card->iobase = pci_resource_start( pci_dev, 0 );
330 card->length = pci_resource_len( pci_dev, 0 ); 331 card->length = pci_resource_len( pci_dev, 0 );
331 332
@@ -338,7 +339,7 @@ static int __devinit gemtek_pci_probe( struct pci_dev *pci_dev, const struct pci
338 pci_read_config_word( pci_dev, PCI_SUBSYSTEM_ID, &card->model ); 339 pci_read_config_word( pci_dev, PCI_SUBSYSTEM_ID, &card->model );
339 340
340 pci_set_drvdata( pci_dev, card ); 341 pci_set_drvdata( pci_dev, card );
341 342
342 if ( (devradio = kmalloc( sizeof( struct video_device ), GFP_KERNEL )) == NULL ) { 343 if ( (devradio = kmalloc( sizeof( struct video_device ), GFP_KERNEL )) == NULL ) {
343 printk( KERN_ERR "gemtek_pci: out of memory\n" ); 344 printk( KERN_ERR "gemtek_pci: out of memory\n" );
344 goto err_video; 345 goto err_video;
@@ -354,7 +355,7 @@ static int __devinit gemtek_pci_probe( struct pci_dev *pci_dev, const struct pci
354 devradio->priv = card; 355 devradio->priv = card;
355 gemtek_pci_mute( card ); 356 gemtek_pci_mute( card );
356 357
357 printk( KERN_INFO "Gemtek PCI Radio (rev. %d) found at 0x%04x-0x%04x.\n", 358 printk( KERN_INFO "Gemtek PCI Radio (rev. %d) found at 0x%04x-0x%04x.\n",
358 card->chiprev, card->iobase, card->iobase + card->length - 1 ); 359 card->chiprev, card->iobase, card->iobase + card->length - 1 );
359 360
360 return 0; 361 return 0;
@@ -364,7 +365,7 @@ err_video:
364 365
365err_pci: 366err_pci:
366 kfree( card ); 367 kfree( card );
367 return -ENODEV; 368 return -ENODEV;
368} 369}
369 370
370static void __devexit gemtek_pci_remove( struct pci_dev *pci_dev ) 371static void __devexit gemtek_pci_remove( struct pci_dev *pci_dev )
@@ -375,12 +376,12 @@ static void __devexit gemtek_pci_remove( struct pci_dev *pci_dev )
375 kfree( card->videodev ); 376 kfree( card->videodev );
376 377
377 release_region( card->iobase, card->length ); 378 release_region( card->iobase, card->length );
378 379
379 if ( mx ) 380 if ( mx )
380 gemtek_pci_mute( card ); 381 gemtek_pci_mute( card );
381 382
382 kfree( card ); 383 kfree( card );
383 384
384 pci_set_drvdata( pci_dev, NULL ); 385 pci_set_drvdata( pci_dev, NULL );
385} 386}
386 387
diff --git a/drivers/media/radio/radio-gemtek.c b/drivers/media/radio/radio-gemtek.c
index 47173be97b9f..162f37d8bf96 100644
--- a/drivers/media/radio/radio-gemtek.c
+++ b/drivers/media/radio/radio-gemtek.c
@@ -6,7 +6,7 @@
6 * Besides the protocol changes, this is mostly a copy of: 6 * Besides the protocol changes, this is mostly a copy of:
7 * 7 *
8 * RadioTrack II driver for Linux radio support (C) 1998 Ben Pfaff 8 * RadioTrack II driver for Linux radio support (C) 1998 Ben Pfaff
9 * 9 *
10 * Based on RadioTrack I/RadioReveal (C) 1997 M. Kirkwood 10 * Based on RadioTrack I/RadioReveal (C) 1997 M. Kirkwood
11 * Converted to new API by Alan Cox <Alan.Cox@linux.org> 11 * Converted to new API by Alan Cox <Alan.Cox@linux.org>
12 * Various bugfixes and enhancements by Russell Kroll <rkroll@exploits.org> 12 * Various bugfixes and enhancements by Russell Kroll <rkroll@exploits.org>
@@ -22,6 +22,7 @@
22#include <asm/io.h> /* outb, outb_p */ 22#include <asm/io.h> /* outb, outb_p */
23#include <asm/uaccess.h> /* copy to/from user */ 23#include <asm/uaccess.h> /* copy to/from user */
24#include <linux/videodev.h> /* kernel radio structs */ 24#include <linux/videodev.h> /* kernel radio structs */
25#include <media/v4l2-common.h>
25#include <linux/config.h> /* CONFIG_RADIO_GEMTEK_PORT */ 26#include <linux/config.h> /* CONFIG_RADIO_GEMTEK_PORT */
26#include <linux/spinlock.h> 27#include <linux/spinlock.h>
27 28
@@ -29,7 +30,7 @@
29#define CONFIG_RADIO_GEMTEK_PORT -1 30#define CONFIG_RADIO_GEMTEK_PORT -1
30#endif 31#endif
31 32
32static int io = CONFIG_RADIO_GEMTEK_PORT; 33static int io = CONFIG_RADIO_GEMTEK_PORT;
33static int radio_nr = -1; 34static int radio_nr = -1;
34static spinlock_t lock; 35static spinlock_t lock;
35 36
@@ -48,7 +49,7 @@ struct gemtek_device
48 */ 49 */
49static void gemtek_mute(struct gemtek_device *dev) 50static void gemtek_mute(struct gemtek_device *dev)
50{ 51{
51 if(dev->muted) 52 if(dev->muted)
52 return; 53 return;
53 spin_lock(&lock); 54 spin_lock(&lock);
54 outb(0x10, io); 55 outb(0x10, io);
@@ -94,20 +95,20 @@ static int gemtek_setfreq(struct gemtek_device *dev, unsigned long freq)
94 freq /= 100000; 95 freq /= 100000;
95 96
96 spin_lock(&lock); 97 spin_lock(&lock);
97 98
98 /* 2 start bits */ 99 /* 2 start bits */
99 outb_p(0x03, io); 100 outb_p(0x03, io);
100 udelay(5); 101 udelay(5);
101 outb_p(0x07, io); 102 outb_p(0x07, io);
102 udelay(5); 103 udelay(5);
103 104
104 /* 28 frequency bits (lsb first) */ 105 /* 28 frequency bits (lsb first) */
105 for (i = 0; i < 14; i++) 106 for (i = 0; i < 14; i++)
106 if (freq & (1 << i)) 107 if (freq & (1 << i))
107 one(); 108 one();
108 else 109 else
109 zero(); 110 zero();
110 /* 36 unknown bits */ 111 /* 36 unknown bits */
111 for (i = 0; i < 11; i++) 112 for (i = 0; i < 11; i++)
112 zero(); 113 zero();
113 one(); 114 one();
@@ -123,7 +124,7 @@ static int gemtek_setfreq(struct gemtek_device *dev, unsigned long freq)
123 udelay(5); 124 udelay(5);
124 125
125 spin_unlock(&lock); 126 spin_unlock(&lock);
126 127
127 return 0; 128 return 0;
128} 129}
129 130
@@ -159,7 +160,7 @@ static int gemtek_do_ioctl(struct inode *inode, struct file *file,
159 case VIDIOCGTUNER: 160 case VIDIOCGTUNER:
160 { 161 {
161 struct video_tuner *v = arg; 162 struct video_tuner *v = arg;
162 if(v->tuner) /* Only 1 tuner */ 163 if(v->tuner) /* Only 1 tuner */
163 return -EINVAL; 164 return -EINVAL;
164 v->rangelow=87*16000; 165 v->rangelow=87*16000;
165 v->rangehigh=108*16000; 166 v->rangehigh=108*16000;
@@ -193,25 +194,25 @@ static int gemtek_do_ioctl(struct inode *inode, struct file *file,
193 return 0; 194 return 0;
194 } 195 }
195 case VIDIOCGAUDIO: 196 case VIDIOCGAUDIO:
196 { 197 {
197 struct video_audio *v = arg; 198 struct video_audio *v = arg;
198 memset(v,0, sizeof(*v)); 199 memset(v,0, sizeof(*v));
199 v->flags|=VIDEO_AUDIO_MUTABLE; 200 v->flags|=VIDEO_AUDIO_MUTABLE;
200 v->volume=1; 201 v->volume=1;
201 v->step=65535; 202 v->step=65535;
202 strcpy(v->name, "Radio"); 203 strcpy(v->name, "Radio");
203 return 0; 204 return 0;
204 } 205 }
205 case VIDIOCSAUDIO: 206 case VIDIOCSAUDIO:
206 { 207 {
207 struct video_audio *v = arg; 208 struct video_audio *v = arg;
208 if(v->audio) 209 if(v->audio)
209 return -EINVAL; 210 return -EINVAL;
210 211
211 if(v->flags&VIDEO_AUDIO_MUTE) 212 if(v->flags&VIDEO_AUDIO_MUTE)
212 gemtek_mute(rt); 213 gemtek_mute(rt);
213 else 214 else
214 gemtek_unmute(rt); 215 gemtek_unmute(rt);
215 216
216 return 0; 217 return 0;
217 } 218 }
@@ -254,14 +255,14 @@ static int __init gemtek_init(void)
254 return -EINVAL; 255 return -EINVAL;
255 } 256 }
256 257
257 if (!request_region(io, 4, "gemtek")) 258 if (!request_region(io, 4, "gemtek"))
258 { 259 {
259 printk(KERN_ERR "gemtek: port 0x%x already in use\n", io); 260 printk(KERN_ERR "gemtek: port 0x%x already in use\n", io);
260 return -EBUSY; 261 return -EBUSY;
261 } 262 }
262 263
263 gemtek_radio.priv=&gemtek_unit; 264 gemtek_radio.priv=&gemtek_unit;
264 265
265 if(video_register_device(&gemtek_radio, VFL_TYPE_RADIO, radio_nr)==-1) 266 if(video_register_device(&gemtek_radio, VFL_TYPE_RADIO, radio_nr)==-1)
266 { 267 {
267 release_region(io, 4); 268 release_region(io, 4);
@@ -274,7 +275,7 @@ static int __init gemtek_init(void)
274 /* this is _maybe_ unnecessary */ 275 /* this is _maybe_ unnecessary */
275 outb(0x01, io); 276 outb(0x01, io);
276 277
277 /* mute card - prevents noisy bootups */ 278 /* mute card - prevents noisy bootups */
278 gemtek_unit.muted = 0; 279 gemtek_unit.muted = 0;
279 gemtek_mute(&gemtek_unit); 280 gemtek_mute(&gemtek_unit);
280 281
diff --git a/drivers/media/radio/radio-maestro.c b/drivers/media/radio/radio-maestro.c
index 39c1d9118636..fcfa6c9fe225 100644
--- a/drivers/media/radio/radio-maestro.c
+++ b/drivers/media/radio/radio-maestro.c
@@ -2,7 +2,7 @@
2 * (c) 2000 A. Tlalka, atlka@pg.gda.pl 2 * (c) 2000 A. Tlalka, atlka@pg.gda.pl
3 * Notes on the hardware 3 * Notes on the hardware
4 * 4 *
5 * + Frequency control is done digitally 5 * + Frequency control is done digitally
6 * + No volume control - only mute/unmute - you have to use Aux line volume 6 * + No volume control - only mute/unmute - you have to use Aux line volume
7 * control on Maestro card to set the volume 7 * control on Maestro card to set the volume
8 * + Radio status (tuned/not_tuned and stereo/mono) is valid some time after 8 * + Radio status (tuned/not_tuned and stereo/mono) is valid some time after
@@ -26,7 +26,7 @@
26#include <linux/mutex.h> 26#include <linux/mutex.h>
27#include <linux/pci.h> 27#include <linux/pci.h>
28#include <linux/videodev.h> 28#include <linux/videodev.h>
29 29#include <media/v4l2-common.h>
30 30
31#define DRIVER_VERSION "0.05" 31#define DRIVER_VERSION "0.05"
32 32
@@ -103,7 +103,7 @@ static struct video_device maestro_radio = {
103struct radio_device { 103struct radio_device {
104 u16 io, /* base of Maestro card radio io (GPIO_DATA)*/ 104 u16 io, /* base of Maestro card radio io (GPIO_DATA)*/
105 muted, /* VIDEO_AUDIO_MUTE */ 105 muted, /* VIDEO_AUDIO_MUTE */
106 stereo, /* VIDEO_TUNER_STEREO_ON */ 106 stereo, /* VIDEO_TUNER_STEREO_ON */
107 tuned; /* signal strength (0 or 0xffff) */ 107 tuned; /* signal strength (0 or 0xffff) */
108 struct mutex lock; 108 struct mutex lock;
109}; 109};
@@ -122,14 +122,14 @@ static u32 radio_bits_get(struct radio_device *dev)
122 for (l=24;l--;) { 122 for (l=24;l--;) {
123 outw(STR_CLK, io); /* HI state */ 123 outw(STR_CLK, io); /* HI state */
124 udelay(2); 124 udelay(2);
125 if(!l) 125 if(!l)
126 dev->tuned = inw(io) & STR_MOST ? 0 : 0xffff; 126 dev->tuned = inw(io) & STR_MOST ? 0 : 0xffff;
127 outw(0, io); /* LO state */ 127 outw(0, io); /* LO state */
128 udelay(2); 128 udelay(2);
129 data <<= 1; /* shift data */ 129 data <<= 1; /* shift data */
130 rdata = inw(io); 130 rdata = inw(io);
131 if(!l) 131 if(!l)
132 dev->stereo = rdata & STR_MOST ? 132 dev->stereo = rdata & STR_MOST ?
133 0 : VIDEO_TUNER_STEREO_ON; 133 0 : VIDEO_TUNER_STEREO_ON;
134 else 134 else
135 if(rdata & STR_DATA) 135 if(rdata & STR_DATA)
diff --git a/drivers/media/radio/radio-maxiradio.c b/drivers/media/radio/radio-maxiradio.c
index f0bf47bcb64c..f93d7afe7304 100644
--- a/drivers/media/radio/radio-maxiradio.c
+++ b/drivers/media/radio/radio-maxiradio.c
@@ -1,15 +1,15 @@
1/* 1/*
2 * Guillemot Maxi Radio FM 2000 PCI radio card driver for Linux 2 * Guillemot Maxi Radio FM 2000 PCI radio card driver for Linux
3 * (C) 2001 Dimitromanolakis Apostolos <apdim@grecian.net> 3 * (C) 2001 Dimitromanolakis Apostolos <apdim@grecian.net>
4 * 4 *
5 * Based in the radio Maestro PCI driver. Actually it uses the same chip 5 * Based in the radio Maestro PCI driver. Actually it uses the same chip
6 * for radio but different pci controller. 6 * for radio but different pci controller.
7 * 7 *
8 * I didn't have any specs I reversed engineered the protocol from 8 * I didn't have any specs I reversed engineered the protocol from
9 * the windows driver (radio.dll). 9 * the windows driver (radio.dll).
10 * 10 *
11 * The card uses the TEA5757 chip that includes a search function but it 11 * The card uses the TEA5757 chip that includes a search function but it
12 * is useless as I haven't found any way to read back the frequency. If 12 * is useless as I haven't found any way to read back the frequency. If
13 * anybody does please mail me. 13 * anybody does please mail me.
14 * 14 *
15 * For the pdf file see: 15 * For the pdf file see:
@@ -24,7 +24,7 @@
24 * - tiding up 24 * - tiding up
25 * - removed support for multiple devices as it didn't work anyway 25 * - removed support for multiple devices as it didn't work anyway
26 * 26 *
27 * BUGS: 27 * BUGS:
28 * - card unmutes if you change frequency 28 * - card unmutes if you change frequency
29 * 29 *
30 */ 30 */
@@ -41,6 +41,7 @@
41 41
42#include <linux/pci.h> 42#include <linux/pci.h>
43#include <linux/videodev.h> 43#include <linux/videodev.h>
44#include <media/v4l2-common.h>
44 45
45/* version 0.75 Sun Feb 4 22:51:27 EET 2001 */ 46/* version 0.75 Sun Feb 4 22:51:27 EET 2001 */
46#define DRIVER_VERSION "0.75" 47#define DRIVER_VERSION "0.75"
@@ -80,7 +81,7 @@ static struct file_operations maxiradio_fops = {
80 .owner = THIS_MODULE, 81 .owner = THIS_MODULE,
81 .open = video_exclusive_open, 82 .open = video_exclusive_open,
82 .release = video_exclusive_release, 83 .release = video_exclusive_release,
83 .ioctl = radio_ioctl, 84 .ioctl = radio_ioctl,
84 .compat_ioctl = v4l_compat_ioctl32, 85 .compat_ioctl = v4l_compat_ioctl32,
85 .llseek = no_llseek, 86 .llseek = no_llseek,
86}; 87};
@@ -97,11 +98,11 @@ static struct radio_device
97{ 98{
98 __u16 io, /* base of radio io */ 99 __u16 io, /* base of radio io */
99 muted, /* VIDEO_AUDIO_MUTE */ 100 muted, /* VIDEO_AUDIO_MUTE */
100 stereo, /* VIDEO_TUNER_STEREO_ON */ 101 stereo, /* VIDEO_TUNER_STEREO_ON */
101 tuned; /* signal strength (0 or 0xffff) */ 102 tuned; /* signal strength (0 or 0xffff) */
102 103
103 unsigned long freq; 104 unsigned long freq;
104 105
105 struct mutex lock; 106 struct mutex lock;
106} radio_unit = {0, 0, 0, 0, }; 107} radio_unit = {0, 0, 0, 0, };
107 108
@@ -114,7 +115,7 @@ static void outbit(unsigned long bit, __u16 io)
114 outb( power|wren|data|clk ,io); udelay(4); 115 outb( power|wren|data|clk ,io); udelay(4);
115 outb( power|wren|data ,io); udelay(4); 116 outb( power|wren|data ,io); udelay(4);
116 } 117 }
117 else 118 else
118 { 119 {
119 outb( power|wren ,io); udelay(4); 120 outb( power|wren ,io); udelay(4);
120 outb( power|wren|clk ,io); udelay(4); 121 outb( power|wren|clk ,io); udelay(4);
@@ -132,12 +133,12 @@ static void set_freq(__u16 io, __u32 data)
132{ 133{
133 unsigned long int si; 134 unsigned long int si;
134 int bl; 135 int bl;
135 136
136 /* TEA5757 shift register bits (see pdf) */ 137 /* TEA5757 shift register bits (see pdf) */
137 138
138 outbit(0,io); // 24 search 139 outbit(0,io); // 24 search
139 outbit(1,io); // 23 search up/down 140 outbit(1,io); // 23 search up/down
140 141
141 outbit(0,io); // 22 stereo/mono 142 outbit(0,io); // 22 stereo/mono
142 143
143 outbit(0,io); // 21 band 144 outbit(0,io); // 21 band
@@ -145,24 +146,24 @@ static void set_freq(__u16 io, __u32 data)
145 146
146 outbit(0,io); // 19 port ? 147 outbit(0,io); // 19 port ?
147 outbit(0,io); // 18 port ? 148 outbit(0,io); // 18 port ?
148 149
149 outbit(0,io); // 17 search level 150 outbit(0,io); // 17 search level
150 outbit(0,io); // 16 search level 151 outbit(0,io); // 16 search level
151 152
152 si = 0x8000; 153 si = 0x8000;
153 for(bl = 1; bl <= 16 ; bl++) { outbit(data & si,io); si >>=1; } 154 for(bl = 1; bl <= 16 ; bl++) { outbit(data & si,io); si >>=1; }
154 155
155 outb(power,io); 156 outb(power,io);
156} 157}
157 158
158static int get_stereo(__u16 io) 159static int get_stereo(__u16 io)
159{ 160{
160 outb(power,io); udelay(4); 161 outb(power,io); udelay(4);
161 return !(inb(io) & mo_st); 162 return !(inb(io) & mo_st);
162} 163}
163 164
164static int get_tune(__u16 io) 165static int get_tune(__u16 io)
165{ 166{
166 outb(power+clk,io); udelay(4); 167 outb(power+clk,io); udelay(4);
167 return !(inb(io) & mo_st); 168 return !(inb(io) & mo_st);
168} 169}
@@ -177,7 +178,7 @@ static inline int radio_function(struct inode *inode, struct file *file,
177 switch(cmd) { 178 switch(cmd) {
178 case VIDIOCGCAP: { 179 case VIDIOCGCAP: {
179 struct video_capability *v = arg; 180 struct video_capability *v = arg;
180 181
181 memset(v,0,sizeof(*v)); 182 memset(v,0,sizeof(*v));
182 strcpy(v->name, "Maxi Radio FM2000 radio"); 183 strcpy(v->name, "Maxi Radio FM2000 radio");
183 v->type=VID_TYPE_TUNER; 184 v->type=VID_TYPE_TUNER;
@@ -186,22 +187,22 @@ static inline int radio_function(struct inode *inode, struct file *file,
186 } 187 }
187 case VIDIOCGTUNER: { 188 case VIDIOCGTUNER: {
188 struct video_tuner *v = arg; 189 struct video_tuner *v = arg;
189 190
190 if(v->tuner) 191 if(v->tuner)
191 return -EINVAL; 192 return -EINVAL;
192 193
193 card->stereo = 0xffff * get_stereo(card->io); 194 card->stereo = 0xffff * get_stereo(card->io);
194 card->tuned = 0xffff * get_tune(card->io); 195 card->tuned = 0xffff * get_tune(card->io);
195 196
196 v->flags = VIDEO_TUNER_LOW | card->stereo; 197 v->flags = VIDEO_TUNER_LOW | card->stereo;
197 v->signal = card->tuned; 198 v->signal = card->tuned;
198 199
199 strcpy(v->name, "FM"); 200 strcpy(v->name, "FM");
200 201
201 v->rangelow = FREQ_LO; 202 v->rangelow = FREQ_LO;
202 v->rangehigh = FREQ_HI; 203 v->rangehigh = FREQ_HI;
203 v->mode = VIDEO_MODE_AUTO; 204 v->mode = VIDEO_MODE_AUTO;
204 205
205 return 0; 206 return 0;
206 } 207 }
207 case VIDIOCSTUNER: { 208 case VIDIOCSTUNER: {
@@ -212,13 +213,13 @@ static inline int radio_function(struct inode *inode, struct file *file,
212 } 213 }
213 case VIDIOCGFREQ: { 214 case VIDIOCGFREQ: {
214 unsigned long *freq = arg; 215 unsigned long *freq = arg;
215 216
216 *freq = card->freq; 217 *freq = card->freq;
217 return 0; 218 return 0;
218 } 219 }
219 case VIDIOCSFREQ: { 220 case VIDIOCSFREQ: {
220 unsigned long *freq = arg; 221 unsigned long *freq = arg;
221 222
222 if (*freq < FREQ_LO || *freq > FREQ_HI) 223 if (*freq < FREQ_LO || *freq > FREQ_HI)
223 return -EINVAL; 224 return -EINVAL;
224 card->freq = *freq; 225 card->freq = *freq;
@@ -226,18 +227,18 @@ static inline int radio_function(struct inode *inode, struct file *file,
226 msleep(125); 227 msleep(125);
227 return 0; 228 return 0;
228 } 229 }
229 case VIDIOCGAUDIO: { 230 case VIDIOCGAUDIO: {
230 struct video_audio *v = arg; 231 struct video_audio *v = arg;
231 memset(v,0,sizeof(*v)); 232 memset(v,0,sizeof(*v));
232 strcpy(v->name, "Radio"); 233 strcpy(v->name, "Radio");
233 v->flags=VIDEO_AUDIO_MUTABLE | card->muted; 234 v->flags=VIDEO_AUDIO_MUTABLE | card->muted;
234 v->mode=VIDEO_SOUND_STEREO; 235 v->mode=VIDEO_SOUND_STEREO;
235 return 0; 236 return 0;
236 } 237 }
237 238
238 case VIDIOCSAUDIO: { 239 case VIDIOCSAUDIO: {
239 struct video_audio *v = arg; 240 struct video_audio *v = arg;
240 241
241 if(v->audio) 242 if(v->audio)
242 return -EINVAL; 243 return -EINVAL;
243 card->muted = v->flags & VIDEO_AUDIO_MUTE; 244 card->muted = v->flags & VIDEO_AUDIO_MUTE;
@@ -249,13 +250,13 @@ static inline int radio_function(struct inode *inode, struct file *file,
249 } 250 }
250 case VIDIOCGUNIT: { 251 case VIDIOCGUNIT: {
251 struct video_unit *v = arg; 252 struct video_unit *v = arg;
252 253
253 v->video=VIDEO_NO_UNIT; 254 v->video=VIDEO_NO_UNIT;
254 v->vbi=VIDEO_NO_UNIT; 255 v->vbi=VIDEO_NO_UNIT;
255 v->radio=dev->minor; 256 v->radio=dev->minor;
256 v->audio=0; 257 v->audio=0;
257 v->teletext=VIDEO_NO_UNIT; 258 v->teletext=VIDEO_NO_UNIT;
258 return 0; 259 return 0;
259 } 260 }
260 default: return -ENOIOCTLCMD; 261 default: return -ENOIOCTLCMD;
261 } 262 }
@@ -267,7 +268,7 @@ static int radio_ioctl(struct inode *inode, struct file *file,
267 struct video_device *dev = video_devdata(file); 268 struct video_device *dev = video_devdata(file);
268 struct radio_device *card=dev->priv; 269 struct radio_device *card=dev->priv;
269 int ret; 270 int ret;
270 271
271 mutex_lock(&card->lock); 272 mutex_lock(&card->lock);
272 ret = video_usercopy(inode, file, cmd, arg, radio_function); 273 ret = video_usercopy(inode, file, cmd, arg, radio_function);
273 mutex_unlock(&card->lock); 274 mutex_unlock(&card->lock);
@@ -282,21 +283,21 @@ MODULE_LICENSE("GPL");
282static int __devinit maxiradio_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) 283static int __devinit maxiradio_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
283{ 284{
284 if(!request_region(pci_resource_start(pdev, 0), 285 if(!request_region(pci_resource_start(pdev, 0),
285 pci_resource_len(pdev, 0), "Maxi Radio FM 2000")) { 286 pci_resource_len(pdev, 0), "Maxi Radio FM 2000")) {
286 printk(KERN_ERR "radio-maxiradio: can't reserve I/O ports\n"); 287 printk(KERN_ERR "radio-maxiradio: can't reserve I/O ports\n");
287 goto err_out; 288 goto err_out;
288 } 289 }
289 290
290 if (pci_enable_device(pdev)) 291 if (pci_enable_device(pdev))
291 goto err_out_free_region; 292 goto err_out_free_region;
292 293
293 radio_unit.io = pci_resource_start(pdev, 0); 294 radio_unit.io = pci_resource_start(pdev, 0);
294 mutex_init(&radio_unit.lock); 295 mutex_init(&radio_unit.lock);
295 maxiradio_radio.priv = &radio_unit; 296 maxiradio_radio.priv = &radio_unit;
296 297
297 if(video_register_device(&maxiradio_radio, VFL_TYPE_RADIO, radio_nr)==-1) { 298 if(video_register_device(&maxiradio_radio, VFL_TYPE_RADIO, radio_nr)==-1) {
298 printk("radio-maxiradio: can't register device!"); 299 printk("radio-maxiradio: can't register device!");
299 goto err_out_free_region; 300 goto err_out_free_region;
300 } 301 }
301 302
302 printk(KERN_INFO "radio-maxiradio: version " 303 printk(KERN_INFO "radio-maxiradio: version "
diff --git a/drivers/media/radio/radio-rtrack2.c b/drivers/media/radio/radio-rtrack2.c
index 28a47c9e7a81..5b68ac4c7322 100644
--- a/drivers/media/radio/radio-rtrack2.c
+++ b/drivers/media/radio/radio-rtrack2.c
@@ -1,5 +1,5 @@
1/* RadioTrack II driver for Linux radio support (C) 1998 Ben Pfaff 1/* RadioTrack II driver for Linux radio support (C) 1998 Ben Pfaff
2 * 2 *
3 * Based on RadioTrack I/RadioReveal (C) 1997 M. Kirkwood 3 * Based on RadioTrack I/RadioReveal (C) 1997 M. Kirkwood
4 * Converted to new API by Alan Cox <Alan.Cox@linux.org> 4 * Converted to new API by Alan Cox <Alan.Cox@linux.org>
5 * Various bugfixes and enhancements by Russell Kroll <rkroll@exploits.org> 5 * Various bugfixes and enhancements by Russell Kroll <rkroll@exploits.org>
@@ -15,6 +15,7 @@
15#include <asm/io.h> /* outb, outb_p */ 15#include <asm/io.h> /* outb, outb_p */
16#include <asm/uaccess.h> /* copy to/from user */ 16#include <asm/uaccess.h> /* copy to/from user */
17#include <linux/videodev.h> /* kernel radio structs */ 17#include <linux/videodev.h> /* kernel radio structs */
18#include <media/v4l2-common.h>
18#include <linux/config.h> /* CONFIG_RADIO_RTRACK2_PORT */ 19#include <linux/config.h> /* CONFIG_RADIO_RTRACK2_PORT */
19#include <linux/spinlock.h> 20#include <linux/spinlock.h>
20 21
@@ -22,7 +23,7 @@
22#define CONFIG_RADIO_RTRACK2_PORT -1 23#define CONFIG_RADIO_RTRACK2_PORT -1
23#endif 24#endif
24 25
25static int io = CONFIG_RADIO_RTRACK2_PORT; 26static int io = CONFIG_RADIO_RTRACK2_PORT;
26static int radio_nr = -1; 27static int radio_nr = -1;
27static spinlock_t lock; 28static spinlock_t lock;
28 29
@@ -38,7 +39,7 @@ struct rt_device
38 39
39static void rt_mute(struct rt_device *dev) 40static void rt_mute(struct rt_device *dev)
40{ 41{
41 if(dev->muted) 42 if(dev->muted)
42 return; 43 return;
43 spin_lock(&lock); 44 spin_lock(&lock);
44 outb(1, io); 45 outb(1, io);
@@ -58,14 +59,14 @@ static void rt_unmute(struct rt_device *dev)
58 59
59static void zero(void) 60static void zero(void)
60{ 61{
61 outb_p(1, io); 62 outb_p(1, io);
62 outb_p(3, io); 63 outb_p(3, io);
63 outb_p(1, io); 64 outb_p(1, io);
64} 65}
65 66
66static void one(void) 67static void one(void)
67{ 68{
68 outb_p(5, io); 69 outb_p(5, io);
69 outb_p(7, io); 70 outb_p(7, io);
70 outb_p(5, io); 71 outb_p(5, io);
71} 72}
@@ -75,7 +76,7 @@ static int rt_setfreq(struct rt_device *dev, unsigned long freq)
75 int i; 76 int i;
76 77
77 freq = freq / 200 + 856; 78 freq = freq / 200 + 856;
78 79
79 spin_lock(&lock); 80 spin_lock(&lock);
80 81
81 outb_p(0xc8, io); 82 outb_p(0xc8, io);
@@ -94,7 +95,7 @@ static int rt_setfreq(struct rt_device *dev, unsigned long freq)
94 outb_p(0xc8, io); 95 outb_p(0xc8, io);
95 if (!dev->muted) 96 if (!dev->muted)
96 outb_p(0, io); 97 outb_p(0, io);
97 98
98 spin_unlock(&lock); 99 spin_unlock(&lock);
99 return 0; 100 return 0;
100} 101}
@@ -127,7 +128,7 @@ static int rt_do_ioctl(struct inode *inode, struct file *file,
127 case VIDIOCGTUNER: 128 case VIDIOCGTUNER:
128 { 129 {
129 struct video_tuner *v = arg; 130 struct video_tuner *v = arg;
130 if(v->tuner) /* Only 1 tuner */ 131 if(v->tuner) /* Only 1 tuner */
131 return -EINVAL; 132 return -EINVAL;
132 v->rangelow=88*16000; 133 v->rangelow=88*16000;
133 v->rangehigh=108*16000; 134 v->rangehigh=108*16000;
@@ -159,25 +160,25 @@ static int rt_do_ioctl(struct inode *inode, struct file *file,
159 return 0; 160 return 0;
160 } 161 }
161 case VIDIOCGAUDIO: 162 case VIDIOCGAUDIO:
162 { 163 {
163 struct video_audio *v = arg; 164 struct video_audio *v = arg;
164 memset(v,0, sizeof(*v)); 165 memset(v,0, sizeof(*v));
165 v->flags|=VIDEO_AUDIO_MUTABLE; 166 v->flags|=VIDEO_AUDIO_MUTABLE;
166 v->volume=1; 167 v->volume=1;
167 v->step=65535; 168 v->step=65535;
168 strcpy(v->name, "Radio"); 169 strcpy(v->name, "Radio");
169 return 0; 170 return 0;
170 } 171 }
171 case VIDIOCSAUDIO: 172 case VIDIOCSAUDIO:
172 { 173 {
173 struct video_audio *v = arg; 174 struct video_audio *v = arg;
174 if(v->audio) 175 if(v->audio)
175 return -EINVAL; 176 return -EINVAL;
176 177
177 if(v->flags&VIDEO_AUDIO_MUTE) 178 if(v->flags&VIDEO_AUDIO_MUTE)
178 rt_mute(rt); 179 rt_mute(rt);
179 else 180 else
180 rt_unmute(rt); 181 rt_unmute(rt);
181 182
182 return 0; 183 return 0;
183 } 184 }
@@ -219,7 +220,7 @@ static int __init rtrack2_init(void)
219 printk(KERN_ERR "You must set an I/O address with io=0x20c or io=0x30c\n"); 220 printk(KERN_ERR "You must set an I/O address with io=0x20c or io=0x30c\n");
220 return -EINVAL; 221 return -EINVAL;
221 } 222 }
222 if (!request_region(io, 4, "rtrack2")) 223 if (!request_region(io, 4, "rtrack2"))
223 { 224 {
224 printk(KERN_ERR "rtrack2: port 0x%x already in use\n", io); 225 printk(KERN_ERR "rtrack2: port 0x%x already in use\n", io);
225 return -EBUSY; 226 return -EBUSY;
@@ -227,16 +228,16 @@ static int __init rtrack2_init(void)
227 228
228 rtrack2_radio.priv=&rtrack2_unit; 229 rtrack2_radio.priv=&rtrack2_unit;
229 230
230 spin_lock_init(&lock); 231 spin_lock_init(&lock);
231 if(video_register_device(&rtrack2_radio, VFL_TYPE_RADIO, radio_nr)==-1) 232 if(video_register_device(&rtrack2_radio, VFL_TYPE_RADIO, radio_nr)==-1)
232 { 233 {
233 release_region(io, 4); 234 release_region(io, 4);
234 return -EINVAL; 235 return -EINVAL;
235 } 236 }
236 237
237 printk(KERN_INFO "AIMSlab Radiotrack II card driver.\n"); 238 printk(KERN_INFO "AIMSlab Radiotrack II card driver.\n");
238 239
239 /* mute card - prevents noisy bootups */ 240 /* mute card - prevents noisy bootups */
240 outb(1, io); 241 outb(1, io);
241 rtrack2_unit.muted = 1; 242 rtrack2_unit.muted = 1;
242 243
diff --git a/drivers/media/radio/radio-sf16fmi.c b/drivers/media/radio/radio-sf16fmi.c
index 53073b424107..efee6e339d15 100644
--- a/drivers/media/radio/radio-sf16fmi.c
+++ b/drivers/media/radio/radio-sf16fmi.c
@@ -12,7 +12,7 @@
12 * Frequency control is done digitally -- ie out(port,encodefreq(95.8)); 12 * Frequency control is done digitally -- ie out(port,encodefreq(95.8));
13 * No volume control - only mute/unmute - you have to use line volume 13 * No volume control - only mute/unmute - you have to use line volume
14 * control on SB-part of SF16FMI 14 * control on SB-part of SF16FMI
15 * 15 *
16 */ 16 */
17 17
18#include <linux/kernel.h> /* __setup */ 18#include <linux/kernel.h> /* __setup */
@@ -21,6 +21,7 @@
21#include <linux/ioport.h> /* request_region */ 21#include <linux/ioport.h> /* request_region */
22#include <linux/delay.h> /* udelay */ 22#include <linux/delay.h> /* udelay */
23#include <linux/videodev.h> /* kernel radio structs */ 23#include <linux/videodev.h> /* kernel radio structs */
24#include <media/v4l2-common.h>
24#include <linux/isapnp.h> 25#include <linux/isapnp.h>
25#include <asm/io.h> /* outb, outb_p */ 26#include <asm/io.h> /* outb, outb_p */
26#include <asm/uaccess.h> /* copy to/from user */ 27#include <asm/uaccess.h> /* copy to/from user */
@@ -29,19 +30,19 @@
29struct fmi_device 30struct fmi_device
30{ 31{
31 int port; 32 int port;
32 int curvol; /* 1 or 0 */ 33 int curvol; /* 1 or 0 */
33 unsigned long curfreq; /* freq in kHz */ 34 unsigned long curfreq; /* freq in kHz */
34 __u32 flags; 35 __u32 flags;
35}; 36};
36 37
37static int io = -1; 38static int io = -1;
38static int radio_nr = -1; 39static int radio_nr = -1;
39static struct pnp_dev *dev = NULL; 40static struct pnp_dev *dev = NULL;
40static struct mutex lock; 41static struct mutex lock;
41 42
42/* freq is in 1/16 kHz to internal number, hw precision is 50 kHz */ 43/* freq is in 1/16 kHz to internal number, hw precision is 50 kHz */
43/* It is only useful to give freq in intervall of 800 (=0.05Mhz), 44/* It is only useful to give freq in intervall of 800 (=0.05Mhz),
44 * other bits will be truncated, e.g 92.7400016 -> 92.7, but 45 * other bits will be truncated, e.g 92.7400016 -> 92.7, but
45 * 92.7400017 -> 92.75 46 * 92.7400017 -> 92.75
46 */ 47 */
47#define RSF16_ENCODE(x) ((x)/800+214) 48#define RSF16_ENCODE(x) ((x)/800+214)
@@ -51,7 +52,7 @@ static struct mutex lock;
51static void outbits(int bits, unsigned int data, int port) 52static void outbits(int bits, unsigned int data, int port)
52{ 53{
53 while(bits--) { 54 while(bits--) {
54 if(data & 1) { 55 if(data & 1) {
55 outb(5, port); 56 outb(5, port);
56 udelay(6); 57 udelay(6);
57 outb(7, port); 58 outb(7, port);
@@ -101,7 +102,7 @@ static inline int fmi_getsigstr(struct fmi_device *dev)
101 int res; 102 int res;
102 int myport = dev->port; 103 int myport = dev->port;
103 104
104 105
105 mutex_lock(&lock); 106 mutex_lock(&lock);
106 val = dev->curvol ? 0x08 : 0x00; /* unmute/mute */ 107 val = dev->curvol ? 0x08 : 0x00; /* unmute/mute */
107 outb(val, myport); 108 outb(val, myport);
@@ -109,7 +110,7 @@ static inline int fmi_getsigstr(struct fmi_device *dev)
109 msleep(143); /* was schedule_timeout(HZ/7) */ 110 msleep(143); /* was schedule_timeout(HZ/7) */
110 res = (int)inb(myport+1); 111 res = (int)inb(myport+1);
111 outb(val, myport); 112 outb(val, myport);
112 113
113 mutex_unlock(&lock); 114 mutex_unlock(&lock);
114 return (res & 2) ? 0 : 0xFFFF; 115 return (res & 2) ? 0 : 0xFFFF;
115} 116}
@@ -119,7 +120,7 @@ static int fmi_do_ioctl(struct inode *inode, struct file *file,
119{ 120{
120 struct video_device *dev = video_devdata(file); 121 struct video_device *dev = video_devdata(file);
121 struct fmi_device *fmi=dev->priv; 122 struct fmi_device *fmi=dev->priv;
122 123
123 switch(cmd) 124 switch(cmd)
124 { 125 {
125 case VIDIOCGCAP: 126 case VIDIOCGCAP:
@@ -174,18 +175,18 @@ static int fmi_do_ioctl(struct inode *inode, struct file *file,
174 return -EINVAL; 175 return -EINVAL;
175 /*rounding in steps of 800 to match th freq 176 /*rounding in steps of 800 to match th freq
176 that will be used */ 177 that will be used */
177 fmi->curfreq = (*freq/800)*800; 178 fmi->curfreq = (*freq/800)*800;
178 fmi_setfreq(fmi); 179 fmi_setfreq(fmi);
179 return 0; 180 return 0;
180 } 181 }
181 case VIDIOCGAUDIO: 182 case VIDIOCGAUDIO:
182 { 183 {
183 struct video_audio *v = arg; 184 struct video_audio *v = arg;
184 memset(v,0,sizeof(*v)); 185 memset(v,0,sizeof(*v));
185 v->flags=( (!fmi->curvol)*VIDEO_AUDIO_MUTE | VIDEO_AUDIO_MUTABLE); 186 v->flags=( (!fmi->curvol)*VIDEO_AUDIO_MUTE | VIDEO_AUDIO_MUTABLE);
186 strcpy(v->name, "Radio"); 187 strcpy(v->name, "Radio");
187 v->mode=VIDEO_SOUND_STEREO; 188 v->mode=VIDEO_SOUND_STEREO;
188 return 0; 189 return 0;
189 } 190 }
190 case VIDIOCSAUDIO: 191 case VIDIOCSAUDIO:
191 { 192 {
@@ -193,19 +194,19 @@ static int fmi_do_ioctl(struct inode *inode, struct file *file,
193 if(v->audio) 194 if(v->audio)
194 return -EINVAL; 195 return -EINVAL;
195 fmi->curvol= v->flags&VIDEO_AUDIO_MUTE ? 0 : 1; 196 fmi->curvol= v->flags&VIDEO_AUDIO_MUTE ? 0 : 1;
196 fmi->curvol ? 197 fmi->curvol ?
197 fmi_unmute(fmi->port) : fmi_mute(fmi->port); 198 fmi_unmute(fmi->port) : fmi_mute(fmi->port);
198 return 0; 199 return 0;
199 } 200 }
200 case VIDIOCGUNIT: 201 case VIDIOCGUNIT:
201 { 202 {
202 struct video_unit *v = arg; 203 struct video_unit *v = arg;
203 v->video=VIDEO_NO_UNIT; 204 v->video=VIDEO_NO_UNIT;
204 v->vbi=VIDEO_NO_UNIT; 205 v->vbi=VIDEO_NO_UNIT;
205 v->radio=dev->minor; 206 v->radio=dev->minor;
206 v->audio=0; /* How do we find out this??? */ 207 v->audio=0; /* How do we find out this??? */
207 v->teletext=VIDEO_NO_UNIT; 208 v->teletext=VIDEO_NO_UNIT;
208 return 0; 209 return 0;
209 } 210 }
210 default: 211 default:
211 return -ENOIOCTLCMD; 212 return -ENOIOCTLCMD;
@@ -295,14 +296,14 @@ static int __init fmi_init(void)
295 fmi_unit.curfreq = 0; 296 fmi_unit.curfreq = 0;
296 fmi_unit.flags = VIDEO_TUNER_LOW; 297 fmi_unit.flags = VIDEO_TUNER_LOW;
297 fmi_radio.priv = &fmi_unit; 298 fmi_radio.priv = &fmi_unit;
298 299
299 mutex_init(&lock); 300 mutex_init(&lock);
300 301
301 if (video_register_device(&fmi_radio, VFL_TYPE_RADIO, radio_nr) == -1) { 302 if (video_register_device(&fmi_radio, VFL_TYPE_RADIO, radio_nr) == -1) {
302 release_region(io, 2); 303 release_region(io, 2);
303 return -EINVAL; 304 return -EINVAL;
304 } 305 }
305 306
306 printk(KERN_INFO "SF16FMx radio card driver at 0x%x\n", io); 307 printk(KERN_INFO "SF16FMx radio card driver at 0x%x\n", io);
307 /* mute card - prevents noisy bootups */ 308 /* mute card - prevents noisy bootups */
308 fmi_mute(io); 309 fmi_mute(io);
diff --git a/drivers/media/radio/radio-sf16fmr2.c b/drivers/media/radio/radio-sf16fmr2.c
index bcebd8cb19ad..3483b2c7bc9d 100644
--- a/drivers/media/radio/radio-sf16fmr2.c
+++ b/drivers/media/radio/radio-sf16fmr2.c
@@ -19,6 +19,7 @@
19#include <asm/io.h> /* outb, outb_p */ 19#include <asm/io.h> /* outb, outb_p */
20#include <asm/uaccess.h> /* copy to/from user */ 20#include <asm/uaccess.h> /* copy to/from user */
21#include <linux/videodev.h> /* kernel radio structs */ 21#include <linux/videodev.h> /* kernel radio structs */
22#include <media/v4l2-common.h>
22#include <linux/mutex.h> 23#include <linux/mutex.h>
23 24
24static struct mutex lock; 25static struct mutex lock;
@@ -202,7 +203,7 @@ static int fmr2_setvolume(struct fmr2_device *dev)
202} 203}
203 204
204static int fmr2_do_ioctl(struct inode *inode, struct file *file, 205static int fmr2_do_ioctl(struct inode *inode, struct file *file,
205 unsigned int cmd, void *arg) 206 unsigned int cmd, void *arg)
206{ 207{
207 struct video_device *dev = video_devdata(file); 208 struct video_device *dev = video_devdata(file);
208 struct fmr2_device *fmr2 = dev->priv; 209 struct fmr2_device *fmr2 = dev->priv;
@@ -344,7 +345,7 @@ static int fmr2_do_ioctl(struct inode *inode, struct file *file,
344} 345}
345 346
346static int fmr2_ioctl(struct inode *inode, struct file *file, 347static int fmr2_ioctl(struct inode *inode, struct file *file,
347 unsigned int cmd, unsigned long arg) 348 unsigned int cmd, unsigned long arg)
348 { 349 {
349 return video_usercopy(inode, file, cmd, arg, fmr2_do_ioctl); 350 return video_usercopy(inode, file, cmd, arg, fmr2_do_ioctl);
350} 351}
diff --git a/drivers/media/radio/radio-terratec.c b/drivers/media/radio/radio-terratec.c
index fcfde2e4f195..dfba4ae596cd 100644
--- a/drivers/media/radio/radio-terratec.c
+++ b/drivers/media/radio/radio-terratec.c
@@ -2,11 +2,11 @@
2 * (c) 1999 R. Offermanns (rolf@offermanns.de) 2 * (c) 1999 R. Offermanns (rolf@offermanns.de)
3 * based on the aimslab radio driver from M. Kirkwood 3 * based on the aimslab radio driver from M. Kirkwood
4 * many thanks to Michael Becker and Friedhelm Birth (from TerraTec) 4 * many thanks to Michael Becker and Friedhelm Birth (from TerraTec)
5 * 5 *
6 * 6 *
7 * History: 7 * History:
8 * 1999-05-21 First preview release 8 * 1999-05-21 First preview release
9 * 9 *
10 * Notes on the hardware: 10 * Notes on the hardware:
11 * There are two "main" chips on the card: 11 * There are two "main" chips on the card:
12 * - Philips OM5610 (http://www-us.semiconductors.philips.com/acrobat/datasheets/OM5610_2.pdf) 12 * - Philips OM5610 (http://www-us.semiconductors.philips.com/acrobat/datasheets/OM5610_2.pdf)
@@ -20,7 +20,7 @@
20 * (as soon i have understand how to get started :) 20 * (as soon i have understand how to get started :)
21 * If you can help me out with that, please contact me!! 21 * If you can help me out with that, please contact me!!
22 * 22 *
23 * 23 *
24 */ 24 */
25 25
26#include <linux/module.h> /* Modules */ 26#include <linux/module.h> /* Modules */
@@ -30,6 +30,7 @@
30#include <asm/io.h> /* outb, outb_p */ 30#include <asm/io.h> /* outb, outb_p */
31#include <asm/uaccess.h> /* copy to/from user */ 31#include <asm/uaccess.h> /* copy to/from user */
32#include <linux/videodev.h> /* kernel radio structs */ 32#include <linux/videodev.h> /* kernel radio structs */
33#include <media/v4l2-common.h>
33#include <linux/config.h> /* CONFIG_RADIO_TERRATEC_PORT */ 34#include <linux/config.h> /* CONFIG_RADIO_TERRATEC_PORT */
34#include <linux/spinlock.h> 35#include <linux/spinlock.h>
35 36
@@ -49,7 +50,7 @@
49#define WRT_EN 0x10 50#define WRT_EN 0x10
50/*******************************************************************/ 51/*******************************************************************/
51 52
52static int io = CONFIG_RADIO_TERRATEC_PORT; 53static int io = CONFIG_RADIO_TERRATEC_PORT;
53static int radio_nr = -1; 54static int radio_nr = -1;
54static spinlock_t lock; 55static spinlock_t lock;
55 56
@@ -88,15 +89,15 @@ static void tt_mute(struct tt_device *dev)
88 89
89static int tt_setvol(struct tt_device *dev, int vol) 90static int tt_setvol(struct tt_device *dev, int vol)
90{ 91{
91 92
92// printk(KERN_ERR "setvol called, vol = %d\n", vol); 93// printk(KERN_ERR "setvol called, vol = %d\n", vol);
93 94
94 if(vol == dev->curvol) { /* requested volume = current */ 95 if(vol == dev->curvol) { /* requested volume = current */
95 if (dev->muted) { /* user is unmuting the card */ 96 if (dev->muted) { /* user is unmuting the card */
96 dev->muted = 0; 97 dev->muted = 0;
97 cardWriteVol(vol); /* enable card */ 98 cardWriteVol(vol); /* enable card */
98 } 99 }
99 100
100 return 0; 101 return 0;
101 } 102 }
102 103
@@ -107,9 +108,9 @@ static int tt_setvol(struct tt_device *dev, int vol)
107 } 108 }
108 109
109 dev->muted = 0; 110 dev->muted = 0;
110 111
111 cardWriteVol(vol); 112 cardWriteVol(vol);
112 113
113 dev->curvol = vol; 114 dev->curvol = vol;
114 115
115 return 0; 116 return 0;
@@ -121,13 +122,13 @@ static int tt_setvol(struct tt_device *dev, int vol)
121/* many more or less strange things are going on here, but hey, it works :) */ 122/* many more or less strange things are going on here, but hey, it works :) */
122 123
123static int tt_setfreq(struct tt_device *dev, unsigned long freq1) 124static int tt_setfreq(struct tt_device *dev, unsigned long freq1)
124{ 125{
125 int freq; 126 int freq;
126 int i; 127 int i;
127 int p; 128 int p;
128 int temp; 129 int temp;
129 long rest; 130 long rest;
130 131
131 unsigned char buffer[25]; /* we have to bit shift 25 registers */ 132 unsigned char buffer[25]; /* we have to bit shift 25 registers */
132 freq = freq1/160; /* convert the freq. to a nice to handle value */ 133 freq = freq1/160; /* convert the freq. to a nice to handle value */
133 for(i=24;i>-1;i--) 134 for(i=24;i>-1;i--)
@@ -142,9 +143,9 @@ static int tt_setfreq(struct tt_device *dev, unsigned long freq1)
142 { 143 {
143 if (rest%temp == rest) 144 if (rest%temp == rest)
144 buffer[i] = 0; 145 buffer[i] = 0;
145 else 146 else
146 { 147 {
147 buffer[i] = 1; 148 buffer[i] = 1;
148 rest = rest-temp; 149 rest = rest-temp;
149 } 150 }
150 i--; 151 i--;
@@ -153,10 +154,10 @@ static int tt_setfreq(struct tt_device *dev, unsigned long freq1)
153 } 154 }
154 155
155 spin_lock(&lock); 156 spin_lock(&lock);
156 157
157 for (i=24;i>-1;i--) /* bit shift the values to the radiocard */ 158 for (i=24;i>-1;i--) /* bit shift the values to the radiocard */
158 { 159 {
159 if (buffer[i]==1) 160 if (buffer[i]==1)
160 { 161 {
161 outb(WRT_EN|DATA, BASEPORT); 162 outb(WRT_EN|DATA, BASEPORT);
162 outb(WRT_EN|DATA|CLK_ON , BASEPORT); 163 outb(WRT_EN|DATA|CLK_ON , BASEPORT);
@@ -168,11 +169,11 @@ static int tt_setfreq(struct tt_device *dev, unsigned long freq1)
168 outb(WRT_EN|0x00|CLK_ON , BASEPORT); 169 outb(WRT_EN|0x00|CLK_ON , BASEPORT);
169 } 170 }
170 } 171 }
171 outb(0x00, BASEPORT); 172 outb(0x00, BASEPORT);
172 173
173 spin_unlock(&lock); 174 spin_unlock(&lock);
174 175
175 return 0; 176 return 0;
176} 177}
177 178
178static int tt_getsigstr(struct tt_device *dev) /* TODO */ 179static int tt_getsigstr(struct tt_device *dev) /* TODO */
@@ -190,7 +191,7 @@ static int tt_do_ioctl(struct inode *inode, struct file *file,
190{ 191{
191 struct video_device *dev = video_devdata(file); 192 struct video_device *dev = video_devdata(file);
192 struct tt_device *tt=dev->priv; 193 struct tt_device *tt=dev->priv;
193 194
194 switch(cmd) 195 switch(cmd)
195 { 196 {
196 case VIDIOCGCAP: 197 case VIDIOCGCAP:
@@ -206,7 +207,7 @@ static int tt_do_ioctl(struct inode *inode, struct file *file,
206 case VIDIOCGTUNER: 207 case VIDIOCGTUNER:
207 { 208 {
208 struct video_tuner *v = arg; 209 struct video_tuner *v = arg;
209 if(v->tuner) /* Only 1 tuner */ 210 if(v->tuner) /* Only 1 tuner */
210 return -EINVAL; 211 return -EINVAL;
211 v->rangelow=(87*16000); 212 v->rangelow=(87*16000);
212 v->rangehigh=(108*16000); 213 v->rangehigh=(108*16000);
@@ -238,21 +239,21 @@ static int tt_do_ioctl(struct inode *inode, struct file *file,
238 return 0; 239 return 0;
239 } 240 }
240 case VIDIOCGAUDIO: 241 case VIDIOCGAUDIO:
241 { 242 {
242 struct video_audio *v = arg; 243 struct video_audio *v = arg;
243 memset(v,0, sizeof(*v)); 244 memset(v,0, sizeof(*v));
244 v->flags|=VIDEO_AUDIO_MUTABLE|VIDEO_AUDIO_VOLUME; 245 v->flags|=VIDEO_AUDIO_MUTABLE|VIDEO_AUDIO_VOLUME;
245 v->volume=tt->curvol * 6554; 246 v->volume=tt->curvol * 6554;
246 v->step=6554; 247 v->step=6554;
247 strcpy(v->name, "Radio"); 248 strcpy(v->name, "Radio");
248 return 0; 249 return 0;
249 } 250 }
250 case VIDIOCSAUDIO: 251 case VIDIOCSAUDIO:
251 { 252 {
252 struct video_audio *v = arg; 253 struct video_audio *v = arg;
253 if(v->audio) 254 if(v->audio)
254 return -EINVAL; 255 return -EINVAL;
255 if(v->flags&VIDEO_AUDIO_MUTE) 256 if(v->flags&VIDEO_AUDIO_MUTE)
256 tt_mute(tt); 257 tt_mute(tt);
257 else 258 else
258 tt_setvol(tt,v->volume/6554); 259 tt_setvol(tt,v->volume/6554);
@@ -296,25 +297,25 @@ static int __init terratec_init(void)
296 printk(KERN_ERR "You must set an I/O address with io=0x???\n"); 297 printk(KERN_ERR "You must set an I/O address with io=0x???\n");
297 return -EINVAL; 298 return -EINVAL;
298 } 299 }
299 if (!request_region(io, 2, "terratec")) 300 if (!request_region(io, 2, "terratec"))
300 { 301 {
301 printk(KERN_ERR "TerraTec: port 0x%x already in use\n", io); 302 printk(KERN_ERR "TerraTec: port 0x%x already in use\n", io);
302 return -EBUSY; 303 return -EBUSY;
303 } 304 }
304 305
305 terratec_radio.priv=&terratec_unit; 306 terratec_radio.priv=&terratec_unit;
306 307
307 spin_lock_init(&lock); 308 spin_lock_init(&lock);
308 309
309 if(video_register_device(&terratec_radio, VFL_TYPE_RADIO, radio_nr)==-1) 310 if(video_register_device(&terratec_radio, VFL_TYPE_RADIO, radio_nr)==-1)
310 { 311 {
311 release_region(io,2); 312 release_region(io,2);
312 return -EINVAL; 313 return -EINVAL;
313 } 314 }
314 315
315 printk(KERN_INFO "TERRATEC ActivRadio Standalone card driver.\n"); 316 printk(KERN_INFO "TERRATEC ActivRadio Standalone card driver.\n");
316 317
317 /* mute card - prevents noisy bootups */ 318 /* mute card - prevents noisy bootups */
318 319
319 /* this ensures that the volume is all the way down */ 320 /* this ensures that the volume is all the way down */
320 cardWriteVol(0); 321 cardWriteVol(0);
@@ -334,7 +335,7 @@ static void __exit terratec_cleanup_module(void)
334{ 335{
335 video_unregister_device(&terratec_radio); 336 video_unregister_device(&terratec_radio);
336 release_region(io,2); 337 release_region(io,2);
337 printk(KERN_INFO "TERRATEC ActivRadio Standalone card driver unloaded.\n"); 338 printk(KERN_INFO "TERRATEC ActivRadio Standalone card driver unloaded.\n");
338} 339}
339 340
340module_init(terratec_init); 341module_init(terratec_init);
diff --git a/drivers/media/radio/radio-trust.c b/drivers/media/radio/radio-trust.c
index 5a099a50d4d0..8da4badc22b4 100644
--- a/drivers/media/radio/radio-trust.c
+++ b/drivers/media/radio/radio-trust.c
@@ -1,14 +1,14 @@
1/* radio-trust.c - Trust FM Radio card driver for Linux 2.2 1/* radio-trust.c - Trust FM Radio card driver for Linux 2.2
2 * by Eric Lammerts <eric@scintilla.utwente.nl> 2 * by Eric Lammerts <eric@scintilla.utwente.nl>
3 * 3 *
4 * Based on radio-aztech.c. Original notes: 4 * Based on radio-aztech.c. Original notes:
5 * 5 *
6 * Adapted to support the Video for Linux API by 6 * Adapted to support the Video for Linux API by
7 * Russell Kroll <rkroll@exploits.org>. Based on original tuner code by: 7 * Russell Kroll <rkroll@exploits.org>. Based on original tuner code by:
8 * 8 *
9 * Quay Ly 9 * Quay Ly
10 * Donald Song 10 * Donald Song
11 * Jason Lewis (jlewis@twilight.vtc.vsc.edu) 11 * Jason Lewis (jlewis@twilight.vtc.vsc.edu)
12 * Scott McGrath (smcgrath@twilight.vtc.vsc.edu) 12 * Scott McGrath (smcgrath@twilight.vtc.vsc.edu)
13 * William McGrath (wmcgrath@twilight.vtc.vsc.edu) 13 * William McGrath (wmcgrath@twilight.vtc.vsc.edu)
14 * 14 *
@@ -22,6 +22,7 @@
22#include <asm/io.h> 22#include <asm/io.h>
23#include <asm/uaccess.h> 23#include <asm/uaccess.h>
24#include <linux/videodev.h> 24#include <linux/videodev.h>
25#include <media/v4l2-common.h>
25#include <linux/config.h> /* CONFIG_RADIO_TRUST_PORT */ 26#include <linux/config.h> /* CONFIG_RADIO_TRUST_PORT */
26 27
27/* acceptable ports: 0x350 (JP3 shorted), 0x358 (JP3 open) */ 28/* acceptable ports: 0x350 (JP3 shorted), 0x358 (JP3 open) */
@@ -30,7 +31,7 @@
30#define CONFIG_RADIO_TRUST_PORT -1 31#define CONFIG_RADIO_TRUST_PORT -1
31#endif 32#endif
32 33
33static int io = CONFIG_RADIO_TRUST_PORT; 34static int io = CONFIG_RADIO_TRUST_PORT;
34static int radio_nr = -1; 35static int radio_nr = -1;
35static int ioval = 0xf; 36static int ioval = 0xf;
36static __u16 curvol; 37static __u16 curvol;
@@ -135,7 +136,7 @@ static void tr_setmute(int mute)
135static int tr_getsigstr(void) 136static int tr_getsigstr(void)
136{ 137{
137 int i, v; 138 int i, v;
138 139
139 for(i = 0, v = 0; i < 100; i++) v |= inb(io); 140 for(i = 0, v = 0; i < 100; i++) v |= inb(io);
140 return (v & 1)? 0 : 0xffff; 141 return (v & 1)? 0 : 0xffff;
141} 142}
@@ -175,7 +176,7 @@ static int tr_do_ioctl(struct inode *inode, struct file *file,
175 { 176 {
176 struct video_tuner *v = arg; 177 struct video_tuner *v = arg;
177 178
178 if(v->tuner) /* Only 1 tuner */ 179 if(v->tuner) /* Only 1 tuner */
179 return -EINVAL; 180 return -EINVAL;
180 181
181 v->rangelow = 87500 * 16; 182 v->rangelow = 87500 * 16;
@@ -211,28 +212,28 @@ static int tr_do_ioctl(struct inode *inode, struct file *file,
211 return 0; 212 return 0;
212 } 213 }
213 case VIDIOCGAUDIO: 214 case VIDIOCGAUDIO:
214 { 215 {
215 struct video_audio *v = arg; 216 struct video_audio *v = arg;
216 217
217 memset(v,0, sizeof(*v)); 218 memset(v,0, sizeof(*v));
218 v->flags = VIDEO_AUDIO_MUTABLE | VIDEO_AUDIO_VOLUME | 219 v->flags = VIDEO_AUDIO_MUTABLE | VIDEO_AUDIO_VOLUME |
219 VIDEO_AUDIO_BASS | VIDEO_AUDIO_TREBLE; 220 VIDEO_AUDIO_BASS | VIDEO_AUDIO_TREBLE;
220 v->mode = curstereo? VIDEO_SOUND_STEREO : VIDEO_SOUND_MONO; 221 v->mode = curstereo? VIDEO_SOUND_STEREO : VIDEO_SOUND_MONO;
221 v->volume = curvol * 2048; 222 v->volume = curvol * 2048;
222 v->step = 2048; 223 v->step = 2048;
223 v->bass = curbass * 4370; 224 v->bass = curbass * 4370;
224 v->treble = curtreble * 4370; 225 v->treble = curtreble * 4370;
225 226
226 strcpy(v->name, "Trust FM Radio"); 227 strcpy(v->name, "Trust FM Radio");
227 return 0; 228 return 0;
228 } 229 }
229 case VIDIOCSAUDIO: 230 case VIDIOCSAUDIO:
230 { 231 {
231 struct video_audio *v = arg; 232 struct video_audio *v = arg;
232 233
233 if(v->audio) 234 if(v->audio)
234 return -EINVAL; 235 return -EINVAL;
235 tr_setvol(v->volume); 236 tr_setvol(v->volume);
236 tr_setbass(v->bass); 237 tr_setbass(v->bass);
237 tr_settreble(v->treble); 238 tr_settreble(v->treble);
238 tr_setstereo(v->mode & VIDEO_SOUND_STEREO); 239 tr_setstereo(v->mode & VIDEO_SOUND_STEREO);
@@ -292,7 +293,7 @@ static int __init trust_init(void)
292 write_i2c(2, TDA7318_ADDR, 0xe0); /* speaker att. RR = 0 dB */ 293 write_i2c(2, TDA7318_ADDR, 0xe0); /* speaker att. RR = 0 dB */
293 write_i2c(2, TDA7318_ADDR, 0x40); /* stereo 1 input, gain = 18.75 dB */ 294 write_i2c(2, TDA7318_ADDR, 0x40); /* stereo 1 input, gain = 18.75 dB */
294 295
295 tr_setvol(0x8000); 296 tr_setvol(0x8000);
296 tr_setbass(0x8000); 297 tr_setbass(0x8000);
297 tr_settreble(0x8000); 298 tr_settreble(0x8000);
298 tr_setstereo(1); 299 tr_setstereo(1);
diff --git a/drivers/media/radio/radio-typhoon.c b/drivers/media/radio/radio-typhoon.c
index e50955836d6b..edd012288669 100644
--- a/drivers/media/radio/radio-typhoon.c
+++ b/drivers/media/radio/radio-typhoon.c
@@ -36,6 +36,7 @@
36#include <asm/io.h> /* outb, outb_p */ 36#include <asm/io.h> /* outb, outb_p */
37#include <asm/uaccess.h> /* copy to/from user */ 37#include <asm/uaccess.h> /* copy to/from user */
38#include <linux/videodev.h> /* kernel radio structs */ 38#include <linux/videodev.h> /* kernel radio structs */
39#include <media/v4l2-common.h>
39#include <linux/config.h> /* CONFIG_RADIO_TYPHOON_* */ 40#include <linux/config.h> /* CONFIG_RADIO_TYPHOON_* */
40 41
41#define BANNER "Typhoon Radio Card driver v0.1\n" 42#define BANNER "Typhoon Radio Card driver v0.1\n"
@@ -361,8 +362,8 @@ static int __init typhoon_init(void)
361 362
362#ifdef CONFIG_RADIO_TYPHOON_PROC_FS 363#ifdef CONFIG_RADIO_TYPHOON_PROC_FS
363 if (!create_proc_info_entry("driver/radio-typhoon", 0, NULL, 364 if (!create_proc_info_entry("driver/radio-typhoon", 0, NULL,
364 typhoon_get_info)) 365 typhoon_get_info))
365 printk(KERN_ERR "radio-typhoon: registering /proc/driver/radio-typhoon failed\n"); 366 printk(KERN_ERR "radio-typhoon: registering /proc/driver/radio-typhoon failed\n");
366#endif 367#endif
367 368
368 return 0; 369 return 0;
diff --git a/drivers/media/radio/radio-zoltrix.c b/drivers/media/radio/radio-zoltrix.c
index 7bf1a4264891..59b86a6b4b0e 100644
--- a/drivers/media/radio/radio-zoltrix.c
+++ b/drivers/media/radio/radio-zoltrix.c
@@ -1,7 +1,7 @@
1/* zoltrix radio plus driver for Linux radio support 1/* zoltrix radio plus driver for Linux radio support
2 * (c) 1998 C. van Schaik <carl@leg.uct.ac.za> 2 * (c) 1998 C. van Schaik <carl@leg.uct.ac.za>
3 * 3 *
4 * BUGS 4 * BUGS
5 * Due to the inconsistency in reading from the signal flags 5 * Due to the inconsistency in reading from the signal flags
6 * it is difficult to get an accurate tuned signal. 6 * it is difficult to get an accurate tuned signal.
7 * 7 *
@@ -14,7 +14,7 @@
14 * 14 *
15 * 1999-05-06 - (C. van Schaik) 15 * 1999-05-06 - (C. van Schaik)
16 * - Make signal strength and stereo scans 16 * - Make signal strength and stereo scans
17 * kinder to cpu while in delay 17 * kinder to cpu while in delay
18 * 1999-01-05 - (C. van Schaik) 18 * 1999-01-05 - (C. van Schaik)
19 * - Changed tuning to 1/160Mhz accuracy 19 * - Changed tuning to 1/160Mhz accuracy
20 * - Added stereo support 20 * - Added stereo support
@@ -33,6 +33,7 @@
33#include <asm/io.h> /* outb, outb_p */ 33#include <asm/io.h> /* outb, outb_p */
34#include <asm/uaccess.h> /* copy to/from user */ 34#include <asm/uaccess.h> /* copy to/from user */
35#include <linux/videodev.h> /* kernel radio structs */ 35#include <linux/videodev.h> /* kernel radio structs */
36#include <media/v4l2-common.h>
36#include <linux/config.h> /* CONFIG_RADIO_ZOLTRIX_PORT */ 37#include <linux/config.h> /* CONFIG_RADIO_ZOLTRIX_PORT */
37 38
38#ifndef CONFIG_RADIO_ZOLTRIX_PORT 39#ifndef CONFIG_RADIO_ZOLTRIX_PORT
@@ -105,7 +106,7 @@ static int zol_setfreq(struct zol_device *dev, unsigned long freq)
105 i = 45; 106 i = 45;
106 107
107 mutex_lock(&dev->lock); 108 mutex_lock(&dev->lock);
108 109
109 outb(0, io); 110 outb(0, io);
110 outb(0, io); 111 outb(0, io);
111 inb(io + 3); /* Zoltrix needs to be read to confirm */ 112 inb(io + 3); /* Zoltrix needs to be read to confirm */
@@ -139,8 +140,8 @@ static int zol_setfreq(struct zol_device *dev, unsigned long freq)
139 udelay(1000); 140 udelay(1000);
140 inb(io+2); 141 inb(io+2);
141 142
142 udelay(1000); 143 udelay(1000);
143 144
144 if (dev->muted) 145 if (dev->muted)
145 { 146 {
146 outb(0, io); 147 outb(0, io);
@@ -148,12 +149,12 @@ static int zol_setfreq(struct zol_device *dev, unsigned long freq)
148 inb(io + 3); 149 inb(io + 3);
149 udelay(1000); 150 udelay(1000);
150 } 151 }
151 152
152 mutex_unlock(&dev->lock); 153 mutex_unlock(&dev->lock);
153 154
154 if(!dev->muted) 155 if(!dev->muted)
155 { 156 {
156 zol_setvol(dev, dev->curvol); 157 zol_setvol(dev, dev->curvol);
157 } 158 }
158 return 0; 159 return 0;
159} 160}
@@ -174,14 +175,14 @@ static int zol_getsigstr(struct zol_device *dev)
174 b = inb(io); 175 b = inb(io);
175 176
176 mutex_unlock(&dev->lock); 177 mutex_unlock(&dev->lock);
177 178
178 if (a != b) 179 if (a != b)
179 return (0); 180 return (0);
180 181
181 if ((a == 0xcf) || (a == 0xdf) /* I found this out by playing */ 182 if ((a == 0xcf) || (a == 0xdf) /* I found this out by playing */
182 || (a == 0xef)) /* with a binary scanner on the card io */ 183 || (a == 0xef)) /* with a binary scanner on the card io */
183 return (1); 184 return (1);
184 return (0); 185 return (0);
185} 186}
186 187
187static int zol_is_stereo (struct zol_device *dev) 188static int zol_is_stereo (struct zol_device *dev)
@@ -189,7 +190,7 @@ static int zol_is_stereo (struct zol_device *dev)
189 int x1, x2; 190 int x1, x2;
190 191
191 mutex_lock(&dev->lock); 192 mutex_lock(&dev->lock);
192 193
193 outb(0x00, io); 194 outb(0x00, io);
194 outb(dev->curvol, io); 195 outb(dev->curvol, io);
195 msleep(20); 196 msleep(20);
@@ -199,7 +200,7 @@ static int zol_is_stereo (struct zol_device *dev)
199 x2 = inb(io); 200 x2 = inb(io);
200 201
201 mutex_unlock(&dev->lock); 202 mutex_unlock(&dev->lock);
202 203
203 if ((x1 == x2) && (x1 == 0xcf)) 204 if ((x1 == x2) && (x1 == 0xcf))
204 return 1; 205 return 1;
205 return 0; 206 return 0;
@@ -226,7 +227,7 @@ static int zol_do_ioctl(struct inode *inode, struct file *file,
226 case VIDIOCGTUNER: 227 case VIDIOCGTUNER:
227 { 228 {
228 struct video_tuner *v = arg; 229 struct video_tuner *v = arg;
229 if (v->tuner) 230 if (v->tuner)
230 return -EINVAL; 231 return -EINVAL;
231 strcpy(v->name, "FM"); 232 strcpy(v->name, "FM");
232 v->rangelow = (int) (88.0 * 16000); 233 v->rangelow = (int) (88.0 * 16000);
@@ -351,7 +352,7 @@ static int __init zoltrix_init(void)
351 printk(KERN_INFO "Zoltrix Radio Plus card driver.\n"); 352 printk(KERN_INFO "Zoltrix Radio Plus card driver.\n");
352 353
353 mutex_init(&zoltrix_unit.lock); 354 mutex_init(&zoltrix_unit.lock);
354 355
355 /* mute card - prevents noisy bootups */ 356 /* mute card - prevents noisy bootups */
356 357
357 /* this ensures that the volume is all the way down */ 358 /* this ensures that the volume is all the way down */
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index 6b4197018561..824a63c92629 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 e5bf2687b76d..6c401b46398a 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 dbe025170599..6e08e32346eb 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 000000000000..05e42bbcfc3d
--- /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 2b64aa835b42..3116345c93b1 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 c4d5e2b70c28..ba081f6f8c82 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 69efa0e5174d..b41f81d2372c 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 3a23265c1538..f9c9e3c4d111 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 ee989d2e15d9..d2956010f763 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 cf61c590f4ad..7d0b6e59c6e2 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 22a7386bbea6..a3989bd2f81b 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 85d84e89d8f4..95c5aceecc5b 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 dde27a6a4a09..6eaa692021c5 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 1764991b0ac9..c5ecb2be5f93 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 481e178ef56d..d129db57fcd4 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 0b00e6027dfb..4c89bd395d3e 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 9c49a4b00116..2ee34a3b9280 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 000000000000..554813e6f65d
--- /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 9a4b813152e5..f897c1ebd5f3 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 a961bb2ab0fd..5c2036b40ea1 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 1736929fc204..28049064dd7d 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 57feca288d2b..6cc8bf215e85 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 630273992a41..91e1c481a164 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 320b3d9384ba..2194cbeca33b 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 e100d8ef369a..67fd3302e8f2 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 f80154b87d22..67cdd8270863 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 e1092d5d4628..c56292d8d93b 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 3619a449aefd..dce1feddd55d 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 f720901e9638..7efa6def0bde 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 78a63b7dd380..72b630a91f41 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 7d16888b4a86..a9d7795a8e14 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 641a0c5a6490..1e4278b588d8 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 846faadc9f1c..aa2a69770098 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 326a25f147f6..dc7bc35f18f4 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 3b4e9985c3d7..f7e33f9ee8e9 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 3ba3439db580..ed882ebc7b95 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 e5ee8bceb210..4350cc75b025 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 5b6cece37aee..d829d8f8c1f6 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 31e89e4f18be..3ffb5684f127 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 cf7cdf9ef617..9286090817cd 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 e1ddc2f27a21..d8fcc9e17ac0 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 dfc9dd732c9d..8992b6e62b9f 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 7e66d83fe0ce..fba30a40e9c6 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 000000000000..3bf7ac4f5288
--- /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 000000000000..1ec578833aea
--- /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 850bee97090c..f68ca7d9f531 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 b806999d6e0f..dbb75a7db199 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 633a10213789..f2fd9195b3ac 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 fdc8e3f13937..a988df226aab 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 12b3d51e1c34..68b082bcee1d 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 d9e3cada52f4..3484e36b6801 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 09835ca098b1..5d681fa8bcb1 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 53cbc950f95c..697145e0bf15 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 33d60126c024..9db2260d10cc 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 4ba549bfa0e0..0bd115588f31 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 000000000000..c29593f589eb
--- /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 000000000000..8b62ddcc5c7e
--- /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 000000000000..9e2d91f26bfe
--- /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 000000000000..1c55298ad153
--- /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 41418294a32b..47d0d83a0264 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 4c96037f7be5..fec39cc5a9f1 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 12929abbb1f0..0bdb22547d86 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 58fe79747992..589c687439da 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 175250d089cf..be65bdcd195b 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 a86b3782a081..eef9e2cd4320 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 b37a89a163f9..5d82028ef942 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 f75e1b6cbe19..041227f65246 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 000000000000..b7eb3ce3b968
--- /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 1b0ee0ced0ed..629f79e44fb6 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 dd830e0e5e96..59a187272c83 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 531e9461cb66..19a8d65699f8 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 41d951db6ec0..676b9970eb2e 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 dceebc0b1250..b59c11717273 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 c271e2e14105..ad401bdefeaf 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 0e0ba50946e8..de7b9e6e932a 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 bb3e0ba946d3..d77e6a8d9432 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 86eae3528330..927413aded10 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 222a36c38917..279828b8f299 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 1d972edb3be6..65d044086ce9 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 1426e4c8602f..7c595492c56b 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 353af3a8b766..d5ee99c574cc 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 a7a216bd4413..c0891b3e0018 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 ea4394dc9415..48d138a7c723 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 07476c71174a..6be9c1131e1f 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 b38bda83a7c5..351b182d921f 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 103ccb919292..827633b3bb43 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 0d54f6c1982b..b6ae969563b2 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 c2b98f81c192..d1c41781ccc4 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 000000000000..76b2e96429d9
--- /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 74ab48c09c6a..bdf506e6ae27 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 1013b4de89a2..e95792fd70f8 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 5d7abed71674..6da6f82b8c88 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 a1ae036b44ec..9d9226cb6393 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 b463e996961a..30f8d80ddcaa 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 9e86caeb96a7..1654576de10e 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 dab4973bcf82..b167ffab2520 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 39269a2c5635..59fb899f31f3 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 bb52eb8dc2f9..4a1b144bee4d 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 000000000000..3f3182a24da1
--- /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 000000000000..baab9c081b52
--- /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 3cbf4fc499a3..49dbee5f5628 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 474a29bc1760..19d3c20dc7ef 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 d330fa985bcc..14e523471354 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 caf3e7e2f219..7ee8a53cd336 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 5f87dd5f1d0b..2dfa7f23d0ca 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 a8c101494cf5..268e69fdefc6 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 779db26771c0..41d23c8acbd8 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 40b205b91481..1eca7e65d235 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 80ef8a1b8f63..4bdc886abc4c 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 115833e4f4dd..a859a6920189 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 d749199d8f06..d9e6d97fade6 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 0fad39754f7a..1b2be2d2a3ec 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 eaadf0252049..ecfd39a56df1 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 000000000000..ed8542e6c50f
--- /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 1f95c28b1015..4363a915b1f4 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 0166f555a5ca..ffcda95ed9d4 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 0a85c9e7fb48..958c1e6fc852 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 c690b2ee880a..02168d9c2187 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 b5a576a37fd2..9711f6248ef7 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 a00fae90229a..f4ffe79bdc5b 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"
diff --git a/drivers/video/matrox/matroxfb_base.c b/drivers/video/matrox/matroxfb_base.c
index 23c1827b2d0b..f4ddd3431f17 100644
--- a/drivers/video/matrox/matroxfb_base.c
+++ b/drivers/video/matrox/matroxfb_base.c
@@ -102,6 +102,8 @@
102#include <linux/config.h> 102#include <linux/config.h>
103#include <linux/version.h> 103#include <linux/version.h>
104 104
105#define __OLD_VIDIOC_
106
105#include "matroxfb_base.h" 107#include "matroxfb_base.h"
106#include "matroxfb_misc.h" 108#include "matroxfb_misc.h"
107#include "matroxfb_accel.h" 109#include "matroxfb_accel.h"
@@ -158,9 +160,9 @@ static void update_crtc2(WPMINFO unsigned int pos) {
158 160
159 /* Make sure that displays are compatible */ 161 /* Make sure that displays are compatible */
160 if (info && (info->fbcon.var.bits_per_pixel == ACCESS_FBINFO(fbcon).var.bits_per_pixel) 162 if (info && (info->fbcon.var.bits_per_pixel == ACCESS_FBINFO(fbcon).var.bits_per_pixel)
161 && (info->fbcon.var.xres_virtual == ACCESS_FBINFO(fbcon).var.xres_virtual) 163 && (info->fbcon.var.xres_virtual == ACCESS_FBINFO(fbcon).var.xres_virtual)
162 && (info->fbcon.var.green.length == ACCESS_FBINFO(fbcon).var.green.length) 164 && (info->fbcon.var.green.length == ACCESS_FBINFO(fbcon).var.green.length)
163 ) { 165 ) {
164 switch (ACCESS_FBINFO(fbcon).var.bits_per_pixel) { 166 switch (ACCESS_FBINFO(fbcon).var.bits_per_pixel) {
165 case 16: 167 case 16:
166 case 32: 168 case 32:
@@ -224,7 +226,7 @@ static irqreturn_t matrox_irq(int irq, void *dev_id, struct pt_regs *fp)
224 226
225int matroxfb_enable_irq(WPMINFO int reenable) { 227int matroxfb_enable_irq(WPMINFO int reenable) {
226 u_int32_t bm; 228 u_int32_t bm;
227 229
228 if (ACCESS_FBINFO(devflags.accelerator) == FB_ACCEL_MATROX_MGAG400) 230 if (ACCESS_FBINFO(devflags.accelerator) == FB_ACCEL_MATROX_MGAG400)
229 bm = 0x220; 231 bm = 0x220;
230 else 232 else
@@ -241,7 +243,7 @@ int matroxfb_enable_irq(WPMINFO int reenable) {
241 mga_outl(M_IEN, mga_inl(M_IEN) | bm); 243 mga_outl(M_IEN, mga_inl(M_IEN) | bm);
242 } else if (reenable) { 244 } else if (reenable) {
243 u_int32_t ien; 245 u_int32_t ien;
244 246
245 ien = mga_inl(M_IEN); 247 ien = mga_inl(M_IEN);
246 if ((ien & bm) != bm) { 248 if ((ien & bm) != bm) {
247 printk(KERN_DEBUG "matroxfb: someone disabled IRQ [%08X]\n", ien); 249 printk(KERN_DEBUG "matroxfb: someone disabled IRQ [%08X]\n", ien);
@@ -347,7 +349,7 @@ static void matrox_pan_var(WPMINFO struct fb_var_screeninfo *var) {
347 mga_setr(M_EXTVGA_INDEX, 0x00, p2); 349 mga_setr(M_EXTVGA_INDEX, 0x00, p2);
348 } 350 }
349 matroxfb_DAC_unlock_irqrestore(flags); 351 matroxfb_DAC_unlock_irqrestore(flags);
350 352
351 update_crtc2(PMINFO pos); 353 update_crtc2(PMINFO pos);
352 354
353 CRITEND 355 CRITEND
@@ -390,7 +392,7 @@ static void matroxfb_remove(WPMINFO int dummy) {
390static int matroxfb_open(struct fb_info *info, int user) 392static int matroxfb_open(struct fb_info *info, int user)
391{ 393{
392 MINFO_FROM_INFO(info); 394 MINFO_FROM_INFO(info);
393 395
394 DBG_LOOP(__FUNCTION__) 396 DBG_LOOP(__FUNCTION__)
395 397
396 if (ACCESS_FBINFO(dead)) { 398 if (ACCESS_FBINFO(dead)) {
@@ -406,7 +408,7 @@ static int matroxfb_open(struct fb_info *info, int user)
406static int matroxfb_release(struct fb_info *info, int user) 408static int matroxfb_release(struct fb_info *info, int user)
407{ 409{
408 MINFO_FROM_INFO(info); 410 MINFO_FROM_INFO(info);
409 411
410 DBG_LOOP(__FUNCTION__) 412 DBG_LOOP(__FUNCTION__)
411 413
412 if (user) { 414 if (user) {
@@ -854,7 +856,7 @@ static int matroxfb_get_vblank(WPMINFO struct fb_vblank *vblank)
854 vblank->flags |= FB_VBLANK_VBLANKING; 856 vblank->flags |= FB_VBLANK_VBLANKING;
855 if (test_bit(0, &ACCESS_FBINFO(irq_flags))) { 857 if (test_bit(0, &ACCESS_FBINFO(irq_flags))) {
856 vblank->flags |= FB_VBLANK_HAVE_COUNT; 858 vblank->flags |= FB_VBLANK_HAVE_COUNT;
857 /* Only one writer, aligned int value... 859 /* Only one writer, aligned int value...
858 it should work without lock and without atomic_t */ 860 it should work without lock and without atomic_t */
859 vblank->count = ACCESS_FBINFO(crtc1).vsync.cnt; 861 vblank->count = ACCESS_FBINFO(crtc1).vsync.cnt;
860 } 862 }
@@ -870,7 +872,7 @@ static int matroxfb_ioctl(struct fb_info *info,
870{ 872{
871 void __user *argp = (void __user *)arg; 873 void __user *argp = (void __user *)arg;
872 MINFO_FROM_INFO(info); 874 MINFO_FROM_INFO(info);
873 875
874 DBG(__FUNCTION__) 876 DBG(__FUNCTION__)
875 877
876 if (ACCESS_FBINFO(dead)) { 878 if (ACCESS_FBINFO(dead)) {
@@ -1081,7 +1083,7 @@ static int matroxfb_ioctl(struct fb_info *info,
1081 case VIDIOC_QUERYCAP: 1083 case VIDIOC_QUERYCAP:
1082 { 1084 {
1083 struct v4l2_capability r; 1085 struct v4l2_capability r;
1084 1086
1085 memset(&r, 0, sizeof(r)); 1087 memset(&r, 0, sizeof(r));
1086 strcpy(r.driver, "matroxfb"); 1088 strcpy(r.driver, "matroxfb");
1087 strcpy(r.card, "Matrox"); 1089 strcpy(r.card, "Matrox");
@@ -1091,7 +1093,7 @@ static int matroxfb_ioctl(struct fb_info *info,
1091 if (copy_to_user(argp, &r, sizeof(r))) 1093 if (copy_to_user(argp, &r, sizeof(r)))
1092 return -EFAULT; 1094 return -EFAULT;
1093 return 0; 1095 return 0;
1094 1096
1095 } 1097 }
1096 case VIDIOC_QUERYCTRL: 1098 case VIDIOC_QUERYCTRL:
1097 { 1099 {
@@ -1690,8 +1692,8 @@ static int initMatrox2(WPMINFO struct board* b){
1690 pci_read_config_dword(ACCESS_FBINFO(pcidev), PCI_COMMAND, &cmd); 1692 pci_read_config_dword(ACCESS_FBINFO(pcidev), PCI_COMMAND, &cmd);
1691 mga_option &= 0x7FFFFFFF; /* clear BIG_ENDIAN */ 1693 mga_option &= 0x7FFFFFFF; /* clear BIG_ENDIAN */
1692 mga_option |= MX_OPTION_BSWAP; 1694 mga_option |= MX_OPTION_BSWAP;
1693 /* disable palette snooping */ 1695 /* disable palette snooping */
1694 cmd &= ~PCI_COMMAND_VGA_PALETTE; 1696 cmd &= ~PCI_COMMAND_VGA_PALETTE;
1695 if (pci_dev_present(intel_82437)) { 1697 if (pci_dev_present(intel_82437)) {
1696 if (!(mga_option & 0x20000000) && !ACCESS_FBINFO(devflags.nopciretry)) { 1698 if (!(mga_option & 0x20000000) && !ACCESS_FBINFO(devflags.nopciretry)) {
1697 printk(KERN_WARNING "matroxfb: Disabling PCI retries due to i82437 present\n"); 1699 printk(KERN_WARNING "matroxfb: Disabling PCI retries due to i82437 present\n");
@@ -1809,12 +1811,12 @@ static int initMatrox2(WPMINFO struct board* b){
1809 1811
1810 if (fv) { 1812 if (fv) {
1811 tmp = fv * (vesafb_defined.upper_margin + vesafb_defined.yres 1813 tmp = fv * (vesafb_defined.upper_margin + vesafb_defined.yres
1812 + vesafb_defined.lower_margin + vesafb_defined.vsync_len); 1814 + vesafb_defined.lower_margin + vesafb_defined.vsync_len);
1813 if ((tmp < fh) || (fh == 0)) fh = tmp; 1815 if ((tmp < fh) || (fh == 0)) fh = tmp;
1814 } 1816 }
1815 if (fh) { 1817 if (fh) {
1816 tmp = fh * (vesafb_defined.left_margin + vesafb_defined.xres 1818 tmp = fh * (vesafb_defined.left_margin + vesafb_defined.xres
1817 + vesafb_defined.right_margin + vesafb_defined.hsync_len); 1819 + vesafb_defined.right_margin + vesafb_defined.hsync_len);
1818 if ((tmp < maxclk) || (maxclk == 0)) maxclk = tmp; 1820 if ((tmp < maxclk) || (maxclk == 0)) maxclk = tmp;
1819 } 1821 }
1820 tmp = (maxclk + 499) / 500; 1822 tmp = (maxclk + 499) / 500;
@@ -1890,14 +1892,14 @@ static int initMatrox2(WPMINFO struct board* b){
1890 1892
1891 /* there is no console on this fb... but we have to initialize hardware 1893 /* there is no console on this fb... but we have to initialize hardware
1892 * until someone tells me what is proper thing to do */ 1894 * until someone tells me what is proper thing to do */
1893 if (!ACCESS_FBINFO(initialized)) { 1895 if (!ACCESS_FBINFO(initialized)) {
1894 printk(KERN_INFO "fb%d: initializing hardware\n", 1896 printk(KERN_INFO "fb%d: initializing hardware\n",
1895 ACCESS_FBINFO(fbcon.node)); 1897 ACCESS_FBINFO(fbcon.node));
1896 /* We have to use FB_ACTIVATE_FORCE, as we had to put vesafb_defined to the fbcon.var 1898 /* We have to use FB_ACTIVATE_FORCE, as we had to put vesafb_defined to the fbcon.var
1897 * already before, so register_framebuffer works correctly. */ 1899 * already before, so register_framebuffer works correctly. */
1898 vesafb_defined.activate |= FB_ACTIVATE_FORCE; 1900 vesafb_defined.activate |= FB_ACTIVATE_FORCE;
1899 fb_set_var(&ACCESS_FBINFO(fbcon), &vesafb_defined); 1901 fb_set_var(&ACCESS_FBINFO(fbcon), &vesafb_defined);
1900 } 1902 }
1901 1903
1902 return 0; 1904 return 0;
1903failVideoIO:; 1905failVideoIO:;
@@ -2356,7 +2358,7 @@ static int __init matroxfb_setup(char *options) {
2356 else if (!strncmp(this_opt, "dfp:", 4)) { 2358 else if (!strncmp(this_opt, "dfp:", 4)) {
2357 dfp_type = simple_strtoul(this_opt+4, NULL, 0); 2359 dfp_type = simple_strtoul(this_opt+4, NULL, 0);
2358 dfp = 1; 2360 dfp = 1;
2359 } 2361 }
2360#ifdef CONFIG_PPC_PMAC 2362#ifdef CONFIG_PPC_PMAC
2361 else if (!strncmp(this_opt, "vmode:", 6)) { 2363 else if (!strncmp(this_opt, "vmode:", 6)) {
2362 unsigned int vmode = simple_strtoul(this_opt+6, NULL, 0); 2364 unsigned int vmode = simple_strtoul(this_opt+6, NULL, 0);