aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-04-27 17:18:45 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-04-27 17:18:45 -0400
commitaa5bc2b58e3344da57f26b62e99e13e91c9e0a94 (patch)
treec6e9ea1b3ee8af88b3a050b3fba160ea2f77e404
parentd868772fff6c4b881d66af8640251714e1aefa98 (diff)
parentd455cf5d0db9e3eb1b204cd4a61d8c5ccfe4305f (diff)
Merge branch 'master' of ssh://master.kernel.org/pub/scm/linux/kernel/git/mchehab/v4l-dvb
* 'master' of ssh://master.kernel.org/pub/scm/linux/kernel/git/mchehab/v4l-dvb: (184 commits) V4L/DVB (5563): Radio-maestro.c Replace radio_ioctl to use video_ioctl2 V4L/DVB (5562): Radio-gemtek-pci.c Replace gemtek_pci_ioctl to use video_ioctl2 V4L/DVB (5560): Ivtv: fix incorrect bitwise-and for command flags. V4L/DVB (5558): Opera: use 7-bit i2c addresses V4L/DVB (5557): Cafe_ccic: check return value of pci_enable_device V4L/DVB (5556): Radio-gemtek.c Replace gemtek_ioctl to use video_ioctl2 V4L/DVB (5555): Radio-aimslab.c Replace rt_ioctl to use video_ioctl2 V4L/DVB (5554): Fix: vidioc_g_parm were not zeroing the memory V4L/DVB (5553): Replace typhoon_do_ioctl to use video_ioctl2 V4L/DVB (5552): Plan-b: Switch to refcounting PCI API V4L/DVB (5551): Plan-b: header change V4L/DVB (5550): Radio-sf16fmi.c Replace fmi_do_ioctl to use video_ioctl2 V4L/DVB (5549): Radio-sf16fmr2.c Replace fmr2_do_ioctl to use video_ioctl2 V4L/DVB (5548): Fix v4l2 buffer to the length V4L/DVB (5547): Add ENUM_FRAMESIZES and ENUM_FRAMEINTERVALS ioctls V4L/DVB (5546): Radio-terratec.c Replace tt_do_ioctl to use video_ioctl2 V4L/DVB (5545): Saa7146: Release capture buffers on device close V4L/DVB (5544): Budget-av: Make inversion setting configurable, add KNC ONE V1.0 card V4L/DVB (5543): Tda10023: Add support for frontend TDA10023 V4L/DVB (5542): Budget-av: Remove polarity switching of the clock for DVB-C ...
-rw-r--r--Documentation/feature-removal-schedule.txt12
-rw-r--r--Documentation/video4linux/CARDLIST.bttv2
-rw-r--r--Documentation/video4linux/CARDLIST.cx882
-rw-r--r--Documentation/video4linux/CARDLIST.ivtv18
-rw-r--r--Documentation/video4linux/CARDLIST.saa71348
-rw-r--r--Documentation/video4linux/CARDLIST.usbvision64
-rw-r--r--Documentation/video4linux/README.ivtv187
-rw-r--r--Documentation/video4linux/cx2341x/fw-decoder-regs.txt12
-rw-r--r--Documentation/video4linux/cx2341x/fw-encoder-api.txt19
-rw-r--r--Documentation/video4linux/cx2341x/fw-osd-api.txt12
-rw-r--r--Documentation/video4linux/sn9c102.txt64
-rw-r--r--Documentation/video4linux/zr364xx.txt65
-rw-r--r--MAINTAINERS46
-rw-r--r--drivers/media/common/ir-keymaps.c18
-rw-r--r--drivers/media/common/saa7146_video.c6
-rw-r--r--drivers/media/dvb/b2c2/Kconfig1
-rw-r--r--drivers/media/dvb/b2c2/flexcop-fe-tuner.c3
-rw-r--r--drivers/media/dvb/b2c2/flexcop-pci.c9
-rw-r--r--drivers/media/dvb/bt8xx/Kconfig2
-rw-r--r--drivers/media/dvb/bt8xx/bt878.c4
-rw-r--r--drivers/media/dvb/bt8xx/dvb-bt8xx.c3
-rw-r--r--drivers/media/dvb/bt8xx/dvb-bt8xx.h2
-rw-r--r--drivers/media/dvb/dvb-core/dmxdev.c56
-rw-r--r--drivers/media/dvb/dvb-core/dmxdev.h2
-rw-r--r--drivers/media/dvb/dvb-core/dvb_frontend.c20
-rw-r--r--drivers/media/dvb/dvb-core/dvb_net.c32
-rw-r--r--drivers/media/dvb/dvb-core/dvb_net.h1
-rw-r--r--drivers/media/dvb/dvb-core/dvbdev.c1
-rw-r--r--drivers/media/dvb/dvb-core/dvbdev.h1
-rw-r--r--drivers/media/dvb/dvb-usb/Kconfig12
-rw-r--r--drivers/media/dvb/dvb-usb/Makefile4
-rw-r--r--drivers/media/dvb/dvb-usb/au6610.c6
-rw-r--r--drivers/media/dvb/dvb-usb/cxusb.c4
-rw-r--r--drivers/media/dvb/dvb-usb/dib0700_core.c4
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-ids.h6
-rw-r--r--drivers/media/dvb/dvb-usb/gl861.c8
-rw-r--r--drivers/media/dvb/dvb-usb/m920x.c235
-rw-r--r--drivers/media/dvb/dvb-usb/m920x.h46
-rw-r--r--drivers/media/dvb/dvb-usb/opera1.c581
-rw-r--r--drivers/media/dvb/dvb-usb/opera1.h9
-rw-r--r--drivers/media/dvb/dvb-usb/ttusb2.c7
-rw-r--r--drivers/media/dvb/frontends/Kconfig28
-rw-r--r--drivers/media/dvb/frontends/Makefile3
-rw-r--r--drivers/media/dvb/frontends/dvb-pll.c340
-rw-r--r--drivers/media/dvb/frontends/dvb-pll.h16
-rw-r--r--drivers/media/dvb/frontends/lgdt330x.c4
-rw-r--r--drivers/media/dvb/frontends/lgh06xf.c134
-rw-r--r--drivers/media/dvb/frontends/lgh06xf.h35
-rw-r--r--drivers/media/dvb/frontends/or51132.c305
-rw-r--r--drivers/media/dvb/frontends/tda10021.c47
-rw-r--r--drivers/media/dvb/frontends/tda10023.c540
-rw-r--r--drivers/media/dvb/frontends/tda1002x.h (renamed from drivers/media/dvb/frontends/tda10021.h)33
-rw-r--r--drivers/media/dvb/frontends/tda1004x.c98
-rw-r--r--drivers/media/dvb/frontends/tda1004x.h54
-rw-r--r--drivers/media/dvb/frontends/tda827x.c512
-rw-r--r--drivers/media/dvb/frontends/tda827x.h62
-rw-r--r--drivers/media/dvb/pluto2/Kconfig1
-rw-r--r--drivers/media/dvb/ttpci/Kconfig6
-rw-r--r--drivers/media/dvb/ttpci/av7110.c17
-rw-r--r--drivers/media/dvb/ttpci/av7110.h28
-rw-r--r--drivers/media/dvb/ttpci/av7110_av.c24
-rw-r--r--drivers/media/dvb/ttpci/av7110_hw.h10
-rw-r--r--drivers/media/dvb/ttpci/av7110_ir.c365
-rw-r--r--drivers/media/dvb/ttpci/budget-av.c147
-rw-r--r--drivers/media/dvb/ttpci/budget-ci.c96
-rw-r--r--drivers/media/dvb/ttpci/budget-core.c58
-rw-r--r--drivers/media/dvb/ttpci/budget.h3
-rw-r--r--drivers/media/dvb/ttusb-budget/Kconfig1
-rw-r--r--drivers/media/radio/radio-aimslab.c240
-rw-r--r--drivers/media/radio/radio-gemtek-pci.c253
-rw-r--r--drivers/media/radio/radio-gemtek.c260
-rw-r--r--drivers/media/radio/radio-maestro.c266
-rw-r--r--drivers/media/radio/radio-rtrack2.c255
-rw-r--r--drivers/media/radio/radio-sf16fmi.c262
-rw-r--r--drivers/media/radio/radio-sf16fmr2.c350
-rw-r--r--drivers/media/radio/radio-terratec.c247
-rw-r--r--drivers/media/radio/radio-trust.c256
-rw-r--r--drivers/media/radio/radio-typhoon.c239
-rw-r--r--drivers/media/radio/radio-zoltrix.c256
-rw-r--r--drivers/media/video/Kconfig14
-rw-r--r--drivers/media/video/Makefile2
-rw-r--r--drivers/media/video/bt8xx/bttv-cards.c53
-rw-r--r--drivers/media/video/bt8xx/bttv-driver.c24
-rw-r--r--drivers/media/video/bt8xx/bttv-gpio.c5
-rw-r--r--drivers/media/video/bt8xx/bttv-i2c.c2
-rw-r--r--drivers/media/video/bt8xx/bttv-if.c48
-rw-r--r--drivers/media/video/bt8xx/bttv.h25
-rw-r--r--drivers/media/video/bt8xx/bttvp.h3
-rw-r--r--drivers/media/video/cafe_ccic.c79
-rw-r--r--drivers/media/video/cpia_pp.c49
-rw-r--r--drivers/media/video/cs53l32a.c4
-rw-r--r--drivers/media/video/cx2341x.c72
-rw-r--r--drivers/media/video/cx25840/cx25840-core.c9
-rw-r--r--drivers/media/video/cx25840/cx25840-core.h3
-rw-r--r--drivers/media/video/cx25840/cx25840-firmware.c1
-rw-r--r--drivers/media/video/cx88/Kconfig1
-rw-r--r--drivers/media/video/cx88/cx88-alsa.c9
-rw-r--r--drivers/media/video/cx88/cx88-cards.c37
-rw-r--r--drivers/media/video/cx88/cx88-core.c8
-rw-r--r--drivers/media/video/cx88/cx88-dvb.c31
-rw-r--r--drivers/media/video/cx88/cx88-i2c.c3
-rw-r--r--drivers/media/video/cx88/cx88-mpeg.c29
-rw-r--r--drivers/media/video/cx88/cx88-video.c5
-rw-r--r--drivers/media/video/cx88/cx88.h4
-rw-r--r--drivers/media/video/em28xx/em28xx-i2c.c2
-rw-r--r--drivers/media/video/ir-kbd-i2c.c2
-rw-r--r--drivers/media/video/ivtv/Kconfig26
-rw-r--r--drivers/media/video/ivtv/Makefile7
-rw-r--r--drivers/media/video/ivtv/ivtv-audio.c74
-rw-r--r--drivers/media/video/ivtv/ivtv-audio.h23
-rw-r--r--drivers/media/video/ivtv/ivtv-cards.c964
-rw-r--r--drivers/media/video/ivtv/ivtv-cards.h207
-rw-r--r--drivers/media/video/ivtv/ivtv-controls.c303
-rw-r--r--drivers/media/video/ivtv/ivtv-controls.h21
-rw-r--r--drivers/media/video/ivtv/ivtv-driver.c1374
-rw-r--r--drivers/media/video/ivtv/ivtv-driver.h868
-rw-r--r--drivers/media/video/ivtv/ivtv-fileops.c921
-rw-r--r--drivers/media/video/ivtv/ivtv-fileops.h44
-rw-r--r--drivers/media/video/ivtv/ivtv-firmware.c272
-rw-r--r--drivers/media/video/ivtv/ivtv-firmware.h25
-rw-r--r--drivers/media/video/ivtv/ivtv-gpio.c307
-rw-r--r--drivers/media/video/ivtv/ivtv-gpio.h25
-rw-r--r--drivers/media/video/ivtv/ivtv-i2c.c748
-rw-r--r--drivers/media/video/ivtv/ivtv-i2c.h36
-rw-r--r--drivers/media/video/ivtv/ivtv-ioctl.c1567
-rw-r--r--drivers/media/video/ivtv/ivtv-ioctl.h28
-rw-r--r--drivers/media/video/ivtv/ivtv-irq.c838
-rw-r--r--drivers/media/video/ivtv/ivtv-irq.h26
-rw-r--r--drivers/media/video/ivtv/ivtv-mailbox.c360
-rw-r--r--drivers/media/video/ivtv/ivtv-mailbox.h25
-rw-r--r--drivers/media/video/ivtv/ivtv-queue.c262
-rw-r--r--drivers/media/video/ivtv/ivtv-queue.h64
-rw-r--r--drivers/media/video/ivtv/ivtv-streams.c977
-rw-r--r--drivers/media/video/ivtv/ivtv-streams.h31
-rw-r--r--drivers/media/video/ivtv/ivtv-udma.c200
-rw-r--r--drivers/media/video/ivtv/ivtv-udma.h43
-rw-r--r--drivers/media/video/ivtv/ivtv-vbi.c538
-rw-r--r--drivers/media/video/ivtv/ivtv-vbi.h26
-rw-r--r--drivers/media/video/ivtv/ivtv-version.h26
-rw-r--r--drivers/media/video/ivtv/ivtv-video.c142
-rw-r--r--drivers/media/video/ivtv/ivtv-video.h24
-rw-r--r--drivers/media/video/ivtv/ivtv-yuv.c1129
-rw-r--r--drivers/media/video/ivtv/ivtv-yuv.h24
-rw-r--r--drivers/media/video/msp3400-driver.c5
-rw-r--r--drivers/media/video/msp3400-driver.h1
-rw-r--r--drivers/media/video/ov7670.c40
-rw-r--r--drivers/media/video/planb.c6
-rw-r--r--drivers/media/video/planb.h1
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-encoder.c2
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h2
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-hdw.c16
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-hdw.h3
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-sysfs.c30
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-v4l2.c2
-rw-r--r--drivers/media/video/pwc/pwc-ctrl.c61
-rw-r--r--drivers/media/video/pwc/pwc-if.c16
-rw-r--r--drivers/media/video/pwc/pwc-ioctl.h36
-rw-r--r--drivers/media/video/pwc/pwc-kiara.c2
-rw-r--r--drivers/media/video/pwc/pwc-kiara.h5
-rw-r--r--drivers/media/video/pwc/pwc-timon.c4
-rw-r--r--drivers/media/video/pwc/pwc-timon.h6
-rw-r--r--drivers/media/video/pwc/pwc-v4l.c60
-rw-r--r--drivers/media/video/pwc/pwc.h5
-rw-r--r--drivers/media/video/saa7115.c10
-rw-r--r--drivers/media/video/saa7127.c12
-rw-r--r--drivers/media/video/saa7134/Kconfig1
-rw-r--r--drivers/media/video/saa7134/saa7134-cards.c204
-rw-r--r--drivers/media/video/saa7134/saa7134-core.c125
-rw-r--r--drivers/media/video/saa7134/saa7134-dvb.c1027
-rw-r--r--drivers/media/video/saa7134/saa7134-i2c.c4
-rw-r--r--drivers/media/video/saa7134/saa7134-input.c1
-rw-r--r--drivers/media/video/saa7134/saa7134-video.c85
-rw-r--r--drivers/media/video/saa7134/saa7134.h10
-rw-r--r--drivers/media/video/se401.c36
-rw-r--r--drivers/media/video/sn9c102/Kconfig2
-rw-r--r--drivers/media/video/sn9c102/Makefile17
-rw-r--r--drivers/media/video/sn9c102/sn9c102.h17
-rw-r--r--drivers/media/video/sn9c102/sn9c102_core.c274
-rw-r--r--drivers/media/video/sn9c102/sn9c102_devtable.h14
-rw-r--r--drivers/media/video/sn9c102/sn9c102_hv7131d.c25
-rw-r--r--drivers/media/video/sn9c102/sn9c102_hv7131r.c366
-rw-r--r--drivers/media/video/sn9c102/sn9c102_mi0343.c130
-rw-r--r--drivers/media/video/sn9c102/sn9c102_mi0360.c338
-rw-r--r--drivers/media/video/sn9c102/sn9c102_ov7630.c121
-rw-r--r--drivers/media/video/sn9c102/sn9c102_ov7660.c234
-rw-r--r--drivers/media/video/sn9c102/sn9c102_pas106b.c23
-rw-r--r--drivers/media/video/sn9c102/sn9c102_pas202bcb.c77
-rw-r--r--drivers/media/video/sn9c102/sn9c102_sensor.h12
-rw-r--r--drivers/media/video/sn9c102/sn9c102_tas5110c1b.c18
-rw-r--r--drivers/media/video/sn9c102/sn9c102_tas5110d.c118
-rw-r--r--drivers/media/video/sn9c102/sn9c102_tas5130d1b.c19
-rw-r--r--drivers/media/video/tda7432.c1
-rw-r--r--drivers/media/video/tda8290.c144
-rw-r--r--drivers/media/video/tda9875.c1
-rw-r--r--drivers/media/video/tuner-core.c28
-rw-r--r--drivers/media/video/tvaudio.c5
-rw-r--r--drivers/media/video/tveeprom.c45
-rw-r--r--drivers/media/video/upd64031a.c4
-rw-r--r--drivers/media/video/upd64083.c5
-rw-r--r--drivers/media/video/usbvideo/usbvideo.c18
-rw-r--r--drivers/media/video/usbvision/usbvision-cards.c1165
-rw-r--r--drivers/media/video/usbvision/usbvision-cards.h66
-rw-r--r--drivers/media/video/usbvision/usbvision-core.c10
-rw-r--r--drivers/media/video/usbvision/usbvision-i2c.c104
-rw-r--r--drivers/media/video/usbvision/usbvision-video.c173
-rw-r--r--drivers/media/video/usbvision/usbvision.h39
-rw-r--r--drivers/media/video/v4l2-common.c41
-rw-r--r--drivers/media/video/videocodec.c3
-rw-r--r--drivers/media/video/videodev.c40
-rw-r--r--drivers/media/video/wm8739.c4
-rw-r--r--drivers/media/video/wm8775.c4
-rw-r--r--drivers/media/video/zr364xx.c929
-rw-r--r--include/linux/dvb/audio.h5
-rw-r--r--include/linux/dvb/version.h2
-rw-r--r--include/linux/dvb/video.h62
-rw-r--r--include/linux/videodev2.h83
-rw-r--r--include/media/cx2341x.h6
-rw-r--r--include/media/ivtv.h65
-rw-r--r--include/media/tuner.h5
-rw-r--r--include/media/v4l2-chip-ident.h149
-rw-r--r--include/media/v4l2-common.h47
-rw-r--r--include/media/v4l2-dev.h10
222 files changed, 23073 insertions, 4357 deletions
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
index ec0b4843b1cb..5c88ba1ea262 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -6,6 +6,18 @@ be removed from this file.
6 6
7--------------------------- 7---------------------------
8 8
9What: V4L2 VIDIOC_G_MPEGCOMP and VIDIOC_S_MPEGCOMP
10When: October 2007
11Why: Broken attempt to set MPEG compression parameters. These ioctls are
12 not able to implement the wide variety of parameters that can be set
13 by hardware MPEG encoders. A new MPEG control mechanism was created
14 in kernel 2.6.18 that replaces these ioctls. See the V4L2 specification
15 (section 1.9: Extended controls) for more information on this topic.
16Who: Hans Verkuil <hverkuil@xs4all.nl> and
17 Mauro Carvalho Chehab <mchehab@infradead.org>
18
19---------------------------
20
9What: /sys/devices/.../power/state 21What: /sys/devices/.../power/state
10 dev->power.power_state 22 dev->power.power_state
11 dpm_runtime_{suspend,resume)() 23 dpm_runtime_{suspend,resume)()
diff --git a/Documentation/video4linux/CARDLIST.bttv b/Documentation/video4linux/CARDLIST.bttv
index fc2fe9bc6713..b60639130a51 100644
--- a/Documentation/video4linux/CARDLIST.bttv
+++ b/Documentation/video4linux/CARDLIST.bttv
@@ -143,3 +143,5 @@
143142 -> Sabrent TV-FM (bttv version) 143142 -> Sabrent TV-FM (bttv version)
144143 -> Hauppauge ImpactVCB (bt878) [0070:13eb] 144143 -> Hauppauge ImpactVCB (bt878) [0070:13eb]
145144 -> MagicTV 145144 -> MagicTV
146145 -> SSAI Security Video Interface [4149:5353]
147146 -> SSAI Ultrasound Video Interface [414a:5353]
diff --git a/Documentation/video4linux/CARDLIST.cx88 b/Documentation/video4linux/CARDLIST.cx88
index 62e32b49cec9..60f838beb9c8 100644
--- a/Documentation/video4linux/CARDLIST.cx88
+++ b/Documentation/video4linux/CARDLIST.cx88
@@ -37,7 +37,7 @@
37 36 -> AVerTV 303 (M126) [1461:000a] 37 36 -> AVerTV 303 (M126) [1461:000a]
38 37 -> Hauppauge Nova-S-Plus DVB-S [0070:9201,0070:9202] 38 37 -> Hauppauge Nova-S-Plus DVB-S [0070:9201,0070:9202]
39 38 -> Hauppauge Nova-SE2 DVB-S [0070:9200] 39 38 -> Hauppauge Nova-SE2 DVB-S [0070:9200]
40 39 -> KWorld DVB-S 100 [17de:08b2] 40 39 -> KWorld DVB-S 100 [17de:08b2,1421:0341]
41 40 -> Hauppauge WinTV-HVR1100 DVB-T/Hybrid [0070:9400,0070:9402] 41 40 -> Hauppauge WinTV-HVR1100 DVB-T/Hybrid [0070:9400,0070:9402]
42 41 -> Hauppauge WinTV-HVR1100 DVB-T/Hybrid (Low Profile) [0070:9800,0070:9802] 42 41 -> Hauppauge WinTV-HVR1100 DVB-T/Hybrid (Low Profile) [0070:9800,0070:9802]
43 42 -> digitalnow DNTV Live! DVB-T Pro [1822:0025,1822:0019] 43 42 -> digitalnow DNTV Live! DVB-T Pro [1822:0025,1822:0019]
diff --git a/Documentation/video4linux/CARDLIST.ivtv b/Documentation/video4linux/CARDLIST.ivtv
new file mode 100644
index 000000000000..ddd76a0eb100
--- /dev/null
+++ b/Documentation/video4linux/CARDLIST.ivtv
@@ -0,0 +1,18 @@
1 1 -> Hauppauge WinTV PVR-250
2 2 -> Hauppauge WinTV PVR-350
3 3 -> Hauppauge WinTV PVR-150 or PVR-500
4 4 -> AVerMedia M179 [1461:a3ce,1461:a3cf]
5 5 -> Yuan MPG600/Kuroutoshikou iTVC16-STVLP [12ab:fff3,12ab:ffff]
6 6 -> Yuan MPG160/Kuroutoshikou iTVC15-STVLP [12ab:0000,10fc:40a0]
7 7 -> Yuan PG600/DiamondMM PVR-550 [ff92:0070,ffab:0600]
8 8 -> Adaptec AVC-2410 [9005:0093]
9 9 -> Adaptec AVC-2010 [9005:0092]
1010 -> NAGASE TRANSGEAR 5000TV [1461:bfff]
1111 -> AOpen VA2000MAX-STN6 [0000:ff5f]
1212 -> YUAN MPG600GR/Kuroutoshikou CX23416GYC-STVLP [12ab:0600,fbab:0600,1154:0523]
1313 -> I/O Data GV-MVP/RX [10fc:d01e,10fc:d038,10fc:d039]
1414 -> I/O Data GV-MVP/RX2E [10fc:d025]
1515 -> GOTVIEW PCI DVD (partial support only) [12ab:0600]
1616 -> GOTVIEW PCI DVD2 Deluxe [ffac:0600]
1717 -> Yuan MPC622 [ff01:d998]
1818 -> Digital Cowboy DCT-MTVP1 [1461:bfff]
diff --git a/Documentation/video4linux/CARDLIST.saa7134 b/Documentation/video4linux/CARDLIST.saa7134
index a12246a9bf23..d7bb2e2e4d9b 100644
--- a/Documentation/video4linux/CARDLIST.saa7134
+++ b/Documentation/video4linux/CARDLIST.saa7134
@@ -53,7 +53,7 @@
53 52 -> AverMedia AverTV/305 [1461:2108] 53 52 -> AverMedia AverTV/305 [1461:2108]
54 53 -> ASUS TV-FM 7135 [1043:4845] 54 53 -> ASUS TV-FM 7135 [1043:4845]
55 54 -> LifeView FlyTV Platinum FM / Gold [5168:0214,1489:0214,5168:0304] 55 54 -> LifeView FlyTV Platinum FM / Gold [5168:0214,1489:0214,5168:0304]
56 55 -> LifeView FlyDVB-T DUO [5168:0306] 56 55 -> LifeView FlyDVB-T DUO / MSI TV@nywhere Duo [5168:0306,4E42:0306]
57 56 -> Avermedia AVerTV 307 [1461:a70a] 57 56 -> Avermedia AVerTV 307 [1461:a70a]
58 57 -> Avermedia AVerTV GO 007 FM [1461:f31f] 58 57 -> Avermedia AVerTV GO 007 FM [1461:f31f]
59 58 -> ADS Tech Instant TV (saa7135) [1421:0350,1421:0351,1421:0370,1421:1370] 59 58 -> ADS Tech Instant TV (saa7135) [1421:0350,1421:0351,1421:0370,1421:1370]
@@ -76,7 +76,7 @@
76 75 -> AVerMedia AVerTVHD MCE A180 [1461:1044] 76 75 -> AVerMedia AVerTVHD MCE A180 [1461:1044]
77 76 -> SKNet MonsterTV Mobile [1131:4ee9] 77 76 -> SKNet MonsterTV Mobile [1131:4ee9]
78 77 -> Pinnacle PCTV 40i/50i/110i (saa7133) [11bd:002e] 78 77 -> Pinnacle PCTV 40i/50i/110i (saa7133) [11bd:002e]
79 78 -> ASUSTeK P7131 Dual [1043:4862,1043:4876] 79 78 -> ASUSTeK P7131 Dual [1043:4862,1043:4857]
80 79 -> Sedna/MuchTV PC TV Cardbus TV/Radio (ITO25 Rev:2B) 80 79 -> Sedna/MuchTV PC TV Cardbus TV/Radio (ITO25 Rev:2B)
81 80 -> ASUS Digimatrix TV [1043:0210] 81 80 -> ASUS Digimatrix TV [1043:0210]
82 81 -> Philips Tiger reference design [1131:2018] 82 81 -> Philips Tiger reference design [1131:2018]
@@ -107,3 +107,7 @@
107106 -> Encore ENLTV [1131:2342,1131:2341,3016:2344] 107106 -> Encore ENLTV [1131:2342,1131:2341,3016:2344]
108107 -> Encore ENLTV-FM [1131:230f] 108107 -> Encore ENLTV-FM [1131:230f]
109108 -> Terratec Cinergy HT PCI [153b:1175] 109108 -> Terratec Cinergy HT PCI [153b:1175]
110109 -> Philips Tiger - S Reference design
111110 -> Avermedia M102 [1461:f31e]
112111 -> ASUS P7131 4871 [1043:4871]
113112 -> ASUSTeK P7131 Hybrid [1043:4876]
diff --git a/Documentation/video4linux/CARDLIST.usbvision b/Documentation/video4linux/CARDLIST.usbvision
new file mode 100644
index 000000000000..3d6850ef0245
--- /dev/null
+++ b/Documentation/video4linux/CARDLIST.usbvision
@@ -0,0 +1,64 @@
1 0 -> Xanboo [0a6f:0400]
2 1 -> Belkin USB VideoBus II Adapter [050d:0106]
3 2 -> Belkin Components USB VideoBus [050d:0207]
4 3 -> Belkin USB VideoBus II [050d:0208]
5 4 -> echoFX InterView Lite [0571:0002]
6 5 -> USBGear USBG-V1 resp. HAMA USB [0573:0003]
7 6 -> D-Link V100 [0573:0400]
8 7 -> X10 USB Camera [0573:2000]
9 8 -> Hauppauge WinTV USB Live (PAL B/G) [0573:2d00]
10 9 -> Hauppauge WinTV USB Live Pro (NTSC M/N) [0573:2d01]
11 10 -> Zoran Co. PMD (Nogatech) AV-grabber Manhattan [0573:2101]
12 11 -> Nogatech USB-TV (NTSC) FM [0573:4100]
13 12 -> PNY USB-TV (NTSC) FM [0573:4110]
14 13 -> PixelView PlayTv-USB PRO (PAL) FM [0573:4450]
15 14 -> ZTV ZT-721 2.4GHz USB A/V Receiver [0573:4550]
16 15 -> Hauppauge WinTV USB (NTSC M/N) [0573:4d00]
17 16 -> Hauppauge WinTV USB (PAL B/G) [0573:4d01]
18 17 -> Hauppauge WinTV USB (PAL I) [0573:4d02]
19 18 -> Hauppauge WinTV USB (PAL/SECAM L) [0573:4d03]
20 19 -> Hauppauge WinTV USB (PAL D/K) [0573:4d04]
21 20 -> Hauppauge WinTV USB (NTSC FM) [0573:4d10]
22 21 -> Hauppauge WinTV USB (PAL B/G FM) [0573:4d11]
23 22 -> Hauppauge WinTV USB (PAL I FM) [0573:4d12]
24 23 -> Hauppauge WinTV USB (PAL D/K FM) [0573:4d14]
25 24 -> Hauppauge WinTV USB Pro (NTSC M/N) [0573:4d2a]
26 25 -> Hauppauge WinTV USB Pro (NTSC M/N) V2 [0573:4d2b]
27 26 -> Hauppauge WinTV USB Pro (PAL/SECAM B/G/I/D/K/L) [0573:4d2c]
28 27 -> Hauppauge WinTV USB Pro (NTSC M/N) V3 [0573:4d20]
29 28 -> Hauppauge WinTV USB Pro (PAL B/G) [0573:4d21]
30 29 -> Hauppauge WinTV USB Pro (PAL I) [0573:4d22]
31 30 -> Hauppauge WinTV USB Pro (PAL/SECAM L) [0573:4d23]
32 31 -> Hauppauge WinTV USB Pro (PAL D/K) [0573:4d24]
33 32 -> Hauppauge WinTV USB Pro (PAL/SECAM BGDK/I/L) [0573:4d25]
34 33 -> Hauppauge WinTV USB Pro (PAL/SECAM BGDK/I/L) V2 [0573:4d26]
35 34 -> Hauppauge WinTV USB Pro (PAL B/G) V2 [0573:4d27]
36 35 -> Hauppauge WinTV USB Pro (PAL B/G,D/K) [0573:4d28]
37 36 -> Hauppauge WinTV USB Pro (PAL I,D/K) [0573:4d29]
38 37 -> Hauppauge WinTV USB Pro (NTSC M/N FM) [0573:4d30]
39 38 -> Hauppauge WinTV USB Pro (PAL B/G FM) [0573:4d31]
40 39 -> Hauppauge WinTV USB Pro (PAL I FM) [0573:4d32]
41 40 -> Hauppauge WinTV USB Pro (PAL D/K FM) [0573:4d34]
42 41 -> Hauppauge WinTV USB Pro (Temic PAL/SECAM B/G/I/D/K/L FM) [0573:4d35]
43 42 -> Hauppauge WinTV USB Pro (Temic PAL B/G FM) [0573:4d36]
44 43 -> Hauppauge WinTV USB Pro (PAL/SECAM B/G/I/D/K/L FM) [0573:4d37]
45 44 -> Hauppauge WinTV USB Pro (NTSC M/N FM) V2 [0573:4d38]
46 45 -> Camtel Technology USB TV Genie Pro FM Model TVB330 [0768:0006]
47 46 -> Digital Video Creator I [07d0:0001]
48 47 -> Global Village GV-007 (NTSC) [07d0:0002]
49 48 -> Dazzle Fusion Model DVC-50 Rev 1 (NTSC) [07d0:0003]
50 49 -> Dazzle Fusion Model DVC-80 Rev 1 (PAL) [07d0:0004]
51 50 -> Dazzle Fusion Model DVC-90 Rev 1 (SECAM) [07d0:0005]
52 51 -> Eskape Labs MyTV2Go [07f8:9104]
53 52 -> Pinnacle Studio PCTV USB (PAL) [2304:010d]
54 53 -> Pinnacle Studio PCTV USB (SECAM) [2304:0109]
55 54 -> Pinnacle Studio PCTV USB (PAL) FM [2304:0110]
56 55 -> Miro PCTV USB [2304:0111]
57 56 -> Pinnacle Studio PCTV USB (NTSC) FM [2304:0112]
58 57 -> Pinnacle Studio PCTV USB (PAL) FM V2 [2304:0210]
59 58 -> Pinnacle Studio PCTV USB (NTSC) FM V2 [2304:0212]
60 59 -> Pinnacle Studio PCTV USB (PAL) FM V3 [2304:0214]
61 60 -> Pinnacle Studio Linx Video input cable (NTSC) [2304:0300]
62 61 -> Pinnacle Studio Linx Video input cable (PAL) [2304:0301]
63 62 -> Pinnacle PCTV Bungee USB (PAL) FM [2304:0419]
64 63 -> Hauppauge WinTv-USB [2400:4200]
diff --git a/Documentation/video4linux/README.ivtv b/Documentation/video4linux/README.ivtv
new file mode 100644
index 000000000000..73df22c40bfe
--- /dev/null
+++ b/Documentation/video4linux/README.ivtv
@@ -0,0 +1,187 @@
1
2ivtv release notes
3==================
4
5This is a v4l2 device driver for the Conexant cx23415/6 MPEG encoder/decoder.
6The cx23415 can do both encoding and decoding, the cx23416 can only do MPEG
7encoding. Currently the only card featuring full decoding support is the
8Hauppauge PVR-350.
9
10NOTE: this driver requires the latest encoder firmware (version 2.06.039, size
11376836 bytes). Get the firmware from here:
12
13http://dl.ivtvdriver.org/ivtv/firmware/firmware.tar.gz
14
15NOTE: 'normal' TV applications do not work with this driver, you need
16an application that can handle MPEG input such as mplayer, xine, MythTV,
17etc.
18
19The primary goal of the IVTV project is to provide a "clean room" Linux
20Open Source driver implementation for video capture cards based on the
21iCompression iTVC15 or Conexant CX23415/CX23416 MPEG Codec.
22
23Features:
24 * Hardware mpeg2 capture of broadcast video (and sound) via the tuner or
25 S-Video/Composite and audio line-in.
26 * Hardware mpeg2 capture of FM radio where hardware support exists
27 * Supports NTSC, PAL, SECAM with stereo sound
28 * Supports SAP and bilingual transmissions.
29 * Supports raw VBI (closed captions and teletext).
30 * Supports sliced VBI (closed captions and teletext) and is able to insert
31 this into the captured MPEG stream.
32 * Supports raw YUV and PCM input.
33
34Additional features for the PVR-350 (CX23415 based):
35 * Provides hardware mpeg2 playback
36 * Provides comprehensive OSD (On Screen Display: ie. graphics overlaying the
37 video signal)
38 * Provides a framebuffer (allowing X applications to appear on the video
39 device) (this framebuffer is not yet part of the kernel. In the meantime it
40 is available from www.ivtvdriver.org).
41 * Supports raw YUV output.
42
43IMPORTANT: In case of problems first read this page:
44 http://www.ivtvdriver.org/index.php/Troubleshooting
45
46See also:
47
48Homepage + Wiki
49http://www.ivtvdriver.org
50
51IRC
52irc://irc.freenode.net/ivtv-dev
53
54----------------------------------------------------------
55
56Devices
57=======
58
59A maximum of 12 ivtv boards are allowed at the moment.
60
61Cards that don't have a video output capability (i.e. non PVR350 cards)
62lack the vbi8, vbi16, video16 and video48 devices. They also do not
63support the framebuffer device /dev/fbx for OSD.
64
65The radio0 device may or may not be present, depending on whether the
66card has a radio tuner or not.
67
68Here is a list of the base v4l devices:
69crw-rw---- 1 root video 81, 0 Jun 19 22:22 /dev/video0
70crw-rw---- 1 root video 81, 16 Jun 19 22:22 /dev/video16
71crw-rw---- 1 root video 81, 24 Jun 19 22:22 /dev/video24
72crw-rw---- 1 root video 81, 32 Jun 19 22:22 /dev/video32
73crw-rw---- 1 root video 81, 48 Jun 19 22:22 /dev/video48
74crw-rw---- 1 root video 81, 64 Jun 19 22:22 /dev/radio0
75crw-rw---- 1 root video 81, 224 Jun 19 22:22 /dev/vbi0
76crw-rw---- 1 root video 81, 228 Jun 19 22:22 /dev/vbi8
77crw-rw---- 1 root video 81, 232 Jun 19 22:22 /dev/vbi16
78
79Base devices
80============
81
82For every extra card you have the numbers increased by one. For example,
83/dev/video0 is listed as the 'base' encoding capture device so we have:
84
85 /dev/video0 is the encoding capture device for the first card (card 0)
86 /dev/video1 is the encoding capture device for the second card (card 1)
87 /dev/video2 is the encoding capture device for the third card (card 2)
88
89Note that if the first card doesn't have a feature (eg no decoder, so no
90video16, the second card will still use video17. The simple rule is 'add
91the card number to the base device number'. If you have other capture
92cards (e.g. WinTV PCI) that are detected first, then you have to tell
93the ivtv module about it so that it will start counting at 1 (or 2, or
94whatever). Otherwise the device numbers can get confusing. The ivtv
95'ivtv_first_minor' module option can be used for that.
96
97
98/dev/video0
99The encoding capture device(s).
100Read-only.
101
102Reading from this device gets you the MPEG1/2 program stream.
103Example:
104
105cat /dev/video0 > my.mpg (you need to hit ctrl-c to exit)
106
107
108/dev/video16
109The decoder output device(s)
110Write-only. Only present if the MPEG decoder (i.e. CX23415) exists.
111
112An mpeg2 stream sent to this device will appear on the selected video
113display, audio will appear on the line-out/audio out. It is only
114available for cards that support video out. Example:
115
116cat my.mpg >/dev/video16
117
118
119/dev/video24
120The raw audio capture device(s).
121Read-only
122
123The raw audio PCM stereo stream from the currently selected
124tuner or audio line-in. Reading from this device results in a raw
125(signed 16 bit Little Endian, 48000 Hz, stereo pcm) capture.
126This device only captures audio. This should be replaced by an ALSA
127device in the future.
128Note that there is no corresponding raw audio output device, this is
129not supported in the decoder firmware.
130
131
132/dev/video32
133The raw video capture device(s)
134Read-only
135
136The raw YUV video output from the current video input. The YUV format
137is non-standard (V4L2_PIX_FMT_HM12).
138
139Note that the YUV and PCM streams are not synchronized, so they are of
140limited use.
141
142
143/dev/video48
144The raw video display device(s)
145Write-only. Only present if the MPEG decoder (i.e. CX23415) exists.
146
147Writes a YUV stream to the decoder of the card.
148
149
150/dev/radio0
151The radio tuner device(s)
152Cannot be read or written.
153
154Used to enable the radio tuner and tune to a frequency. You cannot
155read or write audio streams with this device. Once you use this
156device to tune the radio, use /dev/video24 to read the raw pcm stream
157or /dev/video0 to get an mpeg2 stream with black video.
158
159
160/dev/vbi0
161The 'vertical blank interval' (Teletext, CC, WSS etc) capture device(s)
162Read-only
163
164Captures the raw (or sliced) video data sent during the Vertical Blank
165Interval. This data is used to encode teletext, closed captions, VPS,
166widescreen signalling, electronic program guide information, and other
167services.
168
169
170/dev/vbi8
171Processed vbi feedback device(s)
172Read-only. Only present if the MPEG decoder (i.e. CX23415) exists.
173
174The sliced VBI data embedded in an MPEG stream is reproduced on this
175device. So while playing back a recording on /dev/video16, you can
176read the embedded VBI data from /dev/vbi8.
177
178
179/dev/vbi16
180The vbi 'display' device(s)
181Write-only. Only present if the MPEG decoder (i.e. CX23415) exists.
182
183Can be used to send sliced VBI data to the video-out connector.
184
185---------------------------------
186
187Hans Verkuil <hverkuil@xs4all.nl>
diff --git a/Documentation/video4linux/cx2341x/fw-decoder-regs.txt b/Documentation/video4linux/cx2341x/fw-decoder-regs.txt
index db2366c634e8..cf52c8f20b9e 100644
--- a/Documentation/video4linux/cx2341x/fw-decoder-regs.txt
+++ b/Documentation/video4linux/cx2341x/fw-decoder-regs.txt
@@ -624,11 +624,11 @@ out what values are bad when it hangs.
6242A00 6242A00
625 bits 0:2 625 bits 0:2
626 osd colour mode 626 osd colour mode
627 000 = 8 bit indexed
627 001 = 16 bit (565) 628 001 = 16 bit (565)
628 010 = 15 bit (555) 629 010 = 15 bit (555)
629 011 = 12 bit (444) 630 011 = 12 bit (444)
630 100 = 32 bit (8888) 631 100 = 32 bit (8888)
631 101 = 8 bit indexed
632 632
633 bits 4:5 633 bits 4:5
634 osd display bpp 634 osd display bpp
@@ -676,9 +676,11 @@ out what values are bad when it hangs.
676 completely transparent. When using 565, 555 or 444 colour modes, the 676 completely transparent. When using 565, 555 or 444 colour modes, the
677 colour key is always 16 bits wide. The colour to key on is set in Reg 2A18. 677 colour key is always 16 bits wide. The colour to key on is set in Reg 2A18.
678 678
679 Local alpha is a per-pixel 256 step transparency, with 0 being transparent 679 Local alpha works differently depending on the colour mode. For 32bpp & 8
680 and 255 being solid. This is only available in 32 bit & 8 bit indexed 680 bit indexed, local alpha is a per-pixel 256 step transparency, with 0 being
681 colour modes. 681 transparent and 255 being solid. For the 16bpp modes 555 & 444, the unused
682 bit(s) act as a simple transparency switch, with 0 being solid & 1 being
683 fully transparent. There is no local alpha support for 16bit 565.
682 684
683 Global alpha is a 256 step transparency that applies to the entire osd, 685 Global alpha is a 256 step transparency that applies to the entire osd,
684 with 0 being transparent & 255 being solid. 686 with 0 being transparent & 255 being solid.
@@ -811,5 +813,5 @@ out what values are bad when it hangs.
811 813
812-------------------------------------------------------------------------------- 814--------------------------------------------------------------------------------
813 815
814v0.3 - 2 February 2007 - Ian Armstrong (ian@iarmst.demon.co.uk) 816v0.4 - 12 March 2007 - Ian Armstrong (ian@iarmst.demon.co.uk)
815 817
diff --git a/Documentation/video4linux/cx2341x/fw-encoder-api.txt b/Documentation/video4linux/cx2341x/fw-encoder-api.txt
index 242104ce5b61..5dd3109a8b3f 100644
--- a/Documentation/video4linux/cx2341x/fw-encoder-api.txt
+++ b/Documentation/video4linux/cx2341x/fw-encoder-api.txt
@@ -663,12 +663,13 @@ Param[0]
663 663
664------------------------------------------------------------------------------- 664-------------------------------------------------------------------------------
665 665
666Name CX2341X_ENC_UNKNOWN 666Name CX2341X_ENC_SET_VERT_CROP_LINE
667Enum 219/0xDB 667Enum 219/0xDB
668Description 668Description
669 Unknown API, it's used by Hauppauge though. 669 Something to do with 'Vertical Crop Line'
670Param[0] 670Param[0]
671 0 This is the value Hauppauge uses, Unknown what it means. 671 If saa7114 and raw VBI capture and 60 Hz, then set to 10001.
672 Else 0.
672 673
673------------------------------------------------------------------------------- 674-------------------------------------------------------------------------------
674 675
@@ -682,11 +683,9 @@ Param[0]
682 Command number: 683 Command number:
683 1=set initial SCR value when starting encoding (works). 684 1=set initial SCR value when starting encoding (works).
684 2=set quality mode (apparently some test setting). 685 2=set quality mode (apparently some test setting).
685 3=setup advanced VIM protection handling (supposedly only for the cx23416 686 3=setup advanced VIM protection handling.
686 for raw YUV). 687 Always 1 for the cx23416 and 0 for cx23415.
687 Actually it looks like this should be 0 for saa7114/5 based card and 1 688 4=generate DVD compatible PTS timestamps
688 for cx25840 based cards.
689 4=generate artificial PTS timestamps
690 5=USB flush mode 689 5=USB flush mode
691 6=something to do with the quantization matrix 690 6=something to do with the quantization matrix
692 7=set navigation pack insertion for DVD: adds 0xbf (private stream 2) 691 7=set navigation pack insertion for DVD: adds 0xbf (private stream 2)
@@ -698,7 +697,9 @@ Param[0]
698 9=set history parameters of the video input module 697 9=set history parameters of the video input module
699 10=set input field order of VIM 698 10=set input field order of VIM
700 11=set quantization matrix 699 11=set quantization matrix
701 12=reset audio interface 700 12=reset audio interface after channel change or input switch (has no argument).
701 Needed for the cx2584x, not needed for the mspx4xx, but it doesn't seem to
702 do any harm calling it regardless.
702 13=set audio volume delay 703 13=set audio volume delay
703 14=set audio delay 704 14=set audio delay
704 705
diff --git a/Documentation/video4linux/cx2341x/fw-osd-api.txt b/Documentation/video4linux/cx2341x/fw-osd-api.txt
index 0a602f3e601b..89c4601042c1 100644
--- a/Documentation/video4linux/cx2341x/fw-osd-api.txt
+++ b/Documentation/video4linux/cx2341x/fw-osd-api.txt
@@ -21,7 +21,11 @@ Enum 66/0x42
21Description 21Description
22 Query OSD format 22 Query OSD format
23Result[0] 23Result[0]
24 0=8bit index, 4=AlphaRGB 8:8:8:8 24 0=8bit index
25 1=16bit RGB 5:6:5
26 2=16bit ARGB 1:5:5:5
27 3=16bit ARGB 1:4:4:4
28 4=32bit ARGB 8:8:8:8
25 29
26------------------------------------------------------------------------------- 30-------------------------------------------------------------------------------
27 31
@@ -30,7 +34,11 @@ Enum 67/0x43
30Description 34Description
31 Assign pixel format 35 Assign pixel format
32Param[0] 36Param[0]
33 0=8bit index, 4=AlphaRGB 8:8:8:8 37 0=8bit index
38 1=16bit RGB 5:6:5
39 2=16bit ARGB 1:5:5:5
40 3=16bit ARGB 1:4:4:4
41 4=32bit ARGB 8:8:8:8
34 42
35------------------------------------------------------------------------------- 43-------------------------------------------------------------------------------
36 44
diff --git a/Documentation/video4linux/sn9c102.txt b/Documentation/video4linux/sn9c102.txt
index 2913da3d0878..5fe0ad7dfc20 100644
--- a/Documentation/video4linux/sn9c102.txt
+++ b/Documentation/video4linux/sn9c102.txt
@@ -25,7 +25,7 @@ Index
25 25
261. Copyright 261. Copyright
27============ 27============
28Copyright (C) 2004-2006 by Luca Risolia <luca.risolia@studio.unibo.it> 28Copyright (C) 2004-2007 by Luca Risolia <luca.risolia@studio.unibo.it>
29 29
30 30
312. Disclaimer 312. Disclaimer
@@ -216,10 +216,10 @@ Description: Debugging information level, from 0 to 3:
216 1 = critical errors 216 1 = critical errors
217 2 = significant informations 217 2 = significant informations
218 3 = more verbose messages 218 3 = more verbose messages
219 Level 3 is useful for testing only, when only one device 219 Level 3 is useful for testing only. It also shows some more
220 is used. It also shows some more informations about the 220 informations about the hardware being detected.
221 hardware being detected. This parameter can be changed at 221 This parameter can be changed at runtime thanks to the /sys
222 runtime thanks to the /sys filesystem interface. 222 filesystem interface.
223Default: 2 223Default: 2
224------------------------------------------------------------------------------- 224-------------------------------------------------------------------------------
225 225
@@ -235,7 +235,7 @@ created in the /sys/class/video4linux/videoX directory. You can set the green
235channel's gain by writing the desired value to it. The value may range from 0 235channel's gain by writing the desired value to it. The value may range from 0
236to 15 for the SN9C101 or SN9C102 bridges, from 0 to 127 for the SN9C103, 236to 15 for the SN9C101 or SN9C102 bridges, from 0 to 127 for the SN9C103,
237SN9C105 and SN9C120 bridges. 237SN9C105 and SN9C120 bridges.
238Similarly, only for the SN9C103, SN9C105 and SN9120 controllers, blue and red 238Similarly, only for the SN9C103, SN9C105 and SN9C120 controllers, blue and red
239gain control files are available in the same directory, for which accepted 239gain control files are available in the same directory, for which accepted
240values may range from 0 to 127. 240values may range from 0 to 127.
241 241
@@ -402,38 +402,49 @@ Vendor ID Product ID
4020x0c45 0x60bc 4020x0c45 0x60bc
4030x0c45 0x60be 4030x0c45 0x60be
4040x0c45 0x60c0 4040x0c45 0x60c0
4050x0c45 0x60c2
4050x0c45 0x60c8 4060x0c45 0x60c8
4060x0c45 0x60cc 4070x0c45 0x60cc
4070x0c45 0x60ea 4080x0c45 0x60ea
4080x0c45 0x60ec 4090x0c45 0x60ec
4100x0c45 0x60ef
4090x0c45 0x60fa 4110x0c45 0x60fa
4100x0c45 0x60fb 4120x0c45 0x60fb
4110x0c45 0x60fc 4130x0c45 0x60fc
4120x0c45 0x60fe 4140x0c45 0x60fe
4150x0c45 0x6102
4160x0c45 0x6108
4170x0c45 0x610f
4130x0c45 0x6130 4180x0c45 0x6130
4190x0c45 0x6138
4140x0c45 0x613a 4200x0c45 0x613a
4150x0c45 0x613b 4210x0c45 0x613b
4160x0c45 0x613c 4220x0c45 0x613c
4170x0c45 0x613e 4230x0c45 0x613e
418 424
419The list above does not imply that all those devices work with this driver: up 425The list above does not imply that all those devices work with this driver: up
420until now only the ones that assemble the following image sensors are 426until now only the ones that assemble the following pairs of SN9C1xx bridges
421supported; kernel messages will always tell you whether this is the case (see 427and image sensors are supported; kernel messages will always tell you whether
422"Module loading" paragraph): 428this is the case (see "Module loading" paragraph):
423 429
424Model Manufacturer 430Image sensor / SN9C1xx bridge | SN9C10[12] SN9C103 SN9C105 SN9C120
425----- ------------ 431-------------------------------------------------------------------------------
426HV7131D Hynix Semiconductor, Inc. 432HV7131D Hynix Semiconductor | Yes No No No
427MI-0343 Micron Technology, Inc. 433HV7131R Hynix Semiconductor | No Yes Yes Yes
428OV7630 OmniVision Technologies, Inc. 434MI-0343 Micron Technology | Yes No No No
429OV7660 OmniVision Technologies, Inc. 435MI-0360 Micron Technology | No Yes No No
430PAS106B PixArt Imaging, Inc. 436OV7630 OmniVision Technologies | Yes Yes No No
431PAS202BCA PixArt Imaging, Inc. 437OV7660 OmniVision Technologies | No No Yes Yes
432PAS202BCB PixArt Imaging, Inc. 438PAS106B PixArt Imaging | Yes No No No
433TAS5110C1B Taiwan Advanced Sensor Corporation 439PAS202B PixArt Imaging | Yes Yes No No
434TAS5130D1B Taiwan Advanced Sensor Corporation 440TAS5110C1B Taiwan Advanced Sensor | Yes No No No
435 441TAS5110D Taiwan Advanced Sensor | Yes No No No
436Some of the available control settings of each image sensor are supported 442TAS5130D1B Taiwan Advanced Sensor | Yes No No No
443
444"Yes" means that the pair is supported by the driver, while "No" means that the
445pair does not exist or is not supported by the driver.
446
447Only some of the available control settings of each image sensor are supported
437through the V4L2 interface. 448through the V4L2 interface.
438 449
439Donations of new models for further testing and support would be much 450Donations of new models for further testing and support would be much
@@ -482,8 +493,8 @@ The SN9C1xx PC Camera Controllers can send images in two possible video
482formats over the USB: either native "Sequential RGB Bayer" or compressed. 493formats over the USB: either native "Sequential RGB Bayer" or compressed.
483The compression is used to achieve high frame rates. With regard to the 494The compression is used to achieve high frame rates. With regard to the
484SN9C101, SN9C102 and SN9C103, the compression is based on the Huffman encoding 495SN9C101, SN9C102 and SN9C103, the compression is based on the Huffman encoding
485algorithm described below, while the SN9C105 and SN9C120 the compression is 496algorithm described below, while with regard to the SN9C105 and SN9C120 the
486based on the JPEG standard. 497compression is based on the JPEG standard.
487The current video format may be selected or queried from the user application 498The current video format may be selected or queried from the user application
488by calling the VIDIOC_S_FMT or VIDIOC_G_FMT ioctl's, as described in the V4L2 499by calling the VIDIOC_S_FMT or VIDIOC_G_FMT ioctl's, as described in the V4L2
489API specifications. 500API specifications.
@@ -573,4 +584,5 @@ order):
573- Mizuno Takafumi for the donation of a webcam; 584- Mizuno Takafumi for the donation of a webcam;
574- an "anonymous" donator (who didn't want his name to be revealed) for the 585- an "anonymous" donator (who didn't want his name to be revealed) for the
575 donation of a webcam. 586 donation of a webcam.
576- an anonymous donator for the donation of four webcams. 587- an anonymous donator for the donation of four webcams and two boards with ten
588 image sensors.
diff --git a/Documentation/video4linux/zr364xx.txt b/Documentation/video4linux/zr364xx.txt
new file mode 100644
index 000000000000..c76992d0ff4d
--- /dev/null
+++ b/Documentation/video4linux/zr364xx.txt
@@ -0,0 +1,65 @@
1Zoran 364xx based USB webcam module version 0.72
2site: http://royale.zerezo.com/zr364xx/
3mail: royale@zerezo.com
4
5introduction:
6This brings support under Linux for the Aiptek PocketDV 3300 in webcam mode.
7If you just want to get on your PC the pictures and movies on the camera, you should use the usb-storage module instead.
8The driver works with several other cameras in webcam mode (see the list below).
9Maybe this code can work for other JPEG/USB cams based on the Coach chips from Zoran?
10Possible chipsets are : ZR36430 (ZR36430BGC) and maybe ZR36431, ZR36440, ZR36442...
11You can try the experience changing the vendor/product ID values (look at the source code).
12You can get these values by looking at /var/log/messages when you plug your camera, or by typing : cat /proc/bus/usb/devices.
13If you manage to use your cam with this code, you can send me a mail (royale@zerezo.com) with the name of your cam and a patch if needed.
14This is a beta release of the driver.
15Since version 0.70, this driver is only compatible with V4L2 API and 2.6.x kernels.
16If you need V4L1 or 2.4x kernels support, please use an older version, but the code is not maintained anymore.
17Good luck!
18
19install:
20In order to use this driver, you must compile it with your kernel.
21Location: Device Drivers -> Multimedia devices -> Video For Linux -> Video Capture Adapters -> V4L USB devices
22
23usage:
24modprobe zr364xx debug=X mode=Y
25 - debug : set to 1 to enable verbose debug messages
26 - mode : 0 = 320x240, 1 = 160x120, 2 = 640x480
27You can then use the camera with V4L2 compatible applications, for example Ekiga.
28To capture a single image, try this: dd if=/dev/video0 of=test.jpg bs=1 count=1
29
30links :
31http://mxhaard.free.fr/ (support for many others cams including some Aiptek PocketDV)
32http://www.harmwal.nl/pccam880/ (this project also supports cameras based on this chipset)
33
34supported devices:
35------ ------- ----------- -----
36Vendor Product Distributor Model
37------ ------- ----------- -----
380x08ca 0x0109 Aiptek PocketDV 3300
390x08ca 0x0109 Maxell Maxcam PRO DV3
400x041e 0x4024 Creative PC-CAM 880
410x0d64 0x0108 Aiptek Fidelity 3200
420x0d64 0x0108 Praktica DCZ 1.3 S
430x0d64 0x0108 Genius Digital Camera (?)
440x0d64 0x0108 DXG Technology Fashion Cam
450x0546 0x3187 Polaroid iON 230
460x0d64 0x3108 Praktica Exakta DC 2200
470x0d64 0x3108 Genius G-Shot D211
480x0595 0x4343 Concord Eye-Q Duo 1300
490x0595 0x4343 Concord Eye-Q Duo 2000
500x0595 0x4343 Fujifilm EX-10
510x0595 0x4343 Ricoh RDC-6000
520x0595 0x4343 Digitrex DSC 1300
530x0595 0x4343 Firstline FDC 2000
540x0bb0 0x500d Concord EyeQ Go Wireless
550x0feb 0x2004 CRS Electronic 3.3 Digital Camera
560x0feb 0x2004 Packard Bell DSC-300
570x055f 0xb500 Mustek MDC 3000
580x08ca 0x2062 Aiptek PocketDV 5700
590x052b 0x1a18 Chiphead Megapix V12
600x04c8 0x0729 Konica Revio 2
610x04f2 0xa208 Creative PC-CAM 850
620x0784 0x0040 Traveler Slimline X5
630x06d6 0x0034 Trust Powerc@m 750
640x0a17 0x0062 Pentax Optio 50L
65
diff --git a/MAINTAINERS b/MAINTAINERS
index 5519d257b556..415011c9d84e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -55,7 +55,7 @@ trivial patch so apply some common sense.
55 55
568. Happy hacking. 568. Happy hacking.
57 57
58 ----------------------------------- 58 -----------------------------------
59 59
60Maintainers List (try to look for most precise areas first) 60Maintainers List (try to look for most precise areas first)
61 61
@@ -873,6 +873,12 @@ W: http://linuxtv.org
873T: git kernel.org:/pub/scm/linux/kernel/git/mchehab/v4l-dvb.git 873T: git kernel.org:/pub/scm/linux/kernel/git/mchehab/v4l-dvb.git
874S: Maintained 874S: Maintained
875 875
876CAFE CMOS INTEGRATED CAMERA CONTROLLER DRIVER
877P: Jonathan Corbet
878M: corbet@lwn.net
879L: video4linux-list@redhat.com
880S: Maintained
881
876CALGARY x86-64 IOMMU 882CALGARY x86-64 IOMMU
877P: Muli Ben-Yehuda 883P: Muli Ben-Yehuda
878M: muli@il.ibm.com 884M: muli@il.ibm.com
@@ -907,7 +913,7 @@ L: linux-cifs-client@lists.samba.org
907L: samba-technical@lists.samba.org 913L: samba-technical@lists.samba.org
908W: http://us1.samba.org/samba/Linux_CIFS_client.html 914W: http://us1.samba.org/samba/Linux_CIFS_client.html
909T: git kernel.org:/pub/scm/linux/kernel/git/sfrench/cifs-2.6.git 915T: git kernel.org:/pub/scm/linux/kernel/git/sfrench/cifs-2.6.git
910S: Supported 916S: Supported
911 917
912CONFIGFS 918CONFIGFS
913P: Joel Becker 919P: Joel Becker
@@ -1549,19 +1555,19 @@ P: Chirag Kantharia
1549M: chirag.kantharia@hp.com 1555M: chirag.kantharia@hp.com
1550L: iss_storagedev@hp.com 1556L: iss_storagedev@hp.com
1551S: Maintained 1557S: Maintained
1552 1558
1553HEWLETT-PACKARD SMART2 RAID DRIVER 1559HEWLETT-PACKARD SMART2 RAID DRIVER
1554P: Chirag Kantharia 1560P: Chirag Kantharia
1555M: chirag.kantharia@hp.com 1561M: chirag.kantharia@hp.com
1556L: iss_storagedev@hp.com 1562L: iss_storagedev@hp.com
1557S: Maintained 1563S: Maintained
1558 1564
1559HEWLETT-PACKARD SMART CISS RAID DRIVER (cciss) 1565HEWLETT-PACKARD SMART CISS RAID DRIVER (cciss)
1560P: Mike Miller 1566P: Mike Miller
1561M: mike.miller@hp.com 1567M: mike.miller@hp.com
1562L: iss_storagedev@hp.com 1568L: iss_storagedev@hp.com
1563S: Supported 1569S: Supported
1564 1570
1565HOST AP DRIVER 1571HOST AP DRIVER
1566P: Jouni Malinen 1572P: Jouni Malinen
1567M: jkmaline@cc.hut.fi 1573M: jkmaline@cc.hut.fi
@@ -1673,7 +1679,7 @@ P: Jack Hammer
1673P: Dave Jeffery 1679P: Dave Jeffery
1674M: ipslinux@adaptec.com 1680M: ipslinux@adaptec.com
1675W: http://www.developer.ibm.com/welcome/netfinity/serveraid.html 1681W: http://www.developer.ibm.com/welcome/netfinity/serveraid.html
1676S: Supported 1682S: Supported
1677 1683
1678IDE SUBSYSTEM 1684IDE SUBSYSTEM
1679P: Bartlomiej Zolnierkiewicz 1685P: Bartlomiej Zolnierkiewicz
@@ -1975,7 +1981,7 @@ M: kai@germaschewski.name
1975P: Sam Ravnborg 1981P: Sam Ravnborg
1976M: sam@ravnborg.org 1982M: sam@ravnborg.org
1977T: git kernel.org:/pub/scm/linux/kernel/git/sam/kbuild.git 1983T: git kernel.org:/pub/scm/linux/kernel/git/sam/kbuild.git
1978S: Maintained 1984S: Maintained
1979 1985
1980KERNEL JANITORS 1986KERNEL JANITORS
1981P: Several 1987P: Several
@@ -2155,7 +2161,7 @@ S: Maintained
2155LOGICAL DISK MANAGER SUPPORT (LDM, Windows 2000/XP Dynamic Disks) 2161LOGICAL DISK MANAGER SUPPORT (LDM, Windows 2000/XP Dynamic Disks)
2156P: Richard Russon (FlatCap) 2162P: Richard Russon (FlatCap)
2157M: ldm@flatcap.org 2163M: ldm@flatcap.org
2158L: ldm-devel@lists.sourceforge.net 2164L: ldm-devel@lists.sourceforge.net
2159W: http://ldm.sourceforge.net 2165W: http://ldm.sourceforge.net
2160S: Maintained 2166S: Maintained
2161 2167
@@ -2504,13 +2510,13 @@ P: Kurt Hackel
2504M: kurt.hackel@oracle.com 2510M: kurt.hackel@oracle.com
2505L: ocfs2-devel@oss.oracle.com 2511L: ocfs2-devel@oss.oracle.com
2506W: http://oss.oracle.com/projects/ocfs2/ 2512W: http://oss.oracle.com/projects/ocfs2/
2507S: Supported 2513S: Supported
2508 2514
2509OLYMPIC NETWORK DRIVER 2515OLYMPIC NETWORK DRIVER
2510P: Peter De Shrijver 2516P: Peter De Shrijver
2511M: p2@ace.ulyssis.student.kuleuven.ac.be 2517M: p2@ace.ulyssis.student.kuleuven.ac.be
2512P: Mike Phillips 2518P: Mike Phillips
2513M: mikep@linuxtr.net 2519M: mikep@linuxtr.net
2514L: netdev@vger.kernel.org 2520L: netdev@vger.kernel.org
2515L: linux-tr@linuxtr.net 2521L: linux-tr@linuxtr.net
2516W: http://www.linuxtr.net 2522W: http://www.linuxtr.net
@@ -2526,6 +2532,12 @@ P: Harald Welte
2526M: laforge@gnumonks.org 2532M: laforge@gnumonks.org
2527S: Maintained 2533S: Maintained
2528 2534
2535OMNIVISION OV7670 SENSOR DRIVER
2536P: Jonathan Corbet
2537M: corbet@lwn.net
2538L: video4linux-list@redhat.com
2539S: Maintained
2540
2529ONSTREAM SCSI TAPE DRIVER 2541ONSTREAM SCSI TAPE DRIVER
2530P: Willem Riede 2542P: Willem Riede
2531M: osst@riede.org 2543M: osst@riede.org
@@ -3045,7 +3057,7 @@ SIS FRAMEBUFFER DRIVER
3045P: Thomas Winischhofer 3057P: Thomas Winischhofer
3046M: thomas@winischhofer.net 3058M: thomas@winischhofer.net
3047W: http://www.winischhofer.net/linuxsisvga.shtml 3059W: http://www.winischhofer.net/linuxsisvga.shtml
3048S: Maintained 3060S: Maintained
3049 3061
3050SIS USB2VGA DRIVER 3062SIS USB2VGA DRIVER
3051P: Thomas Winischhofer 3063P: Thomas Winischhofer
@@ -3594,7 +3606,7 @@ L: linux-usb-devel@lists.sourceforge.net
3594W: http://www.connecttech.com 3606W: http://www.connecttech.com
3595S: Supported 3607S: Supported
3596 3608
3597USB SN9C10x DRIVER 3609USB SN9C1xx DRIVER
3598P: Luca Risolia 3610P: Luca Risolia
3599M: luca.risolia@studio.unibo.it 3611M: luca.risolia@studio.unibo.it
3600L: linux-usb-devel@lists.sourceforge.net 3612L: linux-usb-devel@lists.sourceforge.net
@@ -3649,6 +3661,14 @@ L: linux-usb-devel@lists.sourceforge.net
3649W: http://linux-lc100020.sourceforge.net 3661W: http://linux-lc100020.sourceforge.net
3650S: Maintained 3662S: Maintained
3651 3663
3664USB ZR364XX DRIVER
3665P: Antoine Jacquet
3666M: royale@zerezo.com
3667L: linux-usb-devel@lists.sourceforge.net
3668L: video4linux-list@redhat.com
3669W: http://royale.zerezo.com/zr364xx/
3670S: Maintained
3671
3652USER-MODE LINUX 3672USER-MODE LINUX
3653P: Jeff Dike 3673P: Jeff Dike
3654M: jdike@karaya.com 3674M: jdike@karaya.com
@@ -3656,7 +3676,7 @@ L: user-mode-linux-devel@lists.sourceforge.net
3656L: user-mode-linux-user@lists.sourceforge.net 3676L: user-mode-linux-user@lists.sourceforge.net
3657W: http://user-mode-linux.sourceforge.net 3677W: http://user-mode-linux.sourceforge.net
3658S: Maintained 3678S: Maintained
3659 3679
3660FAT/VFAT/MSDOS FILESYSTEM: 3680FAT/VFAT/MSDOS FILESYSTEM:
3661P: OGAWA Hirofumi 3681P: OGAWA Hirofumi
3662M: hirofumi@mail.parknet.co.jp 3682M: hirofumi@mail.parknet.co.jp
diff --git a/drivers/media/common/ir-keymaps.c b/drivers/media/common/ir-keymaps.c
index 03b47a262f27..cbd1184b5219 100644
--- a/drivers/media/common/ir-keymaps.c
+++ b/drivers/media/common/ir-keymaps.c
@@ -667,7 +667,7 @@ IR_KEYTAB_TYPE ir_codes_pinnacle_grey[IR_KEYTAB_SIZE] = {
667 [ 0x1f ] = KEY_L, 667 [ 0x1f ] = KEY_L,
668 [ 0x2b ] = KEY_I, 668 [ 0x2b ] = KEY_I,
669 669
670 [ 0x2d ] = KEY_ZOOM, 670 [ 0x2d ] = KEY_SCREEN,
671 [ 0x1e ] = KEY_ZOOM, 671 [ 0x1e ] = KEY_ZOOM,
672 [ 0x1b ] = KEY_VOLUMEUP, 672 [ 0x1b ] = KEY_VOLUMEUP,
673 [ 0x0f ] = KEY_VOLUMEDOWN, 673 [ 0x0f ] = KEY_VOLUMEDOWN,
@@ -682,12 +682,12 @@ IR_KEYTAB_TYPE ir_codes_pinnacle_grey[IR_KEYTAB_SIZE] = {
682 682
683 [ 0x3f ] = KEY_UP, 683 [ 0x3f ] = KEY_UP,
684 [ 0x3e ] = KEY_DOWN, 684 [ 0x3e ] = KEY_DOWN,
685 [ 0x1a ] = KEY_PAUSE, 685 [ 0x1a ] = KEY_ENTER,
686 686
687 [ 0x1d ] = KEY_MENU, 687 [ 0x1d ] = KEY_MENU,
688 [ 0x19 ] = KEY_PLAY, 688 [ 0x19 ] = KEY_AGAIN,
689 [ 0x16 ] = KEY_REWIND, 689 [ 0x16 ] = KEY_PREVIOUSSONG,
690 [ 0x13 ] = KEY_FORWARD, 690 [ 0x13 ] = KEY_NEXTSONG,
691 [ 0x15 ] = KEY_PAUSE, 691 [ 0x15 ] = KEY_PAUSE,
692 [ 0x0e ] = KEY_REWIND, 692 [ 0x0e ] = KEY_REWIND,
693 [ 0x0d ] = KEY_PLAY, 693 [ 0x0d ] = KEY_PLAY,
@@ -1739,7 +1739,7 @@ IR_KEYTAB_TYPE ir_codes_encore_enltv[IR_KEYTAB_SIZE] = {
1739 1739
1740EXPORT_SYMBOL_GPL(ir_codes_encore_enltv); 1740EXPORT_SYMBOL_GPL(ir_codes_encore_enltv);
1741 1741
1742/* for the Technotrend 1500 bundled remote: */ 1742/* for the Technotrend 1500 bundled remotes (grey and black): */
1743IR_KEYTAB_TYPE ir_codes_tt_1500[IR_KEYTAB_SIZE] = { 1743IR_KEYTAB_TYPE ir_codes_tt_1500[IR_KEYTAB_SIZE] = {
1744 [ 0x01 ] = KEY_POWER, 1744 [ 0x01 ] = KEY_POWER,
1745 [ 0x02 ] = KEY_SHUFFLE, /* ? double-arrow key */ 1745 [ 0x02 ] = KEY_SHUFFLE, /* ? double-arrow key */
@@ -1774,6 +1774,12 @@ IR_KEYTAB_TYPE ir_codes_tt_1500[IR_KEYTAB_SIZE] = {
1774 [ 0x25 ] = KEY_VOLUMEUP, 1774 [ 0x25 ] = KEY_VOLUMEUP,
1775 [ 0x26 ] = KEY_VOLUMEDOWN, 1775 [ 0x26 ] = KEY_VOLUMEDOWN,
1776 [ 0x27 ] = KEY_SETUP, 1776 [ 0x27 ] = KEY_SETUP,
1777 [ 0x3a ] = KEY_RECORD, /* these keys are only in the black remote */
1778 [ 0x3b ] = KEY_PLAY,
1779 [ 0x3c ] = KEY_STOP,
1780 [ 0x3d ] = KEY_REWIND,
1781 [ 0x3e ] = KEY_PAUSE,
1782 [ 0x3f ] = KEY_FORWARD,
1777}; 1783};
1778 1784
1779EXPORT_SYMBOL_GPL(ir_codes_tt_1500); 1785EXPORT_SYMBOL_GPL(ir_codes_tt_1500);
diff --git a/drivers/media/common/saa7146_video.c b/drivers/media/common/saa7146_video.c
index 7e0cedc557df..e3d04a4cef4d 100644
--- a/drivers/media/common/saa7146_video.c
+++ b/drivers/media/common/saa7146_video.c
@@ -1428,6 +1428,7 @@ static void video_close(struct saa7146_dev *dev, struct file *file)
1428{ 1428{
1429 struct saa7146_fh *fh = (struct saa7146_fh *)file->private_data; 1429 struct saa7146_fh *fh = (struct saa7146_fh *)file->private_data;
1430 struct saa7146_vv *vv = dev->vv_data; 1430 struct saa7146_vv *vv = dev->vv_data;
1431 struct videobuf_queue *q = &fh->video_q;
1431 int err; 1432 int err;
1432 1433
1433 if (IS_CAPTURE_ACTIVE(fh) != 0) { 1434 if (IS_CAPTURE_ACTIVE(fh) != 0) {
@@ -1436,6 +1437,11 @@ static void video_close(struct saa7146_dev *dev, struct file *file)
1436 err = saa7146_stop_preview(fh); 1437 err = saa7146_stop_preview(fh);
1437 } 1438 }
1438 1439
1440 // release all capture buffers
1441 mutex_lock(&q->lock);
1442 videobuf_read_stop(q);
1443 mutex_unlock(&q->lock);
1444
1439 /* hmm, why is this function declared void? */ 1445 /* hmm, why is this function declared void? */
1440 /* return err */ 1446 /* return err */
1441} 1447}
diff --git a/drivers/media/dvb/b2c2/Kconfig b/drivers/media/dvb/b2c2/Kconfig
index 79875958930e..a0dcd59da76e 100644
--- a/drivers/media/dvb/b2c2/Kconfig
+++ b/drivers/media/dvb/b2c2/Kconfig
@@ -9,7 +9,6 @@ config DVB_B2C2_FLEXCOP
9 select DVB_STV0297 if !DVB_FE_CUSTOMISE 9 select DVB_STV0297 if !DVB_FE_CUSTOMISE
10 select DVB_BCM3510 if !DVB_FE_CUSTOMISE 10 select DVB_BCM3510 if !DVB_FE_CUSTOMISE
11 select DVB_LGDT330X if !DVB_FE_CUSTOMISE 11 select DVB_LGDT330X if !DVB_FE_CUSTOMISE
12 select DVB_TUNER_LGH06XF if !DVB_FE_CUSTOMISE
13 help 12 help
14 Support for the digital TV receiver chip made by B2C2 Inc. included in 13 Support for the digital TV receiver chip made by B2C2 Inc. included in
15 Technisats PCI cards and USB boxes. 14 Technisats PCI cards and USB boxes.
diff --git a/drivers/media/dvb/b2c2/flexcop-fe-tuner.c b/drivers/media/dvb/b2c2/flexcop-fe-tuner.c
index 752cf79c532f..b02c2fd65baa 100644
--- a/drivers/media/dvb/b2c2/flexcop-fe-tuner.c
+++ b/drivers/media/dvb/b2c2/flexcop-fe-tuner.c
@@ -14,7 +14,6 @@
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 "lgh06xf.h"
18#include "dvb-pll.h" 17#include "dvb-pll.h"
19 18
20/* lnb control */ 19/* lnb control */
@@ -507,7 +506,7 @@ int flexcop_frontend_init(struct flexcop_device *fc)
507 /* try the air atsc 3nd generation (lgdt3303) */ 506 /* try the air atsc 3nd generation (lgdt3303) */
508 if ((fc->fe = dvb_attach(lgdt330x_attach, &air2pc_atsc_hd5000_config, &fc->i2c_adap)) != NULL) { 507 if ((fc->fe = dvb_attach(lgdt330x_attach, &air2pc_atsc_hd5000_config, &fc->i2c_adap)) != NULL) {
509 fc->dev_type = FC_AIR_ATSC3; 508 fc->dev_type = FC_AIR_ATSC3;
510 dvb_attach(lgh06xf_attach, fc->fe, &fc->i2c_adap); 509 dvb_attach(dvb_pll_attach, fc->fe, 0x61, &fc->i2c_adap, &dvb_pll_lg_tdvs_h06xf);
511 info("found the lgdt3303 at i2c address: 0x%02x",air2pc_atsc_hd5000_config.demod_address); 510 info("found the lgdt3303 at i2c address: 0x%02x",air2pc_atsc_hd5000_config.demod_address);
512 } else 511 } else
513 /* try the air atsc 1nd generation (bcm3510)/panasonic ct10s */ 512 /* try the air atsc 1nd generation (bcm3510)/panasonic ct10s */
diff --git a/drivers/media/dvb/b2c2/flexcop-pci.c b/drivers/media/dvb/b2c2/flexcop-pci.c
index 6e166801505d..01af4d237eb1 100644
--- a/drivers/media/dvb/b2c2/flexcop-pci.c
+++ b/drivers/media/dvb/b2c2/flexcop-pci.c
@@ -127,10 +127,11 @@ static irqreturn_t flexcop_pci_isr(int irq, void *dev_id)
127{ 127{
128 struct flexcop_pci *fc_pci = dev_id; 128 struct flexcop_pci *fc_pci = dev_id;
129 struct flexcop_device *fc = fc_pci->fc_dev; 129 struct flexcop_device *fc = fc_pci->fc_dev;
130 unsigned long flags;
130 flexcop_ibi_value v; 131 flexcop_ibi_value v;
131 irqreturn_t ret = IRQ_HANDLED; 132 irqreturn_t ret = IRQ_HANDLED;
132 133
133 spin_lock_irq(&fc_pci->irq_lock); 134 spin_lock_irqsave(&fc_pci->irq_lock,flags);
134 135
135 v = fc->read_ibi_reg(fc,irq_20c); 136 v = fc->read_ibi_reg(fc,irq_20c);
136 137
@@ -194,7 +195,7 @@ static irqreturn_t flexcop_pci_isr(int irq, void *dev_id)
194 ret = IRQ_NONE; 195 ret = IRQ_NONE;
195 } 196 }
196 197
197 spin_unlock_irq(&fc_pci->irq_lock); 198 spin_unlock_irqrestore(&fc_pci->irq_lock,flags);
198 199
199 return ret; 200 return ret;
200} 201}
@@ -293,12 +294,12 @@ static int flexcop_pci_init(struct flexcop_pci *fc_pci)
293 } 294 }
294 295
295 pci_set_drvdata(fc_pci->pdev, fc_pci); 296 pci_set_drvdata(fc_pci->pdev, fc_pci);
296 297 spin_lock_init(&fc_pci->irq_lock);
297 if ((ret = request_irq(fc_pci->pdev->irq, flexcop_pci_isr, 298 if ((ret = request_irq(fc_pci->pdev->irq, flexcop_pci_isr,
298 IRQF_SHARED, DRIVER_NAME, fc_pci)) != 0) 299 IRQF_SHARED, DRIVER_NAME, fc_pci)) != 0)
299 goto err_pci_iounmap; 300 goto err_pci_iounmap;
300 301
301 spin_lock_init(&fc_pci->irq_lock); 302
302 303
303 fc_pci->init_state |= FC_PCI_INIT; 304 fc_pci->init_state |= FC_PCI_INIT;
304 return ret; 305 return ret;
diff --git a/drivers/media/dvb/bt8xx/Kconfig b/drivers/media/dvb/bt8xx/Kconfig
index dd66b60fbc98..cfd6fb729a61 100644
--- a/drivers/media/dvb/bt8xx/Kconfig
+++ b/drivers/media/dvb/bt8xx/Kconfig
@@ -7,7 +7,7 @@ config DVB_BT8XX
7 select DVB_CX24110 if !DVB_FE_CUSTOMISE 7 select DVB_CX24110 if !DVB_FE_CUSTOMISE
8 select DVB_OR51211 if !DVB_FE_CUSTOMISE 8 select DVB_OR51211 if !DVB_FE_CUSTOMISE
9 select DVB_LGDT330X if !DVB_FE_CUSTOMISE 9 select DVB_LGDT330X if !DVB_FE_CUSTOMISE
10 select DVB_TUNER_LGH06XF if !DVB_FE_CUSTOMISE 10 select DVB_PLL
11 select DVB_ZL10353 if !DVB_FE_CUSTOMISE 11 select DVB_ZL10353 if !DVB_FE_CUSTOMISE
12 select FW_LOADER 12 select FW_LOADER
13 help 13 help
diff --git a/drivers/media/dvb/bt8xx/bt878.c b/drivers/media/dvb/bt8xx/bt878.c
index 83b090ef2445..df72b4b8ee10 100644
--- a/drivers/media/dvb/bt8xx/bt878.c
+++ b/drivers/media/dvb/bt8xx/bt878.c
@@ -393,9 +393,7 @@ static struct cards card_list[] __devinitdata = {
393 { 0xdb1118ac, BTTV_BOARD_DVICO_DVBT_LITE, "Ultraview DVB-T Lite" }, 393 { 0xdb1118ac, BTTV_BOARD_DVICO_DVBT_LITE, "Ultraview DVB-T Lite" },
394 { 0xd50018ac, BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE, "DViCO FusionHDTV 5 Lite" }, 394 { 0xd50018ac, BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE, "DViCO FusionHDTV 5 Lite" },
395 { 0x20007063, BTTV_BOARD_PC_HDTV, "pcHDTV HD-2000 TV" }, 395 { 0x20007063, BTTV_BOARD_PC_HDTV, "pcHDTV HD-2000 TV" },
396 { 0x00261822, BTTV_BOARD_TWINHAN_DST, "DNTV Live! Mini" }, 396 { 0x00261822, BTTV_BOARD_TWINHAN_DST, "DNTV Live! Mini" }
397
398 { 0, -1, NULL }
399}; 397};
400 398
401 399
diff --git a/drivers/media/dvb/bt8xx/dvb-bt8xx.c b/drivers/media/dvb/bt8xx/dvb-bt8xx.c
index 58f69f6ae391..4f1c09bee538 100644
--- a/drivers/media/dvb/bt8xx/dvb-bt8xx.c
+++ b/drivers/media/dvb/bt8xx/dvb-bt8xx.c
@@ -610,7 +610,8 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type)
610 lgdt330x_reset(card); 610 lgdt330x_reset(card);
611 card->fe = dvb_attach(lgdt330x_attach, &tdvs_tua6034_config, card->i2c_adapter); 611 card->fe = dvb_attach(lgdt330x_attach, &tdvs_tua6034_config, card->i2c_adapter);
612 if (card->fe != NULL) { 612 if (card->fe != NULL) {
613 dvb_attach(lgh06xf_attach, card->fe, card->i2c_adapter); 613 dvb_attach(dvb_pll_attach, card->fe, 0x61,
614 card->i2c_adapter, &dvb_pll_lg_tdvs_h06xf);
614 dprintk ("dvb_bt8xx: lgdt330x detected\n"); 615 dprintk ("dvb_bt8xx: lgdt330x detected\n");
615 } 616 }
616 break; 617 break;
diff --git a/drivers/media/dvb/bt8xx/dvb-bt8xx.h b/drivers/media/dvb/bt8xx/dvb-bt8xx.h
index e75f4173c059..436880e68672 100644
--- a/drivers/media/dvb/bt8xx/dvb-bt8xx.h
+++ b/drivers/media/dvb/bt8xx/dvb-bt8xx.h
@@ -37,8 +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 "lgh06xf.h"
41#include "zl10353.h" 40#include "zl10353.h"
41#include "dvb-pll.h"
42 42
43struct dvb_bt8xx_card { 43struct dvb_bt8xx_card {
44 struct mutex lock; 44 struct mutex lock;
diff --git a/drivers/media/dvb/dvb-core/dmxdev.c b/drivers/media/dvb/dvb-core/dmxdev.c
index a5c0e1a3e6d1..275df65fde99 100644
--- a/drivers/media/dvb/dvb-core/dmxdev.c
+++ b/drivers/media/dvb/dvb-core/dmxdev.c
@@ -132,6 +132,11 @@ static int dvb_dvr_open(struct inode *inode, struct file *file)
132 if (mutex_lock_interruptible(&dmxdev->mutex)) 132 if (mutex_lock_interruptible(&dmxdev->mutex))
133 return -ERESTARTSYS; 133 return -ERESTARTSYS;
134 134
135 if (dmxdev->exit) {
136 mutex_unlock(&dmxdev->mutex);
137 return -ENODEV;
138 }
139
135 if ((file->f_flags & O_ACCMODE) == O_RDWR) { 140 if ((file->f_flags & O_ACCMODE) == O_RDWR) {
136 if (!(dmxdev->capabilities & DMXDEV_CAP_DUPLEX)) { 141 if (!(dmxdev->capabilities & DMXDEV_CAP_DUPLEX)) {
137 mutex_unlock(&dmxdev->mutex); 142 mutex_unlock(&dmxdev->mutex);
@@ -171,6 +176,7 @@ static int dvb_dvr_open(struct inode *inode, struct file *file)
171 dmxdev->demux->disconnect_frontend(dmxdev->demux); 176 dmxdev->demux->disconnect_frontend(dmxdev->demux);
172 dmxdev->demux->connect_frontend(dmxdev->demux, front); 177 dmxdev->demux->connect_frontend(dmxdev->demux, front);
173 } 178 }
179 dvbdev->users++;
174 mutex_unlock(&dmxdev->mutex); 180 mutex_unlock(&dmxdev->mutex);
175 return 0; 181 return 0;
176} 182}
@@ -198,7 +204,16 @@ static int dvb_dvr_release(struct inode *inode, struct file *file)
198 vfree(mem); 204 vfree(mem);
199 } 205 }
200 } 206 }
201 mutex_unlock(&dmxdev->mutex); 207 /* TODO */
208 dvbdev->users--;
209 if(dvbdev->users==-1 && dmxdev->exit==1) {
210 fops_put(file->f_op);
211 file->f_op = NULL;
212 mutex_unlock(&dmxdev->mutex);
213 wake_up(&dvbdev->wait_queue);
214 } else
215 mutex_unlock(&dmxdev->mutex);
216
202 return 0; 217 return 0;
203} 218}
204 219
@@ -215,6 +230,11 @@ static ssize_t dvb_dvr_write(struct file *file, const char __user *buf,
215 return -EINVAL; 230 return -EINVAL;
216 if (mutex_lock_interruptible(&dmxdev->mutex)) 231 if (mutex_lock_interruptible(&dmxdev->mutex))
217 return -ERESTARTSYS; 232 return -ERESTARTSYS;
233
234 if (dmxdev->exit) {
235 mutex_unlock(&dmxdev->mutex);
236 return -ENODEV;
237 }
218 ret = dmxdev->demux->write(dmxdev->demux, buf, count); 238 ret = dmxdev->demux->write(dmxdev->demux, buf, count);
219 mutex_unlock(&dmxdev->mutex); 239 mutex_unlock(&dmxdev->mutex);
220 return ret; 240 return ret;
@@ -227,6 +247,11 @@ static ssize_t dvb_dvr_read(struct file *file, char __user *buf, size_t count,
227 struct dmxdev *dmxdev = dvbdev->priv; 247 struct dmxdev *dmxdev = dvbdev->priv;
228 int ret; 248 int ret;
229 249
250 if (dmxdev->exit) {
251 mutex_unlock(&dmxdev->mutex);
252 return -ENODEV;
253 }
254
230 //mutex_lock(&dmxdev->mutex); 255 //mutex_lock(&dmxdev->mutex);
231 ret = dvb_dmxdev_buffer_read(&dmxdev->dvr_buffer, 256 ret = dvb_dmxdev_buffer_read(&dmxdev->dvr_buffer,
232 file->f_flags & O_NONBLOCK, 257 file->f_flags & O_NONBLOCK,
@@ -665,6 +690,8 @@ static int dvb_demux_open(struct inode *inode, struct file *file)
665 dmxdevfilter->feed.ts = NULL; 690 dmxdevfilter->feed.ts = NULL;
666 init_timer(&dmxdevfilter->timer); 691 init_timer(&dmxdevfilter->timer);
667 692
693 dvbdev->users++;
694
668 mutex_unlock(&dmxdev->mutex); 695 mutex_unlock(&dmxdev->mutex);
669 return 0; 696 return 0;
670} 697}
@@ -943,7 +970,21 @@ static int dvb_demux_release(struct inode *inode, struct file *file)
943 struct dmxdev_filter *dmxdevfilter = file->private_data; 970 struct dmxdev_filter *dmxdevfilter = file->private_data;
944 struct dmxdev *dmxdev = dmxdevfilter->dev; 971 struct dmxdev *dmxdev = dmxdevfilter->dev;
945 972
946 return dvb_dmxdev_filter_free(dmxdev, dmxdevfilter); 973 int ret;
974
975 ret = dvb_dmxdev_filter_free(dmxdev, dmxdevfilter);
976
977 mutex_lock(&dmxdev->mutex);
978 dmxdev->dvbdev->users--;
979 if(dmxdev->dvbdev->users==1 && dmxdev->exit==1) {
980 fops_put(file->f_op);
981 file->f_op = NULL;
982 mutex_unlock(&dmxdev->mutex);
983 wake_up(&dmxdev->dvbdev->wait_queue);
984 } else
985 mutex_unlock(&dmxdev->mutex);
986
987 return ret;
947} 988}
948 989
949static struct file_operations dvb_demux_fops = { 990static struct file_operations dvb_demux_fops = {
@@ -1027,6 +1068,7 @@ static struct file_operations dvb_dvr_fops = {
1027static struct dvb_device dvbdev_dvr = { 1068static struct dvb_device dvbdev_dvr = {
1028 .priv = NULL, 1069 .priv = NULL,
1029 .readers = 1, 1070 .readers = 1,
1071 .users = 1,
1030 .fops = &dvb_dvr_fops 1072 .fops = &dvb_dvr_fops
1031}; 1073};
1032 1074
@@ -1064,6 +1106,16 @@ EXPORT_SYMBOL(dvb_dmxdev_init);
1064 1106
1065void dvb_dmxdev_release(struct dmxdev *dmxdev) 1107void dvb_dmxdev_release(struct dmxdev *dmxdev)
1066{ 1108{
1109 dmxdev->exit=1;
1110 if (dmxdev->dvbdev->users > 1) {
1111 wait_event(dmxdev->dvbdev->wait_queue,
1112 dmxdev->dvbdev->users==1);
1113 }
1114 if (dmxdev->dvr_dvbdev->users > 1) {
1115 wait_event(dmxdev->dvr_dvbdev->wait_queue,
1116 dmxdev->dvr_dvbdev->users==1);
1117 }
1118
1067 dvb_unregister_device(dmxdev->dvbdev); 1119 dvb_unregister_device(dmxdev->dvbdev);
1068 dvb_unregister_device(dmxdev->dvr_dvbdev); 1120 dvb_unregister_device(dmxdev->dvr_dvbdev);
1069 1121
diff --git a/drivers/media/dvb/dvb-core/dmxdev.h b/drivers/media/dvb/dvb-core/dmxdev.h
index d2bee9ffe43c..29746e70d325 100644
--- a/drivers/media/dvb/dvb-core/dmxdev.h
+++ b/drivers/media/dvb/dvb-core/dmxdev.h
@@ -91,6 +91,8 @@ struct dmxdev {
91 91
92 int filternum; 92 int filternum;
93 int capabilities; 93 int capabilities;
94
95 unsigned int exit:1;
94#define DMXDEV_CAP_DUPLEX 1 96#define DMXDEV_CAP_DUPLEX 1
95 struct dmx_frontend *dvr_orig_fe; 97 struct dmx_frontend *dvr_orig_fe;
96 98
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c
index a21a894d3f98..f4e4ca2dcade 100644
--- a/drivers/media/dvb/dvb-core/dvb_frontend.c
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.c
@@ -606,6 +606,7 @@ static void dvb_frontend_stop(struct dvb_frontend *fe)
606 return; 606 return;
607 607
608 kthread_stop(fepriv->thread); 608 kthread_stop(fepriv->thread);
609
609 init_MUTEX (&fepriv->sem); 610 init_MUTEX (&fepriv->sem);
610 fepriv->state = FESTATE_IDLE; 611 fepriv->state = FESTATE_IDLE;
611 612
@@ -1023,6 +1024,7 @@ static int dvb_frontend_release(struct inode *inode, struct file *file)
1023 struct dvb_device *dvbdev = file->private_data; 1024 struct dvb_device *dvbdev = file->private_data;
1024 struct dvb_frontend *fe = dvbdev->priv; 1025 struct dvb_frontend *fe = dvbdev->priv;
1025 struct dvb_frontend_private *fepriv = fe->frontend_priv; 1026 struct dvb_frontend_private *fepriv = fe->frontend_priv;
1027 int ret;
1026 1028
1027 dprintk ("%s\n", __FUNCTION__); 1029 dprintk ("%s\n", __FUNCTION__);
1028 1030
@@ -1032,7 +1034,14 @@ static int dvb_frontend_release(struct inode *inode, struct file *file)
1032 if (fe->ops.ts_bus_ctrl) 1034 if (fe->ops.ts_bus_ctrl)
1033 fe->ops.ts_bus_ctrl (fe, 0); 1035 fe->ops.ts_bus_ctrl (fe, 0);
1034 1036
1035 return dvb_generic_release (inode, file); 1037 ret = dvb_generic_release (inode, file);
1038
1039 if (dvbdev->users==-1 && fepriv->exit==1) {
1040 fops_put(file->f_op);
1041 file->f_op = NULL;
1042 wake_up(&dvbdev->wait_queue);
1043 }
1044 return ret;
1036} 1045}
1037 1046
1038static struct file_operations dvb_frontend_fops = { 1047static struct file_operations dvb_frontend_fops = {
@@ -1092,8 +1101,15 @@ int dvb_unregister_frontend(struct dvb_frontend* fe)
1092 dprintk ("%s\n", __FUNCTION__); 1101 dprintk ("%s\n", __FUNCTION__);
1093 1102
1094 mutex_lock(&frontend_mutex); 1103 mutex_lock(&frontend_mutex);
1095 dvb_unregister_device (fepriv->dvbdev);
1096 dvb_frontend_stop (fe); 1104 dvb_frontend_stop (fe);
1105 mutex_unlock(&frontend_mutex);
1106
1107 if (fepriv->dvbdev->users < -1)
1108 wait_event(fepriv->dvbdev->wait_queue,
1109 fepriv->dvbdev->users==-1);
1110
1111 mutex_lock(&frontend_mutex);
1112 dvb_unregister_device (fepriv->dvbdev);
1097 1113
1098 /* fe is invalid now */ 1114 /* fe is invalid now */
1099 kfree(fepriv); 1115 kfree(fepriv);
diff --git a/drivers/media/dvb/dvb-core/dvb_net.c b/drivers/media/dvb/dvb-core/dvb_net.c
index 6a5ab409c4e7..4ebf33a5ffa2 100644
--- a/drivers/media/dvb/dvb-core/dvb_net.c
+++ b/drivers/media/dvb/dvb-core/dvb_net.c
@@ -1439,11 +1439,36 @@ static int dvb_net_ioctl(struct inode *inode, struct file *file,
1439 return dvb_usercopy(inode, file, cmd, arg, dvb_net_do_ioctl); 1439 return dvb_usercopy(inode, file, cmd, arg, dvb_net_do_ioctl);
1440} 1440}
1441 1441
1442static int dvb_net_close(struct inode *inode, struct file *file)
1443{
1444 struct dvb_device *dvbdev = file->private_data;
1445 struct dvb_net *dvbnet = dvbdev->priv;
1446
1447 if (!dvbdev)
1448 return -ENODEV;
1449
1450 if ((file->f_flags & O_ACCMODE) == O_RDONLY) {
1451 dvbdev->readers++;
1452 } else {
1453 dvbdev->writers++;
1454 }
1455
1456 dvbdev->users++;
1457
1458 if(dvbdev->users == 1 && dvbnet->exit==1) {
1459 fops_put(file->f_op);
1460 file->f_op = NULL;
1461 wake_up(&dvbdev->wait_queue);
1462 }
1463 return 0;
1464}
1465
1466
1442static struct file_operations dvb_net_fops = { 1467static struct file_operations dvb_net_fops = {
1443 .owner = THIS_MODULE, 1468 .owner = THIS_MODULE,
1444 .ioctl = dvb_net_ioctl, 1469 .ioctl = dvb_net_ioctl,
1445 .open = dvb_generic_open, 1470 .open = dvb_generic_open,
1446 .release = dvb_generic_release, 1471 .release = dvb_net_close,
1447}; 1472};
1448 1473
1449static struct dvb_device dvbdev_net = { 1474static struct dvb_device dvbdev_net = {
@@ -1458,6 +1483,11 @@ void dvb_net_release (struct dvb_net *dvbnet)
1458{ 1483{
1459 int i; 1484 int i;
1460 1485
1486 dvbnet->exit = 1;
1487 if (dvbnet->dvbdev->users < 1)
1488 wait_event(dvbnet->dvbdev->wait_queue,
1489 dvbnet->dvbdev->users==1);
1490
1461 dvb_unregister_device(dvbnet->dvbdev); 1491 dvb_unregister_device(dvbnet->dvbdev);
1462 1492
1463 for (i=0; i<DVB_NET_DEVICES_MAX; i++) { 1493 for (i=0; i<DVB_NET_DEVICES_MAX; i++) {
diff --git a/drivers/media/dvb/dvb-core/dvb_net.h b/drivers/media/dvb/dvb-core/dvb_net.h
index f14e4ca38570..3a3126cae03b 100644
--- a/drivers/media/dvb/dvb-core/dvb_net.h
+++ b/drivers/media/dvb/dvb-core/dvb_net.h
@@ -36,6 +36,7 @@ struct dvb_net {
36 struct dvb_device *dvbdev; 36 struct dvb_device *dvbdev;
37 struct net_device *device[DVB_NET_DEVICES_MAX]; 37 struct net_device *device[DVB_NET_DEVICES_MAX];
38 int state[DVB_NET_DEVICES_MAX]; 38 int state[DVB_NET_DEVICES_MAX];
39 unsigned int exit:1;
39 struct dmx_demux *demux; 40 struct dmx_demux *demux;
40}; 41};
41 42
diff --git a/drivers/media/dvb/dvb-core/dvbdev.c b/drivers/media/dvb/dvb-core/dvbdev.c
index 14a372a0fe8b..e23d8a0ea1d3 100644
--- a/drivers/media/dvb/dvb-core/dvbdev.c
+++ b/drivers/media/dvb/dvb-core/dvbdev.c
@@ -233,6 +233,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
233 dvbdev->adapter = adap; 233 dvbdev->adapter = adap;
234 dvbdev->priv = priv; 234 dvbdev->priv = priv;
235 dvbdev->fops = dvbdevfops; 235 dvbdev->fops = dvbdevfops;
236 init_waitqueue_head (&dvbdev->wait_queue);
236 237
237 memcpy(dvbdev->fops, template->fops, sizeof(struct file_operations)); 238 memcpy(dvbdev->fops, template->fops, sizeof(struct file_operations));
238 dvbdev->fops->owner = adap->module; 239 dvbdev->fops->owner = adap->module;
diff --git a/drivers/media/dvb/dvb-core/dvbdev.h b/drivers/media/dvb/dvb-core/dvbdev.h
index 620e7887b3d3..6dff10ebf470 100644
--- a/drivers/media/dvb/dvb-core/dvbdev.h
+++ b/drivers/media/dvb/dvb-core/dvbdev.h
@@ -69,6 +69,7 @@ struct dvb_device {
69 int writers; 69 int writers;
70 int users; 70 int users;
71 71
72 wait_queue_head_t wait_queue;
72 /* don't really need those !? -- FIXME: use video_usercopy */ 73 /* don't really need those !? -- FIXME: use video_usercopy */
73 int (*kernel_ioctl)(struct inode *inode, struct file *file, 74 int (*kernel_ioctl)(struct inode *inode, struct file *file,
74 unsigned int cmd, void *arg); 75 unsigned int cmd, void *arg);
diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig
index 80f67a51b908..54488737a08f 100644
--- a/drivers/media/dvb/dvb-usb/Kconfig
+++ b/drivers/media/dvb/dvb-usb/Kconfig
@@ -33,6 +33,7 @@ config DVB_USB_A800
33config DVB_USB_DIBUSB_MB 33config DVB_USB_DIBUSB_MB
34 tristate "DiBcom USB DVB-T devices (based on the DiB3000M-B) (see help for device list)" 34 tristate "DiBcom USB DVB-T devices (based on the DiB3000M-B) (see help for device list)"
35 depends on DVB_USB 35 depends on DVB_USB
36 select DVB_PLL
36 select DVB_DIB3000MB 37 select DVB_DIB3000MB
37 select DVB_TUNER_MT2060 if !DVB_FE_CUSTOMISE 38 select DVB_TUNER_MT2060 if !DVB_FE_CUSTOMISE
38 help 39 help
@@ -88,6 +89,7 @@ config DVB_USB_DIB0700
88config DVB_USB_UMT_010 89config DVB_USB_UMT_010
89 tristate "HanfTek UMT-010 DVB-T USB2.0 support" 90 tristate "HanfTek UMT-010 DVB-T USB2.0 support"
90 depends on DVB_USB 91 depends on DVB_USB
92 select DVB_PLL
91 select DVB_DIB3000MC 93 select DVB_DIB3000MC
92 select DVB_TUNER_MT2060 if !DVB_FE_CUSTOMISE 94 select DVB_TUNER_MT2060 if !DVB_FE_CUSTOMISE
93 help 95 help
@@ -96,9 +98,9 @@ config DVB_USB_UMT_010
96config DVB_USB_CXUSB 98config DVB_USB_CXUSB
97 tristate "Conexant USB2.0 hybrid reference design support" 99 tristate "Conexant USB2.0 hybrid reference design support"
98 depends on DVB_USB 100 depends on DVB_USB
101 select DVB_PLL
99 select DVB_CX22702 if !DVB_FE_CUSTOMISE 102 select DVB_CX22702 if !DVB_FE_CUSTOMISE
100 select DVB_LGDT330X if !DVB_FE_CUSTOMISE 103 select DVB_LGDT330X if !DVB_FE_CUSTOMISE
101 select DVB_TUNER_LGH06XF if !DVB_FE_CUSTOMISE
102 select DVB_MT352 if !DVB_FE_CUSTOMISE 104 select DVB_MT352 if !DVB_FE_CUSTOMISE
103 select DVB_ZL10353 if !DVB_FE_CUSTOMISE 105 select DVB_ZL10353 if !DVB_FE_CUSTOMISE
104 help 106 help
@@ -140,6 +142,7 @@ config DVB_USB_AU6610
140config DVB_USB_DIGITV 142config DVB_USB_DIGITV
141 tristate "Nebula Electronics uDigiTV DVB-T USB2.0 support" 143 tristate "Nebula Electronics uDigiTV DVB-T USB2.0 support"
142 depends on DVB_USB 144 depends on DVB_USB
145 select DVB_PLL
143 select DVB_NXT6000 if !DVB_FE_CUSTOMISE 146 select DVB_NXT6000 if !DVB_FE_CUSTOMISE
144 select DVB_MT352 if !DVB_FE_CUSTOMISE 147 select DVB_MT352 if !DVB_FE_CUSTOMISE
145 help 148 help
@@ -208,3 +211,10 @@ config DVB_USB_DTT200U
208 The receivers are also known as DTT200U (Yakumo) and UB300 (Yuan). 211 The receivers are also known as DTT200U (Yakumo) and UB300 (Yuan).
209 212
210 The WT-220U and its clones are pen-sized. 213 The WT-220U and its clones are pen-sized.
214
215config DVB_USB_OPERA1
216 tristate "Opera1 DVB-S USB2.0 receiver"
217 depends on DVB_USB
218 select DVB_STV0299 if !DVB_FE_CUSTOMISE
219 help
220 Say Y here to support the Opera DVB-S USB2.0 receiver.
diff --git a/drivers/media/dvb/dvb-usb/Makefile b/drivers/media/dvb/dvb-usb/Makefile
index 40f28f559b54..976f840cc904 100644
--- a/drivers/media/dvb/dvb-usb/Makefile
+++ b/drivers/media/dvb/dvb-usb/Makefile
@@ -51,4 +51,8 @@ obj-$(CONFIG_DVB_USB_TTUSB2) += dvb-usb-ttusb2.o
51dvb-usb-dib0700-objs = dib0700_core.o dib0700_devices.o 51dvb-usb-dib0700-objs = dib0700_core.o dib0700_devices.o
52obj-$(CONFIG_DVB_USB_DIB0700) += dvb-usb-dib0700.o 52obj-$(CONFIG_DVB_USB_DIB0700) += dvb-usb-dib0700.o
53 53
54dvb-usb-opera-objs = opera1.o
55obj-$(CONFIG_DVB_USB_OPERA1) += dvb-usb-opera.o
56
57
54EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/ 58EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/
diff --git a/drivers/media/dvb/dvb-usb/au6610.c b/drivers/media/dvb/dvb-usb/au6610.c
index 0dc66a8d2baf..18e0b16fb2a9 100644
--- a/drivers/media/dvb/dvb-usb/au6610.c
+++ b/drivers/media/dvb/dvb-usb/au6610.c
@@ -40,7 +40,7 @@ static int au6610_usb_msg(struct dvb_usb_device *d, u8 operation, u8 addr,
40 } 40 }
41 41
42 ret = usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0), operation, 42 ret = usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0), operation,
43 USB_TYPE_VENDOR|USB_DIR_IN, addr, index, usb_buf, 43 USB_TYPE_VENDOR|USB_DIR_IN, addr << 1, index, usb_buf,
44 sizeof(usb_buf), AU6610_USB_TIMEOUT); 44 sizeof(usb_buf), AU6610_USB_TIMEOUT);
45 45
46 if (ret < 0) 46 if (ret < 0)
@@ -124,7 +124,7 @@ static int au6610_identify_state(struct usb_device *udev,
124} 124}
125 125
126static struct zl10353_config au6610_zl10353_config = { 126static struct zl10353_config au6610_zl10353_config = {
127 .demod_address = 0x1e, 127 .demod_address = 0x0f,
128 .no_tuner = 1, 128 .no_tuner = 1,
129 .parallel_ts = 1, 129 .parallel_ts = 1,
130}; 130};
@@ -140,7 +140,7 @@ static int au6610_zl10353_frontend_attach(struct dvb_usb_adapter *adap)
140} 140}
141 141
142static struct qt1010_config au6610_qt1010_config = { 142static struct qt1010_config au6610_qt1010_config = {
143 .i2c_address = 0xc4 143 .i2c_address = 0x62
144}; 144};
145 145
146static int au6610_qt1010_tuner_attach(struct dvb_usb_adapter *adap) 146static int au6610_qt1010_tuner_attach(struct dvb_usb_adapter *adap)
diff --git a/drivers/media/dvb/dvb-usb/cxusb.c b/drivers/media/dvb/dvb-usb/cxusb.c
index 127a94b9a1b5..bac2ae3b4a1f 100644
--- a/drivers/media/dvb/dvb-usb/cxusb.c
+++ b/drivers/media/dvb/dvb-usb/cxusb.c
@@ -27,7 +27,6 @@
27 27
28#include "cx22702.h" 28#include "cx22702.h"
29#include "lgdt330x.h" 29#include "lgdt330x.h"
30#include "lgh06xf.h"
31#include "mt352.h" 30#include "mt352.h"
32#include "mt352_priv.h" 31#include "mt352_priv.h"
33#include "zl10353.h" 32#include "zl10353.h"
@@ -388,7 +387,8 @@ static int cxusb_dtt7579_tuner_attach(struct dvb_usb_adapter *adap)
388 387
389static int cxusb_lgh064f_tuner_attach(struct dvb_usb_adapter *adap) 388static int cxusb_lgh064f_tuner_attach(struct dvb_usb_adapter *adap)
390{ 389{
391 dvb_attach(lgh06xf_attach, adap->fe, &adap->dev->i2c_adap); 390 dvb_attach(dvb_pll_attach, adap->fe, 0x61, &adap->dev->i2c_adap,
391 &dvb_pll_lg_tdvs_h06xf);
392 return 0; 392 return 0;
393} 393}
394 394
diff --git a/drivers/media/dvb/dvb-usb/dib0700_core.c b/drivers/media/dvb/dvb-usb/dib0700_core.c
index 6a4d150784a6..dddf164f269a 100644
--- a/drivers/media/dvb/dvb-usb/dib0700_core.c
+++ b/drivers/media/dvb/dvb-usb/dib0700_core.c
@@ -56,10 +56,6 @@ static int dib0700_ctrl_rd(struct dvb_usb_device *d, u8 *tx, u8 txlen, u8 *rx, u
56 if (txlen > 3) 56 if (txlen > 3)
57 index |= tx[3]; 57 index |= tx[3];
58 58
59 /* think about swapping here */
60 value = le16_to_cpu(value);
61 index = le16_to_cpu(index);
62
63 status = usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev,0), tx[0], 59 status = usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev,0), tx[0],
64 USB_TYPE_VENDOR | USB_DIR_IN, value, index, rx, rxlen, 60 USB_TYPE_VENDOR | USB_DIR_IN, value, index, rx, rxlen,
65 USB_CTRL_GET_TIMEOUT); 61 USB_CTRL_GET_TIMEOUT);
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
index 148386aba275..97715f7514d6 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
@@ -13,6 +13,7 @@
13#define USB_VID_ADSTECH 0x06e1 13#define USB_VID_ADSTECH 0x06e1
14#define USB_VID_ALCOR_MICRO 0x058f 14#define USB_VID_ALCOR_MICRO 0x058f
15#define USB_VID_ANCHOR 0x0547 15#define USB_VID_ANCHOR 0x0547
16#define USB_VID_ANUBIS_ELECTRONIC 0x10fd
16#define USB_VID_AVERMEDIA 0x07ca 17#define USB_VID_AVERMEDIA 0x07ca
17#define USB_VID_COMPRO 0x185b 18#define USB_VID_COMPRO 0x185b
18#define USB_VID_COMPRO_UNK 0x145f 19#define USB_VID_COMPRO_UNK 0x145f
@@ -31,6 +32,7 @@
31#define USB_VID_LITEON 0x04ca 32#define USB_VID_LITEON 0x04ca
32#define USB_VID_MEDION 0x1660 33#define USB_VID_MEDION 0x1660
33#define USB_VID_MSI 0x0db0 34#define USB_VID_MSI 0x0db0
35#define USB_VID_OPERA1 0x695c
34#define USB_VID_PINNACLE 0x2304 36#define USB_VID_PINNACLE 0x2304
35#define USB_VID_VISIONPLUS 0x13d3 37#define USB_VID_VISIONPLUS 0x13d3
36#define USB_VID_TWINHAN 0x1822 38#define USB_VID_TWINHAN 0x1822
@@ -127,6 +129,7 @@
127#define USB_PID_KYE_DVB_T_WARM 0x701f 129#define USB_PID_KYE_DVB_T_WARM 0x701f
128#define USB_PID_PCTV_200E 0x020e 130#define USB_PID_PCTV_200E 0x020e
129#define USB_PID_PCTV_400E 0x020f 131#define USB_PID_PCTV_400E 0x020f
132#define USB_PID_PCTV_450E 0x0222
130#define USB_PID_LITEON_DVB_T_COLD 0xf000 133#define USB_PID_LITEON_DVB_T_COLD 0xf000
131#define USB_PID_LITEON_DVB_T_WARM 0xf001 134#define USB_PID_LITEON_DVB_T_WARM 0xf001
132#define USB_PID_DIGIVOX_MINI_SL_COLD 0xe360 135#define USB_PID_DIGIVOX_MINI_SL_COLD 0xe360
@@ -139,6 +142,9 @@
139#define USB_PID_GENPIX_8PSK_COLD 0x0200 142#define USB_PID_GENPIX_8PSK_COLD 0x0200
140#define USB_PID_GENPIX_8PSK_WARM 0x0201 143#define USB_PID_GENPIX_8PSK_WARM 0x0201
141#define USB_PID_SIGMATEK_DVB_110 0x6610 144#define USB_PID_SIGMATEK_DVB_110 0x6610
145#define USB_PID_MSI_DIGI_VOX_MINI_II 0x1513
146#define USB_PID_OPERA1_COLD 0x2830
147#define USB_PID_OPERA1_WARM 0x3829
142 148
143 149
144#endif 150#endif
diff --git a/drivers/media/dvb/dvb-usb/gl861.c b/drivers/media/dvb/dvb-usb/gl861.c
index c9f38a5e70d3..e0587e663591 100644
--- a/drivers/media/dvb/dvb-usb/gl861.c
+++ b/drivers/media/dvb/dvb-usb/gl861.c
@@ -12,7 +12,7 @@
12#include "qt1010.h" 12#include "qt1010.h"
13 13
14/* debug */ 14/* debug */
15int dvb_usb_gl861_debug; 15static int dvb_usb_gl861_debug;
16module_param_named(debug,dvb_usb_gl861_debug, int, 0644); 16module_param_named(debug,dvb_usb_gl861_debug, int, 0644);
17MODULE_PARM_DESC(debug, "set debugging level (1=rc (or-able))." DVB_USB_DEBUG_STATUS); 17MODULE_PARM_DESC(debug, "set debugging level (1=rc (or-able))." DVB_USB_DEBUG_STATUS);
18 18
@@ -20,7 +20,7 @@ static int gl861_i2c_msg(struct dvb_usb_device *d, u8 addr,
20 u8 *wbuf, u16 wlen, u8 *rbuf, u16 rlen) 20 u8 *wbuf, u16 wlen, u8 *rbuf, u16 rlen)
21{ 21{
22 u16 index; 22 u16 index;
23 u16 value = addr << 8; 23 u16 value = addr << (8 + 1);
24 int wo = (rbuf == NULL || rlen == 0); /* write-only */ 24 int wo = (rbuf == NULL || rlen == 0); /* write-only */
25 u8 req, type; 25 u8 req, type;
26 26
@@ -101,7 +101,7 @@ static int gl861_identify_state(struct usb_device *udev,
101} 101}
102 102
103static struct zl10353_config gl861_zl10353_config = { 103static struct zl10353_config gl861_zl10353_config = {
104 .demod_address = 0x1e, 104 .demod_address = 0x0f,
105 .no_tuner = 1, 105 .no_tuner = 1,
106 .parallel_ts = 1, 106 .parallel_ts = 1,
107}; 107};
@@ -117,7 +117,7 @@ static int gl861_frontend_attach(struct dvb_usb_adapter *adap)
117} 117}
118 118
119static struct qt1010_config gl861_qt1010_config = { 119static struct qt1010_config gl861_qt1010_config = {
120 .i2c_address = 0xc4 120 .i2c_address = 0x62
121}; 121};
122 122
123static int gl861_tuner_attach(struct dvb_usb_adapter *adap) 123static int gl861_tuner_attach(struct dvb_usb_adapter *adap)
diff --git a/drivers/media/dvb/dvb-usb/m920x.c b/drivers/media/dvb/dvb-usb/m920x.c
index d48b24d9abf4..45d7bc214c18 100644
--- a/drivers/media/dvb/dvb-usb/m920x.c
+++ b/drivers/media/dvb/dvb-usb/m920x.c
@@ -14,6 +14,8 @@
14#include "mt352.h" 14#include "mt352.h"
15#include "mt352_priv.h" 15#include "mt352_priv.h"
16#include "qt1010.h" 16#include "qt1010.h"
17#include "tda1004x.h"
18#include "tda827x.h"
17 19
18/* debug */ 20/* debug */
19static int dvb_usb_m920x_debug; 21static int dvb_usb_m920x_debug;
@@ -47,11 +49,15 @@ static inline int m9206_read(struct usb_device *udev, u8 request, u16 value,\
47 ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 49 ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
48 request, USB_TYPE_VENDOR | USB_DIR_IN, 50 request, USB_TYPE_VENDOR | USB_DIR_IN,
49 value, index, data, size, 2000); 51 value, index, data, size, 2000);
50 if (ret < 0) 52 if (ret < 0) {
53 printk(KERN_INFO "m920x_read = error: %d\n", ret);
51 return ret; 54 return ret;
55 }
52 56
53 if (ret != size) 57 if (ret != size) {
58 deb_rc("m920x_read = no data\n");
54 return -EIO; 59 return -EIO;
60 }
55 61
56 return 0; 62 return 0;
57} 63}
@@ -64,19 +70,22 @@ static inline int m9206_write(struct usb_device *udev, u8 request,
64 ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 70 ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
65 request, USB_TYPE_VENDOR | USB_DIR_OUT, 71 request, USB_TYPE_VENDOR | USB_DIR_OUT,
66 value, index, NULL, 0, 2000); 72 value, index, NULL, 0, 2000);
73
67 return ret; 74 return ret;
68} 75}
69 76
70static int m9206_rc_init(struct usb_device *udev) 77static int m9206_init(struct dvb_usb_device *d)
71{ 78{
72 int ret = 0; 79 int ret = 0;
73 80
74 /* Remote controller init. */ 81 /* Remote controller init. */
75 if ((ret = m9206_write(udev, M9206_CORE, 0xa8, M9206_RC_INIT2)) != 0) 82 if (d->props.rc_query) {
76 return ret; 83 if ((ret = m9206_write(d->udev, M9206_CORE, 0xa8, M9206_RC_INIT2)) != 0)
84 return ret;
77 85
78 if ((ret = m9206_write(udev, M9206_CORE, 0x51, M9206_RC_INIT1)) != 0) 86 if ((ret = m9206_write(d->udev, M9206_CORE, 0x51, M9206_RC_INIT1)) != 0)
79 return ret; 87 return ret;
88 }
80 89
81 return ret; 90 return ret;
82} 91}
@@ -87,16 +96,15 @@ static int m9206_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
87 int i, ret = 0; 96 int i, ret = 0;
88 u8 rc_state[2]; 97 u8 rc_state[2];
89 98
90
91 if ((ret = m9206_read(d->udev, M9206_CORE, 0x0, M9206_RC_STATE, rc_state, 1)) != 0) 99 if ((ret = m9206_read(d->udev, M9206_CORE, 0x0, M9206_RC_STATE, rc_state, 1)) != 0)
92 goto unlock; 100 goto unlock;
93 101
94 if ((ret = m9206_read(d->udev, M9206_CORE, 0x0, M9206_RC_KEY, rc_state + 1, 1)) != 0) 102 if ((ret = m9206_read(d->udev, M9206_CORE, 0x0, M9206_RC_KEY, rc_state + 1, 1)) != 0)
95 goto unlock; 103 goto unlock;
96 104
97 for (i = 0; i < ARRAY_SIZE(megasky_rc_keys); i++) 105 for (i = 0; i < d->props.rc_key_map_size; i++)
98 if (megasky_rc_keys[i].data == rc_state[1]) { 106 if (d->props.rc_key_map[i].data == rc_state[1]) {
99 *event = megasky_rc_keys[i].event; 107 *event = d->props.rc_key_map[i].event;
100 108
101 switch(rc_state[0]) { 109 switch(rc_state[0]) {
102 case 0x80: 110 case 0x80:
@@ -137,53 +145,51 @@ static int m9206_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
137 int num) 145 int num)
138{ 146{
139 struct dvb_usb_device *d = i2c_get_adapdata(adap); 147 struct dvb_usb_device *d = i2c_get_adapdata(adap);
140 struct m9206_state *m = d->priv; 148 int i, j;
141 int i;
142 int ret = 0; 149 int ret = 0;
143 150
151 if (!num)
152 return -EINVAL;
153
144 if (mutex_lock_interruptible(&d->i2c_mutex) < 0) 154 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
145 return -EAGAIN; 155 return -EAGAIN;
146 156
147 if (num > 2)
148 return -EINVAL;
149
150 for (i = 0; i < num; i++) { 157 for (i = 0; i < num; i++) {
151 if ((ret = m9206_write(d->udev, M9206_I2C, msg[i].addr, 0x80)) != 0) 158 if (msg[i].flags & (I2C_M_NO_RD_ACK|I2C_M_IGNORE_NAK|I2C_M_TEN) ||
152 goto unlock; 159 msg[i].len == 0) {
153 160 /* For a 0 byte message, I think sending the address to index 0x80|0x40
154 if ((ret = m9206_write(d->udev, M9206_I2C, msg[i].buf[0], 0x0)) != 0) 161 * would be the correct thing to do. However, zero byte messages are
162 * only used for probing, and since we don't know how to get the slave's
163 * ack, we can't probe. */
164 ret = -ENOTSUPP;
155 goto unlock; 165 goto unlock;
156 166 }
157 if (i + 1 < num && msg[i + 1].flags & I2C_M_RD) { 167 /* Send START & address/RW bit */
158 int i2c_i; 168 if (!(msg[i].flags & I2C_M_NOSTART)) {
159 169 if ((ret = m9206_write(d->udev, M9206_I2C, (msg[i].addr<<1)|(msg[i].flags&I2C_M_RD?0x01:0), 0x80)) != 0)
160 for (i2c_i = 0; i2c_i < M9206_I2C_MAX; i2c_i++)
161 if (msg[i].addr == m->i2c_r[i2c_i].addr)
162 break;
163
164 if (i2c_i >= M9206_I2C_MAX) {
165 deb_rc("No magic for i2c addr!\n");
166 ret = -EINVAL;
167 goto unlock; 170 goto unlock;
171 /* Should check for ack here, if we knew how. */
172 }
173 if (msg[i].flags & I2C_M_RD) {
174 for (j = 0; j < msg[i].len; j++) {
175 /* Last byte of transaction? Send STOP, otherwise send ACK. */
176 int stop = (i+1 == num && j+1 == msg[i].len)?0x40:0x01;
177 if ((ret = m9206_read(d->udev, M9206_I2C, 0x0, 0x20|stop, &msg[i].buf[j], 1)) != 0)
178 goto unlock;
168 } 179 }
169
170 if ((ret = m9206_write(d->udev, M9206_I2C, m->i2c_r[i2c_i].magic, 0x80)) != 0)
171 goto unlock;
172
173 if ((ret = m9206_read(d->udev, M9206_I2C, 0x0, 0x60, msg[i + 1].buf, msg[i + 1].len)) != 0)
174 goto unlock;
175
176 i++;
177 } else { 180 } else {
178 if (msg[i].len != 2) 181 for (j = 0; j < msg[i].len; j++) {
179 return -EINVAL; 182 /* Last byte of transaction? Then send STOP. */
180 183 int stop = (i+1 == num && j+1 == msg[i].len)?0x40:0x00;
181 if ((ret = m9206_write(d->udev, M9206_I2C, msg[i].buf[1], 0x40)) != 0) 184 if ((ret = m9206_write(d->udev, M9206_I2C, msg[i].buf[j], stop)) != 0)
182 goto unlock; 185 goto unlock;
186 /* Should check for ack here too. */
187 }
183 } 188 }
184 } 189 }
185 ret = i; 190 ret = num;
186 unlock: 191
192unlock:
187 mutex_unlock(&d->i2c_mutex); 193 mutex_unlock(&d->i2c_mutex);
188 194
189 return ret; 195 return ret;
@@ -324,6 +330,7 @@ static int m9206_firmware_download(struct usb_device *udev,
324 i += size; 330 i += size;
325 } 331 }
326 if (i != fw->size) { 332 if (i != fw->size) {
333 deb_rc("bad firmware file!\n");
327 ret = -EINVAL; 334 ret = -EINVAL;
328 goto done; 335 goto done;
329 } 336 }
@@ -342,10 +349,10 @@ static int m9206_firmware_download(struct usb_device *udev,
342} 349}
343 350
344/* Callbacks for DVB USB */ 351/* Callbacks for DVB USB */
345static int megasky_identify_state(struct usb_device *udev, 352static int m920x_identify_state(struct usb_device *udev,
346 struct dvb_usb_device_properties *props, 353 struct dvb_usb_device_properties *props,
347 struct dvb_usb_device_description **desc, 354 struct dvb_usb_device_description **desc,
348 int *cold) 355 int *cold)
349{ 356{
350 struct usb_host_interface *alt; 357 struct usb_host_interface *alt;
351 358
@@ -381,20 +388,15 @@ static int megasky_mt352_demod_init(struct dvb_frontend *fe)
381} 388}
382 389
383static struct mt352_config megasky_mt352_config = { 390static struct mt352_config megasky_mt352_config = {
384 .demod_address = 0x1e, 391 .demod_address = 0x0f,
385 .no_tuner = 1, 392 .no_tuner = 1,
386 .demod_init = megasky_mt352_demod_init, 393 .demod_init = megasky_mt352_demod_init,
387}; 394};
388 395
389static int megasky_mt352_frontend_attach(struct dvb_usb_adapter *adap) 396static int megasky_mt352_frontend_attach(struct dvb_usb_adapter *adap)
390{ 397{
391 struct m9206_state *m = adap->dev->priv;
392
393 deb_rc("megasky_frontend_attach!\n"); 398 deb_rc("megasky_frontend_attach!\n");
394 399
395 m->i2c_r[M9206_I2C_DEMOD].addr = megasky_mt352_config.demod_address;
396 m->i2c_r[M9206_I2C_DEMOD].magic = 0x1f;
397
398 if ((adap->fe = dvb_attach(mt352_attach, &megasky_mt352_config, &adap->dev->i2c_adap)) == NULL) 400 if ((adap->fe = dvb_attach(mt352_attach, &megasky_mt352_config, &adap->dev->i2c_adap)) == NULL)
399 return -EIO; 401 return -EIO;
400 402
@@ -402,16 +404,11 @@ static int megasky_mt352_frontend_attach(struct dvb_usb_adapter *adap)
402} 404}
403 405
404static struct qt1010_config megasky_qt1010_config = { 406static struct qt1010_config megasky_qt1010_config = {
405 .i2c_address = 0xc4 407 .i2c_address = 0x62
406}; 408};
407 409
408static int megasky_qt1010_tuner_attach(struct dvb_usb_adapter *adap) 410static int megasky_qt1010_tuner_attach(struct dvb_usb_adapter *adap)
409{ 411{
410 struct m9206_state *m = adap->dev->priv;
411
412 m->i2c_r[M9206_I2C_TUNER].addr = megasky_qt1010_config.i2c_address;
413 m->i2c_r[M9206_I2C_TUNER].magic = 0xc5;
414
415 if (dvb_attach(qt1010_attach, adap->fe, &adap->dev->i2c_adap, 412 if (dvb_attach(qt1010_attach, adap->fe, &adap->dev->i2c_adap,
416 &megasky_qt1010_config) == NULL) 413 &megasky_qt1010_config) == NULL)
417 return -ENODEV; 414 return -ENODEV;
@@ -419,8 +416,40 @@ static int megasky_qt1010_tuner_attach(struct dvb_usb_adapter *adap)
419 return 0; 416 return 0;
420} 417}
421 418
419static struct tda1004x_config digivox_tda10046_config = {
420 .demod_address = 0x08,
421 .invert = 0,
422 .invert_oclk = 0,
423 .ts_mode = TDA10046_TS_SERIAL,
424 .xtal_freq = TDA10046_XTAL_16M,
425 .if_freq = TDA10046_FREQ_045,
426 .agc_config = TDA10046_AGC_TDA827X,
427 .gpio_config = TDA10046_GPTRI,
428 .request_firmware = NULL,
429};
430
431static int digivox_tda10046_frontend_attach(struct dvb_usb_adapter *adap)
432{
433 deb_rc("digivox_tda10046_frontend_attach!\n");
434
435 if ((adap->fe = dvb_attach(tda10046_attach, &digivox_tda10046_config,
436 &adap->dev->i2c_adap)) == NULL)
437 return -EIO;
438
439 return 0;
440}
441
442static int digivox_tda8275_tuner_attach(struct dvb_usb_adapter *adap)
443{
444 if (dvb_attach(tda827x_attach, adap->fe, 0x60, &adap->dev->i2c_adap,
445 NULL) == NULL)
446 return -ENODEV;
447 return 0;
448}
449
422/* DVB USB Driver stuff */ 450/* DVB USB Driver stuff */
423static struct dvb_usb_device_properties megasky_properties; 451static struct dvb_usb_device_properties megasky_properties;
452static struct dvb_usb_device_properties digivox_mini_ii_properties;
424 453
425static int m920x_probe(struct usb_interface *intf, 454static int m920x_probe(struct usb_interface *intf,
426 const struct usb_device_id *id) 455 const struct usb_device_id *id)
@@ -429,30 +458,36 @@ static int m920x_probe(struct usb_interface *intf,
429 struct usb_host_interface *alt; 458 struct usb_host_interface *alt;
430 int ret; 459 int ret;
431 460
432 if ((ret = dvb_usb_device_init(intf, &megasky_properties, THIS_MODULE, &d)) == 0) { 461 deb_rc("Probed!\n");
433 deb_rc("probed!\n");
434 462
435 alt = usb_altnum_to_altsetting(intf, 1); 463 if (((ret = dvb_usb_device_init(intf, &megasky_properties, THIS_MODULE, &d)) == 0) ||
436 if (alt == NULL) { 464 ((ret = dvb_usb_device_init(intf, &digivox_mini_ii_properties, THIS_MODULE, &d)) == 0))
437 deb_rc("not alt found!\n"); 465 goto found;
438 return -ENODEV;
439 }
440 466
441 ret = usb_set_interface(d->udev, alt->desc.bInterfaceNumber, 467 return ret;
442 alt->desc.bAlternateSetting);
443 if (ret < 0)
444 return ret;
445
446 deb_rc("Changed to alternate setting!\n");
447 468
448 if ((ret = m9206_rc_init(d->udev)) != 0) 469found:
449 return ret; 470 alt = usb_altnum_to_altsetting(intf, 1);
471 if (alt == NULL) {
472 deb_rc("No alt found!\n");
473 return -ENODEV;
450 } 474 }
475
476 ret = usb_set_interface(d->udev, alt->desc.bInterfaceNumber,
477 alt->desc.bAlternateSetting);
478 if (ret < 0)
479 return ret;
480
481 if ((ret = m9206_init(d)) != 0)
482 return ret;
483
451 return ret; 484 return ret;
452} 485}
453 486
454static struct usb_device_id m920x_table [] = { 487static struct usb_device_id m920x_table [] = {
455 { USB_DEVICE(USB_VID_MSI, USB_PID_MSI_MEGASKY580) }, 488 { USB_DEVICE(USB_VID_MSI, USB_PID_MSI_MEGASKY580) },
489 { USB_DEVICE(USB_VID_ANUBIS_ELECTRONIC,
490 USB_PID_MSI_DIGI_VOX_MINI_II) },
456 { } /* Terminating entry */ 491 { } /* Terminating entry */
457}; 492};
458MODULE_DEVICE_TABLE (usb, m920x_table); 493MODULE_DEVICE_TABLE (usb, m920x_table);
@@ -471,7 +506,7 @@ static struct dvb_usb_device_properties megasky_properties = {
471 506
472 .size_of_priv = sizeof(struct m9206_state), 507 .size_of_priv = sizeof(struct m9206_state),
473 508
474 .identify_state = megasky_identify_state, 509 .identify_state = m920x_identify_state,
475 .num_adapters = 1, 510 .num_adapters = 1,
476 .adapter = {{ 511 .adapter = {{
477 .caps = DVB_USB_ADAP_HAS_PID_FILTER | 512 .caps = DVB_USB_ADAP_HAS_PID_FILTER |
@@ -502,6 +537,50 @@ static struct dvb_usb_device_properties megasky_properties = {
502 { "MSI Mega Sky 580 DVB-T USB2.0", 537 { "MSI Mega Sky 580 DVB-T USB2.0",
503 { &m920x_table[0], NULL }, 538 { &m920x_table[0], NULL },
504 { NULL }, 539 { NULL },
540 }
541 }
542};
543
544static struct dvb_usb_device_properties digivox_mini_ii_properties = {
545 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
546
547 .usb_ctrl = DEVICE_SPECIFIC,
548 .firmware = "dvb-usb-digivox-02.fw",
549 .download_firmware = m9206_firmware_download,
550
551 .size_of_priv = sizeof(struct m9206_state),
552
553 .identify_state = m920x_identify_state,
554 .num_adapters = 1,
555 .adapter = {{
556 .caps = DVB_USB_ADAP_HAS_PID_FILTER |
557 DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
558
559 .pid_filter_count = 8,
560 .pid_filter = m9206_pid_filter,
561 .pid_filter_ctrl = m9206_pid_filter_ctrl,
562
563 .frontend_attach = digivox_tda10046_frontend_attach,
564 .tuner_attach = digivox_tda8275_tuner_attach,
565
566 .stream = {
567 .type = USB_BULK,
568 .count = 8,
569 .endpoint = 0x81,
570 .u = {
571 .bulk = {
572 .buffersize = 0x4000,
573 }
574 }
575 },
576 }},
577 .i2c_algo = &m9206_i2c_algo,
578
579 .num_device_descs = 1,
580 .devices = {
581 { "MSI DIGI VOX mini II DVB-T USB2.0",
582 { &m920x_table[1], NULL },
583 { NULL },
505 }, 584 },
506 } 585 }
507}; 586};
diff --git a/drivers/media/dvb/dvb-usb/m920x.h b/drivers/media/dvb/dvb-usb/m920x.h
index c354196ffe5d..7dd3db65c80e 100644
--- a/drivers/media/dvb/dvb-usb/m920x.h
+++ b/drivers/media/dvb/dvb-usb/m920x.h
@@ -19,17 +19,49 @@
19 19
20#define M9206_MAX_FILTERS 8 20#define M9206_MAX_FILTERS 8
21 21
22#define M9206_I2C_TUNER 0 22/*
23#define M9206_I2C_DEMOD 1 23sequences found in logs:
24#define M9206_I2C_MAX 2 24[index value]
250x80 write addr
26(0x00 out byte)*
270x40 out byte
28
290x80 write addr
30(0x00 out byte)*
310x80 read addr
32(0x21 in byte)*
330x60 in byte
34
35this sequence works:
360x80 read addr
37(0x21 in byte)*
380x60 in byte
39
40Guess at API of the I2C function:
41I2C operation is done one byte at a time with USB control messages. The
42index the messages is sent to is made up of a set of flags that control
43the I2C bus state:
440x80: Send START condition. After a START condition, one would normally
45 always send the 7-bit slave I2C address as the 7 MSB, followed by
46 the read/write bit as the LSB.
470x40: Send STOP condition. This should be set on the last byte of an
48 I2C transaction.
490x20: Read a byte from the slave. As opposed to writing a byte to the
50 slave. The slave will normally not produce any data unless you
51 set the R/W bit to 1 when sending the slave's address after the
52 START condition.
530x01: Respond with ACK, as opposed to a NACK. For a multi-byte read,
54 the master should send an ACK, that is pull SDA low during the 9th
55 clock cycle, after every byte but the last. This flags only makes
56 sense when bit 0x20 is set, indicating a read.
57
58What any other bits might mean, or how to get the slave's ACK/NACK
59response to a write, is unknown.
60*/
25 61
26struct m9206_state { 62struct m9206_state {
27 u16 filters[M9206_MAX_FILTERS]; 63 u16 filters[M9206_MAX_FILTERS];
28 int filtering_enabled; 64 int filtering_enabled;
29 int rep_count; 65 int rep_count;
30 struct {
31 unsigned char addr;
32 unsigned char magic;
33 }i2c_r[M9206_I2C_MAX];
34}; 66};
35#endif 67#endif
diff --git a/drivers/media/dvb/dvb-usb/opera1.c b/drivers/media/dvb/dvb-usb/opera1.c
new file mode 100644
index 000000000000..518d7ad217df
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/opera1.c
@@ -0,0 +1,581 @@
1/* DVB USB framework compliant Linux driver for the Opera1 DVB-S Card
2*
3* Copyright (C) 2006 Mario Hlawitschka (dh1pa@amsat.org)
4* Copyright (C) 2006 Marco Gittler (g.marco@freenet.de)
5*
6* This program is free software; you can redistribute it and/or modify it
7* under the terms of the GNU General Public License as published by the Free
8* Software Foundation, version 2.
9*
10* see Documentation/dvb/README.dvb-usb for more information
11*/
12
13#include "opera1.h"
14#include "stv0299.h"
15
16#define OPERA_READ_MSG 0
17#define OPERA_WRITE_MSG 1
18#define OPERA_I2C_TUNER 0xd1
19
20#define READ_FX2_REG_REQ 0xba
21#define READ_MAC_ADDR 0x08
22#define OPERA_WRITE_FX2 0xbb
23#define OPERA_TUNER_REQ 0xb1
24#define REG_1F_SYMBOLRATE_BYTE0 0x1f
25#define REG_20_SYMBOLRATE_BYTE1 0x20
26#define REG_21_SYMBOLRATE_BYTE2 0x21
27
28#define ADDR_B600_VOLTAGE_13V (0x02)
29#define ADDR_B601_VOLTAGE_18V (0x03)
30#define ADDR_B1A6_STREAM_CTRL (0x04)
31#define ADDR_B880_READ_REMOTE (0x05)
32
33struct opera1_state {
34 u32 last_key_pressed;
35};
36struct opera_rc_keys {
37 u32 keycode;
38 u32 event;
39};
40
41int dvb_usb_opera1_debug;
42module_param_named(debug, dvb_usb_opera1_debug, int, 0644);
43MODULE_PARM_DESC(debug,
44 "set debugging level (1=info,xfer=2,pll=4,ts=8,err=16,rc=32,fw=64 (or-able))."
45 DVB_USB_DEBUG_STATUS);
46
47static int opera1_xilinx_rw(struct usb_device *dev, u8 request, u16 value,
48 u8 * data, u16 len, int flags)
49{
50 int ret;
51 u8 r;
52 u8 u8buf[len];
53
54 unsigned int pipe = (flags == OPERA_READ_MSG) ?
55 usb_rcvctrlpipe(dev,0) : usb_sndctrlpipe(dev, 0);
56 u8 request_type = (flags == OPERA_READ_MSG) ? USB_DIR_IN : USB_DIR_OUT;
57
58 if (flags == OPERA_WRITE_MSG)
59 memcpy(u8buf, data, len);
60 ret =
61 usb_control_msg(dev, pipe, request, request_type | USB_TYPE_VENDOR,
62 value, 0x0, u8buf, len, 2000);
63
64 if (request == OPERA_TUNER_REQ) {
65 if (usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
66 OPERA_TUNER_REQ, USB_DIR_IN | USB_TYPE_VENDOR,
67 0x01, 0x0, &r, 1, 2000)<1 || r!=0x08)
68 return 0;
69 }
70 if (flags == OPERA_READ_MSG)
71 memcpy(data, u8buf, len);
72 return ret;
73}
74
75/* I2C */
76
77static int opera1_usb_i2c_msgxfer(struct dvb_usb_device *dev, u16 addr,
78 u8 * buf, u16 len)
79{
80 int ret = 0;
81 u8 request;
82 u16 value;
83
84 if (!dev) {
85 info("no usb_device");
86 return -EINVAL;
87 }
88 if (mutex_lock_interruptible(&dev->usb_mutex) < 0)
89 return -EAGAIN;
90
91 switch (addr>>1){
92 case ADDR_B600_VOLTAGE_13V:
93 request=0xb6;
94 value=0x00;
95 break;
96 case ADDR_B601_VOLTAGE_18V:
97 request=0xb6;
98 value=0x01;
99 break;
100 case ADDR_B1A6_STREAM_CTRL:
101 request=0xb1;
102 value=0xa6;
103 break;
104 case ADDR_B880_READ_REMOTE:
105 request=0xb8;
106 value=0x80;
107 break;
108 default:
109 request=0xb1;
110 value=addr;
111 }
112 ret = opera1_xilinx_rw(dev->udev, request,
113 value, buf, len,
114 addr&0x01?OPERA_READ_MSG:OPERA_WRITE_MSG);
115
116 mutex_unlock(&dev->usb_mutex);
117 return ret;
118}
119
120static int opera1_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
121 int num)
122{
123 struct dvb_usb_device *d = i2c_get_adapdata(adap);
124 int i = 0, tmp = 0;
125
126 if (!d)
127 return -ENODEV;
128 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
129 return -EAGAIN;
130
131 for (i = 0; i < num; i++) {
132 if ((tmp = opera1_usb_i2c_msgxfer(d,
133 (msg[i].addr<<1)|(msg[i].flags&I2C_M_RD?0x01:0),
134 msg[i].buf,
135 msg[i].len
136 )!= msg[i].len)) {
137 break;
138 }
139 if (dvb_usb_opera1_debug & 0x10)
140 info("sending i2c mesage %d %d", tmp, msg[i].len);
141 }
142 mutex_unlock(&d->i2c_mutex);
143 return num;
144}
145
146static u32 opera1_i2c_func(struct i2c_adapter *adapter)
147{
148 return I2C_FUNC_I2C;
149}
150
151static struct i2c_algorithm opera1_i2c_algo = {
152 .master_xfer = opera1_i2c_xfer,
153 .functionality = opera1_i2c_func,
154};
155
156static int opera1_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
157{
158 static u8 command_13v[1]={0x00};
159 static u8 command_18v[1]={0x01};
160 struct i2c_msg msg[] = {
161 {.addr = ADDR_B600_VOLTAGE_13V,.flags = 0,.buf = command_13v,.len = 1},
162 };
163 struct dvb_usb_adapter *udev_adap =
164 (struct dvb_usb_adapter *)(fe->dvb->priv);
165 if (voltage == SEC_VOLTAGE_18) {
166 msg[0].addr = ADDR_B601_VOLTAGE_18V;
167 msg[0].buf = command_18v;
168 }
169 i2c_transfer(&udev_adap->dev->i2c_adap, msg, 1);
170 return 0;
171}
172
173static int opera1_stv0299_set_symbol_rate(struct dvb_frontend *fe, u32 srate,
174 u32 ratio)
175{
176 stv0299_writereg(fe, 0x13, 0x98);
177 stv0299_writereg(fe, 0x14, 0x95);
178 stv0299_writereg(fe, REG_1F_SYMBOLRATE_BYTE0, (ratio >> 16) & 0xff);
179 stv0299_writereg(fe, REG_20_SYMBOLRATE_BYTE1, (ratio >> 8) & 0xff);
180 stv0299_writereg(fe, REG_21_SYMBOLRATE_BYTE2, (ratio) & 0xf0);
181 return 0;
182
183}
184static u8 opera1_inittab[] = {
185 0x00, 0xa1,
186 0x01, 0x15,
187 0x02, 0x00,
188 0x03, 0x00,
189 0x04, 0x7d,
190 0x05, 0x05,
191 0x06, 0x02,
192 0x07, 0x00,
193 0x0b, 0x00,
194 0x0c, 0x01,
195 0x0d, 0x81,
196 0x0e, 0x44,
197 0x0f, 0x19,
198 0x10, 0x3f,
199 0x11, 0x84,
200 0x12, 0xda,
201 0x13, 0x98,
202 0x14, 0x95,
203 0x15, 0xc9,
204 0x16, 0xeb,
205 0x17, 0x00,
206 0x18, 0x19,
207 0x19, 0x8b,
208 0x1a, 0x00,
209 0x1b, 0x82,
210 0x1c, 0x7f,
211 0x1d, 0x00,
212 0x1e, 0x00,
213 REG_1F_SYMBOLRATE_BYTE0, 0x06,
214 REG_20_SYMBOLRATE_BYTE1, 0x50,
215 REG_21_SYMBOLRATE_BYTE2, 0x10,
216 0x22, 0x00,
217 0x23, 0x00,
218 0x24, 0x37,
219 0x25, 0xbc,
220 0x26, 0x00,
221 0x27, 0x00,
222 0x28, 0x00,
223 0x29, 0x1e,
224 0x2a, 0x14,
225 0x2b, 0x1f,
226 0x2c, 0x09,
227 0x2d, 0x0a,
228 0x2e, 0x00,
229 0x2f, 0x00,
230 0x30, 0x00,
231 0x31, 0x1f,
232 0x32, 0x19,
233 0x33, 0xfc,
234 0x34, 0x13,
235 0xff, 0xff,
236};
237
238static struct stv0299_config opera1_stv0299_config = {
239 .demod_address = 0xd0>>1,
240 .min_delay_ms = 100,
241 .mclk = 88000000UL,
242 .invert = 1,
243 .skip_reinit = 0,
244 .lock_output = STV0229_LOCKOUTPUT_0,
245 .volt13_op0_op1 = STV0299_VOLT13_OP0,
246 .inittab = opera1_inittab,
247 .set_symbol_rate = opera1_stv0299_set_symbol_rate,
248};
249
250static int opera1_frontend_attach(struct dvb_usb_adapter *d)
251{
252 if ((d->fe =
253 dvb_attach(stv0299_attach, &opera1_stv0299_config,
254 &d->dev->i2c_adap)) != NULL) {
255 d->fe->ops.set_voltage = opera1_set_voltage;
256 return 0;
257 }
258 info("not attached stv0299");
259 return -EIO;
260}
261
262static int opera1_tuner_attach(struct dvb_usb_adapter *adap)
263{
264 dvb_attach(
265 dvb_pll_attach, adap->fe, 0xc0>>1,
266 &adap->dev->i2c_adap, &dvb_pll_opera1
267 );
268 return 0;
269}
270
271static int opera1_power_ctrl(struct dvb_usb_device *d, int onoff)
272{
273 u8 val = onoff ? 0x01 : 0x00;
274
275 if (dvb_usb_opera1_debug)
276 info("power %s", onoff ? "on" : "off");
277 return opera1_xilinx_rw(d->udev, 0xb7, val,
278 &val, 1, OPERA_WRITE_MSG);
279}
280
281static int opera1_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
282{
283 static u8 buf_start[2] = { 0xff, 0x03 };
284 static u8 buf_stop[2] = { 0xff, 0x00 };
285 struct i2c_msg start_tuner[] = {
286 {.addr = ADDR_B1A6_STREAM_CTRL,.buf = onoff ? buf_start : buf_stop,.len = 2},
287 };
288 if (dvb_usb_opera1_debug)
289 info("streaming %s", onoff ? "on" : "off");
290 i2c_transfer(&adap->dev->i2c_adap, start_tuner, 1);
291 return 0;
292}
293
294static int opera1_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid,
295 int onoff)
296{
297 u8 b_pid[3];
298 struct i2c_msg msg[] = {
299 {.addr = ADDR_B1A6_STREAM_CTRL,.buf = b_pid,.len = 3},
300 };
301 if (dvb_usb_opera1_debug)
302 info("pidfilter index: %d pid: %d %s", index, pid,
303 onoff ? "on" : "off");
304 b_pid[0] = (2 * index) + 4;
305 b_pid[1] = onoff ? (pid & 0xff) : (0x00);
306 b_pid[2] = onoff ? ((pid >> 8) & 0xff) : (0x00);
307 i2c_transfer(&adap->dev->i2c_adap, msg, 1);
308 return 0;
309}
310
311static int opera1_pid_filter_control(struct dvb_usb_adapter *adap, int onoff)
312{
313 int u = 0x04;
314 u8 b_pid[3];
315 struct i2c_msg msg[] = {
316 {.addr = ADDR_B1A6_STREAM_CTRL,.buf = b_pid,.len = 3},
317 };
318 if (dvb_usb_opera1_debug)
319 info("%s hw-pidfilter", onoff ? "enable" : "disable");
320 for (; u < 0x7e; u += 2) {
321 b_pid[0] = u;
322 b_pid[1] = 0;
323 b_pid[2] = 0x80;
324 i2c_transfer(&adap->dev->i2c_adap, msg, 1);
325 }
326 return 0;
327}
328
329static struct dvb_usb_rc_key opera1_rc_keys[] = {
330 {0x5f, 0xa0, KEY_1},
331 {0x51, 0xaf, KEY_2},
332 {0x5d, 0xa2, KEY_3},
333 {0x41, 0xbe, KEY_4},
334 {0x0b, 0xf5, KEY_5},
335 {0x43, 0xbd, KEY_6},
336 {0x47, 0xb8, KEY_7},
337 {0x49, 0xb6, KEY_8},
338 {0x05, 0xfa, KEY_9},
339 {0x45, 0xba, KEY_0},
340 {0x09, 0xf6, KEY_UP}, /*chanup */
341 {0x1b, 0xe5, KEY_DOWN}, /*chandown */
342 {0x5d, 0xa3, KEY_LEFT}, /*voldown */
343 {0x5f, 0xa1, KEY_RIGHT}, /*volup */
344 {0x07, 0xf8, KEY_SPACE}, /*tab */
345 {0x1f, 0xe1, KEY_ENTER}, /*play ok */
346 {0x1b, 0xe4, KEY_Z}, /*zoom */
347 {0x59, 0xa6, KEY_M}, /*mute */
348 {0x5b, 0xa5, KEY_F}, /*tv/f */
349 {0x19, 0xe7, KEY_R}, /*rec */
350 {0x01, 0xfe, KEY_S}, /*Stop */
351 {0x03, 0xfd, KEY_P}, /*pause */
352 {0x03, 0xfc, KEY_W}, /*<- -> */
353 {0x07, 0xf9, KEY_C}, /*capture */
354 {0x47, 0xb9, KEY_Q}, /*exit */
355 {0x43, 0xbc, KEY_O}, /*power */
356
357};
358
359static int opera1_rc_query(struct dvb_usb_device *dev, u32 * event, int *state)
360{
361 struct opera1_state *opst = dev->priv;
362 u8 rcbuffer[32];
363 const u16 startmarker1 = 0x10ed;
364 const u16 startmarker2 = 0x11ec;
365 struct i2c_msg read_remote[] = {
366 {.addr = ADDR_B880_READ_REMOTE,.buf = rcbuffer,.flags = I2C_M_RD,.len = 32},
367 };
368 int i = 0;
369 u32 send_key = 0;
370
371 if (i2c_transfer(&dev->i2c_adap, read_remote, 1) == 1) {
372 for (i = 0; i < 32; i++) {
373 if (rcbuffer[i])
374 send_key |= 1;
375 if (i < 31)
376 send_key = send_key << 1;
377 }
378 if (send_key & 0x8000)
379 send_key = (send_key << 1) | (send_key >> 15 & 0x01);
380
381 if (send_key == 0xffff && opst->last_key_pressed != 0) {
382 *state = REMOTE_KEY_REPEAT;
383 *event = opst->last_key_pressed;
384 return 0;
385 }
386 for (; send_key != 0;) {
387 if (send_key >> 16 == startmarker2) {
388 break;
389 } else if (send_key >> 16 == startmarker1) {
390 send_key =
391 (send_key & 0xfffeffff) | (startmarker1 << 16);
392 break;
393 } else
394 send_key >>= 1;
395 }
396
397 if (send_key == 0)
398 return 0;
399
400 send_key = (send_key & 0xffff) | 0x0100;
401
402 for (i = 0; i < ARRAY_SIZE(opera1_rc_keys); i++) {
403 if ((opera1_rc_keys[i].custom * 256 +
404 opera1_rc_keys[i].data) == (send_key & 0xffff)) {
405 *state = REMOTE_KEY_PRESSED;
406 *event = opera1_rc_keys[i].event;
407 opst->last_key_pressed =
408 opera1_rc_keys[i].event;
409 break;
410 }
411 opst->last_key_pressed = 0;
412 }
413 } else
414 *state = REMOTE_NO_KEY_PRESSED;
415 return 0;
416}
417
418static struct usb_device_id opera1_table[] = {
419 {USB_DEVICE(USB_VID_CYPRESS, USB_PID_OPERA1_COLD)},
420 {USB_DEVICE(USB_VID_OPERA1, USB_PID_OPERA1_WARM)},
421 {}
422};
423
424MODULE_DEVICE_TABLE(usb, opera1_table);
425
426static int opera1_read_mac_address(struct dvb_usb_device *d, u8 mac[6])
427{
428 u8 command[] = { READ_MAC_ADDR };
429 opera1_xilinx_rw(d->udev, 0xb1, 0xa0, command, 1, OPERA_WRITE_MSG);
430 opera1_xilinx_rw(d->udev, 0xb1, 0xa1, mac, 6, OPERA_READ_MSG);
431 return 0;
432}
433static int opera1_xilinx_load_firmware(struct usb_device *dev,
434 const char *filename)
435{
436 const struct firmware *fw = NULL;
437 u8 *b, *p;
438 int ret = 0, i;
439 u8 testval;
440 info("start downloading fpga firmware");
441
442 if ((ret = request_firmware(&fw, filename, &dev->dev)) != 0) {
443 err("did not find the firmware file. (%s) "
444 "Please see linux/Documentation/dvb/ for more details on firmware-problems.",
445 filename);
446 return ret;
447 } else {
448 p = kmalloc(fw->size, GFP_KERNEL);
449 opera1_xilinx_rw(dev, 0xbc, 0x00, &testval, 1, OPERA_READ_MSG);
450 if (p != NULL && testval != 0x67) {
451
452 u8 reset = 0, fpga_command = 0;
453 memcpy(p, fw->data, fw->size);
454 /* clear fpga ? */
455 opera1_xilinx_rw(dev, 0xbc, 0xaa, &fpga_command, 1,
456 OPERA_WRITE_MSG);
457 for (i = 0; p[i] != 0 && i < fw->size;) {
458 b = (u8 *) p + i;
459 if (opera1_xilinx_rw
460 (dev, OPERA_WRITE_FX2, 0x0, b + 1, b[0],
461 OPERA_WRITE_MSG) != b[0]
462 ) {
463 err("error while transferring firmware");
464 ret = -EINVAL;
465 break;
466 }
467 i = i + 1 + b[0];
468 }
469 /* restart the CPU */
470 if (ret || opera1_xilinx_rw
471 (dev, 0xa0, 0xe600, &reset, 1,
472 OPERA_WRITE_MSG) != 1) {
473 err("could not restart the USB controller CPU.");
474 ret = -EINVAL;
475 }
476 kfree(p);
477 }
478 }
479 if (fw) {
480 release_firmware(fw);
481 }
482 return ret;
483}
484
485static struct dvb_usb_device_properties opera1_properties = {
486 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
487 .usb_ctrl = CYPRESS_FX2,
488 .firmware = "dvb-usb-opera-01.fw",
489 .size_of_priv = sizeof(struct opera1_state),
490
491 .power_ctrl = opera1_power_ctrl,
492 .i2c_algo = &opera1_i2c_algo,
493
494 .rc_key_map = opera1_rc_keys,
495 .rc_key_map_size = ARRAY_SIZE(opera1_rc_keys),
496 .rc_interval = 200,
497 .rc_query = opera1_rc_query,
498 .read_mac_address = opera1_read_mac_address,
499 .generic_bulk_ctrl_endpoint = 0x00,
500 /* parameter for the MPEG2-data transfer */
501 .num_adapters = 1,
502 .adapter = {
503 {
504 .frontend_attach = opera1_frontend_attach,
505 .streaming_ctrl = opera1_streaming_ctrl,
506 .tuner_attach = opera1_tuner_attach,
507 .caps =
508 DVB_USB_ADAP_HAS_PID_FILTER |
509 DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
510 .pid_filter = opera1_pid_filter,
511 .pid_filter_ctrl = opera1_pid_filter_control,
512 .pid_filter_count = 252,
513 .stream = {
514 .type = USB_BULK,
515 .count = 10,
516 .endpoint = 0x82,
517 .u = {
518 .bulk = {
519 .buffersize = 4096,
520 }
521 }
522 },
523 }
524 },
525 .num_device_descs = 1,
526 .devices = {
527 {"Opera1 DVB-S USB2.0",
528 {&opera1_table[0], NULL},
529 {&opera1_table[1], NULL},
530 },
531 }
532};
533
534static int opera1_probe(struct usb_interface *intf,
535 const struct usb_device_id *id)
536{
537 struct dvb_usb_device *d;
538 struct usb_device *udev = interface_to_usbdev(intf);
539
540 if (udev->descriptor.idProduct == USB_PID_OPERA1_WARM &&
541 udev->descriptor.idVendor == USB_VID_OPERA1 &&
542 (d == NULL
543 || opera1_xilinx_load_firmware(udev, "dvb-usb-opera1-fpga.fw") != 0)
544 ) {
545 return -EINVAL;
546 }
547
548 if (dvb_usb_device_init(intf, &opera1_properties, THIS_MODULE, &d) != 0)
549 return -EINVAL;
550 return 0;
551}
552
553static struct usb_driver opera1_driver = {
554 .name = "opera1",
555 .probe = opera1_probe,
556 .disconnect = dvb_usb_device_exit,
557 .id_table = opera1_table,
558};
559
560static int __init opera1_module_init(void)
561{
562 int result = 0;
563 if ((result = usb_register(&opera1_driver))) {
564 err("usb_register failed. Error number %d", result);
565 }
566 return result;
567}
568
569static void __exit opera1_module_exit(void)
570{
571 usb_deregister(&opera1_driver);
572}
573
574module_init(opera1_module_init);
575module_exit(opera1_module_exit);
576
577MODULE_AUTHOR("Mario Hlawitschka (c) dh1pa@amsat.org");
578MODULE_AUTHOR("Marco Gittler (c) g.marco@freenet.de");
579MODULE_DESCRIPTION("Driver for Opera1 DVB-S device");
580MODULE_VERSION("0.1");
581MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/opera1.h b/drivers/media/dvb/dvb-usb/opera1.h
new file mode 100644
index 000000000000..53174427902d
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/opera1.h
@@ -0,0 +1,9 @@
1#ifndef _OPERA1_H_
2#define _OPERA1_H_
3
4#define DVB_USB_LOG_PREFIX "opera"
5#include "dvb-usb.h"
6
7extern int dvb_usb_opera1_debug;
8#define deb_xfer(args...) dprintk(dvb_usb_opera1_debug,0x02,args)
9#endif
diff --git a/drivers/media/dvb/dvb-usb/ttusb2.c b/drivers/media/dvb/dvb-usb/ttusb2.c
index 95d29976ed78..88dc4367a2e3 100644
--- a/drivers/media/dvb/dvb-usb/ttusb2.c
+++ b/drivers/media/dvb/dvb-usb/ttusb2.c
@@ -184,6 +184,7 @@ static int ttusb2_probe(struct usb_interface *intf,
184 184
185static struct usb_device_id ttusb2_table [] = { 185static struct usb_device_id ttusb2_table [] = {
186 { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PCTV_400E) }, 186 { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PCTV_400E) },
187 { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PCTV_450E) },
187 {} /* Terminating entry */ 188 {} /* Terminating entry */
188}; 189};
189MODULE_DEVICE_TABLE (usb, ttusb2_table); 190MODULE_DEVICE_TABLE (usb, ttusb2_table);
@@ -227,12 +228,16 @@ static struct dvb_usb_device_properties ttusb2_properties = {
227 228
228 .generic_bulk_ctrl_endpoint = 0x01, 229 .generic_bulk_ctrl_endpoint = 0x01,
229 230
230 .num_device_descs = 1, 231 .num_device_descs = 2,
231 .devices = { 232 .devices = {
232 { "Pinnacle 400e DVB-S USB2.0", 233 { "Pinnacle 400e DVB-S USB2.0",
233 { &ttusb2_table[0], NULL }, 234 { &ttusb2_table[0], NULL },
234 { NULL }, 235 { NULL },
235 }, 236 },
237 { "Pinnacle 450e DVB-S USB2.0",
238 { &ttusb2_table[1], NULL },
239 { NULL },
240 },
236 } 241 }
237}; 242};
238 243
diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig
index 22c2cf2cea98..ff448761dcef 100644
--- a/drivers/media/dvb/frontends/Kconfig
+++ b/drivers/media/dvb/frontends/Kconfig
@@ -205,6 +205,13 @@ config DVB_TDA10021
205 help 205 help
206 A DVB-C tuner module. Say Y when you want to support this frontend. 206 A DVB-C tuner module. Say Y when you want to support this frontend.
207 207
208config DVB_TDA10023
209 tristate "Philips TDA10023 based"
210 depends on DVB_CORE && I2C
211 default m if DVB_FE_CUSTOMISE
212 help
213 A DVB-C tuner module. Say Y when you want to support this frontend.
214
208config DVB_STV0297 215config DVB_STV0297
209 tristate "ST STV0297 based" 216 tristate "ST STV0297 based"
210 depends on DVB_CORE && I2C 217 depends on DVB_CORE && I2C
@@ -280,8 +287,12 @@ comment "Tuners/PLL support"
280 depends on DVB_CORE 287 depends on DVB_CORE
281 288
282config DVB_PLL 289config DVB_PLL
283 tristate 290 tristate "Generic I2C PLL based tuners"
284 depends on DVB_CORE && I2C 291 depends on DVB_CORE && I2C
292 default m if DVB_FE_CUSTOMISE
293 help
294 This module driver a number of tuners based on PLL chips with a
295 common I2C interface. Say Y when you want to support these tuners.
285 296
286config DVB_TDA826X 297config DVB_TDA826X
287 tristate "Philips TDA826X silicon tuner" 298 tristate "Philips TDA826X silicon tuner"
@@ -290,6 +301,13 @@ config DVB_TDA826X
290 help 301 help
291 A DVB-S silicon tuner module. Say Y when you want to support this tuner. 302 A DVB-S silicon tuner module. Say Y when you want to support this tuner.
292 303
304config DVB_TDA827X
305 tristate "Philips TDA827X silicon tuner"
306 depends on DVB_CORE && I2C
307 default m if DVB_FE_CUSTOMISE
308 help
309 A DVB-T silicon tuner module. Say Y when you want to support this tuner.
310
293config DVB_TUNER_QT1010 311config DVB_TUNER_QT1010
294 tristate "Quantek QT1010 silicon tuner" 312 tristate "Quantek QT1010 silicon tuner"
295 depends on DVB_CORE && I2C 313 depends on DVB_CORE && I2C
@@ -304,14 +322,6 @@ config DVB_TUNER_MT2060
304 help 322 help
305 A driver for the silicon IF tuner MT2060 from Microtune. 323 A driver for the silicon IF tuner MT2060 from Microtune.
306 324
307config DVB_TUNER_LGH06XF
308 tristate "LG TDVS-H06xF ATSC tuner"
309 depends on DVB_CORE && I2C
310 select DVB_PLL
311 default m if DVB_FE_CUSTOMISE
312 help
313 A driver for the LG TDVS-H06xF ATSC tuner family.
314
315comment "Miscellaneous devices" 325comment "Miscellaneous devices"
316 depends on DVB_CORE 326 depends on DVB_CORE
317 327
diff --git a/drivers/media/dvb/frontends/Makefile b/drivers/media/dvb/frontends/Makefile
index a646d9969b71..27f386585d43 100644
--- a/drivers/media/dvb/frontends/Makefile
+++ b/drivers/media/dvb/frontends/Makefile
@@ -25,6 +25,7 @@ obj-$(CONFIG_DVB_MT352) += mt352.o
25obj-$(CONFIG_DVB_ZL10353) += zl10353.o 25obj-$(CONFIG_DVB_ZL10353) += zl10353.o
26obj-$(CONFIG_DVB_CX22702) += cx22702.o 26obj-$(CONFIG_DVB_CX22702) += cx22702.o
27obj-$(CONFIG_DVB_TDA10021) += tda10021.o 27obj-$(CONFIG_DVB_TDA10021) += tda10021.o
28obj-$(CONFIG_DVB_TDA10023) += tda10023.o
28obj-$(CONFIG_DVB_STV0297) += stv0297.o 29obj-$(CONFIG_DVB_STV0297) += stv0297.o
29obj-$(CONFIG_DVB_NXT200X) += nxt200x.o 30obj-$(CONFIG_DVB_NXT200X) += nxt200x.o
30obj-$(CONFIG_DVB_OR51211) += or51211.o 31obj-$(CONFIG_DVB_OR51211) += or51211.o
@@ -37,7 +38,7 @@ obj-$(CONFIG_DVB_LNBP21) += lnbp21.o
37obj-$(CONFIG_DVB_ISL6421) += isl6421.o 38obj-$(CONFIG_DVB_ISL6421) += isl6421.o
38obj-$(CONFIG_DVB_TDA10086) += tda10086.o 39obj-$(CONFIG_DVB_TDA10086) += tda10086.o
39obj-$(CONFIG_DVB_TDA826X) += tda826x.o 40obj-$(CONFIG_DVB_TDA826X) += tda826x.o
41obj-$(CONFIG_DVB_TDA827X) += tda827x.o
40obj-$(CONFIG_DVB_TUNER_MT2060) += mt2060.o 42obj-$(CONFIG_DVB_TUNER_MT2060) += mt2060.o
41obj-$(CONFIG_DVB_TUNER_QT1010) += qt1010.o 43obj-$(CONFIG_DVB_TUNER_QT1010) += qt1010.o
42obj-$(CONFIG_DVB_TUA6100) += tua6100.o 44obj-$(CONFIG_DVB_TUA6100) += tua6100.o
43obj-$(CONFIG_DVB_TUNER_LGH06XF) += lgh06xf.o
diff --git a/drivers/media/dvb/frontends/dvb-pll.c b/drivers/media/dvb/frontends/dvb-pll.c
index 62de760c844f..5f96ffda91ad 100644
--- a/drivers/media/dvb/frontends/dvb-pll.c
+++ b/drivers/media/dvb/frontends/dvb-pll.c
@@ -27,17 +27,29 @@
27/* ----------------------------------------------------------- */ 27/* ----------------------------------------------------------- */
28/* descriptions */ 28/* descriptions */
29 29
30/* Set AGC TOP value to 103 dBuV:
31 0x80 = Control Byte
32 0x40 = 250 uA charge pump (irrelevant)
33 0x18 = Aux Byte to follow
34 0x06 = 64.5 kHz divider (irrelevant)
35 0x01 = Disable Vt (aka sleep)
36
37 0x00 = AGC Time constant 2s Iagc = 300 nA (vs 0x80 = 9 nA)
38 0x50 = AGC Take over point = 103 dBuV */
39static u8 tua603x_agc103[] = { 2, 0x80|0x40|0x18|0x06|0x01, 0x00|0x50 };
40
30struct dvb_pll_desc dvb_pll_thomson_dtt7579 = { 41struct dvb_pll_desc dvb_pll_thomson_dtt7579 = {
31 .name = "Thomson dtt7579", 42 .name = "Thomson dtt7579",
32 .min = 177000000, 43 .min = 177000000,
33 .max = 858000000, 44 .max = 858000000,
34 .count = 5, 45 .iffreq= 36166667,
46 .sleepdata = (u8[]){ 2, 0xb4, 0x03 },
47 .count = 4,
35 .entries = { 48 .entries = {
36 { 0, 36166667, 166666, 0xb4, 0x03 }, /* go sleep */ 49 { 443250000, 166667, 0xb4, 0x02 },
37 { 443250000, 36166667, 166666, 0xb4, 0x02 }, 50 { 542000000, 166667, 0xb4, 0x08 },
38 { 542000000, 36166667, 166666, 0xb4, 0x08 }, 51 { 771000000, 166667, 0xbc, 0x08 },
39 { 771000000, 36166667, 166666, 0xbc, 0x08 }, 52 { 999999999, 166667, 0xf4, 0x08 },
40 { 999999999, 36166667, 166666, 0xf4, 0x08 },
41 }, 53 },
42}; 54};
43EXPORT_SYMBOL(dvb_pll_thomson_dtt7579); 55EXPORT_SYMBOL(dvb_pll_thomson_dtt7579);
@@ -46,11 +58,12 @@ struct dvb_pll_desc dvb_pll_thomson_dtt7610 = {
46 .name = "Thomson dtt7610", 58 .name = "Thomson dtt7610",
47 .min = 44000000, 59 .min = 44000000,
48 .max = 958000000, 60 .max = 958000000,
61 .iffreq= 44000000,
49 .count = 3, 62 .count = 3,
50 .entries = { 63 .entries = {
51 { 157250000, 44000000, 62500, 0x8e, 0x39 }, 64 { 157250000, 62500, 0x8e, 0x39 },
52 { 454000000, 44000000, 62500, 0x8e, 0x3a }, 65 { 454000000, 62500, 0x8e, 0x3a },
53 { 999999999, 44000000, 62500, 0x8e, 0x3c }, 66 { 999999999, 62500, 0x8e, 0x3c },
54 }, 67 },
55}; 68};
56EXPORT_SYMBOL(dvb_pll_thomson_dtt7610); 69EXPORT_SYMBOL(dvb_pll_thomson_dtt7610);
@@ -66,14 +79,15 @@ struct dvb_pll_desc dvb_pll_thomson_dtt759x = {
66 .min = 177000000, 79 .min = 177000000,
67 .max = 896000000, 80 .max = 896000000,
68 .setbw = thomson_dtt759x_bw, 81 .setbw = thomson_dtt759x_bw,
69 .count = 6, 82 .iffreq= 36166667,
83 .sleepdata = (u8[]){ 2, 0x84, 0x03 },
84 .count = 5,
70 .entries = { 85 .entries = {
71 { 0, 36166667, 166666, 0x84, 0x03 }, 86 { 264000000, 166667, 0xb4, 0x02 },
72 { 264000000, 36166667, 166666, 0xb4, 0x02 }, 87 { 470000000, 166667, 0xbc, 0x02 },
73 { 470000000, 36166667, 166666, 0xbc, 0x02 }, 88 { 735000000, 166667, 0xbc, 0x08 },
74 { 735000000, 36166667, 166666, 0xbc, 0x08 }, 89 { 835000000, 166667, 0xf4, 0x08 },
75 { 835000000, 36166667, 166666, 0xf4, 0x08 }, 90 { 999999999, 166667, 0xfc, 0x08 },
76 { 999999999, 36166667, 166666, 0xfc, 0x08 },
77 }, 91 },
78}; 92};
79EXPORT_SYMBOL(dvb_pll_thomson_dtt759x); 93EXPORT_SYMBOL(dvb_pll_thomson_dtt759x);
@@ -82,14 +96,15 @@ struct dvb_pll_desc dvb_pll_lg_z201 = {
82 .name = "LG z201", 96 .name = "LG z201",
83 .min = 174000000, 97 .min = 174000000,
84 .max = 862000000, 98 .max = 862000000,
85 .count = 6, 99 .iffreq= 36166667,
100 .sleepdata = (u8[]){ 2, 0xbc, 0x03 },
101 .count = 5,
86 .entries = { 102 .entries = {
87 { 0, 36166667, 166666, 0xbc, 0x03 }, 103 { 157500000, 166667, 0xbc, 0x01 },
88 { 157500000, 36166667, 166666, 0xbc, 0x01 }, 104 { 443250000, 166667, 0xbc, 0x02 },
89 { 443250000, 36166667, 166666, 0xbc, 0x02 }, 105 { 542000000, 166667, 0xbc, 0x04 },
90 { 542000000, 36166667, 166666, 0xbc, 0x04 }, 106 { 830000000, 166667, 0xf4, 0x04 },
91 { 830000000, 36166667, 166666, 0xf4, 0x04 }, 107 { 999999999, 166667, 0xfc, 0x04 },
92 { 999999999, 36166667, 166666, 0xfc, 0x04 },
93 }, 108 },
94}; 109};
95EXPORT_SYMBOL(dvb_pll_lg_z201); 110EXPORT_SYMBOL(dvb_pll_lg_z201);
@@ -98,11 +113,12 @@ struct dvb_pll_desc dvb_pll_microtune_4042 = {
98 .name = "Microtune 4042 FI5", 113 .name = "Microtune 4042 FI5",
99 .min = 57000000, 114 .min = 57000000,
100 .max = 858000000, 115 .max = 858000000,
116 .iffreq= 44000000,
101 .count = 3, 117 .count = 3,
102 .entries = { 118 .entries = {
103 { 162000000, 44000000, 62500, 0x8e, 0xa1 }, 119 { 162000000, 62500, 0x8e, 0xa1 },
104 { 457000000, 44000000, 62500, 0x8e, 0x91 }, 120 { 457000000, 62500, 0x8e, 0x91 },
105 { 999999999, 44000000, 62500, 0x8e, 0x31 }, 121 { 999999999, 62500, 0x8e, 0x31 },
106 }, 122 },
107}; 123};
108EXPORT_SYMBOL(dvb_pll_microtune_4042); 124EXPORT_SYMBOL(dvb_pll_microtune_4042);
@@ -112,11 +128,13 @@ struct dvb_pll_desc dvb_pll_thomson_dtt761x = {
112 .name = "Thomson dtt761x", 128 .name = "Thomson dtt761x",
113 .min = 57000000, 129 .min = 57000000,
114 .max = 863000000, 130 .max = 863000000,
131 .iffreq= 44000000,
115 .count = 3, 132 .count = 3,
133 .initdata = tua603x_agc103,
116 .entries = { 134 .entries = {
117 { 147000000, 44000000, 62500, 0x8e, 0x39 }, 135 { 147000000, 62500, 0x8e, 0x39 },
118 { 417000000, 44000000, 62500, 0x8e, 0x3a }, 136 { 417000000, 62500, 0x8e, 0x3a },
119 { 999999999, 44000000, 62500, 0x8e, 0x3c }, 137 { 999999999, 62500, 0x8e, 0x3c },
120 }, 138 },
121}; 139};
122EXPORT_SYMBOL(dvb_pll_thomson_dtt761x); 140EXPORT_SYMBOL(dvb_pll_thomson_dtt761x);
@@ -125,17 +143,18 @@ struct dvb_pll_desc dvb_pll_unknown_1 = {
125 .name = "unknown 1", /* used by dntv live dvb-t */ 143 .name = "unknown 1", /* used by dntv live dvb-t */
126 .min = 174000000, 144 .min = 174000000,
127 .max = 862000000, 145 .max = 862000000,
146 .iffreq= 36166667,
128 .count = 9, 147 .count = 9,
129 .entries = { 148 .entries = {
130 { 150000000, 36166667, 166666, 0xb4, 0x01 }, 149 { 150000000, 166667, 0xb4, 0x01 },
131 { 173000000, 36166667, 166666, 0xbc, 0x01 }, 150 { 173000000, 166667, 0xbc, 0x01 },
132 { 250000000, 36166667, 166666, 0xb4, 0x02 }, 151 { 250000000, 166667, 0xb4, 0x02 },
133 { 400000000, 36166667, 166666, 0xbc, 0x02 }, 152 { 400000000, 166667, 0xbc, 0x02 },
134 { 420000000, 36166667, 166666, 0xf4, 0x02 }, 153 { 420000000, 166667, 0xf4, 0x02 },
135 { 470000000, 36166667, 166666, 0xfc, 0x02 }, 154 { 470000000, 166667, 0xfc, 0x02 },
136 { 600000000, 36166667, 166666, 0xbc, 0x08 }, 155 { 600000000, 166667, 0xbc, 0x08 },
137 { 730000000, 36166667, 166666, 0xf4, 0x08 }, 156 { 730000000, 166667, 0xf4, 0x08 },
138 { 999999999, 36166667, 166666, 0xfc, 0x08 }, 157 { 999999999, 166667, 0xfc, 0x08 },
139 }, 158 },
140}; 159};
141EXPORT_SYMBOL(dvb_pll_unknown_1); 160EXPORT_SYMBOL(dvb_pll_unknown_1);
@@ -147,11 +166,12 @@ struct dvb_pll_desc dvb_pll_tua6010xs = {
147 .name = "Infineon TUA6010XS", 166 .name = "Infineon TUA6010XS",
148 .min = 44250000, 167 .min = 44250000,
149 .max = 858000000, 168 .max = 858000000,
169 .iffreq= 36125000,
150 .count = 3, 170 .count = 3,
151 .entries = { 171 .entries = {
152 { 115750000, 36125000, 62500, 0x8e, 0x03 }, 172 { 115750000, 62500, 0x8e, 0x03 },
153 { 403250000, 36125000, 62500, 0x8e, 0x06 }, 173 { 403250000, 62500, 0x8e, 0x06 },
154 { 999999999, 36125000, 62500, 0x8e, 0x85 }, 174 { 999999999, 62500, 0x8e, 0x85 },
155 }, 175 },
156}; 176};
157EXPORT_SYMBOL(dvb_pll_tua6010xs); 177EXPORT_SYMBOL(dvb_pll_tua6010xs);
@@ -161,12 +181,13 @@ struct dvb_pll_desc dvb_pll_env57h1xd5 = {
161 .name = "Panasonic ENV57H1XD5", 181 .name = "Panasonic ENV57H1XD5",
162 .min = 44250000, 182 .min = 44250000,
163 .max = 858000000, 183 .max = 858000000,
184 .iffreq= 36125000,
164 .count = 4, 185 .count = 4,
165 .entries = { 186 .entries = {
166 { 153000000, 36291666, 166666, 0xc2, 0x41 }, 187 { 153000000, 166667, 0xc2, 0x41 },
167 { 470000000, 36291666, 166666, 0xc2, 0x42 }, 188 { 470000000, 166667, 0xc2, 0x42 },
168 { 526000000, 36291666, 166666, 0xc2, 0x84 }, 189 { 526000000, 166667, 0xc2, 0x84 },
169 { 999999999, 36291666, 166666, 0xc2, 0xa4 }, 190 { 999999999, 166667, 0xc2, 0xa4 },
170 }, 191 },
171}; 192};
172EXPORT_SYMBOL(dvb_pll_env57h1xd5); 193EXPORT_SYMBOL(dvb_pll_env57h1xd5);
@@ -185,20 +206,21 @@ struct dvb_pll_desc dvb_pll_tda665x = {
185 .min = 44250000, 206 .min = 44250000,
186 .max = 858000000, 207 .max = 858000000,
187 .setbw = tda665x_bw, 208 .setbw = tda665x_bw,
209 .iffreq= 36166667,
188 .count = 12, 210 .count = 12,
189 .entries = { 211 .entries = {
190 { 93834000, 36249333, 166667, 0xca, 0x61 /* 011 0 0 0 01 */ }, 212 { 93834000, 166667, 0xca, 0x61 /* 011 0 0 0 01 */ },
191 { 123834000, 36249333, 166667, 0xca, 0xa1 /* 101 0 0 0 01 */ }, 213 { 123834000, 166667, 0xca, 0xa1 /* 101 0 0 0 01 */ },
192 { 161000000, 36249333, 166667, 0xca, 0xa1 /* 101 0 0 0 01 */ }, 214 { 161000000, 166667, 0xca, 0xa1 /* 101 0 0 0 01 */ },
193 { 163834000, 36249333, 166667, 0xca, 0xc2 /* 110 0 0 0 10 */ }, 215 { 163834000, 166667, 0xca, 0xc2 /* 110 0 0 0 10 */ },
194 { 253834000, 36249333, 166667, 0xca, 0x62 /* 011 0 0 0 10 */ }, 216 { 253834000, 166667, 0xca, 0x62 /* 011 0 0 0 10 */ },
195 { 383834000, 36249333, 166667, 0xca, 0xa2 /* 101 0 0 0 10 */ }, 217 { 383834000, 166667, 0xca, 0xa2 /* 101 0 0 0 10 */ },
196 { 443834000, 36249333, 166667, 0xca, 0xc2 /* 110 0 0 0 10 */ }, 218 { 443834000, 166667, 0xca, 0xc2 /* 110 0 0 0 10 */ },
197 { 444000000, 36249333, 166667, 0xca, 0xc4 /* 110 0 0 1 00 */ }, 219 { 444000000, 166667, 0xca, 0xc4 /* 110 0 0 1 00 */ },
198 { 583834000, 36249333, 166667, 0xca, 0x64 /* 011 0 0 1 00 */ }, 220 { 583834000, 166667, 0xca, 0x64 /* 011 0 0 1 00 */ },
199 { 793834000, 36249333, 166667, 0xca, 0xa4 /* 101 0 0 1 00 */ }, 221 { 793834000, 166667, 0xca, 0xa4 /* 101 0 0 1 00 */ },
200 { 444834000, 36249333, 166667, 0xca, 0xc4 /* 110 0 0 1 00 */ }, 222 { 444834000, 166667, 0xca, 0xc4 /* 110 0 0 1 00 */ },
201 { 861000000, 36249333, 166667, 0xca, 0xe4 /* 111 0 0 1 00 */ }, 223 { 861000000, 166667, 0xca, 0xe4 /* 111 0 0 1 00 */ },
202 } 224 }
203}; 225};
204EXPORT_SYMBOL(dvb_pll_tda665x); 226EXPORT_SYMBOL(dvb_pll_tda665x);
@@ -216,12 +238,13 @@ struct dvb_pll_desc dvb_pll_tua6034 = {
216 .name = "Infineon TUA6034", 238 .name = "Infineon TUA6034",
217 .min = 44250000, 239 .min = 44250000,
218 .max = 858000000, 240 .max = 858000000,
241 .iffreq= 36166667,
219 .count = 3, 242 .count = 3,
220 .setbw = tua6034_bw, 243 .setbw = tua6034_bw,
221 .entries = { 244 .entries = {
222 { 174500000, 36166667, 62500, 0xce, 0x01 }, 245 { 174500000, 62500, 0xce, 0x01 },
223 { 230000000, 36166667, 62500, 0xce, 0x02 }, 246 { 230000000, 62500, 0xce, 0x02 },
224 { 999999999, 36166667, 62500, 0xce, 0x04 }, 247 { 999999999, 62500, 0xce, 0x04 },
225 }, 248 },
226}; 249};
227EXPORT_SYMBOL(dvb_pll_tua6034); 250EXPORT_SYMBOL(dvb_pll_tua6034);
@@ -233,11 +256,13 @@ struct dvb_pll_desc dvb_pll_lg_tdvs_h06xf = {
233 .name = "LG TDVS-H06xF", 256 .name = "LG TDVS-H06xF",
234 .min = 54000000, 257 .min = 54000000,
235 .max = 863000000, 258 .max = 863000000,
259 .iffreq= 44000000,
260 .initdata = tua603x_agc103,
236 .count = 3, 261 .count = 3,
237 .entries = { 262 .entries = {
238 { 165000000, 44000000, 62500, 0xce, 0x01 }, 263 { 165000000, 62500, 0xce, 0x01 },
239 { 450000000, 44000000, 62500, 0xce, 0x02 }, 264 { 450000000, 62500, 0xce, 0x02 },
240 { 999999999, 44000000, 62500, 0xce, 0x04 }, 265 { 999999999, 62500, 0xce, 0x04 },
241 }, 266 },
242}; 267};
243EXPORT_SYMBOL(dvb_pll_lg_tdvs_h06xf); 268EXPORT_SYMBOL(dvb_pll_lg_tdvs_h06xf);
@@ -255,16 +280,17 @@ struct dvb_pll_desc dvb_pll_fmd1216me = {
255 .name = "Philips FMD1216ME", 280 .name = "Philips FMD1216ME",
256 .min = 50870000, 281 .min = 50870000,
257 .max = 858000000, 282 .max = 858000000,
283 .iffreq= 36125000,
258 .setbw = fmd1216me_bw, 284 .setbw = fmd1216me_bw,
259 .count = 7, 285 .count = 7,
260 .entries = { 286 .entries = {
261 { 143870000, 36213333, 166667, 0xbc, 0x41 }, 287 { 143870000, 166667, 0xbc, 0x41 },
262 { 158870000, 36213333, 166667, 0xf4, 0x41 }, 288 { 158870000, 166667, 0xf4, 0x41 },
263 { 329870000, 36213333, 166667, 0xbc, 0x42 }, 289 { 329870000, 166667, 0xbc, 0x42 },
264 { 441870000, 36213333, 166667, 0xf4, 0x42 }, 290 { 441870000, 166667, 0xf4, 0x42 },
265 { 625870000, 36213333, 166667, 0xbc, 0x44 }, 291 { 625870000, 166667, 0xbc, 0x44 },
266 { 803870000, 36213333, 166667, 0xf4, 0x44 }, 292 { 803870000, 166667, 0xf4, 0x44 },
267 { 999999999, 36213333, 166667, 0xfc, 0x44 }, 293 { 999999999, 166667, 0xfc, 0x44 },
268 } 294 }
269}; 295};
270EXPORT_SYMBOL(dvb_pll_fmd1216me); 296EXPORT_SYMBOL(dvb_pll_fmd1216me);
@@ -282,13 +308,14 @@ struct dvb_pll_desc dvb_pll_tded4 = {
282 .name = "ALPS TDED4", 308 .name = "ALPS TDED4",
283 .min = 47000000, 309 .min = 47000000,
284 .max = 863000000, 310 .max = 863000000,
311 .iffreq= 36166667,
285 .setbw = tded4_bw, 312 .setbw = tded4_bw,
286 .count = 4, 313 .count = 4,
287 .entries = { 314 .entries = {
288 { 153000000, 36166667, 166667, 0x85, 0x01 }, 315 { 153000000, 166667, 0x85, 0x01 },
289 { 470000000, 36166667, 166667, 0x85, 0x02 }, 316 { 470000000, 166667, 0x85, 0x02 },
290 { 823000000, 36166667, 166667, 0x85, 0x08 }, 317 { 823000000, 166667, 0x85, 0x08 },
291 { 999999999, 36166667, 166667, 0x85, 0x88 }, 318 { 999999999, 166667, 0x85, 0x88 },
292 } 319 }
293}; 320};
294EXPORT_SYMBOL(dvb_pll_tded4); 321EXPORT_SYMBOL(dvb_pll_tded4);
@@ -300,12 +327,13 @@ struct dvb_pll_desc dvb_pll_tdhu2 = {
300 .name = "ALPS TDHU2", 327 .name = "ALPS TDHU2",
301 .min = 54000000, 328 .min = 54000000,
302 .max = 864000000, 329 .max = 864000000,
330 .iffreq= 44000000,
303 .count = 4, 331 .count = 4,
304 .entries = { 332 .entries = {
305 { 162000000, 44000000, 62500, 0x85, 0x01 }, 333 { 162000000, 62500, 0x85, 0x01 },
306 { 426000000, 44000000, 62500, 0x85, 0x02 }, 334 { 426000000, 62500, 0x85, 0x02 },
307 { 782000000, 44000000, 62500, 0x85, 0x08 }, 335 { 782000000, 62500, 0x85, 0x08 },
308 { 999999999, 44000000, 62500, 0x85, 0x88 }, 336 { 999999999, 62500, 0x85, 0x88 },
309 } 337 }
310}; 338};
311EXPORT_SYMBOL(dvb_pll_tdhu2); 339EXPORT_SYMBOL(dvb_pll_tdhu2);
@@ -317,11 +345,12 @@ struct dvb_pll_desc dvb_pll_tuv1236d = {
317 .name = "Philips TUV1236D", 345 .name = "Philips TUV1236D",
318 .min = 54000000, 346 .min = 54000000,
319 .max = 864000000, 347 .max = 864000000,
348 .iffreq= 44000000,
320 .count = 3, 349 .count = 3,
321 .entries = { 350 .entries = {
322 { 157250000, 44000000, 62500, 0xc6, 0x41 }, 351 { 157250000, 62500, 0xc6, 0x41 },
323 { 454000000, 44000000, 62500, 0xc6, 0x42 }, 352 { 454000000, 62500, 0xc6, 0x42 },
324 { 999999999, 44000000, 62500, 0xc6, 0x44 }, 353 { 999999999, 62500, 0xc6, 0x44 },
325 }, 354 },
326}; 355};
327EXPORT_SYMBOL(dvb_pll_tuv1236d); 356EXPORT_SYMBOL(dvb_pll_tuv1236d);
@@ -333,14 +362,15 @@ struct dvb_pll_desc dvb_pll_samsung_tbmv = {
333 .name = "Samsung TBMV30111IN / TBMV30712IN1", 362 .name = "Samsung TBMV30111IN / TBMV30712IN1",
334 .min = 54000000, 363 .min = 54000000,
335 .max = 860000000, 364 .max = 860000000,
365 .iffreq= 44000000,
336 .count = 6, 366 .count = 6,
337 .entries = { 367 .entries = {
338 { 172000000, 44000000, 166666, 0xb4, 0x01 }, 368 { 172000000, 166667, 0xb4, 0x01 },
339 { 214000000, 44000000, 166666, 0xb4, 0x02 }, 369 { 214000000, 166667, 0xb4, 0x02 },
340 { 467000000, 44000000, 166666, 0xbc, 0x02 }, 370 { 467000000, 166667, 0xbc, 0x02 },
341 { 721000000, 44000000, 166666, 0xbc, 0x08 }, 371 { 721000000, 166667, 0xbc, 0x08 },
342 { 841000000, 44000000, 166666, 0xf4, 0x08 }, 372 { 841000000, 166667, 0xf4, 0x08 },
343 { 999999999, 44000000, 166666, 0xfc, 0x02 }, 373 { 999999999, 166667, 0xfc, 0x02 },
344 } 374 }
345}; 375};
346EXPORT_SYMBOL(dvb_pll_samsung_tbmv); 376EXPORT_SYMBOL(dvb_pll_samsung_tbmv);
@@ -352,12 +382,13 @@ struct dvb_pll_desc dvb_pll_philips_sd1878_tda8261 = {
352 .name = "Philips SD1878", 382 .name = "Philips SD1878",
353 .min = 950000, 383 .min = 950000,
354 .max = 2150000, 384 .max = 2150000,
385 .iffreq= 249, /* zero-IF, offset 249 is to round up */
355 .count = 4, 386 .count = 4,
356 .entries = { 387 .entries = {
357 { 1250000, 499, 500, 0xc4, 0x00}, 388 { 1250000, 500, 0xc4, 0x00},
358 { 1550000, 499, 500, 0xc4, 0x40}, 389 { 1550000, 500, 0xc4, 0x40},
359 { 2050000, 499, 500, 0xc4, 0x80}, 390 { 2050000, 500, 0xc4, 0x80},
360 { 2150000, 499, 500, 0xc4, 0xc0}, 391 { 2150000, 500, 0xc4, 0xc0},
361 }, 392 },
362}; 393};
363EXPORT_SYMBOL(dvb_pll_philips_sd1878_tda8261); 394EXPORT_SYMBOL(dvb_pll_philips_sd1878_tda8261);
@@ -388,18 +419,19 @@ struct dvb_pll_desc dvb_pll_philips_td1316 = {
388 .name = "Philips TD1316", 419 .name = "Philips TD1316",
389 .min = 87000000, 420 .min = 87000000,
390 .max = 895000000, 421 .max = 895000000,
422 .iffreq= 36166667,
391 .setbw = td1316_bw, 423 .setbw = td1316_bw,
392 .count = 9, 424 .count = 9,
393 .entries = { 425 .entries = {
394 { 93834000, 36166000, 166666, 0xca, 0x60}, 426 { 93834000, 166667, 0xca, 0x60},
395 { 123834000, 36166000, 166666, 0xca, 0xa0}, 427 { 123834000, 166667, 0xca, 0xa0},
396 { 163834000, 36166000, 166666, 0xca, 0xc0}, 428 { 163834000, 166667, 0xca, 0xc0},
397 { 253834000, 36166000, 166666, 0xca, 0x60}, 429 { 253834000, 166667, 0xca, 0x60},
398 { 383834000, 36166000, 166666, 0xca, 0xa0}, 430 { 383834000, 166667, 0xca, 0xa0},
399 { 443834000, 36166000, 166666, 0xca, 0xc0}, 431 { 443834000, 166667, 0xca, 0xc0},
400 { 583834000, 36166000, 166666, 0xca, 0x60}, 432 { 583834000, 166667, 0xca, 0x60},
401 { 793834000, 36166000, 166666, 0xca, 0xa0}, 433 { 793834000, 166667, 0xca, 0xa0},
402 { 858834000, 36166000, 166666, 0xca, 0xe0}, 434 { 858834000, 166667, 0xca, 0xe0},
403 }, 435 },
404}; 436};
405EXPORT_SYMBOL(dvb_pll_philips_td1316); 437EXPORT_SYMBOL(dvb_pll_philips_td1316);
@@ -409,15 +441,41 @@ struct dvb_pll_desc dvb_pll_thomson_fe6600 = {
409 .name = "Thomson FE6600", 441 .name = "Thomson FE6600",
410 .min = 44250000, 442 .min = 44250000,
411 .max = 858000000, 443 .max = 858000000,
444 .iffreq= 36125000,
412 .count = 4, 445 .count = 4,
413 .entries = { 446 .entries = {
414 { 250000000, 36213333, 166667, 0xb4, 0x12 }, 447 { 250000000, 166667, 0xb4, 0x12 },
415 { 455000000, 36213333, 166667, 0xfe, 0x11 }, 448 { 455000000, 166667, 0xfe, 0x11 },
416 { 775500000, 36213333, 166667, 0xbc, 0x18 }, 449 { 775500000, 166667, 0xbc, 0x18 },
417 { 999999999, 36213333, 166667, 0xf4, 0x18 }, 450 { 999999999, 166667, 0xf4, 0x18 },
418 } 451 }
419}; 452};
420EXPORT_SYMBOL(dvb_pll_thomson_fe6600); 453EXPORT_SYMBOL(dvb_pll_thomson_fe6600);
454static void opera1_bw(u8 *buf, u32 freq, int bandwidth)
455{
456 if (bandwidth == BANDWIDTH_8_MHZ)
457 buf[2] |= 0x08;
458}
459
460struct dvb_pll_desc dvb_pll_opera1 = {
461 .name = "Opera Tuner",
462 .min = 900000,
463 .max = 2250000,
464 .iffreq= 0,
465 .setbw = opera1_bw,
466 .count = 8,
467 .entries = {
468 { 1064000, 500, 0xe5, 0xc6 },
469 { 1169000, 500, 0xe5, 0xe6 },
470 { 1299000, 500, 0xe5, 0x24 },
471 { 1444000, 500, 0xe5, 0x44 },
472 { 1606000, 500, 0xe5, 0x64 },
473 { 1777000, 500, 0xe5, 0x84 },
474 { 1941000, 500, 0xe5, 0xa4 },
475 { 2250000, 500, 0xe5, 0xc4 },
476 }
477};
478EXPORT_SYMBOL(dvb_pll_opera1);
421 479
422struct dvb_pll_priv { 480struct dvb_pll_priv {
423 /* i2c details */ 481 /* i2c details */
@@ -459,7 +517,8 @@ int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf,
459 if (i == desc->count) 517 if (i == desc->count)
460 return -EINVAL; 518 return -EINVAL;
461 519
462 div = (freq + desc->entries[i].offset) / desc->entries[i].stepsize; 520 div = (freq + desc->iffreq + desc->entries[i].stepsize/2) /
521 desc->entries[i].stepsize;
463 buf[0] = div >> 8; 522 buf[0] = div >> 8;
464 buf[1] = div & 0xff; 523 buf[1] = div & 0xff;
465 buf[2] = desc->entries[i].config; 524 buf[2] = desc->entries[i].config;
@@ -473,7 +532,7 @@ int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf,
473 desc->name, div, buf[0], buf[1], buf[2], buf[3]); 532 desc->name, div, buf[0], buf[1], buf[2], buf[3]);
474 533
475 // calculate the frequency we set it to 534 // calculate the frequency we set it to
476 return (div * desc->entries[i].stepsize) - desc->entries[i].offset; 535 return (div * desc->entries[i].stepsize) - desc->iffreq;
477} 536}
478EXPORT_SYMBOL(dvb_pll_configure); 537EXPORT_SYMBOL(dvb_pll_configure);
479 538
@@ -487,35 +546,27 @@ static int dvb_pll_release(struct dvb_frontend *fe)
487static int dvb_pll_sleep(struct dvb_frontend *fe) 546static int dvb_pll_sleep(struct dvb_frontend *fe)
488{ 547{
489 struct dvb_pll_priv *priv = fe->tuner_priv; 548 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,
493 .buf = buf, .len = sizeof(buf) };
494 int i;
495 int result;
496 549
497 if (priv->i2c == NULL) 550 if (priv->i2c == NULL)
498 return -EINVAL; 551 return -EINVAL;
499 552
500 for (i = 0; i < priv->pll_desc->count; i++) { 553 if (priv->pll_desc->sleepdata) {
501 if (priv->pll_desc->entries[i].limit == 0) 554 struct i2c_msg msg = { .flags = 0,
502 break; 555 .addr = priv->pll_i2c_address,
503 } 556 .buf = priv->pll_desc->sleepdata + 1,
504 if (i == priv->pll_desc->count) 557 .len = priv->pll_desc->sleepdata[0] };
505 return 0;
506 558
507 buf[0] = 0; 559 int result;
508 buf[1] = 0;
509 buf[2] = priv->pll_desc->entries[i].config;
510 buf[3] = priv->pll_desc->entries[i].cb;
511 560
512 if (fe->ops.i2c_gate_ctrl) 561 if (fe->ops.i2c_gate_ctrl)
513 fe->ops.i2c_gate_ctrl(fe, 1); 562 fe->ops.i2c_gate_ctrl(fe, 1);
514 if ((result = i2c_transfer(priv->i2c, &msg, 1)) != 1) { 563 if ((result = i2c_transfer(priv->i2c, &msg, 1)) != 1) {
515 return result; 564 return result;
565 }
566 return 0;
516 } 567 }
517 568 /* Shouldn't be called when initdata is NULL, maybe BUG()? */
518 return 0; 569 return -EINVAL;
519} 570}
520 571
521static int dvb_pll_set_params(struct dvb_frontend *fe, 572static int dvb_pll_set_params(struct dvb_frontend *fe,
@@ -599,9 +650,35 @@ static int dvb_pll_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
599 return 0; 650 return 0;
600} 651}
601 652
653static int dvb_pll_init(struct dvb_frontend *fe)
654{
655 struct dvb_pll_priv *priv = fe->tuner_priv;
656
657 if (priv->i2c == NULL)
658 return -EINVAL;
659
660 if (priv->pll_desc->initdata) {
661 struct i2c_msg msg = { .flags = 0,
662 .addr = priv->pll_i2c_address,
663 .buf = priv->pll_desc->initdata + 1,
664 .len = priv->pll_desc->initdata[0] };
665
666 int result;
667 if (fe->ops.i2c_gate_ctrl)
668 fe->ops.i2c_gate_ctrl(fe, 1);
669 if ((result = i2c_transfer(priv->i2c, &msg, 1)) != 1) {
670 return result;
671 }
672 return 0;
673 }
674 /* Shouldn't be called when initdata is NULL, maybe BUG()? */
675 return -EINVAL;
676}
677
602static struct dvb_tuner_ops dvb_pll_tuner_ops = { 678static struct dvb_tuner_ops dvb_pll_tuner_ops = {
603 .release = dvb_pll_release, 679 .release = dvb_pll_release,
604 .sleep = dvb_pll_sleep, 680 .sleep = dvb_pll_sleep,
681 .init = dvb_pll_init,
605 .set_params = dvb_pll_set_params, 682 .set_params = dvb_pll_set_params,
606 .calc_regs = dvb_pll_calc_regs, 683 .calc_regs = dvb_pll_calc_regs,
607 .get_frequency = dvb_pll_get_frequency, 684 .get_frequency = dvb_pll_get_frequency,
@@ -640,9 +717,14 @@ struct dvb_frontend *dvb_pll_attach(struct dvb_frontend *fe, int pll_addr,
640 memcpy(&fe->ops.tuner_ops, &dvb_pll_tuner_ops, 717 memcpy(&fe->ops.tuner_ops, &dvb_pll_tuner_ops,
641 sizeof(struct dvb_tuner_ops)); 718 sizeof(struct dvb_tuner_ops));
642 719
643 strncpy(fe->ops.tuner_ops.info.name, desc->name, 128); 720 strncpy(fe->ops.tuner_ops.info.name, desc->name,
721 sizeof(fe->ops.tuner_ops.info.name));
644 fe->ops.tuner_ops.info.frequency_min = desc->min; 722 fe->ops.tuner_ops.info.frequency_min = desc->min;
645 fe->ops.tuner_ops.info.frequency_min = desc->max; 723 fe->ops.tuner_ops.info.frequency_min = desc->max;
724 if (!desc->initdata)
725 fe->ops.tuner_ops.init = NULL;
726 if (!desc->sleepdata)
727 fe->ops.tuner_ops.sleep = NULL;
646 728
647 fe->tuner_priv = priv; 729 fe->tuner_priv = priv;
648 return fe; 730 return fe;
diff --git a/drivers/media/dvb/frontends/dvb-pll.h b/drivers/media/dvb/frontends/dvb-pll.h
index 681186a5e5eb..5209f46f0893 100644
--- a/drivers/media/dvb/frontends/dvb-pll.h
+++ b/drivers/media/dvb/frontends/dvb-pll.h
@@ -12,11 +12,13 @@ struct dvb_pll_desc {
12 char *name; 12 char *name;
13 u32 min; 13 u32 min;
14 u32 max; 14 u32 max;
15 u32 iffreq;
15 void (*setbw)(u8 *buf, u32 freq, int bandwidth); 16 void (*setbw)(u8 *buf, u32 freq, int bandwidth);
17 u8 *initdata;
18 u8 *sleepdata;
16 int count; 19 int count;
17 struct { 20 struct {
18 u32 limit; 21 u32 limit;
19 u32 offset;
20 u32 stepsize; 22 u32 stepsize;
21 u8 config; 23 u8 config;
22 u8 cb; 24 u8 cb;
@@ -46,6 +48,7 @@ extern struct dvb_pll_desc dvb_pll_philips_sd1878_tda8261;
46extern struct dvb_pll_desc dvb_pll_philips_td1316; 48extern struct dvb_pll_desc dvb_pll_philips_td1316;
47 49
48extern struct dvb_pll_desc dvb_pll_thomson_fe6600; 50extern struct dvb_pll_desc dvb_pll_thomson_fe6600;
51extern struct dvb_pll_desc dvb_pll_opera1;
49 52
50extern int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf, 53extern int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf,
51 u32 freq, int bandwidth); 54 u32 freq, int bandwidth);
@@ -59,9 +62,20 @@ extern int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf,
59 * @param desc dvb_pll_desc to use. 62 * @param desc dvb_pll_desc to use.
60 * @return Frontend pointer on success, NULL on failure 63 * @return Frontend pointer on success, NULL on failure
61 */ 64 */
65#if defined(CONFIG_DVB_PLL) || (defined(CONFIG_DVB_PLL_MODULE) && defined(MODULE))
62extern struct dvb_frontend *dvb_pll_attach(struct dvb_frontend *fe, 66extern struct dvb_frontend *dvb_pll_attach(struct dvb_frontend *fe,
63 int pll_addr, 67 int pll_addr,
64 struct i2c_adapter *i2c, 68 struct i2c_adapter *i2c,
65 struct dvb_pll_desc *desc); 69 struct dvb_pll_desc *desc);
70#else
71static inline struct dvb_frontend *dvb_pll_attach(struct dvb_frontend *fe,
72 int pll_addr,
73 struct i2c_adapter *i2c,
74 struct dvb_pll_desc *desc)
75{
76 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
77 return NULL;
78}
79#endif
66 80
67#endif 81#endif
diff --git a/drivers/media/dvb/frontends/lgdt330x.c b/drivers/media/dvb/frontends/lgdt330x.c
index 68aad0f6519f..e25286e2d431 100644
--- a/drivers/media/dvb/frontends/lgdt330x.c
+++ b/drivers/media/dvb/frontends/lgdt330x.c
@@ -475,7 +475,7 @@ static int lgdt3302_read_status(struct dvb_frontend* fe, fe_status_t* status)
475 *status |= FE_HAS_CARRIER; 475 *status |= FE_HAS_CARRIER;
476 break; 476 break;
477 default: 477 default:
478 printk("KERN_WARNING lgdt330x: %s: Modulation set to unsupported value\n", __FUNCTION__); 478 printk(KERN_WARNING "lgdt330x: %s: Modulation set to unsupported value\n", __FUNCTION__);
479 } 479 }
480 480
481 return 0; 481 return 0;
@@ -534,7 +534,7 @@ static int lgdt3303_read_status(struct dvb_frontend* fe, fe_status_t* status)
534 } 534 }
535 break; 535 break;
536 default: 536 default:
537 printk("KERN_WARNING lgdt330x: %s: Modulation set to unsupported value\n", __FUNCTION__); 537 printk(KERN_WARNING "lgdt330x: %s: Modulation set to unsupported value\n", __FUNCTION__);
538 } 538 }
539 return 0; 539 return 0;
540} 540}
diff --git a/drivers/media/dvb/frontends/lgh06xf.c b/drivers/media/dvb/frontends/lgh06xf.c
deleted file mode 100644
index 2202d0cc878b..000000000000
--- a/drivers/media/dvb/frontends/lgh06xf.c
+++ /dev/null
@@ -1,134 +0,0 @@
1/*
2 * lgh06xf.c - 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#include "dvb-pll.h"
20#include "lgh06xf.h"
21
22#define LG_H06XF_PLL_I2C_ADDR 0x61
23
24struct lgh06xf_priv {
25 struct i2c_adapter *i2c;
26 u32 frequency;
27};
28
29static int lgh06xf_release(struct dvb_frontend *fe)
30{
31 kfree(fe->tuner_priv);
32 fe->tuner_priv = NULL;
33 return 0;
34}
35
36static int lgh06xf_set_params(struct dvb_frontend* fe,
37 struct dvb_frontend_parameters* params)
38{
39 struct lgh06xf_priv *priv = fe->tuner_priv;
40 u8 buf[4];
41 struct i2c_msg msg = { .addr = LG_H06XF_PLL_I2C_ADDR, .flags = 0,
42 .buf = buf, .len = sizeof(buf) };
43 u32 frequency;
44 int result;
45
46 if ((result = dvb_pll_configure(&dvb_pll_lg_tdvs_h06xf, buf,
47 params->frequency, 0)) < 0)
48 return result;
49 else
50 frequency = result;
51
52 if (fe->ops.i2c_gate_ctrl)
53 fe->ops.i2c_gate_ctrl(fe, 1);
54 if ((result = i2c_transfer(priv->i2c, &msg, 1)) != 1) {
55 printk(KERN_WARNING "lgh06xf: %s error "
56 "(addr %02x <- %02x, result = %i)\n",
57 __FUNCTION__, buf[0], buf[1], result);
58 if (result < 0)
59 return result;
60 else
61 return -EREMOTEIO;
62 }
63
64 /* Set the Auxiliary Byte. */
65 buf[0] = buf[2];
66 buf[0] &= ~0x20;
67 buf[0] |= 0x18;
68 buf[1] = 0x50;
69 msg.len = 2;
70 if (fe->ops.i2c_gate_ctrl)
71 fe->ops.i2c_gate_ctrl(fe, 1);
72 if ((result = i2c_transfer(priv->i2c, &msg, 1)) != 1) {
73 printk(KERN_WARNING "lgh06xf: %s error "
74 "(addr %02x <- %02x, result = %i)\n",
75 __FUNCTION__, buf[0], buf[1], result);
76 if (result < 0)
77 return result;
78 else
79 return -EREMOTEIO;
80 }
81
82 priv->frequency = frequency;
83
84 return 0;
85}
86
87static int lgh06xf_get_frequency(struct dvb_frontend *fe, u32 *frequency)
88{
89 struct lgh06xf_priv *priv = fe->tuner_priv;
90 *frequency = priv->frequency;
91 return 0;
92}
93
94static struct dvb_tuner_ops lgh06xf_tuner_ops = {
95 .release = lgh06xf_release,
96 .set_params = lgh06xf_set_params,
97 .get_frequency = lgh06xf_get_frequency,
98};
99
100struct dvb_frontend* lgh06xf_attach(struct dvb_frontend *fe,
101 struct i2c_adapter *i2c)
102{
103 struct lgh06xf_priv *priv = NULL;
104
105 priv = kzalloc(sizeof(struct lgh06xf_priv), GFP_KERNEL);
106 if (priv == NULL)
107 return NULL;
108
109 priv->i2c = i2c;
110
111 memcpy(&fe->ops.tuner_ops, &lgh06xf_tuner_ops,
112 sizeof(struct dvb_tuner_ops));
113
114 strlcpy(fe->ops.tuner_ops.info.name, dvb_pll_lg_tdvs_h06xf.name,
115 sizeof(fe->ops.tuner_ops.info.name));
116
117 fe->ops.tuner_ops.info.frequency_min = dvb_pll_lg_tdvs_h06xf.min;
118 fe->ops.tuner_ops.info.frequency_max = dvb_pll_lg_tdvs_h06xf.max;
119
120 fe->tuner_priv = priv;
121 return fe;
122}
123
124EXPORT_SYMBOL(lgh06xf_attach);
125
126MODULE_DESCRIPTION("LG TDVS-H06xF ATSC Tuner support");
127MODULE_AUTHOR("Michael Krufky");
128MODULE_LICENSE("GPL");
129
130/*
131 * Local variables:
132 * c-basic-offset: 8
133 * End:
134 */
diff --git a/drivers/media/dvb/frontends/lgh06xf.h b/drivers/media/dvb/frontends/lgh06xf.h
deleted file mode 100644
index 510b4bedfb24..000000000000
--- a/drivers/media/dvb/frontends/lgh06xf.h
+++ /dev/null
@@ -1,35 +0,0 @@
1/*
2 * lgh06xf.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 _LGH06XF_H_
20#define _LGH06XF_H_
21#include "dvb_frontend.h"
22
23#if defined(CONFIG_DVB_TUNER_LGH06XF) || (defined(CONFIG_DVB_TUNER_LGH06XF_MODULE) && defined(MODULE))
24extern struct dvb_frontend* lgh06xf_attach(struct dvb_frontend* fe,
25 struct i2c_adapter *i2c);
26#else
27static inline struct dvb_frontend* lgh06xf_attach(struct dvb_frontend* fe,
28 struct i2c_adapter *i2c)
29{
30 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
31 return NULL;
32}
33#endif /* CONFIG_DVB_TUNER_LGH06XF */
34
35#endif /* _LGH06XF_H_ */
diff --git a/drivers/media/dvb/frontends/or51132.c b/drivers/media/dvb/frontends/or51132.c
index 5a3a6e53cda2..4e0aca7c67aa 100644
--- a/drivers/media/dvb/frontends/or51132.c
+++ b/drivers/media/dvb/frontends/or51132.c
@@ -1,6 +1,9 @@
1/* 1/*
2 * Support for OR51132 (pcHDTV HD-3000) - VSB/QAM 2 * Support for OR51132 (pcHDTV HD-3000) - VSB/QAM
3 * 3 *
4 *
5 * Copyright (C) 2007 Trent Piepho <xyzzy@speakeasy.org>
6 *
4 * Copyright (C) 2005 Kirk Lapray <kirk_lapray@bigfoot.com> 7 * Copyright (C) 2005 Kirk Lapray <kirk_lapray@bigfoot.com>
5 * 8 *
6 * Based on code from Jack Kelliher (kelliher@xmission.com) 9 * Based on code from Jack Kelliher (kelliher@xmission.com)
@@ -69,46 +72,70 @@ struct or51132_state
69 u32 current_frequency; 72 u32 current_frequency;
70}; 73};
71 74
72static int i2c_writebytes (struct or51132_state* state, u8 reg, u8 *buf, int len) 75
76/* Write buffer to demod */
77static int or51132_writebuf(struct or51132_state *state, const u8 *buf, int len)
73{ 78{
74 int err; 79 int err;
75 struct i2c_msg msg; 80 struct i2c_msg msg = { .addr = state->config->demod_address,
76 msg.addr = reg; 81 .flags = 0, .buf = (u8*)buf, .len = len };
77 msg.flags = 0;
78 msg.len = len;
79 msg.buf = buf;
80 82
83 /* msleep(20); */ /* doesn't appear to be necessary */
81 if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) { 84 if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) {
82 printk(KERN_WARNING "or51132: i2c_writebytes error (addr %02x, err == %i)\n", reg, err); 85 printk(KERN_WARNING "or51132: I2C write (addr 0x%02x len %d) error: %d\n",
86 msg.addr, msg.len, err);
83 return -EREMOTEIO; 87 return -EREMOTEIO;
84 } 88 }
85
86 return 0; 89 return 0;
87} 90}
88 91
89static u8 i2c_readbytes (struct or51132_state* state, u8 reg, u8* buf, int len) 92/* Write constant bytes, e.g. or51132_writebytes(state, 0x04, 0x42, 0x00);
93 Less code and more efficient that loading a buffer on the stack with
94 the bytes to send and then calling or51132_writebuf() on that. */
95#define or51132_writebytes(state, data...) \
96 ({ const static u8 _data[] = {data}; \
97 or51132_writebuf(state, _data, sizeof(_data)); })
98
99/* Read data from demod into buffer. Returns 0 on success. */
100static int or51132_readbuf(struct or51132_state *state, u8 *buf, int len)
90{ 101{
91 int err; 102 int err;
92 struct i2c_msg msg; 103 struct i2c_msg msg = { .addr = state->config->demod_address,
93 msg.addr = reg; 104 .flags = I2C_M_RD, .buf = buf, .len = len };
94 msg.flags = I2C_M_RD;
95 msg.len = len;
96 msg.buf = buf;
97 105
106 /* msleep(20); */ /* doesn't appear to be necessary */
98 if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) { 107 if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) {
99 printk(KERN_WARNING "or51132: i2c_readbytes error (addr %02x, err == %i)\n", reg, err); 108 printk(KERN_WARNING "or51132: I2C read (addr 0x%02x len %d) error: %d\n",
109 msg.addr, msg.len, err);
100 return -EREMOTEIO; 110 return -EREMOTEIO;
101 } 111 }
102
103 return 0; 112 return 0;
104} 113}
105 114
115/* Reads a 16-bit demod register. Returns <0 on error. */
116static int or51132_readreg(struct or51132_state *state, u8 reg)
117{
118 u8 buf[2] = { 0x04, reg };
119 struct i2c_msg msg[2] = {
120 {.addr = state->config->demod_address, .flags = 0,
121 .buf = buf, .len = 2 },
122 {.addr = state->config->demod_address, .flags = I2C_M_RD,
123 .buf = buf, .len = 2 }};
124 int err;
125
126 if ((err = i2c_transfer(state->i2c, msg, 2)) != 2) {
127 printk(KERN_WARNING "or51132: I2C error reading register %d: %d\n",
128 reg, err);
129 return -EREMOTEIO;
130 }
131 return le16_to_cpup((u16*)buf);
132}
133
106static int or51132_load_firmware (struct dvb_frontend* fe, const struct firmware *fw) 134static int or51132_load_firmware (struct dvb_frontend* fe, const struct firmware *fw)
107{ 135{
108 struct or51132_state* state = fe->demodulator_priv; 136 struct or51132_state* state = fe->demodulator_priv;
109 static u8 run_buf[] = {0x7F,0x01}; 137 const static u8 run_buf[] = {0x7F,0x01};
110 u8 rec_buf[8]; 138 u8 rec_buf[8];
111 u8 cmd_buf[3];
112 u32 firmwareAsize, firmwareBsize; 139 u32 firmwareAsize, firmwareBsize;
113 int i,ret; 140 int i,ret;
114 141
@@ -121,30 +148,21 @@ static int or51132_load_firmware (struct dvb_frontend* fe, const struct firmware
121 dprintk("FirmwareB is %i bytes\n",firmwareBsize); 148 dprintk("FirmwareB is %i bytes\n",firmwareBsize);
122 149
123 /* Upload firmware */ 150 /* Upload firmware */
124 if ((ret = i2c_writebytes(state,state->config->demod_address, 151 if ((ret = or51132_writebuf(state, &fw->data[8], firmwareAsize))) {
125 &fw->data[8],firmwareAsize))) {
126 printk(KERN_WARNING "or51132: load_firmware error 1\n"); 152 printk(KERN_WARNING "or51132: load_firmware error 1\n");
127 return ret; 153 return ret;
128 } 154 }
129 msleep(1); /* 1ms */ 155 if ((ret = or51132_writebuf(state, &fw->data[8+firmwareAsize],
130 if ((ret = i2c_writebytes(state,state->config->demod_address, 156 firmwareBsize))) {
131 &fw->data[8+firmwareAsize],firmwareBsize))) {
132 printk(KERN_WARNING "or51132: load_firmware error 2\n"); 157 printk(KERN_WARNING "or51132: load_firmware error 2\n");
133 return ret; 158 return ret;
134 } 159 }
135 msleep(1); /* 1ms */
136 160
137 if ((ret = i2c_writebytes(state,state->config->demod_address, 161 if ((ret = or51132_writebuf(state, run_buf, 2))) {
138 run_buf,2))) {
139 printk(KERN_WARNING "or51132: load_firmware error 3\n"); 162 printk(KERN_WARNING "or51132: load_firmware error 3\n");
140 return ret; 163 return ret;
141 } 164 }
142 165 if ((ret = or51132_writebuf(state, run_buf, 2))) {
143 /* Wait at least 5 msec */
144 msleep(20); /* 10ms */
145
146 if ((ret = i2c_writebytes(state,state->config->demod_address,
147 run_buf,2))) {
148 printk(KERN_WARNING "or51132: load_firmware error 4\n"); 166 printk(KERN_WARNING "or51132: load_firmware error 4\n");
149 return ret; 167 return ret;
150 } 168 }
@@ -154,43 +172,25 @@ static int or51132_load_firmware (struct dvb_frontend* fe, const struct firmware
154 172
155 /* Read back ucode version to besure we loaded correctly and are really up and running */ 173 /* Read back ucode version to besure we loaded correctly and are really up and running */
156 /* Get uCode version */ 174 /* Get uCode version */
157 cmd_buf[0] = 0x10; 175 if ((ret = or51132_writebytes(state, 0x10, 0x10, 0x00))) {
158 cmd_buf[1] = 0x10;
159 cmd_buf[2] = 0x00;
160 msleep(20); /* 20ms */
161 if ((ret = i2c_writebytes(state,state->config->demod_address,
162 cmd_buf,3))) {
163 printk(KERN_WARNING "or51132: load_firmware error a\n"); 176 printk(KERN_WARNING "or51132: load_firmware error a\n");
164 return ret; 177 return ret;
165 } 178 }
166 179 if ((ret = or51132_writebytes(state, 0x04, 0x17))) {
167 cmd_buf[0] = 0x04;
168 cmd_buf[1] = 0x17;
169 msleep(20); /* 20ms */
170 if ((ret = i2c_writebytes(state,state->config->demod_address,
171 cmd_buf,2))) {
172 printk(KERN_WARNING "or51132: load_firmware error b\n"); 180 printk(KERN_WARNING "or51132: load_firmware error b\n");
173 return ret; 181 return ret;
174 } 182 }
175 183 if ((ret = or51132_writebytes(state, 0x00, 0x00))) {
176 cmd_buf[0] = 0x00;
177 cmd_buf[1] = 0x00;
178 msleep(20); /* 20ms */
179 if ((ret = i2c_writebytes(state,state->config->demod_address,
180 cmd_buf,2))) {
181 printk(KERN_WARNING "or51132: load_firmware error c\n"); 184 printk(KERN_WARNING "or51132: load_firmware error c\n");
182 return ret; 185 return ret;
183 } 186 }
184 187 for (i=0;i<4;i++) {
185 for(i=0;i<4;i++) {
186 msleep(20); /* 20ms */
187 /* Once upon a time, this command might have had something 188 /* Once upon a time, this command might have had something
188 to do with getting the firmware version, but it's 189 to do with getting the firmware version, but it's
189 not used anymore: 190 not used anymore:
190 {0x04,0x00,0x30,0x00,i+1} */ 191 {0x04,0x00,0x30,0x00,i+1} */
191 /* Read 8 bytes, two bytes at a time */ 192 /* Read 8 bytes, two bytes at a time */
192 if ((ret = i2c_readbytes(state,state->config->demod_address, 193 if ((ret = or51132_readbuf(state, &rec_buf[i*2], 2))) {
193 &rec_buf[i*2],2))) {
194 printk(KERN_WARNING 194 printk(KERN_WARNING
195 "or51132: load_firmware error d - %d\n",i); 195 "or51132: load_firmware error d - %d\n",i);
196 return ret; 196 return ret;
@@ -204,12 +204,7 @@ static int or51132_load_firmware (struct dvb_frontend* fe, const struct firmware
204 rec_buf[3],rec_buf[2]>>4,rec_buf[2]&0x0f, 204 rec_buf[3],rec_buf[2]>>4,rec_buf[2]&0x0f,
205 rec_buf[5],rec_buf[4]>>4,rec_buf[4]&0x0f); 205 rec_buf[5],rec_buf[4]>>4,rec_buf[4]&0x0f);
206 206
207 cmd_buf[0] = 0x10; 207 if ((ret = or51132_writebytes(state, 0x10, 0x00, 0x00))) {
208 cmd_buf[1] = 0x00;
209 cmd_buf[2] = 0x00;
210 msleep(20); /* 20ms */
211 if ((ret = i2c_writebytes(state,state->config->demod_address,
212 cmd_buf,3))) {
213 printk(KERN_WARNING "or51132: load_firmware error e\n"); 208 printk(KERN_WARNING "or51132: load_firmware error e\n");
214 return ret; 209 return ret;
215 } 210 }
@@ -241,70 +236,55 @@ static int or51132_sleep(struct dvb_frontend* fe)
241static int or51132_setmode(struct dvb_frontend* fe) 236static int or51132_setmode(struct dvb_frontend* fe)
242{ 237{
243 struct or51132_state* state = fe->demodulator_priv; 238 struct or51132_state* state = fe->demodulator_priv;
244 unsigned char cmd_buf[3]; 239 u8 cmd_buf1[3] = {0x04, 0x01, 0x5f};
240 u8 cmd_buf2[3] = {0x1c, 0x00, 0 };
245 241
246 dprintk("setmode %d\n",(int)state->current_modulation); 242 dprintk("setmode %d\n",(int)state->current_modulation);
247 /* set operation mode in Receiver 1 register; */ 243
248 cmd_buf[0] = 0x04;
249 cmd_buf[1] = 0x01;
250 switch (state->current_modulation) { 244 switch (state->current_modulation) {
251 case QAM_256:
252 case QAM_64:
253 case QAM_AUTO:
254 /* Auto-deinterleave; MPEG ser, MPEG2tr, phase noise-high*/
255 cmd_buf[2] = 0x5F;
256 break;
257 case VSB_8: 245 case VSB_8:
258 /* Auto CH, Auto NTSC rej, MPEGser, MPEG2tr, phase noise-high*/ 246 /* Auto CH, Auto NTSC rej, MPEGser, MPEG2tr, phase noise-high */
259 cmd_buf[2] = 0x50; 247 cmd_buf1[2] = 0x50;
248 /* REC MODE inv IF spectrum, Normal */
249 cmd_buf2[1] = 0x03;
250 /* Channel MODE ATSC/VSB8 */
251 cmd_buf2[2] = 0x06;
260 break; 252 break;
261 default: 253 /* All QAM modes are:
262 printk("setmode:Modulation set to unsupported value\n"); 254 Auto-deinterleave; MPEGser, MPEG2tr, phase noise-high
263 }; 255 REC MODE Normal Carrier Lock */
264 if (i2c_writebytes(state,state->config->demod_address,
265 cmd_buf,3)) {
266 printk(KERN_WARNING "or51132: set_mode error 1\n");
267 return -1;
268 }
269 dprintk("or51132: set #1 to %02x\n", cmd_buf[2]);
270
271 /* Set operation mode in Receiver 6 register */
272 cmd_buf[0] = 0x1C;
273 switch (state->current_modulation) {
274 case QAM_AUTO: 256 case QAM_AUTO:
275 /* REC MODE Normal Carrier Lock */
276 cmd_buf[1] = 0x00;
277 /* Channel MODE Auto QAM64/256 */ 257 /* Channel MODE Auto QAM64/256 */
278 cmd_buf[2] = 0x4f; 258 cmd_buf2[2] = 0x4f;
279 break; 259 break;
280 case QAM_256: 260 case QAM_256:
281 /* REC MODE Normal Carrier Lock */
282 cmd_buf[1] = 0x00;
283 /* Channel MODE QAM256 */ 261 /* Channel MODE QAM256 */
284 cmd_buf[2] = 0x45; 262 cmd_buf2[2] = 0x45;
285 break; 263 break;
286 case QAM_64: 264 case QAM_64:
287 /* REC MODE Normal Carrier Lock */
288 cmd_buf[1] = 0x00;
289 /* Channel MODE QAM64 */ 265 /* Channel MODE QAM64 */
290 cmd_buf[2] = 0x43; 266 cmd_buf2[2] = 0x43;
291 break;
292 case VSB_8:
293 /* REC MODE inv IF spectrum, Normal */
294 cmd_buf[1] = 0x03;
295 /* Channel MODE ATSC/VSB8 */
296 cmd_buf[2] = 0x06;
297 break; 267 break;
298 default: 268 default:
299 printk("setmode: Modulation set to unsupported value\n"); 269 printk(KERN_WARNING
300 }; 270 "or51132: setmode: Modulation set to unsupported value (%d)\n",
301 msleep(20); /* 20ms */ 271 state->current_modulation);
302 if (i2c_writebytes(state,state->config->demod_address, 272 return -EINVAL;
303 cmd_buf,3)) { 273 }
274
275 /* Set Receiver 1 register */
276 if (or51132_writebuf(state, cmd_buf1, 3)) {
277 printk(KERN_WARNING "or51132: set_mode error 1\n");
278 return -EREMOTEIO;
279 }
280 dprintk("set #1 to %02x\n", cmd_buf1[2]);
281
282 /* Set operation mode in Receiver 6 register */
283 if (or51132_writebuf(state, cmd_buf2, 3)) {
304 printk(KERN_WARNING "or51132: set_mode error 2\n"); 284 printk(KERN_WARNING "or51132: set_mode error 2\n");
305 return -1; 285 return -EREMOTEIO;
306 } 286 }
307 dprintk("or51132: set #6 to 0x%02x%02x\n", cmd_buf[1], cmd_buf[2]); 287 dprintk("set #6 to 0x%02x%02x\n", cmd_buf2[1], cmd_buf2[2]);
308 288
309 return 0; 289 return 0;
310} 290}
@@ -401,28 +381,23 @@ static int or51132_get_parameters(struct dvb_frontend* fe,
401 struct dvb_frontend_parameters *param) 381 struct dvb_frontend_parameters *param)
402{ 382{
403 struct or51132_state* state = fe->demodulator_priv; 383 struct or51132_state* state = fe->demodulator_priv;
404 u8 buf[2]; 384 int status;
385 int retry = 1;
405 386
387start:
406 /* Receiver Status */ 388 /* Receiver Status */
407 buf[0]=0x04; 389 if ((status = or51132_readreg(state, 0x00)) < 0) {
408 buf[1]=0x00; 390 printk(KERN_WARNING "or51132: get_parameters: error reading receiver status\n");
409 msleep(30); /* 30ms */
410 if (i2c_writebytes(state,state->config->demod_address,buf,2)) {
411 printk(KERN_WARNING "or51132: get_parameters write error\n");
412 return -EREMOTEIO;
413 }
414 msleep(30); /* 30ms */
415 if (i2c_readbytes(state,state->config->demod_address,buf,2)) {
416 printk(KERN_WARNING "or51132: get_parameters read error\n");
417 return -EREMOTEIO; 391 return -EREMOTEIO;
418 } 392 }
419 switch(buf[0]) { 393 switch(status&0xff) {
420 case 0x06: param->u.vsb.modulation = VSB_8; break; 394 case 0x06: param->u.vsb.modulation = VSB_8; break;
421 case 0x43: param->u.vsb.modulation = QAM_64; break; 395 case 0x43: param->u.vsb.modulation = QAM_64; break;
422 case 0x45: param->u.vsb.modulation = QAM_256; break; 396 case 0x45: param->u.vsb.modulation = QAM_256; break;
423 default: 397 default:
398 if (retry--) goto start;
424 printk(KERN_WARNING "or51132: unknown status 0x%02x\n", 399 printk(KERN_WARNING "or51132: unknown status 0x%02x\n",
425 buf[0]); 400 status&0xff);
426 return -EREMOTEIO; 401 return -EREMOTEIO;
427 } 402 }
428 403
@@ -438,32 +413,21 @@ static int or51132_get_parameters(struct dvb_frontend* fe,
438static int or51132_read_status(struct dvb_frontend* fe, fe_status_t* status) 413static int or51132_read_status(struct dvb_frontend* fe, fe_status_t* status)
439{ 414{
440 struct or51132_state* state = fe->demodulator_priv; 415 struct or51132_state* state = fe->demodulator_priv;
441 unsigned char rec_buf[2]; 416 int reg;
442 unsigned char snd_buf[2];
443 *status = 0;
444 417
445 /* Receiver Status */ 418 /* Receiver Status */
446 snd_buf[0]=0x04; 419 if ((reg = or51132_readreg(state, 0x00)) < 0) {
447 snd_buf[1]=0x00; 420 printk(KERN_WARNING "or51132: read_status: error reading receiver status: %d\n", reg);
448 msleep(30); /* 30ms */ 421 *status = 0;
449 if (i2c_writebytes(state,state->config->demod_address,snd_buf,2)) { 422 return -EREMOTEIO;
450 printk(KERN_WARNING "or51132: read_status write error\n");
451 return -1;
452 }
453 msleep(30); /* 30ms */
454 if (i2c_readbytes(state,state->config->demod_address,rec_buf,2)) {
455 printk(KERN_WARNING "or51132: read_status read error\n");
456 return -1;
457 }
458 dprintk("read_status %x %x\n",rec_buf[0],rec_buf[1]);
459
460 if (rec_buf[1] & 0x01) { /* Receiver Lock */
461 *status |= FE_HAS_SIGNAL;
462 *status |= FE_HAS_CARRIER;
463 *status |= FE_HAS_VITERBI;
464 *status |= FE_HAS_SYNC;
465 *status |= FE_HAS_LOCK;
466 } 423 }
424 dprintk("%s: read_status %04x\n", __FUNCTION__, reg);
425
426 if (reg & 0x0100) /* Receiver Lock */
427 *status = FE_HAS_SIGNAL|FE_HAS_CARRIER|FE_HAS_VITERBI|
428 FE_HAS_SYNC|FE_HAS_LOCK;
429 else
430 *status = 0;
467 return 0; 431 return 0;
468} 432}
469 433
@@ -506,47 +470,30 @@ static u32 calculate_snr(u32 mse, u32 c)
506static int or51132_read_snr(struct dvb_frontend* fe, u16* snr) 470static int or51132_read_snr(struct dvb_frontend* fe, u16* snr)
507{ 471{
508 struct or51132_state* state = fe->demodulator_priv; 472 struct or51132_state* state = fe->demodulator_priv;
509 u8 rec_buf[2]; 473 int noise, reg;
510 u8 snd_buf[2]; 474 u32 c, usK = 0;
511 u32 noise; 475 int retry = 1;
512 u32 c; 476
513 u32 usK; 477start:
514 478 /* SNR after Equalizer */
515 /* Register is same for VSB or QAM firmware */ 479 noise = or51132_readreg(state, 0x02);
516 snd_buf[0]=0x04; 480 if (noise < 0) {
517 snd_buf[1]=0x02; /* SNR after Equalizer */ 481 printk(KERN_WARNING "or51132: read_snr: error reading equalizer\n");
518 msleep(30); /* 30ms */
519 if (i2c_writebytes(state,state->config->demod_address,snd_buf,2)) {
520 printk(KERN_WARNING "or51132: snr write error\n");
521 return -EREMOTEIO;
522 }
523 msleep(30); /* 30ms */
524 if (i2c_readbytes(state,state->config->demod_address,rec_buf,2)) {
525 printk(KERN_WARNING "or51132: snr read error\n");
526 return -EREMOTEIO; 482 return -EREMOTEIO;
527 } 483 }
528 noise = rec_buf[0] | (rec_buf[1] << 8); 484 dprintk("read_snr noise (%d)\n", noise);
529 dprintk("read_snr noise %x %x (%i)\n",rec_buf[0],rec_buf[1],noise);
530 485
531 /* Read status, contains modulation type for QAM_AUTO and 486 /* Read status, contains modulation type for QAM_AUTO and
532 NTSC filter for VSB */ 487 NTSC filter for VSB */
533 snd_buf[0]=0x04; 488 reg = or51132_readreg(state, 0x00);
534 snd_buf[1]=0x00; /* Status register */ 489 if (reg < 0) {
535 msleep(30); /* 30ms */ 490 printk(KERN_WARNING "or51132: read_snr: error reading receiver status\n");
536 if (i2c_writebytes(state,state->config->demod_address,snd_buf,2)) {
537 printk(KERN_WARNING "or51132: status write error\n");
538 return -EREMOTEIO;
539 }
540 msleep(30); /* 30ms */
541 if (i2c_readbytes(state,state->config->demod_address,rec_buf,2)) {
542 printk(KERN_WARNING "or51132: status read error\n");
543 return -EREMOTEIO; 491 return -EREMOTEIO;
544 } 492 }
545 493
546 usK = 0; 494 switch (reg&0xff) {
547 switch (rec_buf[0]) {
548 case 0x06: 495 case 0x06:
549 usK = (rec_buf[1] & 0x10) ? 0x03000000 : 0; 496 if (reg & 0x1000) usK = 3 << 24;
550 /* Fall through to QAM64 case */ 497 /* Fall through to QAM64 case */
551 case 0x43: 498 case 0x43:
552 c = 150204167; 499 c = 150204167;
@@ -555,11 +502,12 @@ static int or51132_read_snr(struct dvb_frontend* fe, u16* snr)
555 c = 150290396; 502 c = 150290396;
556 break; 503 break;
557 default: 504 default:
558 printk(KERN_ERR "or51132: unknown status 0x%02x\n", rec_buf[0]); 505 printk(KERN_WARNING "or51132: unknown status 0x%02x\n", reg&0xff);
506 if (retry--) goto start;
559 return -EREMOTEIO; 507 return -EREMOTEIO;
560 } 508 }
561 dprintk("%s: modulation %02x, NTSC rej O%s\n", __FUNCTION__, 509 dprintk("%s: modulation %02x, NTSC rej O%s\n", __FUNCTION__,
562 rec_buf[0], rec_buf[1]&0x10?"n":"ff"); 510 reg&0xff, reg&0x1000?"n":"ff");
563 511
564 /* Calculate SNR using noise, c, and NTSC rejection correction */ 512 /* Calculate SNR using noise, c, and NTSC rejection correction */
565 state->snr = calculate_snr(noise, c) - usK; 513 state->snr = calculate_snr(noise, c) - usK;
@@ -671,6 +619,7 @@ MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
671 619
672MODULE_DESCRIPTION("OR51132 ATSC [pcHDTV HD-3000] (8VSB & ITU J83 AnnexB FEC QAM64/256) Demodulator Driver"); 620MODULE_DESCRIPTION("OR51132 ATSC [pcHDTV HD-3000] (8VSB & ITU J83 AnnexB FEC QAM64/256) Demodulator Driver");
673MODULE_AUTHOR("Kirk Lapray"); 621MODULE_AUTHOR("Kirk Lapray");
622MODULE_AUTHOR("Trent Piepho");
674MODULE_LICENSE("GPL"); 623MODULE_LICENSE("GPL");
675 624
676EXPORT_SYMBOL(or51132_attach); 625EXPORT_SYMBOL(or51132_attach);
diff --git a/drivers/media/dvb/frontends/tda10021.c b/drivers/media/dvb/frontends/tda10021.c
index 5b9c5bb29b23..110536843e8e 100644
--- a/drivers/media/dvb/frontends/tda10021.c
+++ b/drivers/media/dvb/frontends/tda10021.c
@@ -30,13 +30,13 @@
30#include <linux/slab.h> 30#include <linux/slab.h>
31 31
32#include "dvb_frontend.h" 32#include "dvb_frontend.h"
33#include "tda10021.h" 33#include "tda1002x.h"
34 34
35 35
36struct tda10021_state { 36struct tda10021_state {
37 struct i2c_adapter* i2c; 37 struct i2c_adapter* i2c;
38 /* configuration settings */ 38 /* configuration settings */
39 const struct tda10021_config* config; 39 const struct tda1002x_config* config;
40 struct dvb_frontend frontend; 40 struct dvb_frontend frontend;
41 41
42 u8 pwm; 42 u8 pwm;
@@ -53,9 +53,6 @@ struct tda10021_state {
53static int verbose; 53static int verbose;
54 54
55#define XIN 57840000UL 55#define XIN 57840000UL
56#define DISABLE_INVERSION(reg0) do { reg0 |= 0x20; } while (0)
57#define ENABLE_INVERSION(reg0) do { reg0 &= ~0x20; } while (0)
58#define HAS_INVERSION(reg0) (!(reg0 & 0x20))
59 56
60#define FIN (XIN >> 4) 57#define FIN (XIN >> 4)
61 58
@@ -64,7 +61,7 @@ static u8 tda10021_inittab[0x40]=
64{ 61{
65 0x73, 0x6a, 0x23, 0x0a, 0x02, 0x37, 0x77, 0x1a, 62 0x73, 0x6a, 0x23, 0x0a, 0x02, 0x37, 0x77, 0x1a,
66 0x37, 0x6a, 0x17, 0x8a, 0x1e, 0x86, 0x43, 0x40, 63 0x37, 0x6a, 0x17, 0x8a, 0x1e, 0x86, 0x43, 0x40,
67 0xb8, 0x3f, 0xa0, 0x00, 0xcd, 0x01, 0x00, 0xff, 64 0xb8, 0x3f, 0xa1, 0x00, 0xcd, 0x01, 0x00, 0xff,
68 0x11, 0x00, 0x7c, 0x31, 0x30, 0x20, 0x00, 0x00, 65 0x11, 0x00, 0x7c, 0x31, 0x30, 0x20, 0x00, 0x00,
69 0x02, 0x00, 0x00, 0x7d, 0x00, 0x00, 0x00, 0x00, 66 0x02, 0x00, 0x00, 0x7d, 0x00, 0x00, 0x00, 0x00,
70 0x07, 0x00, 0x33, 0x11, 0x0d, 0x95, 0x08, 0x58, 67 0x07, 0x00, 0x33, 0x11, 0x0d, 0x95, 0x08, 0x58,
@@ -97,7 +94,8 @@ static u8 tda10021_readreg (struct tda10021_state* state, u8 reg)
97 int ret; 94 int ret;
98 95
99 ret = i2c_transfer (state->i2c, msg, 2); 96 ret = i2c_transfer (state->i2c, msg, 2);
100 if (ret != 2) 97 // Don't print an error message if the id is read.
98 if (ret != 2 && reg != 0x1a)
101 printk("DVB: TDA10021: %s: readreg error (ret == %i)\n", 99 printk("DVB: TDA10021: %s: readreg error (ret == %i)\n",
102 __FUNCTION__, ret); 100 __FUNCTION__, ret);
103 return b1[0]; 101 return b1[0];
@@ -136,10 +134,10 @@ static int tda10021_setup_reg0 (struct tda10021_state* state, u8 reg0,
136{ 134{
137 reg0 |= state->reg0 & 0x63; 135 reg0 |= state->reg0 & 0x63;
138 136
139 if (INVERSION_ON == inversion) 137 if ((INVERSION_ON == inversion) ^ (state->config->invert == 0))
140 ENABLE_INVERSION(reg0); 138 reg0 &= ~0x20;
141 else if (INVERSION_OFF == inversion) 139 else
142 DISABLE_INVERSION(reg0); 140 reg0 |= 0x20;
143 141
144 _tda10021_writereg (state, 0x00, reg0 & 0xfe); 142 _tda10021_writereg (state, 0x00, reg0 & 0xfe);
145 _tda10021_writereg (state, 0x00, reg0 | 0x01); 143 _tda10021_writereg (state, 0x00, reg0 | 0x01);
@@ -201,16 +199,6 @@ static int tda10021_set_symbolrate (struct tda10021_state* state, u32 symbolrate
201 return 0; 199 return 0;
202} 200}
203 201
204static int tda10021_write(struct dvb_frontend* fe, u8 *buf, int len)
205{
206 struct tda10021_state* state = fe->demodulator_priv;
207
208 if (len != 2)
209 return -EINVAL;
210
211 return _tda10021_writereg(state, buf[0], buf[1]);
212}
213
214static int tda10021_init (struct dvb_frontend *fe) 202static int tda10021_init (struct dvb_frontend *fe)
215{ 203{
216 struct tda10021_state* state = fe->demodulator_priv; 204 struct tda10021_state* state = fe->demodulator_priv;
@@ -258,6 +246,9 @@ static int tda10021_set_parameters (struct dvb_frontend *fe,
258 if (qam < 0 || qam > 5) 246 if (qam < 0 || qam > 5)
259 return -EINVAL; 247 return -EINVAL;
260 248
249 if (p->inversion != INVERSION_ON && p->inversion != INVERSION_OFF)
250 return -EINVAL;
251
261 //printk("tda10021: set frequency to %d qam=%d symrate=%d\n", p->frequency,qam,p->u.qam.symbol_rate); 252 //printk("tda10021: set frequency to %d qam=%d symrate=%d\n", p->frequency,qam,p->u.qam.symbol_rate);
262 253
263 if (fe->ops.tuner_ops.set_params) { 254 if (fe->ops.tuner_ops.set_params) {
@@ -366,7 +357,7 @@ static int tda10021_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_pa
366 -((s32)p->u.qam.symbol_rate * afc) >> 10); 357 -((s32)p->u.qam.symbol_rate * afc) >> 10);
367 } 358 }
368 359
369 p->inversion = HAS_INVERSION(state->reg0) ? INVERSION_ON : INVERSION_OFF; 360 p->inversion = ((state->reg0 & 0x20) == 0x20) ^ (state->config->invert != 0) ? INVERSION_ON : INVERSION_OFF;
370 p->u.qam.modulation = ((state->reg0 >> 2) & 7) + QAM_16; 361 p->u.qam.modulation = ((state->reg0 >> 2) & 7) + QAM_16;
371 362
372 p->u.qam.fec_inner = FEC_NONE; 363 p->u.qam.fec_inner = FEC_NONE;
@@ -408,11 +399,12 @@ static void tda10021_release(struct dvb_frontend* fe)
408 399
409static struct dvb_frontend_ops tda10021_ops; 400static struct dvb_frontend_ops tda10021_ops;
410 401
411struct dvb_frontend* tda10021_attach(const struct tda10021_config* config, 402struct dvb_frontend* tda10021_attach(const struct tda1002x_config* config,
412 struct i2c_adapter* i2c, 403 struct i2c_adapter* i2c,
413 u8 pwm) 404 u8 pwm)
414{ 405{
415 struct tda10021_state* state = NULL; 406 struct tda10021_state* state = NULL;
407 u8 id;
416 408
417 /* allocate memory for the internal state */ 409 /* allocate memory for the internal state */
418 state = kmalloc(sizeof(struct tda10021_state), GFP_KERNEL); 410 state = kmalloc(sizeof(struct tda10021_state), GFP_KERNEL);
@@ -425,7 +417,11 @@ struct dvb_frontend* tda10021_attach(const struct tda10021_config* config,
425 state->reg0 = tda10021_inittab[0]; 417 state->reg0 = tda10021_inittab[0];
426 418
427 /* check if the demod is there */ 419 /* check if the demod is there */
428 if ((tda10021_readreg(state, 0x1a) & 0xf0) != 0x70) goto error; 420 id = tda10021_readreg(state, 0x1a);
421 if ((id & 0xf0) != 0x70) goto error;
422
423 printk("TDA10021: i2c-addr = 0x%02x, id = 0x%02x\n",
424 state->config->demod_address, id);
429 425
430 /* create dvb_frontend */ 426 /* create dvb_frontend */
431 memcpy(&state->frontend.ops, &tda10021_ops, sizeof(struct dvb_frontend_ops)); 427 memcpy(&state->frontend.ops, &tda10021_ops, sizeof(struct dvb_frontend_ops));
@@ -447,7 +443,7 @@ static struct dvb_frontend_ops tda10021_ops = {
447 .frequency_max = 858000000, 443 .frequency_max = 858000000,
448 .symbol_rate_min = (XIN/2)/64, /* SACLK/64 == (XIN/2)/64 */ 444 .symbol_rate_min = (XIN/2)/64, /* SACLK/64 == (XIN/2)/64 */
449 .symbol_rate_max = (XIN/2)/4, /* SACLK/4 */ 445 .symbol_rate_max = (XIN/2)/4, /* SACLK/4 */
450#if 0 446 #if 0
451 .frequency_tolerance = ???, 447 .frequency_tolerance = ???,
452 .symbol_rate_tolerance = ???, /* ppm */ /* == 8% (spec p. 5) */ 448 .symbol_rate_tolerance = ???, /* ppm */ /* == 8% (spec p. 5) */
453 #endif 449 #endif
@@ -461,7 +457,6 @@ static struct dvb_frontend_ops tda10021_ops = {
461 457
462 .init = tda10021_init, 458 .init = tda10021_init,
463 .sleep = tda10021_sleep, 459 .sleep = tda10021_sleep,
464 .write = tda10021_write,
465 .i2c_gate_ctrl = tda10021_i2c_gate_ctrl, 460 .i2c_gate_ctrl = tda10021_i2c_gate_ctrl,
466 461
467 .set_frontend = tda10021_set_parameters, 462 .set_frontend = tda10021_set_parameters,
diff --git a/drivers/media/dvb/frontends/tda10023.c b/drivers/media/dvb/frontends/tda10023.c
new file mode 100644
index 000000000000..da796e784be3
--- /dev/null
+++ b/drivers/media/dvb/frontends/tda10023.c
@@ -0,0 +1,540 @@
1/*
2 TDA10023 - DVB-C decoder
3 (as used in Philips CU1216-3 NIM and the Reelbox DVB-C tuner card)
4
5 Copyright (C) 2005 Georg Acher, BayCom GmbH (acher at baycom dot de)
6 Copyright (c) 2006 Hartmut Birr (e9hack at gmail dot com)
7
8 Remotely based on tda10021.c
9 Copyright (C) 1999 Convergence Integrated Media GmbH <ralph@convergence.de>
10 Copyright (C) 2004 Markus Schulz <msc@antzsystem.de>
11 Support for TDA10021
12
13 This program is free software; you can redistribute it and/or modify
14 it under the terms of the GNU General Public License as published by
15 the Free Software Foundation; either version 2 of the License, or
16 (at your option) any later version.
17
18 This program is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 GNU General Public License for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26*/
27
28#include <linux/delay.h>
29#include <linux/errno.h>
30#include <linux/init.h>
31#include <linux/kernel.h>
32#include <linux/module.h>
33#include <linux/string.h>
34#include <linux/slab.h>
35
36#include <asm/div64.h>
37
38#include "dvb_frontend.h"
39#include "tda1002x.h"
40
41
42struct tda10023_state {
43 struct i2c_adapter* i2c;
44 /* configuration settings */
45 const struct tda1002x_config* config;
46 struct dvb_frontend frontend;
47
48 u8 pwm;
49 u8 reg0;
50};
51
52
53#define dprintk(x...)
54
55static int verbose;
56
57#define XTAL 28920000UL
58#define PLL_M 8UL
59#define PLL_P 4UL
60#define PLL_N 1UL
61#define SYSCLK (XTAL*PLL_M/(PLL_N*PLL_P)) // -> 57840000
62
63static u8 tda10023_inittab[]={
64 // reg mask val
65 0x2a,0xff,0x02, // PLL3, Bypass, Power Down
66 0xff,0x64,0x00, // Sleep 100ms
67 0x2a,0xff,0x03, // PLL3, Bypass, Power Down
68 0xff,0x64,0x00, // Sleep 100ms
69 0x28,0xff,PLL_M-1, // PLL1 M=8
70 0x29,0xff,((PLL_P-1)<<6)|(PLL_N-1), // PLL2
71 0x00,0xff,0x23, // GPR FSAMPLING=1
72 0x2a,0xff,0x08, // PLL3 PSACLK=1
73 0xff,0x64,0x00, // Sleep 100ms
74 0x1f,0xff,0x00, // RESET
75 0xff,0x64,0x00, // Sleep 100ms
76 0xe6,0x0c,0x04, // RSCFG_IND
77 0x10,0xc0,0x80, // DECDVBCFG1 PBER=1
78
79 0x0e,0xff,0x82, // GAIN1
80 0x03,0x08,0x08, // CLKCONF DYN=1
81 0x2e,0xbf,0x30, // AGCCONF2 TRIAGC=0,POSAGC=ENAGCIF=1 PPWMTUN=0 PPWMIF=0
82 0x01,0xff,0x30, // AGCREF
83 0x1e,0x84,0x84, // CONTROL SACLK_ON=1
84 0x1b,0xff,0xc8, // ADC TWOS=1
85 0x3b,0xff,0xff, // IFMAX
86 0x3c,0xff,0x00, // IFMIN
87 0x34,0xff,0x00, // PWMREF
88 0x35,0xff,0xff, // TUNMAX
89 0x36,0xff,0x00, // TUNMIN
90 0x06,0xff,0x7f, // EQCONF1 POSI=7 ENADAPT=ENEQUAL=DFE=1 // 0x77
91 0x1c,0x30,0x30, // EQCONF2 STEPALGO=SGNALGO=1
92 0x37,0xff,0xf6, // DELTAF_LSB
93 0x38,0xff,0xff, // DELTAF_MSB
94 0x02,0xff,0x93, // AGCCONF1 IFS=1 KAGCIF=2 KAGCTUN=3
95 0x2d,0xff,0xf6, // SWEEP SWPOS=1 SWDYN=7 SWSTEP=1 SWLEN=2
96 0x04,0x10,0x00, // SWRAMP=1
97 0x12,0xff,0xa1, // INTP1 POCLKP=1 FEL=1 MFS=0
98 0x2b,0x01,0xa1, // INTS1
99 0x20,0xff,0x04, // INTP2 SWAPP=? MSBFIRSTP=? INTPSEL=?
100 0x2c,0xff,0x0d, // INTP/S TRIP=0 TRIS=0
101 0xc4,0xff,0x00,
102 0xc3,0x30,0x00,
103 0xb5,0xff,0x19, // ERAGC_THD
104 0x00,0x03,0x01, // GPR, CLBS soft reset
105 0x00,0x03,0x03, // GPR, CLBS soft reset
106 0xff,0x64,0x00, // Sleep 100ms
107 0xff,0xff,0xff
108};
109
110static u8 tda10023_readreg (struct tda10023_state* state, u8 reg)
111{
112 u8 b0 [] = { reg };
113 u8 b1 [] = { 0 };
114 struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 1 },
115 { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } };
116 int ret;
117
118 ret = i2c_transfer (state->i2c, msg, 2);
119 if (ret != 2)
120 printk("DVB: TDA10023: %s: readreg error (ret == %i)\n",
121 __FUNCTION__, ret);
122 return b1[0];
123}
124
125static int tda10023_writereg (struct tda10023_state* state, u8 reg, u8 data)
126{
127 u8 buf[] = { reg, data };
128 struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 };
129 int ret;
130
131 ret = i2c_transfer (state->i2c, &msg, 1);
132 if (ret != 1)
133 printk("DVB: TDA10023(%d): %s, writereg error "
134 "(reg == 0x%02x, val == 0x%02x, ret == %i)\n",
135 state->frontend.dvb->num, __FUNCTION__, reg, data, ret);
136
137 return (ret != 1) ? -EREMOTEIO : 0;
138}
139
140
141static int tda10023_writebit (struct tda10023_state* state, u8 reg, u8 mask,u8 data)
142{
143 if (mask==0xff)
144 return tda10023_writereg(state, reg, data);
145 else {
146 u8 val;
147 val=tda10023_readreg(state,reg);
148 val&=~mask;
149 val|=(data&mask);
150 return tda10023_writereg(state, reg, val);
151 }
152}
153
154static void tda10023_writetab(struct tda10023_state* state, u8* tab)
155{
156 u8 r,m,v;
157 while (1) {
158 r=*tab++;
159 m=*tab++;
160 v=*tab++;
161 if (r==0xff) {
162 if (m==0xff)
163 break;
164 else
165 msleep(m);
166 }
167 else
168 tda10023_writebit(state,r,m,v);
169 }
170}
171
172//get access to tuner
173static int lock_tuner(struct tda10023_state* state)
174{
175 u8 buf[2] = { 0x0f, 0xc0 };
176 struct i2c_msg msg = {.addr=state->config->demod_address, .flags=0, .buf=buf, .len=2};
177
178 if(i2c_transfer(state->i2c, &msg, 1) != 1)
179 {
180 printk("tda10023: lock tuner fails\n");
181 return -EREMOTEIO;
182 }
183 return 0;
184}
185
186//release access from tuner
187static int unlock_tuner(struct tda10023_state* state)
188{
189 u8 buf[2] = { 0x0f, 0x40 };
190 struct i2c_msg msg_post={.addr=state->config->demod_address, .flags=0, .buf=buf, .len=2};
191
192 if(i2c_transfer(state->i2c, &msg_post, 1) != 1)
193 {
194 printk("tda10023: unlock tuner fails\n");
195 return -EREMOTEIO;
196 }
197 return 0;
198}
199
200static int tda10023_setup_reg0 (struct tda10023_state* state, u8 reg0)
201{
202 reg0 |= state->reg0 & 0x63;
203
204 tda10023_writereg (state, 0x00, reg0 & 0xfe);
205 tda10023_writereg (state, 0x00, reg0 | 0x01);
206
207 state->reg0 = reg0;
208 return 0;
209}
210
211static int tda10023_set_symbolrate (struct tda10023_state* state, u32 sr)
212{
213 s32 BDR;
214 s32 BDRI;
215 s16 SFIL=0;
216 u16 NDEC = 0;
217
218 if (sr > (SYSCLK/(2*4)))
219 sr=SYSCLK/(2*4);
220
221 if (sr<870000)
222 sr=870000;
223
224 if (sr < (u32)(SYSCLK/98.40)) {
225 NDEC=3;
226 SFIL=1;
227 } else if (sr<(u32)(SYSCLK/64.0)) {
228 NDEC=3;
229 SFIL=0;
230 } else if (sr<(u32)(SYSCLK/49.2)) {
231 NDEC=2;
232 SFIL=1;
233 } else if (sr<(u32)(SYSCLK/32.0)) {
234 NDEC=2;
235 SFIL=0;
236 } else if (sr<(u32)(SYSCLK/24.6)) {
237 NDEC=1;
238 SFIL=1;
239 } else if (sr<(u32)(SYSCLK/16.0)) {
240 NDEC=1;
241 SFIL=0;
242 } else if (sr<(u32)(SYSCLK/12.3)) {
243 NDEC=0;
244 SFIL=1;
245 }
246
247 BDRI=SYSCLK*16;
248 BDRI>>=NDEC;
249 BDRI +=sr/2;
250 BDRI /=sr;
251
252 if (BDRI>255)
253 BDRI=255;
254
255 {
256 u64 BDRX;
257
258 BDRX=1<<(24+NDEC);
259 BDRX*=sr;
260 do_div(BDRX,SYSCLK); // BDRX/=SYSCLK;
261
262 BDR=(s32)BDRX;
263 }
264// printk("Symbolrate %i, BDR %i BDRI %i, NDEC %i\n",sr,BDR,BDRI,NDEC);
265 tda10023_writebit (state, 0x03, 0xc0, NDEC<<6);
266 tda10023_writereg (state, 0x0a, BDR&255);
267 tda10023_writereg (state, 0x0b, (BDR>>8)&255);
268 tda10023_writereg (state, 0x0c, (BDR>>16)&31);
269 tda10023_writereg (state, 0x0d, BDRI);
270 tda10023_writereg (state, 0x3d, (SFIL<<7));
271 return 0;
272}
273
274static int tda10023_init (struct dvb_frontend *fe)
275{
276 struct tda10023_state* state = fe->demodulator_priv;
277
278 dprintk("DVB: TDA10023(%d): init chip\n", fe->adapter->num);
279
280 tda10023_writetab(state, tda10023_inittab);
281
282 return 0;
283}
284
285static int tda10023_set_parameters (struct dvb_frontend *fe,
286 struct dvb_frontend_parameters *p)
287{
288 struct tda10023_state* state = fe->demodulator_priv;
289
290 static int qamvals[6][6] = {
291 // QAM LOCKTHR MSETH AREF AGCREFNYQ ERAGCNYQ_THD
292 { (5<<2), 0x78, 0x8c, 0x96, 0x78, 0x4c }, // 4 QAM
293 { (0<<2), 0x87, 0xa2, 0x91, 0x8c, 0x57 }, // 16 QAM
294 { (1<<2), 0x64, 0x74, 0x96, 0x8c, 0x57 }, // 32 QAM
295 { (2<<2), 0x46, 0x43, 0x6a, 0x6a, 0x44 }, // 64 QAM
296 { (3<<2), 0x36, 0x34, 0x7e, 0x78, 0x4c }, // 128 QAM
297 { (4<<2), 0x26, 0x23, 0x6c, 0x5c, 0x3c }, // 256 QAM
298 };
299
300 int qam = p->u.qam.modulation;
301
302 if (qam < 0 || qam > 5)
303 return -EINVAL;
304
305 if (fe->ops.tuner_ops.set_params) {
306 fe->ops.tuner_ops.set_params(fe, p);
307 if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
308 }
309
310 tda10023_set_symbolrate (state, p->u.qam.symbol_rate);
311 tda10023_writereg (state, 0x05, qamvals[qam][1]);
312 tda10023_writereg (state, 0x08, qamvals[qam][2]);
313 tda10023_writereg (state, 0x09, qamvals[qam][3]);
314 tda10023_writereg (state, 0xb4, qamvals[qam][4]);
315 tda10023_writereg (state, 0xb6, qamvals[qam][5]);
316
317// tda10023_writereg (state, 0x04, (p->inversion?0x12:0x32));
318// tda10023_writebit (state, 0x04, 0x60, (p->inversion?0:0x20));
319 tda10023_writebit (state, 0x04, 0x40, 0x40);
320 tda10023_setup_reg0 (state, qamvals[qam][0]);
321
322 return 0;
323}
324
325static int tda10023_read_status(struct dvb_frontend* fe, fe_status_t* status)
326{
327 struct tda10023_state* state = fe->demodulator_priv;
328 int sync;
329
330 *status = 0;
331
332 //0x11[1] == CARLOCK -> Carrier locked
333 //0x11[2] == FSYNC -> Frame synchronisation
334 //0x11[3] == FEL -> Front End locked
335 //0x11[6] == NODVB -> DVB Mode Information
336 sync = tda10023_readreg (state, 0x11);
337
338 if (sync & 2)
339 *status |= FE_HAS_SIGNAL|FE_HAS_CARRIER;
340
341 if (sync & 4)
342 *status |= FE_HAS_SYNC|FE_HAS_VITERBI;
343
344 if (sync & 8)
345 *status |= FE_HAS_LOCK;
346
347 return 0;
348}
349
350static int tda10023_read_ber(struct dvb_frontend* fe, u32* ber)
351{
352 struct tda10023_state* state = fe->demodulator_priv;
353 u8 a,b,c;
354 a=tda10023_readreg(state, 0x14);
355 b=tda10023_readreg(state, 0x15);
356 c=tda10023_readreg(state, 0x16)&0xf;
357 tda10023_writebit (state, 0x10, 0xc0, 0x00);
358
359 *ber = a | (b<<8)| (c<<16);
360 return 0;
361}
362
363static int tda10023_read_signal_strength(struct dvb_frontend* fe, u16* strength)
364{
365 struct tda10023_state* state = fe->demodulator_priv;
366 u8 ifgain=tda10023_readreg(state, 0x2f);
367
368 u16 gain = ((255-tda10023_readreg(state, 0x17))) + (255-ifgain)/16;
369 // Max raw value is about 0xb0 -> Normalize to >0xf0 after 0x90
370 if (gain>0x90)
371 gain=gain+2*(gain-0x90);
372 if (gain>255)
373 gain=255;
374
375 *strength = (gain<<8)|gain;
376 return 0;
377}
378
379static int tda10023_read_snr(struct dvb_frontend* fe, u16* snr)
380{
381 struct tda10023_state* state = fe->demodulator_priv;
382
383 u8 quality = ~tda10023_readreg(state, 0x18);
384 *snr = (quality << 8) | quality;
385 return 0;
386}
387
388static int tda10023_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
389{
390 struct tda10023_state* state = fe->demodulator_priv;
391 u8 a,b,c,d;
392 a= tda10023_readreg (state, 0x74);
393 b= tda10023_readreg (state, 0x75);
394 c= tda10023_readreg (state, 0x76);
395 d= tda10023_readreg (state, 0x77);
396 *ucblocks = a | (b<<8)|(c<<16)|(d<<24);
397
398 tda10023_writebit (state, 0x10, 0x20,0x00);
399 tda10023_writebit (state, 0x10, 0x20,0x20);
400 tda10023_writebit (state, 0x13, 0x01, 0x00);
401
402 return 0;
403}
404
405static int tda10023_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
406{
407 struct tda10023_state* state = fe->demodulator_priv;
408 int sync,inv;
409 s8 afc = 0;
410
411 sync = tda10023_readreg(state, 0x11);
412 afc = tda10023_readreg(state, 0x19);
413 inv = tda10023_readreg(state, 0x04);
414
415 if (verbose) {
416 /* AFC only valid when carrier has been recovered */
417 printk(sync & 2 ? "DVB: TDA10023(%d): AFC (%d) %dHz\n" :
418 "DVB: TDA10023(%d): [AFC (%d) %dHz]\n",
419 state->frontend.dvb->num, afc,
420 -((s32)p->u.qam.symbol_rate * afc) >> 10);
421 }
422
423 p->inversion = (inv&0x20?0:1);
424 p->u.qam.modulation = ((state->reg0 >> 2) & 7) + QAM_16;
425
426 p->u.qam.fec_inner = FEC_NONE;
427 p->frequency = ((p->frequency + 31250) / 62500) * 62500;
428
429 if (sync & 2)
430 p->frequency -= ((s32)p->u.qam.symbol_rate * afc) >> 10;
431
432 return 0;
433}
434
435static int tda10023_sleep(struct dvb_frontend* fe)
436{
437 struct tda10023_state* state = fe->demodulator_priv;
438
439 tda10023_writereg (state, 0x1b, 0x02); /* pdown ADC */
440 tda10023_writereg (state, 0x00, 0x80); /* standby */
441
442 return 0;
443}
444
445static int tda10023_i2c_gate_ctrl(struct dvb_frontend* fe, int enable)
446{
447 struct tda10023_state* state = fe->demodulator_priv;
448
449 if (enable) {
450 lock_tuner(state);
451 } else {
452 unlock_tuner(state);
453 }
454 return 0;
455}
456
457static void tda10023_release(struct dvb_frontend* fe)
458{
459 struct tda10023_state* state = fe->demodulator_priv;
460 kfree(state);
461}
462
463static struct dvb_frontend_ops tda10023_ops;
464
465struct dvb_frontend* tda10023_attach(const struct tda1002x_config* config,
466 struct i2c_adapter* i2c,
467 u8 pwm)
468{
469 struct tda10023_state* state = NULL;
470 int i;
471
472 /* allocate memory for the internal state */
473 state = kmalloc(sizeof(struct tda10023_state), GFP_KERNEL);
474 if (state == NULL) goto error;
475
476 /* setup the state */
477 state->config = config;
478 state->i2c = i2c;
479 memcpy(&state->frontend.ops, &tda10023_ops, sizeof(struct dvb_frontend_ops));
480 state->pwm = pwm;
481 for (i=0; i < sizeof(tda10023_inittab)/sizeof(*tda10023_inittab);i+=3) {
482 if (tda10023_inittab[i] == 0x00) {
483 state->reg0 = tda10023_inittab[i+2];
484 break;
485 }
486 }
487
488 // Wakeup if in standby
489 tda10023_writereg (state, 0x00, 0x33);
490 /* check if the demod is there */
491 if ((tda10023_readreg(state, 0x1a) & 0xf0) != 0x70) goto error;
492
493 /* create dvb_frontend */
494 memcpy(&state->frontend.ops, &tda10023_ops, sizeof(struct dvb_frontend_ops));
495 state->frontend.demodulator_priv = state;
496 return &state->frontend;
497
498error:
499 kfree(state);
500 return NULL;
501}
502
503static struct dvb_frontend_ops tda10023_ops = {
504
505 .info = {
506 .name = "Philips TDA10023 DVB-C",
507 .type = FE_QAM,
508 .frequency_stepsize = 62500,
509 .frequency_min = 51000000,
510 .frequency_max = 858000000,
511 .symbol_rate_min = (SYSCLK/2)/64, /* SACLK/64 == (SYSCLK/2)/64 */
512 .symbol_rate_max = (SYSCLK/2)/4, /* SACLK/4 */
513 .caps = 0x400 | //FE_CAN_QAM_4
514 FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 |
515 FE_CAN_QAM_128 | FE_CAN_QAM_256 |
516 FE_CAN_FEC_AUTO
517 },
518
519 .release = tda10023_release,
520
521 .init = tda10023_init,
522 .sleep = tda10023_sleep,
523 .i2c_gate_ctrl = tda10023_i2c_gate_ctrl,
524
525 .set_frontend = tda10023_set_parameters,
526 .get_frontend = tda10023_get_frontend,
527
528 .read_status = tda10023_read_status,
529 .read_ber = tda10023_read_ber,
530 .read_signal_strength = tda10023_read_signal_strength,
531 .read_snr = tda10023_read_snr,
532 .read_ucblocks = tda10023_read_ucblocks,
533};
534
535
536MODULE_DESCRIPTION("Philips TDA10023 DVB-C demodulator driver");
537MODULE_AUTHOR("Georg Acher, Hartmut Birr");
538MODULE_LICENSE("GPL");
539
540EXPORT_SYMBOL(tda10023_attach);
diff --git a/drivers/media/dvb/frontends/tda10021.h b/drivers/media/dvb/frontends/tda1002x.h
index e3da780108f6..e9094d8123f6 100644
--- a/drivers/media/dvb/frontends/tda10021.h
+++ b/drivers/media/dvb/frontends/tda1002x.h
@@ -1,6 +1,6 @@
1/* 1/*
2 TDA10021 - Single Chip Cable Channel Receiver driver module 2 TDA10021/TDA10023 - Single Chip Cable Channel Receiver driver module
3 used on the the Siemens DVB-C cards 3 used on the the Siemens DVB-C cards
4 4
5 Copyright (C) 1999 Convergence Integrated Media GmbH <ralph@convergence.de> 5 Copyright (C) 1999 Convergence Integrated Media GmbH <ralph@convergence.de>
6 Copyright (C) 2004 Markus Schulz <msc@antzsystem.de> 6 Copyright (C) 2004 Markus Schulz <msc@antzsystem.de>
@@ -21,22 +21,23 @@
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22*/ 22*/
23 23
24#ifndef TDA10021_H 24#ifndef TDA1002x_H
25#define TDA10021_H 25#define TDA1002x_H
26 26
27#include <linux/dvb/frontend.h> 27#include <linux/dvb/frontend.h>
28 28
29struct tda10021_config 29struct tda1002x_config
30{ 30{
31 /* the demodulator's i2c address */ 31 /* the demodulator's i2c address */
32 u8 demod_address; 32 u8 demod_address;
33 u8 invert;
33}; 34};
34 35
35#if defined(CONFIG_DVB_TDA10021) || (defined(CONFIG_DVB_TDA10021_MODULE) && defined(MODULE)) 36#if defined(CONFIG_DVB_TDA10021) || (defined(CONFIG_DVB_TDA10021_MODULE) && defined(MODULE))
36extern struct dvb_frontend* tda10021_attach(const struct tda10021_config* config, 37extern struct dvb_frontend* tda10021_attach(const struct tda1002x_config* config,
37 struct i2c_adapter* i2c, u8 pwm); 38 struct i2c_adapter* i2c, u8 pwm);
38#else 39#else
39static inline struct dvb_frontend* tda10021_attach(const struct tda10021_config* config, 40static inline struct dvb_frontend* tda10021_attach(const struct tda1002x_config* config,
40 struct i2c_adapter* i2c, u8 pwm) 41 struct i2c_adapter* i2c, u8 pwm)
41{ 42{
42 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__); 43 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
@@ -44,12 +45,16 @@ static inline struct dvb_frontend* tda10021_attach(const struct tda10021_config*
44} 45}
45#endif // CONFIG_DVB_TDA10021 46#endif // CONFIG_DVB_TDA10021
46 47
47static inline int tda10021_writereg(struct dvb_frontend *fe, u8 reg, u8 val) { 48#if defined(CONFIG_DVB_TDA10023) || (defined(CONFIG_DVB_TDA10023_MODULE) && defined(MODULE))
48 int r = 0; 49extern struct dvb_frontend* tda10023_attach(const struct tda1002x_config* config,
49 u8 buf[] = {reg, val}; 50 struct i2c_adapter* i2c, u8 pwm);
50 if (fe->ops.write) 51#else
51 r = fe->ops.write(fe, buf, 2); 52static inline struct dvb_frontend* tda10023_attach(const struct tda1002x_config* config,
52 return r; 53 struct i2c_adapter* i2c, u8 pwm)
54{
55 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
56 return NULL;
53} 57}
58#endif // CONFIG_DVB_TDA10023
54 59
55#endif // TDA10021_H 60#endif // TDA1002x_H
diff --git a/drivers/media/dvb/frontends/tda1004x.c b/drivers/media/dvb/frontends/tda1004x.c
index f4a9cf9d26d0..33a84372c9e6 100644
--- a/drivers/media/dvb/frontends/tda1004x.c
+++ b/drivers/media/dvb/frontends/tda1004x.c
@@ -40,20 +40,6 @@
40#include "dvb_frontend.h" 40#include "dvb_frontend.h"
41#include "tda1004x.h" 41#include "tda1004x.h"
42 42
43enum tda1004x_demod {
44 TDA1004X_DEMOD_TDA10045,
45 TDA1004X_DEMOD_TDA10046,
46};
47
48struct tda1004x_state {
49 struct i2c_adapter* i2c;
50 const struct tda1004x_config* config;
51 struct dvb_frontend frontend;
52
53 /* private demod data */
54 enum tda1004x_demod demod_type;
55};
56
57static int debug; 43static int debug;
58#define dprintk(args...) \ 44#define dprintk(args...) \
59 do { \ 45 do { \
@@ -507,35 +493,51 @@ static int tda10046_fwupload(struct dvb_frontend* fe)
507 tda1004x_write_byteI(state, TDA1004X_CONFC4, 0x80); 493 tda1004x_write_byteI(state, TDA1004X_CONFC4, 0x80);
508 } 494 }
509 tda1004x_write_mask(state, TDA10046H_CONF_TRISTATE1, 1, 0); 495 tda1004x_write_mask(state, TDA10046H_CONF_TRISTATE1, 1, 0);
496 /* set GPIO 1 and 3 */
497 if (state->config->gpio_config != TDA10046_GPTRI) {
498 tda1004x_write_byteI(state, TDA10046H_CONF_TRISTATE2, 0x33);
499 tda1004x_write_mask(state, TDA10046H_CONF_POLARITY, 0x0f, state->config->gpio_config &0x0f);
500 }
510 /* let the clocks recover from sleep */ 501 /* let the clocks recover from sleep */
511 msleep(5); 502 msleep(10);
512 503
513 /* The PLLs need to be reprogrammed after sleep */ 504 /* The PLLs need to be reprogrammed after sleep */
514 tda10046_init_plls(fe); 505 tda10046_init_plls(fe);
506 tda1004x_write_mask(state, TDA1004X_CONFADC2, 0xc0, 0);
515 507
516 /* don't re-upload unless necessary */ 508 /* don't re-upload unless necessary */
517 if (tda1004x_check_upload_ok(state) == 0) 509 if (tda1004x_check_upload_ok(state) == 0)
518 return 0; 510 return 0;
519 511
512 printk(KERN_INFO "tda1004x: trying to boot from eeprom\n");
513 tda1004x_write_mask(state, TDA1004X_CONFC4, 4, 4);
514 msleep(300);
515 /* don't re-upload unless necessary */
516 if (tda1004x_check_upload_ok(state) == 0)
517 return 0;
518
520 if (state->config->request_firmware != NULL) { 519 if (state->config->request_firmware != NULL) {
521 /* request the firmware, this will block until someone uploads it */ 520 /* request the firmware, this will block until someone uploads it */
522 printk(KERN_INFO "tda1004x: waiting for firmware upload...\n"); 521 printk(KERN_INFO "tda1004x: waiting for firmware upload...\n");
523 ret = state->config->request_firmware(fe, &fw, TDA10046_DEFAULT_FIRMWARE); 522 ret = state->config->request_firmware(fe, &fw, TDA10046_DEFAULT_FIRMWARE);
524 if (ret) { 523 if (ret) {
525 printk(KERN_ERR "tda1004x: no firmware upload (timeout or file not found?)\n"); 524 /* remain compatible to old bug: try to load with tda10045 image name */
526 return ret; 525 ret = state->config->request_firmware(fe, &fw, TDA10045_DEFAULT_FIRMWARE);
526 if (ret) {
527 printk(KERN_ERR "tda1004x: no firmware upload (timeout or file not found?)\n");
528 return ret;
529 } else {
530 printk(KERN_INFO "tda1004x: please rename the firmware file to %s\n",
531 TDA10046_DEFAULT_FIRMWARE);
532 }
527 } 533 }
528 tda1004x_write_mask(state, TDA1004X_CONFC4, 8, 8); // going to boot from HOST
529 ret = tda1004x_do_upload(state, fw->data, fw->size, TDA10046H_CODE_CPT, TDA10046H_CODE_IN);
530 release_firmware(fw);
531 if (ret)
532 return ret;
533 } else { 534 } else {
534 /* boot from firmware eeprom */ 535 printk(KERN_ERR "tda1004x: no request function defined, can't upload from file\n");
535 printk(KERN_INFO "tda1004x: booting from eeprom\n"); 536 return -EIO;
536 tda1004x_write_mask(state, TDA1004X_CONFC4, 4, 4);
537 msleep(300);
538 } 537 }
538 tda1004x_write_mask(state, TDA1004X_CONFC4, 8, 8); // going to boot from HOST
539 ret = tda1004x_do_upload(state, fw->data, fw->size, TDA10046H_CODE_CPT, TDA10046H_CODE_IN);
540 release_firmware(fw);
539 return tda1004x_check_upload_ok(state); 541 return tda1004x_check_upload_ok(state);
540} 542}
541 543
@@ -638,37 +640,33 @@ static int tda10046_init(struct dvb_frontend* fe)
638 switch (state->config->agc_config) { 640 switch (state->config->agc_config) {
639 case TDA10046_AGC_DEFAULT: 641 case TDA10046_AGC_DEFAULT:
640 tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x00); // AGC setup 642 tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x00); // AGC setup
641 tda1004x_write_byteI(state, TDA10046H_CONF_POLARITY, 0x60); // set AGC polarities 643 tda1004x_write_mask(state, TDA10046H_CONF_POLARITY, 0xf0, 0x60); // set AGC polarities
642 break; 644 break;
643 case TDA10046_AGC_IFO_AUTO_NEG: 645 case TDA10046_AGC_IFO_AUTO_NEG:
644 tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x0a); // AGC setup 646 tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x0a); // AGC setup
645 tda1004x_write_byteI(state, TDA10046H_CONF_POLARITY, 0x60); // set AGC polarities 647 tda1004x_write_mask(state, TDA10046H_CONF_POLARITY, 0xf0, 0x60); // set AGC polarities
646 break; 648 break;
647 case TDA10046_AGC_IFO_AUTO_POS: 649 case TDA10046_AGC_IFO_AUTO_POS:
648 tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x0a); // AGC setup 650 tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x0a); // AGC setup
649 tda1004x_write_byteI(state, TDA10046H_CONF_POLARITY, 0x00); // set AGC polarities 651 tda1004x_write_mask(state, TDA10046H_CONF_POLARITY, 0xf0, 0x00); // set AGC polarities
650 break;
651 case TDA10046_AGC_TDA827X_GP11:
652 tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x02); // AGC setup
653 tda1004x_write_byteI(state, TDA10046H_AGC_THR, 0x70); // AGC Threshold
654 tda1004x_write_byteI(state, TDA10046H_AGC_RENORM, 0x08); // Gain Renormalize
655 tda1004x_write_byteI(state, TDA10046H_CONF_POLARITY, 0x6a); // set AGC polarities
656 break;
657 case TDA10046_AGC_TDA827X_GP00:
658 tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x02); // AGC setup
659 tda1004x_write_byteI(state, TDA10046H_AGC_THR, 0x70); // AGC Threshold
660 tda1004x_write_byteI(state, TDA10046H_AGC_RENORM, 0x08); // Gain Renormalize
661 tda1004x_write_byteI(state, TDA10046H_CONF_POLARITY, 0x60); // set AGC polarities
662 break; 652 break;
663 case TDA10046_AGC_TDA827X_GP01: 653 case TDA10046_AGC_TDA827X:
664 tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x02); // AGC setup 654 tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x02); // AGC setup
665 tda1004x_write_byteI(state, TDA10046H_AGC_THR, 0x70); // AGC Threshold 655 tda1004x_write_byteI(state, TDA10046H_AGC_THR, 0x70); // AGC Threshold
666 tda1004x_write_byteI(state, TDA10046H_AGC_RENORM, 0x08); // Gain Renormalize 656 tda1004x_write_byteI(state, TDA10046H_AGC_RENORM, 0x08); // Gain Renormalize
667 tda1004x_write_byteI(state, TDA10046H_CONF_POLARITY, 0x62); // set AGC polarities 657 tda1004x_write_mask(state, TDA10046H_CONF_POLARITY, 0xf0, 0x60); // set AGC polarities
668 break; 658 break;
669 } 659 }
660 if (state->config->ts_mode == 0) {
661 tda1004x_write_mask(state, TDA10046H_CONF_TRISTATE1, 0xc0, 0x40);
662 tda1004x_write_mask(state, 0x3a, 0x80, state->config->invert_oclk << 7);
663 } else {
664 tda1004x_write_mask(state, TDA10046H_CONF_TRISTATE1, 0xc0, 0x80);
665 tda1004x_write_mask(state, TDA10046H_CONF_POLARITY, 0x10,
666 state->config->invert_oclk << 4);
667 }
670 tda1004x_write_byteI(state, TDA1004X_CONFADC2, 0x38); 668 tda1004x_write_byteI(state, TDA1004X_CONFADC2, 0x38);
671 tda1004x_write_byteI(state, TDA10046H_CONF_TRISTATE1, 0x61); // Turn both AGC outputs on 669 tda1004x_write_mask (state, TDA10046H_CONF_TRISTATE1, 0x3e, 0x38); // Turn IF AGC output on
672 tda1004x_write_byteI(state, TDA10046H_AGC_TUN_MIN, 0); // } 670 tda1004x_write_byteI(state, TDA10046H_AGC_TUN_MIN, 0); // }
673 tda1004x_write_byteI(state, TDA10046H_AGC_TUN_MAX, 0xff); // } AGC min/max values 671 tda1004x_write_byteI(state, TDA10046H_AGC_TUN_MAX, 0xff); // } AGC min/max values
674 tda1004x_write_byteI(state, TDA10046H_AGC_IF_MIN, 0); // } 672 tda1004x_write_byteI(state, TDA10046H_AGC_IF_MIN, 0); // }
@@ -678,7 +676,6 @@ static int tda10046_init(struct dvb_frontend* fe)
678 tda1004x_write_byteI(state, TDA1004X_CONF_TS1, 7); // MPEG2 interface config 676 tda1004x_write_byteI(state, TDA1004X_CONF_TS1, 7); // MPEG2 interface config
679 tda1004x_write_byteI(state, TDA1004X_CONF_TS2, 0xc0); // MPEG2 interface config 677 tda1004x_write_byteI(state, TDA1004X_CONF_TS2, 0xc0); // MPEG2 interface config
680 // tda1004x_write_mask(state, 0x50, 0x80, 0x80); // handle out of guard echoes 678 // tda1004x_write_mask(state, 0x50, 0x80, 0x80); // handle out of guard echoes
681 tda1004x_write_mask(state, 0x3a, 0x80, state->config->invert_oclk << 7);
682 679
683 return 0; 680 return 0;
684} 681}
@@ -705,7 +702,8 @@ static int tda1004x_set_fe(struct dvb_frontend* fe,
705 // set frequency 702 // set frequency
706 if (fe->ops.tuner_ops.set_params) { 703 if (fe->ops.tuner_ops.set_params) {
707 fe->ops.tuner_ops.set_params(fe, fe_params); 704 fe->ops.tuner_ops.set_params(fe, fe_params);
708 if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); 705 if (fe->ops.i2c_gate_ctrl)
706 fe->ops.i2c_gate_ctrl(fe, 0);
709 } 707 }
710 708
711 // Hardcoded to use auto as much as possible on the TDA10045 as it 709 // Hardcoded to use auto as much as possible on the TDA10045 as it
@@ -1165,6 +1163,7 @@ static int tda1004x_read_ber(struct dvb_frontend* fe, u32* ber)
1165static int tda1004x_sleep(struct dvb_frontend* fe) 1163static int tda1004x_sleep(struct dvb_frontend* fe)
1166{ 1164{
1167 struct tda1004x_state* state = fe->demodulator_priv; 1165 struct tda1004x_state* state = fe->demodulator_priv;
1166 int gpio_conf;
1168 1167
1169 switch (state->demod_type) { 1168 switch (state->demod_type) {
1170 case TDA1004X_DEMOD_TDA10045: 1169 case TDA1004X_DEMOD_TDA10045:
@@ -1174,6 +1173,13 @@ static int tda1004x_sleep(struct dvb_frontend* fe)
1174 case TDA1004X_DEMOD_TDA10046: 1173 case TDA1004X_DEMOD_TDA10046:
1175 /* set outputs to tristate */ 1174 /* set outputs to tristate */
1176 tda1004x_write_byteI(state, TDA10046H_CONF_TRISTATE1, 0xff); 1175 tda1004x_write_byteI(state, TDA10046H_CONF_TRISTATE1, 0xff);
1176 /* invert GPIO 1 and 3 if desired*/
1177 gpio_conf = state->config->gpio_config;
1178 if (gpio_conf >= TDA10046_GP00_I)
1179 tda1004x_write_mask(state, TDA10046H_CONF_POLARITY, 0x0f,
1180 (gpio_conf & 0x0f) ^ 0x0a);
1181
1182 tda1004x_write_mask(state, TDA1004X_CONFADC2, 0xc0, 0xc0);
1177 tda1004x_write_mask(state, TDA1004X_CONFC4, 1, 1); 1183 tda1004x_write_mask(state, TDA1004X_CONFC4, 1, 1);
1178 break; 1184 break;
1179 } 1185 }
diff --git a/drivers/media/dvb/frontends/tda1004x.h b/drivers/media/dvb/frontends/tda1004x.h
index ec502d71b83c..abae84350142 100644
--- a/drivers/media/dvb/frontends/tda1004x.h
+++ b/drivers/media/dvb/frontends/tda1004x.h
@@ -35,9 +35,23 @@ enum tda10046_agc {
35 TDA10046_AGC_DEFAULT, /* original configuration */ 35 TDA10046_AGC_DEFAULT, /* original configuration */
36 TDA10046_AGC_IFO_AUTO_NEG, /* IF AGC only, automatic, negtive */ 36 TDA10046_AGC_IFO_AUTO_NEG, /* IF AGC only, automatic, negtive */
37 TDA10046_AGC_IFO_AUTO_POS, /* IF AGC only, automatic, positive */ 37 TDA10046_AGC_IFO_AUTO_POS, /* IF AGC only, automatic, positive */
38 TDA10046_AGC_TDA827X_GP11, /* IF AGC only, special setup for tda827x */ 38 TDA10046_AGC_TDA827X, /* IF AGC only, special setup for tda827x */
39 TDA10046_AGC_TDA827X_GP00, /* same as above, but GPIOs 0 */ 39};
40 TDA10046_AGC_TDA827X_GP01, /* same as above, but GPIO3=0 GPIO1=1*/ 40
41/* Many (hybrid) boards use GPIO 1 and 3
42 GPIO1 analog - dvb switch
43 GPIO3 firmware eeprom address switch
44*/
45enum tda10046_gpio {
46 TDA10046_GPTRI = 0x00, /* All GPIOs tristate */
47 TDA10046_GP00 = 0x40, /* GPIO3=0, GPIO1=0 */
48 TDA10046_GP01 = 0x42, /* GPIO3=0, GPIO1=1 */
49 TDA10046_GP10 = 0x48, /* GPIO3=1, GPIO1=0 */
50 TDA10046_GP11 = 0x4a, /* GPIO3=1, GPIO1=1 */
51 TDA10046_GP00_I = 0x80, /* GPIO3=0, GPIO1=0, invert in sleep mode*/
52 TDA10046_GP01_I = 0x82, /* GPIO3=0, GPIO1=1, invert in sleep mode */
53 TDA10046_GP10_I = 0x88, /* GPIO3=1, GPIO1=0, invert in sleep mode */
54 TDA10046_GP11_I = 0x8a, /* GPIO3=1, GPIO1=1, invert in sleep mode */
41}; 55};
42 56
43enum tda10046_if { 57enum tda10046_if {
@@ -47,6 +61,11 @@ enum tda10046_if {
47 TDA10046_FREQ_052, /* low IF, 5.1667 MHZ for tda9889 */ 61 TDA10046_FREQ_052, /* low IF, 5.1667 MHZ for tda9889 */
48}; 62};
49 63
64enum tda10046_tsout {
65 TDA10046_TS_PARALLEL = 0x00, /* parallel transport stream, default */
66 TDA10046_TS_SERIAL = 0x01, /* serial transport stream */
67};
68
50struct tda1004x_config 69struct tda1004x_config
51{ 70{
52 /* the demodulator's i2c address */ 71 /* the demodulator's i2c address */
@@ -58,6 +77,9 @@ struct tda1004x_config
58 /* Does the OCLK signal need inverted? */ 77 /* Does the OCLK signal need inverted? */
59 u8 invert_oclk; 78 u8 invert_oclk;
60 79
80 /* parallel or serial transport stream */
81 enum tda10046_tsout ts_mode;
82
61 /* Xtal frequency, 4 or 16MHz*/ 83 /* Xtal frequency, 4 or 16MHz*/
62 enum tda10046_xtal xtal_freq; 84 enum tda10046_xtal xtal_freq;
63 85
@@ -67,11 +89,35 @@ struct tda1004x_config
67 /* AGC configuration */ 89 /* AGC configuration */
68 enum tda10046_agc agc_config; 90 enum tda10046_agc agc_config;
69 91
92 /* setting of GPIO1 and 3 */
93 enum tda10046_gpio gpio_config;
94
95 /* slave address and configuration of the tuner */
96 u8 tuner_address;
97 u8 tuner_config;
98 u8 antenna_switch;
99
100 /* if the board uses another I2c Bridge (tda8290), its address */
101 u8 i2c_gate;
102
70 /* request firmware for device */ 103 /* request firmware for device */
71 /* set this to NULL if the card has a firmware EEPROM */
72 int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name); 104 int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name);
73}; 105};
74 106
107enum tda1004x_demod {
108 TDA1004X_DEMOD_TDA10045,
109 TDA1004X_DEMOD_TDA10046,
110};
111
112struct tda1004x_state {
113 struct i2c_adapter* i2c;
114 const struct tda1004x_config* config;
115 struct dvb_frontend frontend;
116
117 /* private demod data */
118 enum tda1004x_demod demod_type;
119};
120
75#if defined(CONFIG_DVB_TDA1004X) || (defined(CONFIG_DVB_TDA1004X_MODULE) && defined(MODULE)) 121#if defined(CONFIG_DVB_TDA1004X) || (defined(CONFIG_DVB_TDA1004X_MODULE) && defined(MODULE))
76extern struct dvb_frontend* tda10045_attach(const struct tda1004x_config* config, 122extern struct dvb_frontend* tda10045_attach(const struct tda1004x_config* config,
77 struct i2c_adapter* i2c); 123 struct i2c_adapter* i2c);
diff --git a/drivers/media/dvb/frontends/tda827x.c b/drivers/media/dvb/frontends/tda827x.c
new file mode 100644
index 000000000000..256fc4bf500b
--- /dev/null
+++ b/drivers/media/dvb/frontends/tda827x.c
@@ -0,0 +1,512 @@
1/*
2 *
3 * (c) 2005 Hartmut Hackmann
4 * (c) 2007 Michael Krufky
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#include <linux/module.h>
22#include <linux/dvb/frontend.h>
23#include <asm/types.h>
24
25#include "tda827x.h"
26
27static int debug = 0;
28#define dprintk(args...) \
29 do { \
30 if (debug) printk(KERN_DEBUG "tda827x: " args); \
31 } while (0)
32
33struct tda827x_priv {
34 int i2c_addr;
35 struct i2c_adapter *i2c_adap;
36 struct tda827x_config *cfg;
37 u32 frequency;
38 u32 bandwidth;
39};
40
41struct tda827x_data {
42 u32 lomax;
43 u8 spd;
44 u8 bs;
45 u8 bp;
46 u8 cp;
47 u8 gc3;
48 u8 div1p5;
49};
50
51static const struct tda827x_data tda827x_dvbt[] = {
52 { .lomax = 62000000, .spd = 3, .bs = 2, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 1},
53 { .lomax = 66000000, .spd = 3, .bs = 3, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 1},
54 { .lomax = 76000000, .spd = 3, .bs = 1, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 0},
55 { .lomax = 84000000, .spd = 3, .bs = 2, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 0},
56 { .lomax = 93000000, .spd = 3, .bs = 2, .bp = 0, .cp = 0, .gc3 = 1, .div1p5 = 0},
57 { .lomax = 98000000, .spd = 3, .bs = 3, .bp = 0, .cp = 0, .gc3 = 1, .div1p5 = 0},
58 { .lomax = 109000000, .spd = 3, .bs = 3, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 0},
59 { .lomax = 123000000, .spd = 2, .bs = 2, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 1},
60 { .lomax = 133000000, .spd = 2, .bs = 3, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 1},
61 { .lomax = 151000000, .spd = 2, .bs = 1, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 0},
62 { .lomax = 154000000, .spd = 2, .bs = 2, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 0},
63 { .lomax = 181000000, .spd = 2, .bs = 2, .bp = 1, .cp = 0, .gc3 = 0, .div1p5 = 0},
64 { .lomax = 185000000, .spd = 2, .bs = 2, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0},
65 { .lomax = 217000000, .spd = 2, .bs = 3, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0},
66 { .lomax = 244000000, .spd = 1, .bs = 2, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 1},
67 { .lomax = 265000000, .spd = 1, .bs = 3, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 1},
68 { .lomax = 302000000, .spd = 1, .bs = 1, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0},
69 { .lomax = 324000000, .spd = 1, .bs = 2, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0},
70 { .lomax = 370000000, .spd = 1, .bs = 2, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 0},
71 { .lomax = 454000000, .spd = 1, .bs = 3, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 0},
72 { .lomax = 493000000, .spd = 0, .bs = 2, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 1},
73 { .lomax = 530000000, .spd = 0, .bs = 3, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 1},
74 { .lomax = 554000000, .spd = 0, .bs = 1, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 0},
75 { .lomax = 604000000, .spd = 0, .bs = 1, .bp = 4, .cp = 0, .gc3 = 0, .div1p5 = 0},
76 { .lomax = 696000000, .spd = 0, .bs = 2, .bp = 4, .cp = 0, .gc3 = 0, .div1p5 = 0},
77 { .lomax = 740000000, .spd = 0, .bs = 2, .bp = 4, .cp = 1, .gc3 = 0, .div1p5 = 0},
78 { .lomax = 820000000, .spd = 0, .bs = 3, .bp = 4, .cp = 0, .gc3 = 0, .div1p5 = 0},
79 { .lomax = 865000000, .spd = 0, .bs = 3, .bp = 4, .cp = 1, .gc3 = 0, .div1p5 = 0},
80 { .lomax = 0, .spd = 0, .bs = 0, .bp = 0, .cp = 0, .gc3 = 0, .div1p5 = 0}
81};
82
83static int tda827xo_set_params(struct dvb_frontend *fe,
84 struct dvb_frontend_parameters *params)
85{
86 struct tda827x_priv *priv = fe->tuner_priv;
87 u8 buf[14];
88
89 struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0,
90 .buf = buf, .len = sizeof(buf) };
91 int i, tuner_freq, if_freq;
92 u32 N;
93
94 dprintk("%s:\n", __FUNCTION__);
95 switch (params->u.ofdm.bandwidth) {
96 case BANDWIDTH_6_MHZ:
97 if_freq = 4000000;
98 break;
99 case BANDWIDTH_7_MHZ:
100 if_freq = 4500000;
101 break;
102 default: /* 8 MHz or Auto */
103 if_freq = 5000000;
104 break;
105 }
106 tuner_freq = params->frequency + if_freq;
107
108 i = 0;
109 while (tda827x_dvbt[i].lomax < tuner_freq) {
110 if(tda827x_dvbt[i + 1].lomax == 0)
111 break;
112 i++;
113 }
114
115 N = ((tuner_freq + 125000) / 250000) << (tda827x_dvbt[i].spd + 2);
116 buf[0] = 0;
117 buf[1] = (N>>8) | 0x40;
118 buf[2] = N & 0xff;
119 buf[3] = 0;
120 buf[4] = 0x52;
121 buf[5] = (tda827x_dvbt[i].spd << 6) + (tda827x_dvbt[i].div1p5 << 5) +
122 (tda827x_dvbt[i].bs << 3) + tda827x_dvbt[i].bp;
123 buf[6] = (tda827x_dvbt[i].gc3 << 4) + 0x8f;
124 buf[7] = 0xbf;
125 buf[8] = 0x2a;
126 buf[9] = 0x05;
127 buf[10] = 0xff;
128 buf[11] = 0x00;
129 buf[12] = 0x00;
130 buf[13] = 0x40;
131
132 msg.len = 14;
133 if (fe->ops.i2c_gate_ctrl)
134 fe->ops.i2c_gate_ctrl(fe, 1);
135 if (i2c_transfer(priv->i2c_adap, &msg, 1) != 1) {
136 printk("%s: could not write to tuner at addr: 0x%02x\n",
137 __FUNCTION__, priv->i2c_addr << 1);
138 return -EIO;
139 }
140 msleep(500);
141 /* correct CP value */
142 buf[0] = 0x30;
143 buf[1] = 0x50 + tda827x_dvbt[i].cp;
144 msg.len = 2;
145
146 if (fe->ops.i2c_gate_ctrl)
147 fe->ops.i2c_gate_ctrl(fe, 1);
148 i2c_transfer(priv->i2c_adap, &msg, 1);
149
150 priv->frequency = tuner_freq - if_freq; // FIXME
151 priv->bandwidth = (fe->ops.info.type == FE_OFDM) ? params->u.ofdm.bandwidth : 0;
152
153 return 0;
154}
155
156static int tda827xo_sleep(struct dvb_frontend *fe)
157{
158 struct tda827x_priv *priv = fe->tuner_priv;
159 static u8 buf[] = { 0x30, 0xd0 };
160 struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0,
161 .buf = buf, .len = sizeof(buf) };
162
163 dprintk("%s:\n", __FUNCTION__);
164 if (fe->ops.i2c_gate_ctrl)
165 fe->ops.i2c_gate_ctrl(fe, 1);
166 i2c_transfer(priv->i2c_adap, &msg, 1);
167
168 if (priv->cfg && priv->cfg->sleep)
169 priv->cfg->sleep(fe);
170
171 return 0;
172}
173
174/* ------------------------------------------------------------------ */
175
176struct tda827xa_data {
177 u32 lomax;
178 u8 svco;
179 u8 spd;
180 u8 scr;
181 u8 sbs;
182 u8 gc3;
183};
184
185static const struct tda827xa_data tda827xa_dvbt[] = {
186 { .lomax = 56875000, .svco = 3, .spd = 4, .scr = 0, .sbs = 0, .gc3 = 1},
187 { .lomax = 67250000, .svco = 0, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 1},
188 { .lomax = 81250000, .svco = 1, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 1},
189 { .lomax = 97500000, .svco = 2, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 1},
190 { .lomax = 113750000, .svco = 3, .spd = 3, .scr = 0, .sbs = 1, .gc3 = 1},
191 { .lomax = 134500000, .svco = 0, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1},
192 { .lomax = 154000000, .svco = 1, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1},
193 { .lomax = 162500000, .svco = 1, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1},
194 { .lomax = 183000000, .svco = 2, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1},
195 { .lomax = 195000000, .svco = 2, .spd = 2, .scr = 0, .sbs = 2, .gc3 = 1},
196 { .lomax = 227500000, .svco = 3, .spd = 2, .scr = 0, .sbs = 2, .gc3 = 1},
197 { .lomax = 269000000, .svco = 0, .spd = 1, .scr = 0, .sbs = 2, .gc3 = 1},
198 { .lomax = 290000000, .svco = 1, .spd = 1, .scr = 0, .sbs = 2, .gc3 = 1},
199 { .lomax = 325000000, .svco = 1, .spd = 1, .scr = 0, .sbs = 3, .gc3 = 1},
200 { .lomax = 390000000, .svco = 2, .spd = 1, .scr = 0, .sbs = 3, .gc3 = 1},
201 { .lomax = 455000000, .svco = 3, .spd = 1, .scr = 0, .sbs = 3, .gc3 = 1},
202 { .lomax = 520000000, .svco = 0, .spd = 0, .scr = 0, .sbs = 3, .gc3 = 1},
203 { .lomax = 538000000, .svco = 0, .spd = 0, .scr = 1, .sbs = 3, .gc3 = 1},
204 { .lomax = 550000000, .svco = 1, .spd = 0, .scr = 0, .sbs = 3, .gc3 = 1},
205 { .lomax = 620000000, .svco = 1, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0},
206 { .lomax = 650000000, .svco = 1, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0},
207 { .lomax = 700000000, .svco = 2, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0},
208 { .lomax = 780000000, .svco = 2, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0},
209 { .lomax = 820000000, .svco = 3, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0},
210 { .lomax = 870000000, .svco = 3, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0},
211 { .lomax = 911000000, .svco = 3, .spd = 0, .scr = 2, .sbs = 4, .gc3 = 0},
212 { .lomax = 0, .svco = 0, .spd = 0, .scr = 0, .sbs = 0, .gc3 = 0}
213};
214
215static int tda827xa_set_params(struct dvb_frontend *fe,
216 struct dvb_frontend_parameters *params)
217{
218 struct tda827x_priv *priv = fe->tuner_priv;
219 u8 buf[11];
220
221 struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0,
222 .buf = buf, .len = sizeof(buf) };
223
224 int i, tuner_freq, if_freq;
225 u32 N;
226
227 dprintk("%s:\n", __FUNCTION__);
228 if (priv->cfg && priv->cfg->lna_gain)
229 priv->cfg->lna_gain(fe, 1);
230 msleep(20);
231
232 switch (params->u.ofdm.bandwidth) {
233 case BANDWIDTH_6_MHZ:
234 if_freq = 4000000;
235 break;
236 case BANDWIDTH_7_MHZ:
237 if_freq = 4500000;
238 break;
239 default: /* 8 MHz or Auto */
240 if_freq = 5000000;
241 break;
242 }
243 tuner_freq = params->frequency + if_freq;
244
245 i = 0;
246 while (tda827xa_dvbt[i].lomax < tuner_freq) {
247 if(tda827xa_dvbt[i + 1].lomax == 0)
248 break;
249 i++;
250 }
251
252 N = ((tuner_freq + 31250) / 62500) << tda827xa_dvbt[i].spd;
253 buf[0] = 0; // subaddress
254 buf[1] = N >> 8;
255 buf[2] = N & 0xff;
256 buf[3] = 0;
257 buf[4] = 0x16;
258 buf[5] = (tda827xa_dvbt[i].spd << 5) + (tda827xa_dvbt[i].svco << 3) +
259 tda827xa_dvbt[i].sbs;
260 buf[6] = 0x4b + (tda827xa_dvbt[i].gc3 << 4);
261 buf[7] = 0x1c;
262 buf[8] = 0x06;
263 buf[9] = 0x24;
264 buf[10] = 0x00;
265 msg.len = 11;
266 if (fe->ops.i2c_gate_ctrl)
267 fe->ops.i2c_gate_ctrl(fe, 1);
268 if (i2c_transfer(priv->i2c_adap, &msg, 1) != 1) {
269 printk("%s: could not write to tuner at addr: 0x%02x\n",
270 __FUNCTION__, priv->i2c_addr << 1);
271 return -EIO;
272 }
273 buf[0] = 0x90;
274 buf[1] = 0xff;
275 buf[2] = 0x60;
276 buf[3] = 0x00;
277 buf[4] = 0x59; // lpsel, for 6MHz + 2
278 msg.len = 5;
279 if (fe->ops.i2c_gate_ctrl)
280 fe->ops.i2c_gate_ctrl(fe, 1);
281 i2c_transfer(priv->i2c_adap, &msg, 1);
282
283 buf[0] = 0xa0;
284 buf[1] = 0x40;
285 msg.len = 2;
286 if (fe->ops.i2c_gate_ctrl)
287 fe->ops.i2c_gate_ctrl(fe, 1);
288 i2c_transfer(priv->i2c_adap, &msg, 1);
289
290 msleep(11);
291 msg.flags = I2C_M_RD;
292 if (fe->ops.i2c_gate_ctrl)
293 fe->ops.i2c_gate_ctrl(fe, 1);
294 i2c_transfer(priv->i2c_adap, &msg, 1);
295 msg.flags = 0;
296
297 buf[1] >>= 4;
298 dprintk("tda8275a AGC2 gain is: %d\n", buf[1]);
299 if ((buf[1]) < 2) {
300 if (priv->cfg && priv->cfg->lna_gain)
301 priv->cfg->lna_gain(fe, 0);
302 buf[0] = 0x60;
303 buf[1] = 0x0c;
304 if (fe->ops.i2c_gate_ctrl)
305 fe->ops.i2c_gate_ctrl(fe, 1);
306 i2c_transfer(priv->i2c_adap, &msg, 1);
307 }
308
309 buf[0] = 0xc0;
310 buf[1] = 0x99; // lpsel, for 6MHz + 2
311 if (fe->ops.i2c_gate_ctrl)
312 fe->ops.i2c_gate_ctrl(fe, 1);
313 i2c_transfer(priv->i2c_adap, &msg, 1);
314
315 buf[0] = 0x60;
316 buf[1] = 0x3c;
317 if (fe->ops.i2c_gate_ctrl)
318 fe->ops.i2c_gate_ctrl(fe, 1);
319 i2c_transfer(priv->i2c_adap, &msg, 1);
320
321 /* correct CP value */
322 buf[0] = 0x30;
323 buf[1] = 0x10 + tda827xa_dvbt[i].scr;
324 if (fe->ops.i2c_gate_ctrl)
325 fe->ops.i2c_gate_ctrl(fe, 1);
326 i2c_transfer(priv->i2c_adap, &msg, 1);
327
328 msleep(163);
329 buf[0] = 0xc0;
330 buf[1] = 0x39; // lpsel, for 6MHz + 2
331 if (fe->ops.i2c_gate_ctrl)
332 fe->ops.i2c_gate_ctrl(fe, 1);
333 i2c_transfer(priv->i2c_adap, &msg, 1);
334
335 msleep(3);
336 /* freeze AGC1 */
337 buf[0] = 0x50;
338 buf[1] = 0x4f + (tda827xa_dvbt[i].gc3 << 4);
339 if (fe->ops.i2c_gate_ctrl)
340 fe->ops.i2c_gate_ctrl(fe, 1);
341 i2c_transfer(priv->i2c_adap, &msg, 1);
342
343 priv->frequency = tuner_freq - if_freq; // FIXME
344 priv->bandwidth = (fe->ops.info.type == FE_OFDM) ? params->u.ofdm.bandwidth : 0;
345
346 return 0;
347}
348
349static int tda827xa_sleep(struct dvb_frontend *fe)
350{
351 struct tda827x_priv *priv = fe->tuner_priv;
352 static u8 buf[] = { 0x30, 0x90 };
353 struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0,
354 .buf = buf, .len = sizeof(buf) };
355
356 dprintk("%s:\n", __FUNCTION__);
357 if (fe->ops.i2c_gate_ctrl)
358 fe->ops.i2c_gate_ctrl(fe, 1);
359
360 i2c_transfer(priv->i2c_adap, &msg, 1);
361
362 if (fe->ops.i2c_gate_ctrl)
363 fe->ops.i2c_gate_ctrl(fe, 0);
364
365 if (priv->cfg && priv->cfg->sleep)
366 priv->cfg->sleep(fe);
367
368 return 0;
369}
370
371static int tda827x_release(struct dvb_frontend *fe)
372{
373 kfree(fe->tuner_priv);
374 fe->tuner_priv = NULL;
375 return 0;
376}
377
378static int tda827x_get_frequency(struct dvb_frontend *fe, u32 *frequency)
379{
380 struct tda827x_priv *priv = fe->tuner_priv;
381 *frequency = priv->frequency;
382 return 0;
383}
384
385static int tda827x_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
386{
387 struct tda827x_priv *priv = fe->tuner_priv;
388 *bandwidth = priv->bandwidth;
389 return 0;
390}
391
392static int tda827x_init(struct dvb_frontend *fe)
393{
394 struct tda827x_priv *priv = fe->tuner_priv;
395 dprintk("%s:\n", __FUNCTION__);
396 if (priv->cfg && priv->cfg->init)
397 priv->cfg->init(fe);
398
399 return 0;
400}
401
402static int tda827x_probe_version(struct dvb_frontend *fe);
403
404static int tda827x_initial_init(struct dvb_frontend *fe)
405{
406 int ret;
407 ret = tda827x_probe_version(fe);
408 if (ret)
409 return ret;
410 return fe->ops.tuner_ops.init(fe);
411}
412
413static int tda827x_initial_sleep(struct dvb_frontend *fe)
414{
415 int ret;
416 ret = tda827x_probe_version(fe);
417 if (ret)
418 return ret;
419 return fe->ops.tuner_ops.sleep(fe);
420}
421
422static struct dvb_tuner_ops tda827xo_tuner_ops = {
423 .info = {
424 .name = "Philips TDA827X",
425 .frequency_min = 55000000,
426 .frequency_max = 860000000,
427 .frequency_step = 250000
428 },
429 .release = tda827x_release,
430 .init = tda827x_initial_init,
431 .sleep = tda827x_initial_sleep,
432 .set_params = tda827xo_set_params,
433 .get_frequency = tda827x_get_frequency,
434 .get_bandwidth = tda827x_get_bandwidth,
435};
436
437static struct dvb_tuner_ops tda827xa_tuner_ops = {
438 .info = {
439 .name = "Philips TDA827XA",
440 .frequency_min = 44000000,
441 .frequency_max = 906000000,
442 .frequency_step = 62500
443 },
444 .release = tda827x_release,
445 .init = tda827x_init,
446 .sleep = tda827xa_sleep,
447 .set_params = tda827xa_set_params,
448 .get_frequency = tda827x_get_frequency,
449 .get_bandwidth = tda827x_get_bandwidth,
450};
451
452static int tda827x_probe_version(struct dvb_frontend *fe)
453{ u8 data;
454 struct tda827x_priv *priv = fe->tuner_priv;
455 struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = I2C_M_RD,
456 .buf = &data, .len = 1 };
457 if (fe->ops.i2c_gate_ctrl)
458 fe->ops.i2c_gate_ctrl(fe, 1);
459 if (i2c_transfer(priv->i2c_adap, &msg, 1) != 1) {
460 printk("%s: could not read from tuner at addr: 0x%02x\n",
461 __FUNCTION__, msg.addr << 1);
462 return -EIO;
463 }
464 if ((data & 0x3c) == 0) {
465 dprintk("tda827x tuner found\n");
466 fe->ops.tuner_ops.init = tda827x_init;
467 fe->ops.tuner_ops.sleep = tda827xo_sleep;
468 } else {
469 dprintk("tda827xa tuner found\n");
470 memcpy(&fe->ops.tuner_ops, &tda827xa_tuner_ops, sizeof(struct dvb_tuner_ops));
471 }
472 return 0;
473}
474
475struct dvb_frontend *tda827x_attach(struct dvb_frontend *fe, int addr,
476 struct i2c_adapter *i2c,
477 struct tda827x_config *cfg)
478{
479 struct tda827x_priv *priv = NULL;
480
481 dprintk("%s:\n", __FUNCTION__);
482 priv = kzalloc(sizeof(struct tda827x_priv), GFP_KERNEL);
483 if (priv == NULL)
484 return NULL;
485
486 priv->i2c_addr = addr;
487 priv->i2c_adap = i2c;
488 priv->cfg = cfg;
489 memcpy(&fe->ops.tuner_ops, &tda827xo_tuner_ops, sizeof(struct dvb_tuner_ops));
490
491 fe->tuner_priv = priv;
492
493 return fe;
494}
495
496EXPORT_SYMBOL(tda827x_attach);
497
498module_param(debug, int, 0644);
499MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
500
501MODULE_DESCRIPTION("DVB TDA827x driver");
502MODULE_AUTHOR("Hartmut Hackmann <hartmut.hackmann@t-online.de>");
503MODULE_AUTHOR("Michael Krufky <mkrufky@linuxtv.org>");
504MODULE_LICENSE("GPL");
505
506/*
507 * Overrides for Emacs so that we follow Linus's tabbing style.
508 * ---------------------------------------------------------------------------
509 * Local variables:
510 * c-basic-offset: 8
511 * End:
512 */
diff --git a/drivers/media/dvb/frontends/tda827x.h b/drivers/media/dvb/frontends/tda827x.h
new file mode 100644
index 000000000000..69e8263d6d59
--- /dev/null
+++ b/drivers/media/dvb/frontends/tda827x.h
@@ -0,0 +1,62 @@
1 /*
2 DVB Driver for Philips tda827x / tda827xa Silicon tuners
3
4 (c) 2005 Hartmut Hackmann
5 (c) 2007 Michael Krufky
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21
22 */
23
24#ifndef __DVB_TDA827X_H__
25#define __DVB_TDA827X_H__
26
27#include <linux/i2c.h>
28#include "dvb_frontend.h"
29
30struct tda827x_config
31{
32 void (*lna_gain) (struct dvb_frontend *fe, int high);
33 int (*init) (struct dvb_frontend *fe);
34 int (*sleep) (struct dvb_frontend *fe);
35};
36
37
38/**
39 * Attach a tda827x tuner to the supplied frontend structure.
40 *
41 * @param fe Frontend to attach to.
42 * @param addr i2c address of the tuner.
43 * @param i2c i2c adapter to use.
44 * @param cfg optional callback function pointers.
45 * @return FE pointer on success, NULL on failure.
46 */
47#if defined(CONFIG_DVB_TDA827X) || (defined(CONFIG_DVB_TDA827X_MODULE) && defined(MODULE))
48extern struct dvb_frontend* tda827x_attach(struct dvb_frontend *fe, int addr,
49 struct i2c_adapter *i2c,
50 struct tda827x_config *cfg);
51#else
52static inline struct dvb_frontend* tda827x_attach(struct dvb_frontend *fe,
53 int addr,
54 struct i2c_adapter *i2c,
55 struct tda827x_config *cfg)
56{
57 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
58 return NULL;
59}
60#endif // CONFIG_DVB_TDA827X
61
62#endif // __DVB_TDA827X_H__
diff --git a/drivers/media/dvb/pluto2/Kconfig b/drivers/media/dvb/pluto2/Kconfig
index 9b84b1bdc313..7d8e6e87bdbb 100644
--- a/drivers/media/dvb/pluto2/Kconfig
+++ b/drivers/media/dvb/pluto2/Kconfig
@@ -2,7 +2,6 @@ config DVB_PLUTO2
2 tristate "Pluto2 cards" 2 tristate "Pluto2 cards"
3 depends on DVB_CORE && PCI && I2C 3 depends on DVB_CORE && PCI && I2C
4 select I2C_ALGOBIT 4 select I2C_ALGOBIT
5 select DVB_PLL
6 select DVB_TDA1004X 5 select DVB_TDA1004X
7 help 6 help
8 Support for PCI cards based on the Pluto2 FPGA like the Satelco 7 Support for PCI cards based on the Pluto2 FPGA like the Satelco
diff --git a/drivers/media/dvb/ttpci/Kconfig b/drivers/media/dvb/ttpci/Kconfig
index eec7ccf41f8b..7751628e1415 100644
--- a/drivers/media/dvb/ttpci/Kconfig
+++ b/drivers/media/dvb/ttpci/Kconfig
@@ -3,7 +3,6 @@ config DVB_AV7110
3 depends on DVB_CORE && PCI && I2C && VIDEO_V4L1 3 depends on DVB_CORE && PCI && I2C && VIDEO_V4L1
4 select FW_LOADER if !DVB_AV7110_FIRMWARE 4 select FW_LOADER if !DVB_AV7110_FIRMWARE
5 select VIDEO_SAA7146_VV 5 select VIDEO_SAA7146_VV
6 select DVB_PLL
7 select DVB_VES1820 if !DVB_FE_CUSTOMISE 6 select DVB_VES1820 if !DVB_FE_CUSTOMISE
8 select DVB_VES1X93 if !DVB_FE_CUSTOMISE 7 select DVB_VES1X93 if !DVB_FE_CUSTOMISE
9 select DVB_STV0299 if !DVB_FE_CUSTOMISE 8 select DVB_STV0299 if !DVB_FE_CUSTOMISE
@@ -62,13 +61,13 @@ config DVB_BUDGET
62 tristate "Budget cards" 61 tristate "Budget cards"
63 depends on DVB_CORE && PCI && I2C && VIDEO_V4L1 62 depends on DVB_CORE && PCI && I2C && VIDEO_V4L1
64 select VIDEO_SAA7146 63 select VIDEO_SAA7146
65 select DVB_PLL
66 select DVB_STV0299 if !DVB_FE_CUSTOMISE 64 select DVB_STV0299 if !DVB_FE_CUSTOMISE
67 select DVB_VES1X93 if !DVB_FE_CUSTOMISE 65 select DVB_VES1X93 if !DVB_FE_CUSTOMISE
68 select DVB_VES1820 if !DVB_FE_CUSTOMISE 66 select DVB_VES1820 if !DVB_FE_CUSTOMISE
69 select DVB_L64781 if !DVB_FE_CUSTOMISE 67 select DVB_L64781 if !DVB_FE_CUSTOMISE
70 select DVB_TDA8083 if !DVB_FE_CUSTOMISE 68 select DVB_TDA8083 if !DVB_FE_CUSTOMISE
71 select DVB_TDA10021 if !DVB_FE_CUSTOMISE 69 select DVB_TDA10021 if !DVB_FE_CUSTOMISE
70 select DVB_TDA10023 if !DVB_FE_CUSTOMISE
72 select DVB_S5H1420 if !DVB_FE_CUSTOMISE 71 select DVB_S5H1420 if !DVB_FE_CUSTOMISE
73 select DVB_TDA10086 if !DVB_FE_CUSTOMISE 72 select DVB_TDA10086 if !DVB_FE_CUSTOMISE
74 select DVB_TDA826X if !DVB_FE_CUSTOMISE 73 select DVB_TDA826X if !DVB_FE_CUSTOMISE
@@ -87,7 +86,6 @@ config DVB_BUDGET_CI
87 tristate "Budget cards with onboard CI connector" 86 tristate "Budget cards with onboard CI connector"
88 depends on DVB_CORE && PCI && I2C && VIDEO_V4L1 87 depends on DVB_CORE && PCI && I2C && VIDEO_V4L1
89 select VIDEO_SAA7146 88 select VIDEO_SAA7146
90 select DVB_PLL
91 select DVB_STV0297 if !DVB_FE_CUSTOMISE 89 select DVB_STV0297 if !DVB_FE_CUSTOMISE
92 select DVB_STV0299 if !DVB_FE_CUSTOMISE 90 select DVB_STV0299 if !DVB_FE_CUSTOMISE
93 select DVB_TDA1004X if !DVB_FE_CUSTOMISE 91 select DVB_TDA1004X if !DVB_FE_CUSTOMISE
@@ -114,6 +112,7 @@ config DVB_BUDGET_AV
114 select DVB_STV0299 if !DVB_FE_CUSTOMISE 112 select DVB_STV0299 if !DVB_FE_CUSTOMISE
115 select DVB_TDA1004X if !DVB_FE_CUSTOMISE 113 select DVB_TDA1004X if !DVB_FE_CUSTOMISE
116 select DVB_TDA10021 if !DVB_FE_CUSTOMISE 114 select DVB_TDA10021 if !DVB_FE_CUSTOMISE
115 select DVB_TDA10023 if !DVB_FE_CUSTOMISE
117 select DVB_TUA6100 if !DVB_FE_CUSTOMISE 116 select DVB_TUA6100 if !DVB_FE_CUSTOMISE
118 select FW_LOADER 117 select FW_LOADER
119 help 118 help
@@ -130,7 +129,6 @@ config DVB_BUDGET_PATCH
130 tristate "AV7110 cards with Budget Patch" 129 tristate "AV7110 cards with Budget Patch"
131 depends on DVB_CORE && DVB_BUDGET && VIDEO_V4L1 130 depends on DVB_CORE && DVB_BUDGET && VIDEO_V4L1
132 select DVB_AV7110 131 select DVB_AV7110
133 select DVB_PLL
134 select DVB_STV0299 if !DVB_FE_CUSTOMISE 132 select DVB_STV0299 if !DVB_FE_CUSTOMISE
135 select DVB_VES1X93 if !DVB_FE_CUSTOMISE 133 select DVB_VES1X93 if !DVB_FE_CUSTOMISE
136 select DVB_TDA8083 if !DVB_FE_CUSTOMISE 134 select DVB_TDA8083 if !DVB_FE_CUSTOMISE
diff --git a/drivers/media/dvb/ttpci/av7110.c b/drivers/media/dvb/ttpci/av7110.c
index 29ed532ba966..67becdd4db60 100644
--- a/drivers/media/dvb/ttpci/av7110.c
+++ b/drivers/media/dvb/ttpci/av7110.c
@@ -219,7 +219,10 @@ static void recover_arm(struct av7110 *av7110)
219 av7110->recover(av7110); 219 av7110->recover(av7110);
220 220
221 restart_feeds(av7110); 221 restart_feeds(av7110);
222 av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, SetIR, 1, av7110->ir_config); 222
223#if defined(CONFIG_INPUT_EVDEV) || defined(CONFIG_INPUT_EVDEV_MODULE)
224 av7110_check_ir_config(av7110, true);
225#endif
223} 226}
224 227
225static void av7110_arm_sync(struct av7110 *av7110) 228static void av7110_arm_sync(struct av7110 *av7110)
@@ -250,6 +253,10 @@ static int arm_thread(void *data)
250 if (!av7110->arm_ready) 253 if (!av7110->arm_ready)
251 continue; 254 continue;
252 255
256#if defined(CONFIG_INPUT_EVDEV) || defined(CONFIG_INPUT_EVDEV_MODULE)
257 av7110_check_ir_config(av7110, false);
258#endif
259
253 if (mutex_lock_interruptible(&av7110->dcomlock)) 260 if (mutex_lock_interruptible(&av7110->dcomlock))
254 break; 261 break;
255 newloops = rdebi(av7110, DEBINOSWAP, STATUS_LOOPS, 0, 2); 262 newloops = rdebi(av7110, DEBINOSWAP, STATUS_LOOPS, 0, 2);
@@ -667,8 +674,8 @@ static void gpioirq(unsigned long data)
667 return; 674 return;
668 675
669 case DATA_IRCOMMAND: 676 case DATA_IRCOMMAND:
670 if (av7110->ir_handler) 677 if (av7110->ir.ir_handler)
671 av7110->ir_handler(av7110, 678 av7110->ir.ir_handler(av7110,
672 swahw32(irdebi(av7110, DEBINOSWAP, Reserved, 0, 4))); 679 swahw32(irdebi(av7110, DEBINOSWAP, Reserved, 0, 4)));
673 iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2); 680 iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2);
674 break; 681 break;
@@ -1907,8 +1914,10 @@ static int av7110_fe_lock_fix(struct av7110* av7110, fe_status_t status)
1907 if (av7110->fe_synced == synced) 1914 if (av7110->fe_synced == synced)
1908 return 0; 1915 return 0;
1909 1916
1910 if (av7110->playing) 1917 if (av7110->playing) {
1918 av7110->fe_synced = synced;
1911 return 0; 1919 return 0;
1920 }
1912 1921
1913 if (mutex_lock_interruptible(&av7110->pid_mutex)) 1922 if (mutex_lock_interruptible(&av7110->pid_mutex))
1914 return -ERESTARTSYS; 1923 return -ERESTARTSYS;
diff --git a/drivers/media/dvb/ttpci/av7110.h b/drivers/media/dvb/ttpci/av7110.h
index b98bd453cade..115002b0390c 100644
--- a/drivers/media/dvb/ttpci/av7110.h
+++ b/drivers/media/dvb/ttpci/av7110.h
@@ -5,6 +5,7 @@
5#include <linux/socket.h> 5#include <linux/socket.h>
6#include <linux/netdevice.h> 6#include <linux/netdevice.h>
7#include <linux/i2c.h> 7#include <linux/i2c.h>
8#include <linux/input.h>
8 9
9#include <linux/dvb/video.h> 10#include <linux/dvb/video.h>
10#include <linux/dvb/audio.h> 11#include <linux/dvb/audio.h>
@@ -66,6 +67,27 @@ struct dvb_video_events {
66}; 67};
67 68
68 69
70struct av7110;
71
72/* infrared remote control */
73struct infrared {
74 u16 key_map[256];
75 struct input_dev *input_dev;
76 char input_phys[32];
77 struct timer_list keyup_timer;
78 struct tasklet_struct ir_tasklet;
79 void (*ir_handler)(struct av7110 *av7110, u32 ircom);
80 u32 ir_command;
81 u32 ir_config;
82 u32 device_mask;
83 u8 protocol;
84 u8 inversion;
85 u16 last_key;
86 u16 last_toggle;
87 u8 delay_timer_finished;
88};
89
90
69/* place to store all the necessary device information */ 91/* place to store all the necessary device information */
70struct av7110 { 92struct av7110 {
71 93
@@ -227,10 +249,7 @@ struct av7110 {
227 u16 wssMode; 249 u16 wssMode;
228 u16 wssData; 250 u16 wssData;
229 251
230 u32 ir_config; 252 struct infrared ir;
231 u32 ir_command;
232 void (*ir_handler)(struct av7110 *av7110, u32 ircom);
233 struct tasklet_struct ir_tasklet;
234 253
235 /* firmware stuff */ 254 /* firmware stuff */
236 unsigned char *bin_fw; 255 unsigned char *bin_fw;
@@ -268,6 +287,7 @@ struct av7110 {
268extern int ChangePIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid, 287extern int ChangePIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid,
269 u16 subpid, u16 pcrpid); 288 u16 subpid, u16 pcrpid);
270 289
290extern int av7110_check_ir_config(struct av7110 *av7110, int force);
271extern int av7110_ir_init(struct av7110 *av7110); 291extern int av7110_ir_init(struct av7110 *av7110);
272extern void av7110_ir_exit(struct av7110 *av7110); 292extern void av7110_ir_exit(struct av7110 *av7110);
273 293
diff --git a/drivers/media/dvb/ttpci/av7110_av.c b/drivers/media/dvb/ttpci/av7110_av.c
index e719af807685..654c9e919e04 100644
--- a/drivers/media/dvb/ttpci/av7110_av.c
+++ b/drivers/media/dvb/ttpci/av7110_av.c
@@ -1009,7 +1009,7 @@ static int dvb_video_ioctl(struct inode *inode, struct file *file,
1009 if (av7110->videostate.stream_source == VIDEO_SOURCE_MEMORY) 1009 if (av7110->videostate.stream_source == VIDEO_SOURCE_MEMORY)
1010 ret = av7110_av_stop(av7110, RP_VIDEO); 1010 ret = av7110_av_stop(av7110, RP_VIDEO);
1011 else 1011 else
1012 ret = vidcom(av7110, VIDEO_CMD_STOP, 1012 ret = vidcom(av7110, AV_VIDEO_CMD_STOP,
1013 av7110->videostate.video_blank ? 0 : 1); 1013 av7110->videostate.video_blank ? 0 : 1);
1014 if (!ret) 1014 if (!ret)
1015 av7110->trickmode = TRICK_NONE; 1015 av7110->trickmode = TRICK_NONE;
@@ -1019,7 +1019,7 @@ static int dvb_video_ioctl(struct inode *inode, struct file *file,
1019 av7110->trickmode = TRICK_NONE; 1019 av7110->trickmode = TRICK_NONE;
1020 if (av7110->videostate.play_state == VIDEO_FREEZED) { 1020 if (av7110->videostate.play_state == VIDEO_FREEZED) {
1021 av7110->videostate.play_state = VIDEO_PLAYING; 1021 av7110->videostate.play_state = VIDEO_PLAYING;
1022 ret = vidcom(av7110, VIDEO_CMD_PLAY, 0); 1022 ret = vidcom(av7110, AV_VIDEO_CMD_PLAY, 0);
1023 if (ret) 1023 if (ret)
1024 break; 1024 break;
1025 } 1025 }
@@ -1034,7 +1034,7 @@ static int dvb_video_ioctl(struct inode *inode, struct file *file,
1034 ret = av7110_av_start_play(av7110, RP_VIDEO); 1034 ret = av7110_av_start_play(av7110, RP_VIDEO);
1035 } 1035 }
1036 if (!ret) 1036 if (!ret)
1037 ret = vidcom(av7110, VIDEO_CMD_PLAY, 0); 1037 ret = vidcom(av7110, AV_VIDEO_CMD_PLAY, 0);
1038 if (!ret) 1038 if (!ret)
1039 av7110->videostate.play_state = VIDEO_PLAYING; 1039 av7110->videostate.play_state = VIDEO_PLAYING;
1040 break; 1040 break;
@@ -1044,7 +1044,7 @@ static int dvb_video_ioctl(struct inode *inode, struct file *file,
1044 if (av7110->playing & RP_VIDEO) 1044 if (av7110->playing & RP_VIDEO)
1045 ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Pause, 0); 1045 ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Pause, 0);
1046 else 1046 else
1047 ret = vidcom(av7110, VIDEO_CMD_FREEZE, 1); 1047 ret = vidcom(av7110, AV_VIDEO_CMD_FREEZE, 1);
1048 if (!ret) 1048 if (!ret)
1049 av7110->trickmode = TRICK_FREEZE; 1049 av7110->trickmode = TRICK_FREEZE;
1050 break; 1050 break;
@@ -1053,7 +1053,7 @@ static int dvb_video_ioctl(struct inode *inode, struct file *file,
1053 if (av7110->playing & RP_VIDEO) 1053 if (av7110->playing & RP_VIDEO)
1054 ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Continue, 0); 1054 ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Continue, 0);
1055 if (!ret) 1055 if (!ret)
1056 ret = vidcom(av7110, VIDEO_CMD_PLAY, 0); 1056 ret = vidcom(av7110, AV_VIDEO_CMD_PLAY, 0);
1057 if (!ret) { 1057 if (!ret) {
1058 av7110->videostate.play_state = VIDEO_PLAYING; 1058 av7110->videostate.play_state = VIDEO_PLAYING;
1059 av7110->trickmode = TRICK_NONE; 1059 av7110->trickmode = TRICK_NONE;
@@ -1136,7 +1136,7 @@ static int dvb_video_ioctl(struct inode *inode, struct file *file,
1136 ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, 1136 ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY,
1137 __Scan_I, 2, AV_PES, 0); 1137 __Scan_I, 2, AV_PES, 0);
1138 else 1138 else
1139 ret = vidcom(av7110, VIDEO_CMD_FFWD, arg); 1139 ret = vidcom(av7110, AV_VIDEO_CMD_FFWD, arg);
1140 if (!ret) { 1140 if (!ret) {
1141 av7110->trickmode = TRICK_FAST; 1141 av7110->trickmode = TRICK_FAST;
1142 av7110->videostate.play_state = VIDEO_PLAYING; 1142 av7110->videostate.play_state = VIDEO_PLAYING;
@@ -1147,13 +1147,13 @@ static int dvb_video_ioctl(struct inode *inode, struct file *file,
1147 if (av7110->playing&RP_VIDEO) { 1147 if (av7110->playing&RP_VIDEO) {
1148 ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Slow, 2, 0, 0); 1148 ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Slow, 2, 0, 0);
1149 if (!ret) 1149 if (!ret)
1150 ret = vidcom(av7110, VIDEO_CMD_SLOW, arg); 1150 ret = vidcom(av7110, AV_VIDEO_CMD_SLOW, arg);
1151 } else { 1151 } else {
1152 ret = vidcom(av7110, VIDEO_CMD_PLAY, 0); 1152 ret = vidcom(av7110, AV_VIDEO_CMD_PLAY, 0);
1153 if (!ret) 1153 if (!ret)
1154 ret = vidcom(av7110, VIDEO_CMD_STOP, 0); 1154 ret = vidcom(av7110, AV_VIDEO_CMD_STOP, 0);
1155 if (!ret) 1155 if (!ret)
1156 ret = vidcom(av7110, VIDEO_CMD_SLOW, arg); 1156 ret = vidcom(av7110, AV_VIDEO_CMD_SLOW, arg);
1157 } 1157 }
1158 if (!ret) { 1158 if (!ret) {
1159 av7110->trickmode = TRICK_SLOW; 1159 av7110->trickmode = TRICK_SLOW;
@@ -1182,10 +1182,10 @@ static int dvb_video_ioctl(struct inode *inode, struct file *file,
1182 ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, 1182 ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY,
1183 __Slow, 2, 0, 0); 1183 __Slow, 2, 0, 0);
1184 if (!ret) 1184 if (!ret)
1185 ret = vidcom(av7110, VIDEO_CMD_SLOW, arg); 1185 ret = vidcom(av7110, AV_VIDEO_CMD_SLOW, arg);
1186 } 1186 }
1187 if (av7110->trickmode == TRICK_FREEZE) 1187 if (av7110->trickmode == TRICK_FREEZE)
1188 ret = vidcom(av7110, VIDEO_CMD_STOP, 1); 1188 ret = vidcom(av7110, AV_VIDEO_CMD_STOP, 1);
1189 } 1189 }
1190 break; 1190 break;
1191 1191
diff --git a/drivers/media/dvb/ttpci/av7110_hw.h b/drivers/media/dvb/ttpci/av7110_hw.h
index 4e173c67fbb2..673d9b3f064c 100644
--- a/drivers/media/dvb/ttpci/av7110_hw.h
+++ b/drivers/media/dvb/ttpci/av7110_hw.h
@@ -216,11 +216,11 @@ enum av7110_command_type {
216#define VID_CENTRE_CUT_PREF 0x05 /* PanScan with zero vector */ 216#define VID_CENTRE_CUT_PREF 0x05 /* PanScan with zero vector */
217 217
218/* MPEG video decoder commands */ 218/* MPEG video decoder commands */
219#define VIDEO_CMD_STOP 0x000e 219#define AV_VIDEO_CMD_STOP 0x000e
220#define VIDEO_CMD_PLAY 0x000d 220#define AV_VIDEO_CMD_PLAY 0x000d
221#define VIDEO_CMD_FREEZE 0x0102 221#define AV_VIDEO_CMD_FREEZE 0x0102
222#define VIDEO_CMD_FFWD 0x0016 222#define AV_VIDEO_CMD_FFWD 0x0016
223#define VIDEO_CMD_SLOW 0x0022 223#define AV_VIDEO_CMD_SLOW 0x0022
224 224
225/* MPEG audio decoder commands */ 225/* MPEG audio decoder commands */
226#define AUDIO_CMD_MUTE 0x0001 226#define AUDIO_CMD_MUTE 0x0001
diff --git a/drivers/media/dvb/ttpci/av7110_ir.c b/drivers/media/dvb/ttpci/av7110_ir.c
index f59465bb0af3..a97f166bb523 100644
--- a/drivers/media/dvb/ttpci/av7110_ir.c
+++ b/drivers/media/dvb/ttpci/av7110_ir.c
@@ -1,8 +1,31 @@
1/*
2 * Driver for the remote control of SAA7146 based AV7110 cards
3 *
4 * Copyright (C) 1999-2003 Holger Waechtler <holger@convergence.de>
5 * Copyright (C) 2003-2007 Oliver Endriss <o.endriss@gmx.de>
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 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
21 *
22 */
23
24
1#include <linux/types.h> 25#include <linux/types.h>
2#include <linux/init.h> 26#include <linux/init.h>
3#include <linux/module.h> 27#include <linux/module.h>
4#include <linux/moduleparam.h> 28#include <linux/moduleparam.h>
5#include <linux/input.h>
6#include <linux/proc_fs.h> 29#include <linux/proc_fs.h>
7#include <linux/kernel.h> 30#include <linux/kernel.h>
8#include <asm/bitops.h> 31#include <asm/bitops.h>
@@ -10,18 +33,37 @@
10#include "av7110.h" 33#include "av7110.h"
11#include "av7110_hw.h" 34#include "av7110_hw.h"
12 35
13#define UP_TIMEOUT (HZ*7/25)
14 36
15/* enable ir debugging by or'ing debug with 16 */ 37#define AV_CNT 4
38
39#define IR_RC5 0
40#define IR_RCMM 1
41#define IR_RC5_EXT 2 /* internal only */
42
43#define IR_ALL 0xffffffff
44
45#define UP_TIMEOUT (HZ*7/25)
16 46
17static int av_cnt;
18static struct av7110 *av_list[4];
19static struct input_dev *input_dev;
20static char input_phys[32];
21 47
22static u8 delay_timer_finished; 48/* Note: enable ir debugging by or'ing debug with 16 */
49
50static int ir_protocol[AV_CNT] = { IR_RCMM, IR_RCMM, IR_RCMM, IR_RCMM};
51module_param_array(ir_protocol, int, NULL, 0644);
52MODULE_PARM_DESC(ir_protocol, "Infrared protocol: 0 RC5, 1 RCMM (default)");
53
54static int ir_inversion[AV_CNT];
55module_param_array(ir_inversion, int, NULL, 0644);
56MODULE_PARM_DESC(ir_inversion, "Inversion of infrared signal: 0 not inverted (default), 1 inverted");
57
58static uint ir_device_mask[AV_CNT] = { IR_ALL, IR_ALL, IR_ALL, IR_ALL };
59module_param_array(ir_device_mask, uint, NULL, 0644);
60MODULE_PARM_DESC(ir_device_mask, "Bitmask of infrared devices: bit 0..31 = device 0..31 (default: all)");
61
62
63static int av_cnt;
64static struct av7110 *av_list[AV_CNT];
23 65
24static u16 key_map [256] = { 66static u16 default_key_map [256] = {
25 KEY_0, KEY_1, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6, KEY_7, 67 KEY_0, KEY_1, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6, KEY_7,
26 KEY_8, KEY_9, KEY_BACK, 0, KEY_POWER, KEY_MUTE, 0, KEY_INFO, 68 KEY_8, KEY_9, KEY_BACK, 0, KEY_POWER, KEY_MUTE, 0, KEY_INFO,
27 KEY_VOLUMEUP, KEY_VOLUMEDOWN, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 69 KEY_VOLUMEUP, KEY_VOLUMEDOWN, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -45,141 +87,194 @@ static u16 key_map [256] = {
45}; 87};
46 88
47 89
48static void av7110_emit_keyup(unsigned long data) 90/* key-up timer */
91static void av7110_emit_keyup(unsigned long parm)
49{ 92{
50 if (!data || !test_bit(data, input_dev->key)) 93 struct infrared *ir = (struct infrared *) parm;
94
95 if (!ir || !test_bit(ir->last_key, ir->input_dev->key))
51 return; 96 return;
52 97
53 input_report_key(input_dev, data, 0); 98 input_report_key(ir->input_dev, ir->last_key, 0);
54 input_sync(input_dev); 99 input_sync(ir->input_dev);
55} 100}
56 101
57 102
58static struct timer_list keyup_timer = { .function = av7110_emit_keyup }; 103/* tasklet */
59
60
61static void av7110_emit_key(unsigned long parm) 104static void av7110_emit_key(unsigned long parm)
62{ 105{
63 struct av7110 *av7110 = (struct av7110 *) parm; 106 struct infrared *ir = (struct infrared *) parm;
64 u32 ir_config = av7110->ir_config; 107 u32 ircom = ir->ir_command;
65 u32 ircom = av7110->ir_command;
66 u8 data; 108 u8 data;
67 u8 addr; 109 u8 addr;
68 static u16 old_toggle = 0; 110 u16 toggle;
69 u16 new_toggle;
70 u16 keycode; 111 u16 keycode;
71 112
72 /* extract device address and data */ 113 /* extract device address and data */
73 switch (ir_config & 0x0003) { 114 switch (ir->protocol) {
74 case 0: /* RC5: 5 bits device address, 6 bits data */ 115 case IR_RC5: /* RC5: 5 bits device address, 6 bits data */
75 data = ircom & 0x3f; 116 data = ircom & 0x3f;
76 addr = (ircom >> 6) & 0x1f; 117 addr = (ircom >> 6) & 0x1f;
118 toggle = ircom & 0x0800;
77 break; 119 break;
78 120
79 case 1: /* RCMM: 8(?) bits device address, 8(?) bits data */ 121 case IR_RCMM: /* RCMM: ? bits device address, ? bits data */
80 data = ircom & 0xff; 122 data = ircom & 0xff;
81 addr = (ircom >> 8) & 0xff; 123 addr = (ircom >> 8) & 0x1f;
124 toggle = ircom & 0x8000;
82 break; 125 break;
83 126
84 case 2: /* extended RC5: 5 bits device address, 7 bits data */ 127 case IR_RC5_EXT: /* extended RC5: 5 bits device address, 7 bits data */
85 data = ircom & 0x3f; 128 data = ircom & 0x3f;
86 addr = (ircom >> 6) & 0x1f; 129 addr = (ircom >> 6) & 0x1f;
87 /* invert 7th data bit for backward compatibility with RC5 keymaps */ 130 /* invert 7th data bit for backward compatibility with RC5 keymaps */
88 if (!(ircom & 0x1000)) 131 if (!(ircom & 0x1000))
89 data |= 0x40; 132 data |= 0x40;
133 toggle = ircom & 0x0800;
90 break; 134 break;
91 135
92 default: 136 default:
93 printk("invalid ir_config %x\n", ir_config); 137 printk("%s invalid protocol %x\n", __FUNCTION__, ir->protocol);
94 return; 138 return;
95 } 139 }
96 140
97 keycode = key_map[data]; 141 input_event(ir->input_dev, EV_MSC, MSC_RAW, (addr << 16) | data);
142 input_event(ir->input_dev, EV_MSC, MSC_SCAN, data);
98 143
99 dprintk(16, "code %08x -> addr %i data 0x%02x -> keycode %i\n", 144 keycode = ir->key_map[data];
100 ircom, addr, data, keycode);
101 145
102 /* check device address (if selected) */ 146 dprintk(16, "%s: code %08x -> addr %i data 0x%02x -> keycode %i\n",
103 if (ir_config & 0x4000) 147 __FUNCTION__, ircom, addr, data, keycode);
104 if (addr != ((ir_config >> 16) & 0xff)) 148
105 return; 149 /* check device address */
150 if (!(ir->device_mask & (1 << addr)))
151 return;
106 152
107 if (!keycode) { 153 if (!keycode) {
108 printk ("%s: unknown key 0x%02x!!\n", __FUNCTION__, data); 154 printk ("%s: code %08x -> addr %i data 0x%02x -> unknown key!\n",
155 __FUNCTION__, ircom, addr, data);
109 return; 156 return;
110 } 157 }
111 158
112 if ((ir_config & 0x0003) == 1) 159 if (timer_pending(&ir->keyup_timer)) {
113 new_toggle = 0; /* RCMM */ 160 del_timer(&ir->keyup_timer);
114 else 161 if (ir->last_key != keycode || toggle != ir->last_toggle) {
115 new_toggle = (ircom & 0x800); /* RC5, extended RC5 */ 162 ir->delay_timer_finished = 0;
116 163 input_event(ir->input_dev, EV_KEY, ir->last_key, 0);
117 if (timer_pending(&keyup_timer)) { 164 input_event(ir->input_dev, EV_KEY, keycode, 1);
118 del_timer(&keyup_timer); 165 input_sync(ir->input_dev);
119 if (keyup_timer.data != keycode || new_toggle != old_toggle) { 166 } else if (ir->delay_timer_finished) {
120 delay_timer_finished = 0; 167 input_event(ir->input_dev, EV_KEY, keycode, 2);
121 input_event(input_dev, EV_KEY, keyup_timer.data, 0); 168 input_sync(ir->input_dev);
122 input_event(input_dev, EV_KEY, keycode, 1);
123 input_sync(input_dev);
124 } else if (delay_timer_finished) {
125 input_event(input_dev, EV_KEY, keycode, 2);
126 input_sync(input_dev);
127 } 169 }
128 } else { 170 } else {
129 delay_timer_finished = 0; 171 ir->delay_timer_finished = 0;
130 input_event(input_dev, EV_KEY, keycode, 1); 172 input_event(ir->input_dev, EV_KEY, keycode, 1);
131 input_sync(input_dev); 173 input_sync(ir->input_dev);
132 } 174 }
133 175
134 keyup_timer.expires = jiffies + UP_TIMEOUT; 176 ir->last_key = keycode;
135 keyup_timer.data = keycode; 177 ir->last_toggle = toggle;
136 178
137 add_timer(&keyup_timer); 179 ir->keyup_timer.expires = jiffies + UP_TIMEOUT;
180 add_timer(&ir->keyup_timer);
138 181
139 old_toggle = new_toggle;
140} 182}
141 183
142static void input_register_keys(void) 184
185/* register with input layer */
186static void input_register_keys(struct infrared *ir)
143{ 187{
144 int i; 188 int i;
145 189
146 memset(input_dev->keybit, 0, sizeof(input_dev->keybit)); 190 set_bit(EV_KEY, ir->input_dev->evbit);
191 set_bit(EV_REP, ir->input_dev->evbit);
192 set_bit(EV_MSC, ir->input_dev->evbit);
147 193
148 for (i = 0; i < ARRAY_SIZE(key_map); i++) { 194 set_bit(MSC_RAW, ir->input_dev->mscbit);
149 if (key_map[i] > KEY_MAX) 195 set_bit(MSC_SCAN, ir->input_dev->mscbit);
150 key_map[i] = 0; 196
151 else if (key_map[i] > KEY_RESERVED) 197 memset(ir->input_dev->keybit, 0, sizeof(ir->input_dev->keybit));
152 set_bit(key_map[i], input_dev->keybit); 198
199 for (i = 0; i < ARRAY_SIZE(ir->key_map); i++) {
200 if (ir->key_map[i] > KEY_MAX)
201 ir->key_map[i] = 0;
202 else if (ir->key_map[i] > KEY_RESERVED)
203 set_bit(ir->key_map[i], ir->input_dev->keybit);
153 } 204 }
205
206 ir->input_dev->keycode = ir->key_map;
207 ir->input_dev->keycodesize = sizeof(ir->key_map[0]);
208 ir->input_dev->keycodemax = ARRAY_SIZE(ir->key_map);
154} 209}
155 210
156 211
157static void input_repeat_key(unsigned long data) 212/* called by the input driver after rep[REP_DELAY] ms */
213static void input_repeat_key(unsigned long parm)
158{ 214{
159 /* called by the input driver after rep[REP_DELAY] ms */ 215 struct infrared *ir = (struct infrared *) parm;
160 delay_timer_finished = 1; 216
217 ir->delay_timer_finished = 1;
161} 218}
162 219
163 220
164static int av7110_setup_irc_config(struct av7110 *av7110, u32 ir_config) 221/* check for configuration changes */
222int av7110_check_ir_config(struct av7110 *av7110, int force)
165{ 223{
166 int ret = 0; 224 int i;
225 int modified = force;
226 int ret = -ENODEV;
167 227
168 dprintk(4, "%p\n", av7110); 228 for (i = 0; i < av_cnt; i++)
169 if (av7110) { 229 if (av7110 == av_list[i])
170 ret = av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, SetIR, 1, ir_config); 230 break;
171 av7110->ir_config = ir_config; 231
232 if (i < av_cnt && av7110) {
233 if ((av7110->ir.protocol & 1) != ir_protocol[i] ||
234 av7110->ir.inversion != ir_inversion[i])
235 modified = true;
236
237 if (modified) {
238 /* protocol */
239 if (ir_protocol[i]) {
240 ir_protocol[i] = 1;
241 av7110->ir.protocol = IR_RCMM;
242 av7110->ir.ir_config = 0x0001;
243 } else if (FW_VERSION(av7110->arm_app) >= 0x2620) {
244 av7110->ir.protocol = IR_RC5_EXT;
245 av7110->ir.ir_config = 0x0002;
246 } else {
247 av7110->ir.protocol = IR_RC5;
248 av7110->ir.ir_config = 0x0000;
249 }
250 /* inversion */
251 if (ir_inversion[i]) {
252 ir_inversion[i] = 1;
253 av7110->ir.ir_config |= 0x8000;
254 }
255 av7110->ir.inversion = ir_inversion[i];
256 /* update ARM */
257 ret = av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, SetIR, 1,
258 av7110->ir.ir_config);
259 } else
260 ret = 0;
261
262 /* address */
263 if (av7110->ir.device_mask != ir_device_mask[i])
264 av7110->ir.device_mask = ir_device_mask[i];
172 } 265 }
266
173 return ret; 267 return ret;
174} 268}
175 269
176 270
271/* /proc/av7110_ir interface */
177static int av7110_ir_write_proc(struct file *file, const char __user *buffer, 272static int av7110_ir_write_proc(struct file *file, const char __user *buffer,
178 unsigned long count, void *data) 273 unsigned long count, void *data)
179{ 274{
180 char *page; 275 char *page;
181 int size = 4 + 256 * sizeof(u16);
182 u32 ir_config; 276 u32 ir_config;
277 int size = sizeof ir_config + sizeof av_list[0]->ir.key_map;
183 int i; 278 int i;
184 279
185 if (count < size) 280 if (count < size)
@@ -194,71 +289,86 @@ static int av7110_ir_write_proc(struct file *file, const char __user *buffer,
194 return -EFAULT; 289 return -EFAULT;
195 } 290 }
196 291
197 memcpy(&ir_config, page, 4); 292 memcpy(&ir_config, page, sizeof ir_config);
198 memcpy(&key_map, page + 4, 256 * sizeof(u16)); 293
294 for (i = 0; i < av_cnt; i++) {
295 /* keymap */
296 memcpy(av_list[i]->ir.key_map, page + sizeof ir_config,
297 sizeof(av_list[i]->ir.key_map));
298 /* protocol, inversion, address */
299 ir_protocol[i] = ir_config & 0x0001;
300 ir_inversion[i] = ir_config & 0x8000 ? 1 : 0;
301 if (ir_config & 0x4000)
302 ir_device_mask[i] = 1 << ((ir_config >> 16) & 0x1f);
303 else
304 ir_device_mask[i] = IR_ALL;
305 /* update configuration */
306 av7110_check_ir_config(av_list[i], false);
307 input_register_keys(&av_list[i]->ir);
308 }
199 vfree(page); 309 vfree(page);
200 if (FW_VERSION(av_list[0]->arm_app) >= 0x2620 && !(ir_config & 0x0001))
201 ir_config |= 0x0002; /* enable extended RC5 */
202 for (i = 0; i < av_cnt; i++)
203 av7110_setup_irc_config(av_list[i], ir_config);
204 input_register_keys();
205 return count; 310 return count;
206} 311}
207 312
208 313
314/* interrupt handler */
209static void ir_handler(struct av7110 *av7110, u32 ircom) 315static void ir_handler(struct av7110 *av7110, u32 ircom)
210{ 316{
211 dprintk(4, "ircommand = %08x\n", ircom); 317 dprintk(4, "ir command = %08x\n", ircom);
212 av7110->ir_command = ircom; 318 av7110->ir.ir_command = ircom;
213 tasklet_schedule(&av7110->ir_tasklet); 319 tasklet_schedule(&av7110->ir.ir_tasklet);
214} 320}
215 321
216 322
217int __devinit av7110_ir_init(struct av7110 *av7110) 323int __devinit av7110_ir_init(struct av7110 *av7110)
218{ 324{
325 struct input_dev *input_dev;
219 static struct proc_dir_entry *e; 326 static struct proc_dir_entry *e;
220 int err; 327 int err;
221 328
222 if (av_cnt >= ARRAY_SIZE(av_list)) 329 if (av_cnt >= ARRAY_SIZE(av_list))
223 return -ENOSPC; 330 return -ENOSPC;
224 331
225 av7110_setup_irc_config(av7110, 0x0001);
226 av_list[av_cnt++] = av7110; 332 av_list[av_cnt++] = av7110;
333 av7110_check_ir_config(av7110, true);
227 334
228 if (av_cnt == 1) { 335 init_timer(&av7110->ir.keyup_timer);
229 init_timer(&keyup_timer); 336 av7110->ir.keyup_timer.function = av7110_emit_keyup;
230 keyup_timer.data = 0; 337 av7110->ir.keyup_timer.data = (unsigned long) &av7110->ir;
231 338
232 input_dev = input_allocate_device(); 339 input_dev = input_allocate_device();
233 if (!input_dev) 340 if (!input_dev)
234 return -ENOMEM; 341 return -ENOMEM;
235
236 snprintf(input_phys, sizeof(input_phys),
237 "pci-%s/ir0", pci_name(av7110->dev->pci));
238
239 input_dev->name = "DVB on-card IR receiver";
240
241 input_dev->phys = input_phys;
242 input_dev->id.bustype = BUS_PCI;
243 input_dev->id.version = 1;
244 if (av7110->dev->pci->subsystem_vendor) {
245 input_dev->id.vendor = av7110->dev->pci->subsystem_vendor;
246 input_dev->id.product = av7110->dev->pci->subsystem_device;
247 } else {
248 input_dev->id.vendor = av7110->dev->pci->vendor;
249 input_dev->id.product = av7110->dev->pci->device;
250 }
251 input_dev->cdev.dev = &av7110->dev->pci->dev;
252 set_bit(EV_KEY, input_dev->evbit);
253 set_bit(EV_REP, input_dev->evbit);
254 input_register_keys();
255 err = input_register_device(input_dev);
256 if (err) {
257 input_free_device(input_dev);
258 return err;
259 }
260 input_dev->timer.function = input_repeat_key;
261 342
343 av7110->ir.input_dev = input_dev;
344 snprintf(av7110->ir.input_phys, sizeof(av7110->ir.input_phys),
345 "pci-%s/ir0", pci_name(av7110->dev->pci));
346
347 input_dev->name = "DVB on-card IR receiver";
348
349 input_dev->phys = av7110->ir.input_phys;
350 input_dev->id.bustype = BUS_PCI;
351 input_dev->id.version = 2;
352 if (av7110->dev->pci->subsystem_vendor) {
353 input_dev->id.vendor = av7110->dev->pci->subsystem_vendor;
354 input_dev->id.product = av7110->dev->pci->subsystem_device;
355 } else {
356 input_dev->id.vendor = av7110->dev->pci->vendor;
357 input_dev->id.product = av7110->dev->pci->device;
358 }
359 input_dev->cdev.dev = &av7110->dev->pci->dev;
360 /* initial keymap */
361 memcpy(av7110->ir.key_map, default_key_map, sizeof av7110->ir.key_map);
362 input_register_keys(&av7110->ir);
363 err = input_register_device(input_dev);
364 if (err) {
365 input_free_device(input_dev);
366 return err;
367 }
368 input_dev->timer.function = input_repeat_key;
369 input_dev->timer.data = (unsigned long) &av7110->ir;
370
371 if (av_cnt == 1) {
262 e = create_proc_entry("av7110_ir", S_IFREG | S_IRUGO | S_IWUSR, NULL); 372 e = create_proc_entry("av7110_ir", S_IFREG | S_IRUGO | S_IWUSR, NULL);
263 if (e) { 373 if (e) {
264 e->write_proc = av7110_ir_write_proc; 374 e->write_proc = av7110_ir_write_proc;
@@ -266,8 +376,8 @@ int __devinit av7110_ir_init(struct av7110 *av7110)
266 } 376 }
267 } 377 }
268 378
269 tasklet_init(&av7110->ir_tasklet, av7110_emit_key, (unsigned long) av7110); 379 tasklet_init(&av7110->ir.ir_tasklet, av7110_emit_key, (unsigned long) &av7110->ir);
270 av7110->ir_handler = ir_handler; 380 av7110->ir.ir_handler = ir_handler;
271 381
272 return 0; 382 return 0;
273} 383}
@@ -280,8 +390,10 @@ void __devexit av7110_ir_exit(struct av7110 *av7110)
280 if (av_cnt == 0) 390 if (av_cnt == 0)
281 return; 391 return;
282 392
283 av7110->ir_handler = NULL; 393 del_timer_sync(&av7110->ir.keyup_timer);
284 tasklet_kill(&av7110->ir_tasklet); 394 av7110->ir.ir_handler = NULL;
395 tasklet_kill(&av7110->ir.ir_tasklet);
396
285 for (i = 0; i < av_cnt; i++) 397 for (i = 0; i < av_cnt; i++)
286 if (av_list[i] == av7110) { 398 if (av_list[i] == av7110) {
287 av_list[i] = av_list[av_cnt-1]; 399 av_list[i] = av_list[av_cnt-1];
@@ -289,14 +401,13 @@ void __devexit av7110_ir_exit(struct av7110 *av7110)
289 break; 401 break;
290 } 402 }
291 403
292 if (av_cnt == 1) { 404 if (av_cnt == 1)
293 del_timer_sync(&keyup_timer);
294 remove_proc_entry("av7110_ir", NULL); 405 remove_proc_entry("av7110_ir", NULL);
295 input_unregister_device(input_dev); 406
296 } 407 input_unregister_device(av7110->ir.input_dev);
297 408
298 av_cnt--; 409 av_cnt--;
299} 410}
300 411
301//MODULE_AUTHOR("Holger Waechtler <holger@convergence.de>"); 412//MODULE_AUTHOR("Holger Waechtler <holger@convergence.de>, Oliver Endriss <o.endriss@gmx.de>");
302//MODULE_LICENSE("GPL"); 413//MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/ttpci/budget-av.c b/drivers/media/dvb/ttpci/budget-av.c
index 3035b224c7a3..0e817d6f1ce5 100644
--- a/drivers/media/dvb/ttpci/budget-av.c
+++ b/drivers/media/dvb/ttpci/budget-av.c
@@ -35,7 +35,7 @@
35 35
36#include "budget.h" 36#include "budget.h"
37#include "stv0299.h" 37#include "stv0299.h"
38#include "tda10021.h" 38#include "tda1002x.h"
39#include "tda1004x.h" 39#include "tda1004x.h"
40#include "tua6100.h" 40#include "tua6100.h"
41#include "dvb-pll.h" 41#include "dvb-pll.h"
@@ -66,9 +66,6 @@ struct budget_av {
66 int slot_status; 66 int slot_status;
67 struct dvb_ca_en50221 ca; 67 struct dvb_ca_en50221 ca;
68 u8 reinitialise_demod:1; 68 u8 reinitialise_demod:1;
69 u8 tda10021_poclkp:1;
70 u8 tda10021_ts_enabled;
71 int (*tda10021_set_frontend)(struct dvb_frontend *fe, struct dvb_frontend_parameters *p);
72}; 69};
73 70
74static int ciintf_slot_shutdown(struct dvb_ca_en50221 *ca, int slot); 71static int ciintf_slot_shutdown(struct dvb_ca_en50221 *ca, int slot);
@@ -234,12 +231,6 @@ static int ciintf_slot_reset(struct dvb_ca_en50221 *ca, int slot)
234 if (budget_av->reinitialise_demod) 231 if (budget_av->reinitialise_demod)
235 dvb_frontend_reinitialise(budget_av->budget.dvb_frontend); 232 dvb_frontend_reinitialise(budget_av->budget.dvb_frontend);
236 233
237 /* set tda10021 back to original clock configuration on reset */
238 if (budget_av->tda10021_poclkp) {
239 tda10021_writereg(budget_av->budget.dvb_frontend, 0x12, 0xa0);
240 budget_av->tda10021_ts_enabled = 0;
241 }
242
243 return 0; 234 return 0;
244} 235}
245 236
@@ -256,11 +247,6 @@ static int ciintf_slot_shutdown(struct dvb_ca_en50221 *ca, int slot)
256 ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTB); 247 ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTB);
257 budget_av->slot_status = SLOTSTATUS_NONE; 248 budget_av->slot_status = SLOTSTATUS_NONE;
258 249
259 /* set tda10021 back to original clock configuration when cam removed */
260 if (budget_av->tda10021_poclkp) {
261 tda10021_writereg(budget_av->budget.dvb_frontend, 0x12, 0xa0);
262 budget_av->tda10021_ts_enabled = 0;
263 }
264 return 0; 250 return 0;
265} 251}
266 252
@@ -276,12 +262,6 @@ static int ciintf_slot_ts_enable(struct dvb_ca_en50221 *ca, int slot)
276 262
277 ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTA); 263 ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTA);
278 264
279 /* tda10021 seems to need a different TS clock config when data is routed to the CAM */
280 if (budget_av->tda10021_poclkp) {
281 tda10021_writereg(budget_av->budget.dvb_frontend, 0x12, 0xa1);
282 budget_av->tda10021_ts_enabled = 1;
283 }
284
285 return 0; 265 return 0;
286} 266}
287 267
@@ -631,37 +611,62 @@ static struct stv0299_config cinergy_1200s_1894_0010_config = {
631static int philips_cu1216_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) 611static int philips_cu1216_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
632{ 612{
633 struct budget *budget = (struct budget *) fe->dvb->priv; 613 struct budget *budget = (struct budget *) fe->dvb->priv;
634 u8 buf[4]; 614 u8 buf[6];
635 struct i2c_msg msg = {.addr = 0x60,.flags = 0,.buf = buf,.len = sizeof(buf) }; 615 struct i2c_msg msg = {.addr = 0x60,.flags = 0,.buf = buf,.len = sizeof(buf) };
616 int i;
636 617
618#define CU1216_IF 36125000
637#define TUNER_MUL 62500 619#define TUNER_MUL 62500
638 620
639 u32 div = (params->frequency + 36125000 + TUNER_MUL / 2) / TUNER_MUL; 621 u32 div = (params->frequency + CU1216_IF + TUNER_MUL / 2) / TUNER_MUL;
640 622
641 buf[0] = (div >> 8) & 0x7f; 623 buf[0] = (div >> 8) & 0x7f;
642 buf[1] = div & 0xff; 624 buf[1] = div & 0xff;
643 buf[2] = 0x86; 625 buf[2] = 0xce;
644 buf[3] = (params->frequency < 150000000 ? 0x01 : 626 buf[3] = (params->frequency < 150000000 ? 0x01 :
645 params->frequency < 445000000 ? 0x02 : 0x04); 627 params->frequency < 445000000 ? 0x02 : 0x04);
628 buf[4] = 0xde;
629 buf[5] = 0x20;
630
631 if (fe->ops.i2c_gate_ctrl)
632 fe->ops.i2c_gate_ctrl(fe, 1);
633 if (i2c_transfer(&budget->i2c_adap, &msg, 1) != 1)
634 return -EIO;
646 635
636 /* wait for the pll lock */
637 msg.flags = I2C_M_RD;
638 msg.len = 1;
639 for (i = 0; i < 20; i++) {
640 if (fe->ops.i2c_gate_ctrl)
641 fe->ops.i2c_gate_ctrl(fe, 1);
642 if (i2c_transfer(&budget->i2c_adap, &msg, 1) == 1 && (buf[0] & 0x40))
643 break;
644 msleep(10);
645 }
646
647 /* switch the charge pump to the lower current */
648 msg.flags = 0;
649 msg.len = 2;
650 msg.buf = &buf[2];
651 buf[2] &= ~0x40;
647 if (fe->ops.i2c_gate_ctrl) 652 if (fe->ops.i2c_gate_ctrl)
648 fe->ops.i2c_gate_ctrl(fe, 1); 653 fe->ops.i2c_gate_ctrl(fe, 1);
649 if (i2c_transfer(&budget->i2c_adap, &msg, 1) != 1) 654 if (i2c_transfer(&budget->i2c_adap, &msg, 1) != 1)
650 return -EIO; 655 return -EIO;
656
651 return 0; 657 return 0;
652} 658}
653 659
654static struct tda10021_config philips_cu1216_config = { 660static struct tda1002x_config philips_cu1216_config = {
655 .demod_address = 0x0c, 661 .demod_address = 0x0c,
662 .invert = 1,
656}; 663};
657 664
658static struct tda10021_config philips_cu1216_config_altaddress = { 665static struct tda1002x_config philips_cu1216_config_altaddress = {
659 .demod_address = 0x0d, 666 .demod_address = 0x0d,
667 .invert = 0,
660}; 668};
661 669
662
663
664
665static int philips_tu1216_tuner_init(struct dvb_frontend *fe) 670static int philips_tu1216_tuner_init(struct dvb_frontend *fe)
666{ 671{
667 struct budget *budget = (struct budget *) fe->dvb->priv; 672 struct budget *budget = (struct budget *) fe->dvb->priv;
@@ -908,41 +913,28 @@ static u8 read_pwm(struct budget_av *budget_av)
908 return pwm; 913 return pwm;
909} 914}
910 915
911#define SUBID_DVBS_KNC1 0x0010 916#define SUBID_DVBS_KNC1 0x0010
912#define SUBID_DVBS_KNC1_PLUS 0x0011 917#define SUBID_DVBS_KNC1_PLUS 0x0011
913#define SUBID_DVBS_TYPHOON 0x4f56 918#define SUBID_DVBS_TYPHOON 0x4f56
914#define SUBID_DVBS_CINERGY1200 0x1154 919#define SUBID_DVBS_CINERGY1200 0x1154
915#define SUBID_DVBS_CYNERGY1200N 0x1155 920#define SUBID_DVBS_CYNERGY1200N 0x1155
916 921#define SUBID_DVBS_TV_STAR 0x0014
917#define SUBID_DVBS_TV_STAR 0x0014 922#define SUBID_DVBS_TV_STAR_CI 0x0016
918#define SUBID_DVBS_TV_STAR_CI 0x0016 923#define SUBID_DVBS_EASYWATCH_1 0x001a
919#define SUBID_DVBS_EASYWATCH_1 0x001a 924#define SUBID_DVBS_EASYWATCH 0x001e
920#define SUBID_DVBS_EASYWATCH 0x001e 925
921#define SUBID_DVBC_EASYWATCH 0x002a 926#define SUBID_DVBC_EASYWATCH 0x002a
922#define SUBID_DVBC_KNC1 0x0020 927#define SUBID_DVBC_EASYWATCH_MK3 0x002c
923#define SUBID_DVBC_KNC1_PLUS 0x0021 928#define SUBID_DVBC_KNC1 0x0020
924#define SUBID_DVBC_CINERGY1200 0x1156 929#define SUBID_DVBC_KNC1_PLUS 0x0021
925 930#define SUBID_DVBC_KNC1_MK3 0x0022
926#define SUBID_DVBT_KNC1_PLUS 0x0031 931#define SUBID_DVBC_KNC1_PLUS_MK3 0x0023
927#define SUBID_DVBT_KNC1 0x0030 932#define SUBID_DVBC_CINERGY1200 0x1156
928#define SUBID_DVBT_CINERGY1200 0x1157 933#define SUBID_DVBC_CINERGY1200_MK3 0x1176
929 934
930 935#define SUBID_DVBT_KNC1_PLUS 0x0031
931static int tda10021_set_frontend(struct dvb_frontend *fe, 936#define SUBID_DVBT_KNC1 0x0030
932 struct dvb_frontend_parameters *p) 937#define SUBID_DVBT_CINERGY1200 0x1157
933{
934 struct budget_av* budget_av = fe->dvb->priv;
935 int result;
936
937 result = budget_av->tda10021_set_frontend(fe, p);
938 if (budget_av->tda10021_ts_enabled) {
939 tda10021_writereg(budget_av->budget.dvb_frontend, 0x12, 0xa1);
940 } else {
941 tda10021_writereg(budget_av->budget.dvb_frontend, 0x12, 0xa0);
942 }
943
944 return result;
945}
946 938
947static void frontend_init(struct budget_av *budget_av) 939static void frontend_init(struct budget_av *budget_av)
948{ 940{
@@ -961,6 +953,7 @@ static void frontend_init(struct budget_av *budget_av)
961 case SUBID_DVBC_KNC1_PLUS: 953 case SUBID_DVBC_KNC1_PLUS:
962 case SUBID_DVBT_KNC1_PLUS: 954 case SUBID_DVBT_KNC1_PLUS:
963 case SUBID_DVBC_EASYWATCH: 955 case SUBID_DVBC_EASYWATCH:
956 case SUBID_DVBC_KNC1_PLUS_MK3:
964 saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTHI); 957 saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTHI);
965 break; 958 break;
966 } 959 }
@@ -1017,6 +1010,7 @@ static void frontend_init(struct budget_av *budget_av)
1017 case SUBID_DVBC_CINERGY1200: 1010 case SUBID_DVBC_CINERGY1200:
1018 case SUBID_DVBC_EASYWATCH: 1011 case SUBID_DVBC_EASYWATCH:
1019 budget_av->reinitialise_demod = 1; 1012 budget_av->reinitialise_demod = 1;
1013 budget_av->budget.dev->i2c_bitrate = SAA7146_I2C_BUS_BIT_RATE_240;
1020 fe = dvb_attach(tda10021_attach, &philips_cu1216_config, 1014 fe = dvb_attach(tda10021_attach, &philips_cu1216_config,
1021 &budget_av->budget.i2c_adap, 1015 &budget_av->budget.i2c_adap,
1022 read_pwm(budget_av)); 1016 read_pwm(budget_av));
@@ -1025,9 +1019,20 @@ static void frontend_init(struct budget_av *budget_av)
1025 &budget_av->budget.i2c_adap, 1019 &budget_av->budget.i2c_adap,
1026 read_pwm(budget_av)); 1020 read_pwm(budget_av));
1027 if (fe) { 1021 if (fe) {
1028 budget_av->tda10021_poclkp = 1; 1022 fe->ops.tuner_ops.set_params = philips_cu1216_tuner_set_params;
1029 budget_av->tda10021_set_frontend = fe->ops.set_frontend; 1023 }
1030 fe->ops.set_frontend = tda10021_set_frontend; 1024 break;
1025
1026 case SUBID_DVBC_EASYWATCH_MK3:
1027 case SUBID_DVBC_CINERGY1200_MK3:
1028 case SUBID_DVBC_KNC1_MK3:
1029 case SUBID_DVBC_KNC1_PLUS_MK3:
1030 budget_av->reinitialise_demod = 1;
1031 budget_av->budget.dev->i2c_bitrate = SAA7146_I2C_BUS_BIT_RATE_240;
1032 fe = dvb_attach(tda10023_attach, &philips_cu1216_config,
1033 &budget_av->budget.i2c_adap,
1034 read_pwm(budget_av));
1035 if (fe) {
1031 fe->ops.tuner_ops.set_params = philips_cu1216_tuner_set_params; 1036 fe->ops.tuner_ops.set_params = philips_cu1216_tuner_set_params;
1032 } 1037 }
1033 break; 1038 break;
@@ -1260,12 +1265,16 @@ MAKE_BUDGET_INFO(kncxs, "KNC TV STAR DVB-S", BUDGET_TVSTAR);
1260MAKE_BUDGET_INFO(satewpls, "Satelco EasyWatch DVB-S light", BUDGET_TVSTAR); 1265MAKE_BUDGET_INFO(satewpls, "Satelco EasyWatch DVB-S light", BUDGET_TVSTAR);
1261MAKE_BUDGET_INFO(satewpls1, "Satelco EasyWatch DVB-S light", BUDGET_KNC1S); 1266MAKE_BUDGET_INFO(satewpls1, "Satelco EasyWatch DVB-S light", BUDGET_KNC1S);
1262MAKE_BUDGET_INFO(satewplc, "Satelco EasyWatch DVB-C", BUDGET_KNC1CP); 1267MAKE_BUDGET_INFO(satewplc, "Satelco EasyWatch DVB-C", BUDGET_KNC1CP);
1268MAKE_BUDGET_INFO(satewcmk3, "Satelco EasyWatch DVB-C MK3", BUDGET_KNC1C_MK3);
1263MAKE_BUDGET_INFO(knc1sp, "KNC1 DVB-S Plus", BUDGET_KNC1SP); 1269MAKE_BUDGET_INFO(knc1sp, "KNC1 DVB-S Plus", BUDGET_KNC1SP);
1264MAKE_BUDGET_INFO(knc1cp, "KNC1 DVB-C Plus", BUDGET_KNC1CP); 1270MAKE_BUDGET_INFO(knc1cp, "KNC1 DVB-C Plus", BUDGET_KNC1CP);
1271MAKE_BUDGET_INFO(knc1cmk3, "KNC1 DVB-C MK3", BUDGET_KNC1C_MK3);
1272MAKE_BUDGET_INFO(knc1cpmk3, "KNC1 DVB-C Plus MK3", BUDGET_KNC1CP_MK3);
1265MAKE_BUDGET_INFO(knc1tp, "KNC1 DVB-T Plus", BUDGET_KNC1TP); 1273MAKE_BUDGET_INFO(knc1tp, "KNC1 DVB-T Plus", BUDGET_KNC1TP);
1266MAKE_BUDGET_INFO(cin1200s, "TerraTec Cinergy 1200 DVB-S", BUDGET_CIN1200S); 1274MAKE_BUDGET_INFO(cin1200s, "TerraTec Cinergy 1200 DVB-S", BUDGET_CIN1200S);
1267MAKE_BUDGET_INFO(cin1200sn, "TerraTec Cinergy 1200 DVB-S", BUDGET_CIN1200S); 1275MAKE_BUDGET_INFO(cin1200sn, "TerraTec Cinergy 1200 DVB-S", BUDGET_CIN1200S);
1268MAKE_BUDGET_INFO(cin1200c, "Terratec Cinergy 1200 DVB-C", BUDGET_CIN1200C); 1276MAKE_BUDGET_INFO(cin1200c, "Terratec Cinergy 1200 DVB-C", BUDGET_CIN1200C);
1277MAKE_BUDGET_INFO(cin1200cmk3, "Terratec Cinergy 1200 DVB-C MK3", BUDGET_CIN1200C_MK3);
1269MAKE_BUDGET_INFO(cin1200t, "Terratec Cinergy 1200 DVB-T", BUDGET_CIN1200T); 1278MAKE_BUDGET_INFO(cin1200t, "Terratec Cinergy 1200 DVB-T", BUDGET_CIN1200T);
1270 1279
1271static struct pci_device_id pci_tbl[] = { 1280static struct pci_device_id pci_tbl[] = {
@@ -1279,13 +1288,17 @@ static struct pci_device_id pci_tbl[] = {
1279 MAKE_EXTENSION_PCI(satewpls, 0x1894, 0x001e), 1288 MAKE_EXTENSION_PCI(satewpls, 0x1894, 0x001e),
1280 MAKE_EXTENSION_PCI(satewpls1, 0x1894, 0x001a), 1289 MAKE_EXTENSION_PCI(satewpls1, 0x1894, 0x001a),
1281 MAKE_EXTENSION_PCI(satewplc, 0x1894, 0x002a), 1290 MAKE_EXTENSION_PCI(satewplc, 0x1894, 0x002a),
1291 MAKE_EXTENSION_PCI(satewcmk3, 0x1894, 0x002c),
1282 MAKE_EXTENSION_PCI(knc1c, 0x1894, 0x0020), 1292 MAKE_EXTENSION_PCI(knc1c, 0x1894, 0x0020),
1283 MAKE_EXTENSION_PCI(knc1cp, 0x1894, 0x0021), 1293 MAKE_EXTENSION_PCI(knc1cp, 0x1894, 0x0021),
1294 MAKE_EXTENSION_PCI(knc1cmk3, 0x1894, 0x0022),
1295 MAKE_EXTENSION_PCI(knc1cpmk3, 0x1894, 0x0023),
1284 MAKE_EXTENSION_PCI(knc1t, 0x1894, 0x0030), 1296 MAKE_EXTENSION_PCI(knc1t, 0x1894, 0x0030),
1285 MAKE_EXTENSION_PCI(knc1tp, 0x1894, 0x0031), 1297 MAKE_EXTENSION_PCI(knc1tp, 0x1894, 0x0031),
1286 MAKE_EXTENSION_PCI(cin1200s, 0x153b, 0x1154), 1298 MAKE_EXTENSION_PCI(cin1200s, 0x153b, 0x1154),
1287 MAKE_EXTENSION_PCI(cin1200sn, 0x153b, 0x1155), 1299 MAKE_EXTENSION_PCI(cin1200sn, 0x153b, 0x1155),
1288 MAKE_EXTENSION_PCI(cin1200c, 0x153b, 0x1156), 1300 MAKE_EXTENSION_PCI(cin1200c, 0x153b, 0x1156),
1301 MAKE_EXTENSION_PCI(cin1200cmk3, 0x153b, 0x1176),
1289 MAKE_EXTENSION_PCI(cin1200t, 0x153b, 0x1157), 1302 MAKE_EXTENSION_PCI(cin1200t, 0x153b, 0x1157),
1290 { 1303 {
1291 .vendor = 0, 1304 .vendor = 0,
diff --git a/drivers/media/dvb/ttpci/budget-ci.c b/drivers/media/dvb/ttpci/budget-ci.c
index 464feaf1a9ad..4ed4599ce816 100644
--- a/drivers/media/dvb/ttpci/budget-ci.c
+++ b/drivers/media/dvb/ttpci/budget-ci.c
@@ -73,21 +73,15 @@
73#define SLOTSTATUS_READY 8 73#define SLOTSTATUS_READY 8
74#define SLOTSTATUS_OCCUPIED (SLOTSTATUS_PRESENT|SLOTSTATUS_RESET|SLOTSTATUS_READY) 74#define SLOTSTATUS_OCCUPIED (SLOTSTATUS_PRESENT|SLOTSTATUS_RESET|SLOTSTATUS_READY)
75 75
76/* Milliseconds during which key presses are regarded as key repeat and during 76/*
77 * which the debounce logic is active 77 * Milliseconds during which a key is regarded as pressed.
78 * If an identical command arrives within this time, the timer will start over.
78 */ 79 */
79#define IR_REPEAT_TIMEOUT 350 80#define IR_KEYPRESS_TIMEOUT 250
80 81
81/* RC5 device wildcard */ 82/* RC5 device wildcard */
82#define IR_DEVICE_ANY 255 83#define IR_DEVICE_ANY 255
83 84
84/* Some remotes sends multiple sequences per keypress (e.g. Zenith sends two),
85 * this setting allows the superflous sequences to be ignored
86 */
87static int debounce = 0;
88module_param(debounce, int, 0644);
89MODULE_PARM_DESC(debounce, "ignore repeated IR sequences (default: 0 = ignore no sequences)");
90
91static int rc5_device = -1; 85static int rc5_device = -1;
92module_param(rc5_device, int, 0644); 86module_param(rc5_device, int, 0644);
93MODULE_PARM_DESC(rc5_device, "only IR commands to given RC5 device (device = 0 - 31, any device = 255, default: autodetect)"); 87MODULE_PARM_DESC(rc5_device, "only IR commands to given RC5 device (device = 0 - 31, any device = 255, default: autodetect)");
@@ -99,10 +93,14 @@ MODULE_PARM_DESC(ir_debug, "enable debugging information for IR decoding");
99struct budget_ci_ir { 93struct budget_ci_ir {
100 struct input_dev *dev; 94 struct input_dev *dev;
101 struct tasklet_struct msp430_irq_tasklet; 95 struct tasklet_struct msp430_irq_tasklet;
96 struct timer_list timer_keyup;
102 char name[72]; /* 40 + 32 for (struct saa7146_dev).name */ 97 char name[72]; /* 40 + 32 for (struct saa7146_dev).name */
103 char phys[32]; 98 char phys[32];
104 struct ir_input_state state; 99 struct ir_input_state state;
105 int rc5_device; 100 int rc5_device;
101 u32 last_raw;
102 u32 ir_key;
103 bool have_command;
106}; 104};
107 105
108struct budget_ci { 106struct budget_ci {
@@ -125,13 +123,8 @@ static void msp430_ir_interrupt(unsigned long data)
125{ 123{
126 struct budget_ci *budget_ci = (struct budget_ci *) data; 124 struct budget_ci *budget_ci = (struct budget_ci *) data;
127 struct input_dev *dev = budget_ci->ir.dev; 125 struct input_dev *dev = budget_ci->ir.dev;
128 static int bounces = 0;
129 int device;
130 int toggle;
131 static int prev_toggle = -1;
132 static u32 ir_key;
133 static int state = 0;
134 u32 command = ttpci_budget_debiread(&budget_ci->budget, DEBINOSWAP, DEBIADDR_IR, 2, 1, 0) >> 8; 126 u32 command = ttpci_budget_debiread(&budget_ci->budget, DEBINOSWAP, DEBIADDR_IR, 2, 1, 0) >> 8;
127 u32 raw;
135 128
136 /* 129 /*
137 * The msp430 chip can generate two different bytes, command and device 130 * The msp430 chip can generate two different bytes, command and device
@@ -143,7 +136,7 @@ static void msp430_ir_interrupt(unsigned long data)
143 * bytes and one or more device bytes. For the repeated bytes, the 136 * bytes and one or more device bytes. For the repeated bytes, the
144 * highest bit (X) is set. The first command byte is always generated 137 * highest bit (X) is set. The first command byte is always generated
145 * before the first device byte. Other than that, no specific order 138 * before the first device byte. Other than that, no specific order
146 * seems to apply. 139 * seems to apply. To make life interesting, bytes can also be lost.
147 * 140 *
148 * Only when we have a command and device byte, a keypress is 141 * Only when we have a command and device byte, a keypress is
149 * generated. 142 * generated.
@@ -152,53 +145,35 @@ static void msp430_ir_interrupt(unsigned long data)
152 if (ir_debug) 145 if (ir_debug)
153 printk("budget_ci: received byte 0x%02x\n", command); 146 printk("budget_ci: received byte 0x%02x\n", command);
154 147
155 /* Is this a repeated byte? */ 148 /* Remove repeat bit, we use every command */
156 if (command & 0x80) 149 command = command & 0x7f;
157 return;
158 150
159 /* Is this a RC5 command byte? */ 151 /* Is this a RC5 command byte? */
160 if (command & 0x40) { 152 if (command & 0x40) {
161 state = 1; 153 budget_ci->ir.have_command = true;
162 ir_key = command & 0x3f; 154 budget_ci->ir.ir_key = command & 0x3f;
163 return; 155 return;
164 } 156 }
165 157
166 /* It's a RC5 device byte */ 158 /* It's a RC5 device byte */
167 if (!state) 159 if (!budget_ci->ir.have_command)
168 return; 160 return;
169 state = 0; 161 budget_ci->ir.have_command = false;
170 device = command & 0x1f;
171 toggle = command & 0x20;
172 162
173 if (budget_ci->ir.rc5_device != IR_DEVICE_ANY && budget_ci->ir.rc5_device != device) 163 if (budget_ci->ir.rc5_device != IR_DEVICE_ANY &&
164 budget_ci->ir.rc5_device != (command & 0x1f))
174 return; 165 return;
175 166
176 /* Ignore repeated key sequences if requested */ 167 /* Is this a repeated key sequence? (same device, command, toggle) */
177 if (toggle == prev_toggle && ir_key == dev->repeat_key && 168 raw = budget_ci->ir.ir_key | (command << 8);
178 bounces > 0 && timer_pending(&dev->timer)) { 169 if (budget_ci->ir.last_raw != raw || !timer_pending(&budget_ci->ir.timer_keyup)) {
179 if (ir_debug)
180 printk("budget_ci: debounce logic ignored IR command\n");
181 bounces--;
182 return;
183 }
184 prev_toggle = toggle;
185
186 /* Are we still waiting for a keyup event? */
187 if (del_timer(&dev->timer))
188 ir_input_nokey(dev, &budget_ci->ir.state);
189
190 /* Generate keypress */
191 if (ir_debug)
192 printk("budget_ci: generating keypress 0x%02x\n", ir_key);
193 ir_input_keydown(dev, &budget_ci->ir.state, ir_key, (ir_key & (command << 8)));
194
195 /* Do we want to delay the keyup event? */
196 if (debounce) {
197 bounces = debounce;
198 mod_timer(&dev->timer, jiffies + msecs_to_jiffies(IR_REPEAT_TIMEOUT));
199 } else {
200 ir_input_nokey(dev, &budget_ci->ir.state); 170 ir_input_nokey(dev, &budget_ci->ir.state);
171 ir_input_keydown(dev, &budget_ci->ir.state,
172 budget_ci->ir.ir_key, raw);
173 budget_ci->ir.last_raw = raw;
201 } 174 }
175
176 mod_timer(&budget_ci->ir.timer_keyup, jiffies + msecs_to_jiffies(IR_KEYPRESS_TIMEOUT));
202} 177}
203 178
204static int msp430_ir_init(struct budget_ci *budget_ci) 179static int msp430_ir_init(struct budget_ci *budget_ci)
@@ -271,16 +246,21 @@ static int msp430_ir_init(struct budget_ci *budget_ci)
271 break; 246 break;
272 } 247 }
273 248
274 /* initialise the key-up debounce timeout handler */ 249 /* initialise the key-up timeout handler */
275 input_dev->timer.function = msp430_ir_keyup; 250 init_timer(&budget_ci->ir.timer_keyup);
276 input_dev->timer.data = (unsigned long) &budget_ci->ir; 251 budget_ci->ir.timer_keyup.function = msp430_ir_keyup;
277 252 budget_ci->ir.timer_keyup.data = (unsigned long) &budget_ci->ir;
253 budget_ci->ir.last_raw = 0xffff; /* An impossible value */
278 error = input_register_device(input_dev); 254 error = input_register_device(input_dev);
279 if (error) { 255 if (error) {
280 printk(KERN_ERR "budget_ci: could not init driver for IR device (code %d)\n", error); 256 printk(KERN_ERR "budget_ci: could not init driver for IR device (code %d)\n", error);
281 goto out2; 257 goto out2;
282 } 258 }
283 259
260 /* note: these must be after input_register_device */
261 input_dev->rep[REP_DELAY] = 400;
262 input_dev->rep[REP_PERIOD] = 250;
263
284 tasklet_init(&budget_ci->ir.msp430_irq_tasklet, msp430_ir_interrupt, 264 tasklet_init(&budget_ci->ir.msp430_irq_tasklet, msp430_ir_interrupt,
285 (unsigned long) budget_ci); 265 (unsigned long) budget_ci);
286 266
@@ -304,10 +284,8 @@ static void msp430_ir_deinit(struct budget_ci *budget_ci)
304 saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT); 284 saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT);
305 tasklet_kill(&budget_ci->ir.msp430_irq_tasklet); 285 tasklet_kill(&budget_ci->ir.msp430_irq_tasklet);
306 286
307 if (del_timer(&dev->timer)) { 287 del_timer_sync(&dev->timer);
308 ir_input_nokey(dev, &budget_ci->ir.state); 288 ir_input_nokey(dev, &budget_ci->ir.state);
309 input_sync(dev);
310 }
311 289
312 input_unregister_device(dev); 290 input_unregister_device(dev);
313} 291}
diff --git a/drivers/media/dvb/ttpci/budget-core.c b/drivers/media/dvb/ttpci/budget-core.c
index e15562f81664..6b97dc1e6b65 100644
--- a/drivers/media/dvb/ttpci/budget-core.c
+++ b/drivers/media/dvb/ttpci/budget-core.c
@@ -41,11 +41,14 @@
41 41
42#define TS_WIDTH (2 * TS_SIZE) 42#define TS_WIDTH (2 * TS_SIZE)
43#define TS_WIDTH_ACTIVY TS_SIZE 43#define TS_WIDTH_ACTIVY TS_SIZE
44#define TS_WIDTH_DVBC TS_SIZE
44#define TS_HEIGHT_MASK 0xf00 45#define TS_HEIGHT_MASK 0xf00
45#define TS_HEIGHT_MASK_ACTIVY 0xc00 46#define TS_HEIGHT_MASK_ACTIVY 0xc00
47#define TS_HEIGHT_MASK_DVBC 0xe00
46#define TS_MIN_BUFSIZE_K 188 48#define TS_MIN_BUFSIZE_K 188
47#define TS_MAX_BUFSIZE_K 1410 49#define TS_MAX_BUFSIZE_K 1410
48#define TS_MAX_BUFSIZE_K_ACTIVY 564 50#define TS_MAX_BUFSIZE_K_ACTIVY 564
51#define TS_MAX_BUFSIZE_K_DVBC 1316
49#define BUFFER_WARNING_WAIT (30*HZ) 52#define BUFFER_WARNING_WAIT (30*HZ)
50 53
51int budget_debug; 54int budget_debug;
@@ -106,6 +109,19 @@ static int start_ts_capture(struct budget *budget)
106 saa7146_write(dev, MC2, (MASK_10 | MASK_26)); 109 saa7146_write(dev, MC2, (MASK_10 | MASK_26));
107 saa7146_write(dev, BRS_CTRL, 0x60000000); 110 saa7146_write(dev, BRS_CTRL, 0x60000000);
108 break; 111 break;
112 case BUDGET_CIN1200C_MK3:
113 case BUDGET_KNC1C_MK3:
114 case BUDGET_KNC1CP_MK3:
115 if (budget->video_port == BUDGET_VIDEO_PORTA) {
116 saa7146_write(dev, DD1_INIT, 0x06000200);
117 saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26));
118 saa7146_write(dev, BRS_CTRL, 0x00000000);
119 } else {
120 saa7146_write(dev, DD1_INIT, 0x00000600);
121 saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26));
122 saa7146_write(dev, BRS_CTRL, 0x60000000);
123 }
124 break;
109 default: 125 default:
110 if (budget->video_port == BUDGET_VIDEO_PORTA) { 126 if (budget->video_port == BUDGET_VIDEO_PORTA) {
111 saa7146_write(dev, DD1_INIT, 0x06000200); 127 saa7146_write(dev, DD1_INIT, 0x06000200);
@@ -122,7 +138,13 @@ static int start_ts_capture(struct budget *budget)
122 mdelay(10); 138 mdelay(10);
123 139
124 saa7146_write(dev, BASE_ODD3, 0); 140 saa7146_write(dev, BASE_ODD3, 0);
125 saa7146_write(dev, BASE_EVEN3, 0); 141 if (budget->buffer_size > budget->buffer_height * budget->buffer_width) {
142 // using odd/even buffers
143 saa7146_write(dev, BASE_EVEN3, budget->buffer_height * budget->buffer_width);
144 } else {
145 // using a single buffer
146 saa7146_write(dev, BASE_EVEN3, 0);
147 }
126 saa7146_write(dev, PROT_ADDR3, budget->buffer_size); 148 saa7146_write(dev, PROT_ADDR3, budget->buffer_size);
127 saa7146_write(dev, BASE_PAGE3, budget->pt.dma | ME1 | 0x90); 149 saa7146_write(dev, BASE_PAGE3, budget->pt.dma | ME1 | 0x90);
128 150
@@ -399,11 +421,25 @@ int ttpci_budget_init(struct budget *budget, struct saa7146_dev *dev,
399 budget->card = bi; 421 budget->card = bi;
400 budget->dev = (struct saa7146_dev *) dev; 422 budget->dev = (struct saa7146_dev *) dev;
401 423
402 if (budget->card->type == BUDGET_FS_ACTIVY) { 424 switch(budget->card->type) {
425 case BUDGET_FS_ACTIVY:
403 budget->buffer_width = TS_WIDTH_ACTIVY; 426 budget->buffer_width = TS_WIDTH_ACTIVY;
404 max_bufsize = TS_MAX_BUFSIZE_K_ACTIVY; 427 max_bufsize = TS_MAX_BUFSIZE_K_ACTIVY;
405 height_mask = TS_HEIGHT_MASK_ACTIVY; 428 height_mask = TS_HEIGHT_MASK_ACTIVY;
406 } else { 429 break;
430
431 case BUDGET_KNC1C:
432 case BUDGET_KNC1CP:
433 case BUDGET_CIN1200C:
434 case BUDGET_KNC1C_MK3:
435 case BUDGET_KNC1CP_MK3:
436 case BUDGET_CIN1200C_MK3:
437 budget->buffer_width = TS_WIDTH_DVBC;
438 max_bufsize = TS_MAX_BUFSIZE_K_DVBC;
439 height_mask = TS_HEIGHT_MASK_DVBC;
440 break;
441
442 default:
407 budget->buffer_width = TS_WIDTH; 443 budget->buffer_width = TS_WIDTH;
408 max_bufsize = TS_MAX_BUFSIZE_K; 444 max_bufsize = TS_MAX_BUFSIZE_K;
409 height_mask = TS_HEIGHT_MASK; 445 height_mask = TS_HEIGHT_MASK;
@@ -415,14 +451,22 @@ int ttpci_budget_init(struct budget *budget, struct saa7146_dev *dev,
415 dma_buffer_size = max_bufsize; 451 dma_buffer_size = max_bufsize;
416 452
417 budget->buffer_height = dma_buffer_size * 1024 / budget->buffer_width; 453 budget->buffer_height = dma_buffer_size * 1024 / budget->buffer_width;
418 budget->buffer_height &= height_mask; 454 if (budget->buffer_height > 0xfff) {
419 budget->buffer_size = budget->buffer_height * budget->buffer_width; 455 budget->buffer_height /= 2;
456 budget->buffer_height &= height_mask;
457 budget->buffer_size = 2 * budget->buffer_height * budget->buffer_width;
458 } else {
459 budget->buffer_height &= height_mask;
460 budget->buffer_size = budget->buffer_height * budget->buffer_width;
461 }
420 budget->buffer_warning_threshold = budget->buffer_size * 80/100; 462 budget->buffer_warning_threshold = budget->buffer_size * 80/100;
421 budget->buffer_warnings = 0; 463 budget->buffer_warnings = 0;
422 budget->buffer_warning_time = jiffies; 464 budget->buffer_warning_time = jiffies;
423 465
424 dprintk(2, "%s: width = %d, height = %d\n", 466 dprintk(2, "%s: buffer type = %s, width = %d, height = %d\n",
425 budget->dev->name, budget->buffer_width, budget->buffer_height); 467 budget->dev->name,
468 budget->buffer_size > budget->buffer_width * budget->buffer_height ? "odd/even" : "single",
469 budget->buffer_width, budget->buffer_height);
426 printk("%s: dma buffer size %u\n", budget->dev->name, budget->buffer_size); 470 printk("%s: dma buffer size %u\n", budget->dev->name, budget->buffer_size);
427 471
428 if ((ret = dvb_register_adapter(&budget->dvb_adapter, budget->card->name, owner, &budget->dev->pci->dev)) < 0) { 472 if ((ret = dvb_register_adapter(&budget->dvb_adapter, budget->card->name, owner, &budget->dev->pci->dev)) < 0) {
diff --git a/drivers/media/dvb/ttpci/budget.h b/drivers/media/dvb/ttpci/budget.h
index e8a5c79178e1..d764ffa728b0 100644
--- a/drivers/media/dvb/ttpci/budget.h
+++ b/drivers/media/dvb/ttpci/budget.h
@@ -99,6 +99,9 @@ static struct saa7146_pci_extension_data x_var = { \
99#define BUDGET_KNC1CP 12 99#define BUDGET_KNC1CP 12
100#define BUDGET_KNC1TP 13 100#define BUDGET_KNC1TP 13
101#define BUDGET_TVSTAR 14 101#define BUDGET_TVSTAR 14
102#define BUDGET_CIN1200C_MK3 15
103#define BUDGET_KNC1C_MK3 16
104#define BUDGET_KNC1CP_MK3 17
102 105
103#define BUDGET_VIDEO_PORTA 0 106#define BUDGET_VIDEO_PORTA 0
104#define BUDGET_VIDEO_PORTB 1 107#define BUDGET_VIDEO_PORTB 1
diff --git a/drivers/media/dvb/ttusb-budget/Kconfig b/drivers/media/dvb/ttusb-budget/Kconfig
index e78ea9227b0e..f546bccdb997 100644
--- a/drivers/media/dvb/ttusb-budget/Kconfig
+++ b/drivers/media/dvb/ttusb-budget/Kconfig
@@ -1,7 +1,6 @@
1config DVB_TTUSB_BUDGET 1config DVB_TTUSB_BUDGET
2 tristate "Technotrend/Hauppauge Nova-USB devices" 2 tristate "Technotrend/Hauppauge Nova-USB devices"
3 depends on DVB_CORE && USB && I2C 3 depends on DVB_CORE && USB && I2C
4 select DVB_PLL
5 select DVB_CX22700 if !DVB_FE_CUSTOMISE 4 select DVB_CX22700 if !DVB_FE_CUSTOMISE
6 select DVB_TDA1004X if !DVB_FE_CUSTOMISE 5 select DVB_TDA1004X if !DVB_FE_CUSTOMISE
7 select DVB_VES1820 if !DVB_FE_CUSTOMISE 6 select DVB_VES1820 if !DVB_FE_CUSTOMISE
diff --git a/drivers/media/radio/radio-aimslab.c b/drivers/media/radio/radio-aimslab.c
index b2e88ad28977..5adc27c3ced9 100644
--- a/drivers/media/radio/radio-aimslab.c
+++ b/drivers/media/radio/radio-aimslab.c
@@ -231,129 +231,149 @@ static struct v4l2_queryctrl radio_qctrl[] = {
231 } 231 }
232}; 232};
233 233
234static int rt_do_ioctl(struct inode *inode, struct file *file, 234static int vidioc_querycap(struct file *file, void *priv,
235 unsigned int cmd, void *arg) 235 struct v4l2_capability *v)
236{
237 strlcpy(v->driver, "radio-aimslab", sizeof(v->driver));
238 strlcpy(v->card, "RadioTrack", sizeof(v->card));
239 sprintf(v->bus_info, "ISA");
240 v->version = RADIO_VERSION;
241 v->capabilities = V4L2_CAP_TUNER;
242 return 0;
243}
244
245static int vidioc_g_tuner(struct file *file, void *priv,
246 struct v4l2_tuner *v)
236{ 247{
237 struct video_device *dev = video_devdata(file); 248 struct video_device *dev = video_devdata(file);
238 struct rt_device *rt=dev->priv; 249 struct rt_device *rt = dev->priv;
239 250
240 switch(cmd) 251 if (v->index > 0)
241 { 252 return -EINVAL;
242 case VIDIOC_QUERYCAP:
243 {
244 struct v4l2_capability *v = arg;
245 memset(v,0,sizeof(*v));
246 strlcpy(v->driver, "radio-aimslab", sizeof (v->driver));
247 strlcpy(v->card, "RadioTrack", sizeof (v->card));
248 sprintf(v->bus_info,"ISA");
249 v->version = RADIO_VERSION;
250 v->capabilities = V4L2_CAP_TUNER;
251 253
252 return 0; 254 strcpy(v->name, "FM");
253 } 255 v->type = V4L2_TUNER_RADIO;
254 case VIDIOC_G_TUNER: 256 v->rangelow = (87*16000);
255 { 257 v->rangehigh = (108*16000);
256 struct v4l2_tuner *v = arg; 258 v->rxsubchans = V4L2_TUNER_SUB_MONO;
259 v->capability = V4L2_TUNER_CAP_LOW;
260 v->audmode = V4L2_TUNER_MODE_MONO;
261 v->signal = 0xffff*rt_getsigstr(rt);
262 return 0;
263}
264
265static int vidioc_s_tuner(struct file *file, void *priv,
266 struct v4l2_tuner *v)
267{
268 if (v->index > 0)
269 return -EINVAL;
270 return 0;
271}
257 272
258 if (v->index > 0) 273static int vidioc_s_frequency(struct file *file, void *priv,
259 return -EINVAL; 274 struct v4l2_frequency *f)
275{
276 struct video_device *dev = video_devdata(file);
277 struct rt_device *rt = dev->priv;
260 278
261 memset(v,0,sizeof(*v)); 279 rt->curfreq = f->frequency;
262 strcpy(v->name, "FM"); 280 rt_setfreq(rt, rt->curfreq);
263 v->type = V4L2_TUNER_RADIO; 281 return 0;
282}
264 283
265 v->rangelow=(87*16000); 284static int vidioc_g_frequency(struct file *file, void *priv,
266 v->rangehigh=(108*16000); 285 struct v4l2_frequency *f)
267 v->rxsubchans =V4L2_TUNER_SUB_MONO; 286{
268 v->capability=V4L2_TUNER_CAP_LOW; 287 struct video_device *dev = video_devdata(file);
269 v->audmode = V4L2_TUNER_MODE_MONO; 288 struct rt_device *rt = dev->priv;
270 v->signal=0xFFFF*rt_getsigstr(rt);
271 289
272 return 0; 290 f->type = V4L2_TUNER_RADIO;
273 } 291 f->frequency = rt->curfreq;
274 case VIDIOC_S_TUNER: 292 return 0;
275 { 293}
276 struct v4l2_tuner *v = arg;
277 294
278 if (v->index > 0) 295static int vidioc_queryctrl(struct file *file, void *priv,
279 return -EINVAL; 296 struct v4l2_queryctrl *qc)
297{
298 int i;
280 299
300 for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
301 if (qc->id && qc->id == radio_qctrl[i].id) {
302 memcpy(qc, &(radio_qctrl[i]),
303 sizeof(*qc));
281 return 0; 304 return 0;
282 } 305 }
283 case VIDIOC_S_FREQUENCY: 306 }
284 { 307 return -EINVAL;
285 struct v4l2_frequency *f = arg; 308}
286 309
287 rt->curfreq = f->frequency; 310static int vidioc_g_ctrl(struct file *file, void *priv,
288 rt_setfreq(rt, rt->curfreq); 311 struct v4l2_control *ctrl)
289 return 0; 312{
290 } 313 struct video_device *dev = video_devdata(file);
291 case VIDIOC_G_FREQUENCY: 314 struct rt_device *rt = dev->priv;
292 {
293 struct v4l2_frequency *f = arg;
294 315
295 f->type = V4L2_TUNER_RADIO; 316 switch (ctrl->id) {
296 f->frequency = rt->curfreq; 317 case V4L2_CID_AUDIO_MUTE:
318 ctrl->value = rt->muted;
319 return 0;
320 case V4L2_CID_AUDIO_VOLUME:
321 ctrl->value = rt->curvol * 6554;
322 return 0;
323 }
324 return -EINVAL;
325}
297 326
298 return 0; 327static int vidioc_s_ctrl(struct file *file, void *priv,
299 } 328 struct v4l2_control *ctrl)
300 case VIDIOC_QUERYCTRL: 329{
301 { 330 struct video_device *dev = video_devdata(file);
302 struct v4l2_queryctrl *qc = arg; 331 struct rt_device *rt = dev->priv;
303 int i;
304
305 for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
306 if (qc->id && qc->id == radio_qctrl[i].id) {
307 memcpy(qc, &(radio_qctrl[i]),
308 sizeof(*qc));
309 return (0);
310 }
311 }
312 return -EINVAL;
313 }
314 case VIDIOC_G_CTRL:
315 {
316 struct v4l2_control *ctrl= arg;
317
318 switch (ctrl->id) {
319 case V4L2_CID_AUDIO_MUTE:
320 ctrl->value=rt->muted;
321 return (0);
322 case V4L2_CID_AUDIO_VOLUME:
323 ctrl->value=rt->curvol * 6554;
324 return (0);
325 }
326 return -EINVAL;
327 }
328 case VIDIOC_S_CTRL:
329 {
330 struct v4l2_control *ctrl= arg;
331
332 switch (ctrl->id) {
333 case V4L2_CID_AUDIO_MUTE:
334 if (ctrl->value) {
335 rt_mute(rt);
336 } else {
337 rt_setvol(rt,rt->curvol);
338 }
339 return (0);
340 case V4L2_CID_AUDIO_VOLUME:
341 rt_setvol(rt,ctrl->value);
342 return (0);
343 }
344 return -EINVAL;
345 }
346 332
347 default: 333 switch (ctrl->id) {
348 return v4l_compat_translate_ioctl(inode,file,cmd,arg, 334 case V4L2_CID_AUDIO_MUTE:
349 rt_do_ioctl); 335 if (ctrl->value)
336 rt_mute(rt);
337 else
338 rt_setvol(rt,rt->curvol);
339 return 0;
340 case V4L2_CID_AUDIO_VOLUME:
341 rt_setvol(rt,ctrl->value);
342 return 0;
350 } 343 }
344 return -EINVAL;
345}
346
347static int vidioc_g_audio (struct file *file, void *priv,
348 struct v4l2_audio *a)
349{
350 if (a->index > 1)
351 return -EINVAL;
352
353 strcpy(a->name, "Radio");
354 a->capability = V4L2_AUDCAP_STEREO;
355 return 0;
356}
357
358static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
359{
360 *i = 0;
361 return 0;
362}
363
364static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
365{
366 if (i != 0)
367 return -EINVAL;
368 return 0;
351} 369}
352 370
353static int rt_ioctl(struct inode *inode, struct file *file, 371static int vidioc_s_audio(struct file *file, void *priv,
354 unsigned int cmd, unsigned long arg) 372 struct v4l2_audio *a)
355{ 373{
356 return video_usercopy(inode, file, cmd, arg, rt_do_ioctl); 374 if (a->index != 0)
375 return -EINVAL;
376 return 0;
357} 377}
358 378
359static struct rt_device rtrack_unit; 379static struct rt_device rtrack_unit;
@@ -362,7 +382,7 @@ static const struct file_operations rtrack_fops = {
362 .owner = THIS_MODULE, 382 .owner = THIS_MODULE,
363 .open = video_exclusive_open, 383 .open = video_exclusive_open,
364 .release = video_exclusive_release, 384 .release = video_exclusive_release,
365 .ioctl = rt_ioctl, 385 .ioctl = video_ioctl2,
366 .compat_ioctl = v4l_compat_ioctl32, 386 .compat_ioctl = v4l_compat_ioctl32,
367 .llseek = no_llseek, 387 .llseek = no_llseek,
368}; 388};
@@ -374,6 +394,18 @@ static struct video_device rtrack_radio=
374 .type = VID_TYPE_TUNER, 394 .type = VID_TYPE_TUNER,
375 .hardware = 0, 395 .hardware = 0,
376 .fops = &rtrack_fops, 396 .fops = &rtrack_fops,
397 .vidioc_querycap = vidioc_querycap,
398 .vidioc_g_tuner = vidioc_g_tuner,
399 .vidioc_s_tuner = vidioc_s_tuner,
400 .vidioc_g_audio = vidioc_g_audio,
401 .vidioc_s_audio = vidioc_s_audio,
402 .vidioc_g_input = vidioc_g_input,
403 .vidioc_s_input = vidioc_s_input,
404 .vidioc_g_frequency = vidioc_g_frequency,
405 .vidioc_s_frequency = vidioc_s_frequency,
406 .vidioc_queryctrl = vidioc_queryctrl,
407 .vidioc_g_ctrl = vidioc_g_ctrl,
408 .vidioc_s_ctrl = vidioc_s_ctrl,
377}; 409};
378 410
379static int __init rtrack_init(void) 411static int __init rtrack_init(void)
diff --git a/drivers/media/radio/radio-gemtek-pci.c b/drivers/media/radio/radio-gemtek-pci.c
index 74976cba869f..fdf5d6e46eac 100644
--- a/drivers/media/radio/radio-gemtek-pci.c
+++ b/drivers/media/radio/radio-gemtek-pci.c
@@ -192,131 +192,158 @@ static inline unsigned int gemtek_pci_getsignal( struct gemtek_pci_card *card )
192 return ( inb( card->iobase ) & 0x08 ) ? 0 : 1; 192 return ( inb( card->iobase ) & 0x08 ) ? 0 : 1;
193} 193}
194 194
195static int gemtek_pci_do_ioctl(struct inode *inode, struct file *file, 195static int vidioc_querycap(struct file *file, void *priv,
196 unsigned int cmd, void *arg) 196 struct v4l2_capability *v)
197{
198 strlcpy(v->driver, "radio-gemtek-pci", sizeof(v->driver));
199 strlcpy(v->card, "GemTek PCI Radio", sizeof(v->card));
200 sprintf(v->bus_info, "ISA");
201 v->version = RADIO_VERSION;
202 v->capabilities = V4L2_CAP_TUNER;
203 return 0;
204}
205
206static int vidioc_g_tuner(struct file *file, void *priv,
207 struct v4l2_tuner *v)
197{ 208{
198 struct video_device *dev = video_devdata(file); 209 struct video_device *dev = video_devdata(file);
199 struct gemtek_pci_card *card = dev->priv; 210 struct gemtek_pci_card *card = dev->priv;
200 211
201 switch ( cmd ) { 212 if (v->index > 0)
202 case VIDIOC_QUERYCAP: 213 return -EINVAL;
203 { 214
204 struct v4l2_capability *v = arg; 215 strcpy(v->name, "FM");
205 memset(v,0,sizeof(*v)); 216 v->type = V4L2_TUNER_RADIO;
206 strlcpy(v->driver, "radio-gemtek-pci", sizeof (v->driver)); 217 v->rangelow = GEMTEK_PCI_RANGE_LOW;
207 strlcpy(v->card, "GemTek PCI Radio", sizeof (v->card)); 218 v->rangehigh = GEMTEK_PCI_RANGE_HIGH;
208 sprintf(v->bus_info,"ISA"); 219 v->rxsubchans = V4L2_TUNER_SUB_MONO;
209 v->version = RADIO_VERSION; 220 v->capability = V4L2_TUNER_CAP_LOW;
210 v->capabilities = V4L2_CAP_TUNER; 221 v->audmode = V4L2_TUNER_MODE_MONO;
211 222 v->signal = 0xffff * gemtek_pci_getsignal(card);
212 return 0; 223 return 0;
213 } 224}
214 case VIDIOC_G_TUNER:
215 {
216 struct v4l2_tuner *v = arg;
217 225
218 if (v->index > 0) 226static int vidioc_s_tuner(struct file *file, void *priv,
219 return -EINVAL; 227 struct v4l2_tuner *v)
228{
229 if (v->index > 0)
230 return -EINVAL;
231 return 0;
232}
220 233
221 memset(v,0,sizeof(*v)); 234static int vidioc_s_frequency(struct file *file, void *priv,
222 strcpy(v->name, "FM"); 235 struct v4l2_frequency *f)
223 v->type = V4L2_TUNER_RADIO; 236{
237 struct video_device *dev = video_devdata(file);
238 struct gemtek_pci_card *card = dev->priv;
224 239
225 v->rangelow = GEMTEK_PCI_RANGE_LOW; 240 if ( (f->frequency < GEMTEK_PCI_RANGE_LOW) ||
226 v->rangehigh = GEMTEK_PCI_RANGE_HIGH; 241 (f->frequency > GEMTEK_PCI_RANGE_HIGH) )
227 v->rxsubchans =V4L2_TUNER_SUB_MONO; 242 return -EINVAL;
228 v->capability=V4L2_TUNER_CAP_LOW; 243 gemtek_pci_setfrequency(card, f->frequency);
229 v->audmode = V4L2_TUNER_MODE_MONO; 244 card->current_frequency = f->frequency;
230 v->signal=0xFFFF*gemtek_pci_getsignal( card ); 245 card->mute = false;
246 return 0;
247}
231 248
232 return 0; 249static int vidioc_g_frequency(struct file *file, void *priv,
233 } 250 struct v4l2_frequency *f)
234 case VIDIOC_S_TUNER: 251{
235 { 252 struct video_device *dev = video_devdata(file);
236 struct v4l2_tuner *v = arg; 253 struct gemtek_pci_card *card = dev->priv;
237 254
238 if (v->index > 0) 255 f->type = V4L2_TUNER_RADIO;
239 return -EINVAL; 256 f->frequency = card->current_frequency;
257 return 0;
258}
240 259
260static int vidioc_queryctrl(struct file *file, void *priv,
261 struct v4l2_queryctrl *qc)
262{
263 int i;
264 for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
265 if (qc->id && qc->id == radio_qctrl[i].id) {
266 memcpy(qc, &(radio_qctrl[i]),
267 sizeof(*qc));
241 return 0; 268 return 0;
242 } 269 }
243 case VIDIOC_S_FREQUENCY: 270 }
244 { 271 return -EINVAL;
245 struct v4l2_frequency *f = arg; 272}
246 273
247 if ( (f->frequency < GEMTEK_PCI_RANGE_LOW) || 274static int vidioc_g_ctrl(struct file *file, void *priv,
248 (f->frequency > GEMTEK_PCI_RANGE_HIGH) ) 275 struct v4l2_control *ctrl)
249 return -EINVAL; 276{
277 struct video_device *dev = video_devdata(file);
278 struct gemtek_pci_card *card = dev->priv;
250 279
280 switch (ctrl->id) {
281 case V4L2_CID_AUDIO_MUTE:
282 ctrl->value = card->mute;
283 return 0;
284 case V4L2_CID_AUDIO_VOLUME:
285 if (card->mute)
286 ctrl->value = 0;
287 else
288 ctrl->value = 65535;
289 return 0;
290 }
291 return -EINVAL;
292}
251 293
252 gemtek_pci_setfrequency( card, f->frequency ); 294static int vidioc_s_ctrl(struct file *file, void *priv,
253 card->current_frequency = f->frequency; 295 struct v4l2_control *ctrl)
254 card->mute = false; 296{
255 return 0; 297 struct video_device *dev = video_devdata(file);
256 } 298 struct gemtek_pci_card *card = dev->priv;
257 case VIDIOC_QUERYCTRL: 299
258 { 300 switch (ctrl->id) {
259 struct v4l2_queryctrl *qc = arg; 301 case V4L2_CID_AUDIO_MUTE:
260 int i; 302 if (ctrl->value)
261 303 gemtek_pci_mute(card);
262 for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) { 304 else
263 if (qc->id && qc->id == radio_qctrl[i].id) { 305 gemtek_pci_unmute(card);
264 memcpy(qc, &(radio_qctrl[i]), 306 return 0;
265 sizeof(*qc)); 307 case V4L2_CID_AUDIO_VOLUME:
266 return (0); 308 if (ctrl->value)
267 } 309 gemtek_pci_unmute(card);
268 } 310 else
269 return -EINVAL; 311 gemtek_pci_mute(card);
270 } 312 return 0;
271 case VIDIOC_G_CTRL:
272 {
273 struct v4l2_control *ctrl= arg;
274
275 switch (ctrl->id) {
276 case V4L2_CID_AUDIO_MUTE:
277 ctrl->value=card->mute;
278 return (0);
279 case V4L2_CID_AUDIO_VOLUME:
280 if (card->mute)
281 ctrl->value=0;
282 else
283 ctrl->value=65535;
284 return (0);
285 }
286 return -EINVAL;
287 }
288 case VIDIOC_S_CTRL:
289 {
290 struct v4l2_control *ctrl= arg;
291
292 switch (ctrl->id) {
293 case V4L2_CID_AUDIO_MUTE:
294 if (ctrl->value) {
295 gemtek_pci_mute(card);
296 } else {
297 gemtek_pci_unmute(card);
298 }
299 return (0);
300 case V4L2_CID_AUDIO_VOLUME:
301 if (ctrl->value) {
302 gemtek_pci_unmute(card);
303 } else {
304 gemtek_pci_mute(card);
305 }
306 return (0);
307 }
308 return -EINVAL;
309 }
310 default:
311 return v4l_compat_translate_ioctl(inode,file,cmd,arg,
312 gemtek_pci_do_ioctl);
313 } 313 }
314 return -EINVAL;
314} 315}
315 316
316static int gemtek_pci_ioctl(struct inode *inode, struct file *file, 317static int vidioc_g_audio(struct file *file, void *priv,
317 unsigned int cmd, unsigned long arg) 318 struct v4l2_audio *a)
318{ 319{
319 return video_usercopy(inode, file, cmd, arg, gemtek_pci_do_ioctl); 320 if (a->index > 1)
321 return -EINVAL;
322
323 strcpy(a->name, "Radio");
324 a->capability = V4L2_AUDCAP_STEREO;
325 return 0;
326}
327
328static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
329{
330 *i = 0;
331 return 0;
332}
333
334static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
335{
336 if (i != 0)
337 return -EINVAL;
338 return 0;
339}
340
341static int vidioc_s_audio(struct file *file, void *priv,
342 struct v4l2_audio *a)
343{
344 if (a->index != 0)
345 return -EINVAL;
346 return 0;
320} 347}
321 348
322enum { 349enum {
@@ -342,7 +369,7 @@ static const struct file_operations gemtek_pci_fops = {
342 .owner = THIS_MODULE, 369 .owner = THIS_MODULE,
343 .open = video_exclusive_open, 370 .open = video_exclusive_open,
344 .release = video_exclusive_release, 371 .release = video_exclusive_release,
345 .ioctl = gemtek_pci_ioctl, 372 .ioctl = video_ioctl2,
346 .compat_ioctl = v4l_compat_ioctl32, 373 .compat_ioctl = v4l_compat_ioctl32,
347 .llseek = no_llseek, 374 .llseek = no_llseek,
348}; 375};
@@ -353,6 +380,18 @@ static struct video_device vdev_template = {
353 .type = VID_TYPE_TUNER, 380 .type = VID_TYPE_TUNER,
354 .hardware = 0, 381 .hardware = 0,
355 .fops = &gemtek_pci_fops, 382 .fops = &gemtek_pci_fops,
383 .vidioc_querycap = vidioc_querycap,
384 .vidioc_g_tuner = vidioc_g_tuner,
385 .vidioc_s_tuner = vidioc_s_tuner,
386 .vidioc_g_audio = vidioc_g_audio,
387 .vidioc_s_audio = vidioc_s_audio,
388 .vidioc_g_input = vidioc_g_input,
389 .vidioc_s_input = vidioc_s_input,
390 .vidioc_g_frequency = vidioc_g_frequency,
391 .vidioc_s_frequency = vidioc_s_frequency,
392 .vidioc_queryctrl = vidioc_queryctrl,
393 .vidioc_g_ctrl = vidioc_g_ctrl,
394 .vidioc_s_ctrl = vidioc_s_ctrl,
356}; 395};
357 396
358static int __devinit gemtek_pci_probe( struct pci_dev *pci_dev, const struct pci_device_id *pci_id ) 397static int __devinit gemtek_pci_probe( struct pci_dev *pci_dev, const struct pci_device_id *pci_id )
diff --git a/drivers/media/radio/radio-gemtek.c b/drivers/media/radio/radio-gemtek.c
index 36c4be6622c7..b04b6a7fff7c 100644
--- a/drivers/media/radio/radio-gemtek.c
+++ b/drivers/media/radio/radio-gemtek.c
@@ -161,137 +161,157 @@ static int gemtek_getsigstr(struct gemtek_device *dev)
161 return 1; /* signal present */ 161 return 1; /* signal present */
162} 162}
163 163
164static int gemtek_do_ioctl(struct inode *inode, struct file *file, 164static int vidioc_querycap(struct file *file, void *priv,
165 unsigned int cmd, void *arg) 165 struct v4l2_capability *v)
166{
167 strlcpy(v->driver, "radio-gemtek", sizeof(v->driver));
168 strlcpy(v->card, "GemTek", sizeof(v->card));
169 sprintf(v->bus_info, "ISA");
170 v->version = RADIO_VERSION;
171 v->capabilities = V4L2_CAP_TUNER;
172 return 0;
173}
174
175static int vidioc_g_tuner(struct file *file, void *priv,
176 struct v4l2_tuner *v)
166{ 177{
167 struct video_device *dev = video_devdata(file); 178 struct video_device *dev = video_devdata(file);
168 struct gemtek_device *rt=dev->priv; 179 struct gemtek_device *rt = dev->priv;
169 180
170 switch(cmd) 181 if (v->index > 0)
171 { 182 return -EINVAL;
172 case VIDIOC_QUERYCAP:
173 {
174 struct v4l2_capability *v = arg;
175 memset(v,0,sizeof(*v));
176 strlcpy(v->driver, "radio-gemtek", sizeof (v->driver));
177 strlcpy(v->card, "GemTek", sizeof (v->card));
178 sprintf(v->bus_info,"ISA");
179 v->version = RADIO_VERSION;
180 v->capabilities = V4L2_CAP_TUNER;
181 183
182 return 0; 184 strcpy(v->name, "FM");
183 } 185 v->type = V4L2_TUNER_RADIO;
184 case VIDIOC_G_TUNER: 186 v->rangelow = (87*16000);
185 { 187 v->rangehigh = (108*16000);
186 struct v4l2_tuner *v = arg; 188 v->rxsubchans = V4L2_TUNER_SUB_MONO;
189 v->capability = V4L2_TUNER_CAP_LOW;
190 v->audmode = V4L2_TUNER_MODE_MONO;
191 v->signal = 0xffff*gemtek_getsigstr(rt);
192 return 0;
193}
194
195static int vidioc_s_tuner(struct file *file, void *priv,
196 struct v4l2_tuner *v)
197{
198 if (v->index > 0)
199 return -EINVAL;
200 return 0;
201}
187 202
188 if (v->index > 0) 203static int vidioc_s_frequency(struct file *file, void *priv,
189 return -EINVAL; 204 struct v4l2_frequency *f)
205{
206 struct video_device *dev = video_devdata(file);
207 struct gemtek_device *rt = dev->priv;
190 208
191 memset(v,0,sizeof(*v)); 209 rt->curfreq = f->frequency;
192 strcpy(v->name, "FM"); 210 /* needs to be called twice in order for getsigstr to work */
193 v->type = V4L2_TUNER_RADIO; 211 gemtek_setfreq(rt, rt->curfreq);
212 gemtek_setfreq(rt, rt->curfreq);
213 return 0;
214}
194 215
195 v->rangelow=(87*16000); 216static int vidioc_g_frequency(struct file *file, void *priv,
196 v->rangehigh=(108*16000); 217 struct v4l2_frequency *f)
197 v->rxsubchans =V4L2_TUNER_SUB_MONO; 218{
198 v->capability=V4L2_TUNER_CAP_LOW; 219 struct video_device *dev = video_devdata(file);
199 v->audmode = V4L2_TUNER_MODE_MONO; 220 struct gemtek_device *rt = dev->priv;
200 v->signal=0xFFFF*gemtek_getsigstr(rt);
201 221
202 return 0; 222 f->type = V4L2_TUNER_RADIO;
203 } 223 f->frequency = rt->curfreq;
204 case VIDIOC_S_TUNER: 224 return 0;
205 { 225}
206 struct v4l2_tuner *v = arg;
207 226
208 if (v->index > 0) 227static int vidioc_queryctrl(struct file *file, void *priv,
209 return -EINVAL; 228 struct v4l2_queryctrl *qc)
229{
230 int i;
210 231
232 for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
233 if (qc->id && qc->id == radio_qctrl[i].id) {
234 memcpy(qc, &(radio_qctrl[i]),
235 sizeof(*qc));
211 return 0; 236 return 0;
212 } 237 }
213 case VIDIOC_S_FREQUENCY: 238 }
214 { 239 return -EINVAL;
215 struct v4l2_frequency *f = arg; 240}
216
217 rt->curfreq = f->frequency;
218 /* needs to be called twice in order for getsigstr to work */
219 gemtek_setfreq(rt, rt->curfreq);
220 gemtek_setfreq(rt, rt->curfreq);
221 return 0;
222 }
223 case VIDIOC_G_FREQUENCY:
224 {
225 struct v4l2_frequency *f = arg;
226 241
227 f->type = V4L2_TUNER_RADIO; 242static int vidioc_g_ctrl(struct file *file, void *priv,
228 f->frequency = rt->curfreq; 243 struct v4l2_control *ctrl)
244{
245 struct video_device *dev = video_devdata(file);
246 struct gemtek_device *rt = dev->priv;
229 247
230 return 0; 248 switch (ctrl->id) {
231 } 249 case V4L2_CID_AUDIO_MUTE:
232 case VIDIOC_QUERYCTRL: 250 ctrl->value = rt->muted;
233 { 251 return 0;
234 struct v4l2_queryctrl *qc = arg; 252 case V4L2_CID_AUDIO_VOLUME:
235 int i; 253 if (rt->muted)
236 254 ctrl->value = 0;
237 for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) { 255 else
238 if (qc->id && qc->id == radio_qctrl[i].id) { 256 ctrl->value = 65535;
239 memcpy(qc, &(radio_qctrl[i]), 257 return 0;
240 sizeof(*qc)); 258 }
241 return (0); 259 return -EINVAL;
242 } 260}
243 } 261
244 return -EINVAL; 262static int vidioc_s_ctrl(struct file *file, void *priv,
245 } 263 struct v4l2_control *ctrl)
246 case VIDIOC_G_CTRL: 264{
247 { 265 struct video_device *dev = video_devdata(file);
248 struct v4l2_control *ctrl= arg; 266 struct gemtek_device *rt = dev->priv;
249 267
250 switch (ctrl->id) { 268 switch (ctrl->id) {
251 case V4L2_CID_AUDIO_MUTE: 269 case V4L2_CID_AUDIO_MUTE:
252 ctrl->value=rt->muted; 270 if (ctrl->value)
253 return (0); 271 gemtek_mute(rt);
254 case V4L2_CID_AUDIO_VOLUME: 272 else
255 if (rt->muted) 273 gemtek_unmute(rt);
256 ctrl->value=0; 274 return 0;
257 else 275 case V4L2_CID_AUDIO_VOLUME:
258 ctrl->value=65535; 276 if (ctrl->value)
259 return (0); 277 gemtek_unmute(rt);
260 } 278 else
261 return -EINVAL; 279 gemtek_mute(rt);
262 } 280 return 0;
263 case VIDIOC_S_CTRL:
264 {
265 struct v4l2_control *ctrl= arg;
266
267 switch (ctrl->id) {
268 case V4L2_CID_AUDIO_MUTE:
269 if (ctrl->value) {
270 gemtek_mute(rt);
271 } else {
272 gemtek_unmute(rt);
273 }
274 return (0);
275 case V4L2_CID_AUDIO_VOLUME:
276 if (ctrl->value) {
277 gemtek_unmute(rt);
278 } else {
279 gemtek_mute(rt);
280 }
281 return (0);
282 }
283 return -EINVAL;
284 }
285 default:
286 return v4l_compat_translate_ioctl(inode,file,cmd,arg,
287 gemtek_do_ioctl);
288 } 281 }
282 return -EINVAL;
289} 283}
290 284
291static int gemtek_ioctl(struct inode *inode, struct file *file, 285static int vidioc_g_audio (struct file *file, void *priv,
292 unsigned int cmd, unsigned long arg) 286 struct v4l2_audio *a)
293{ 287{
294 return video_usercopy(inode, file, cmd, arg, gemtek_do_ioctl); 288 if (a->index > 1)
289 return -EINVAL;
290
291 strcpy(a->name, "Radio");
292 a->capability = V4L2_AUDCAP_STEREO;
293 return 0;
294}
295
296static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
297{
298 *i = 0;
299 return 0;
300}
301
302static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
303{
304 if (i != 0)
305 return -EINVAL;
306 return 0;
307}
308
309static int vidioc_s_audio(struct file *file, void *priv,
310 struct v4l2_audio *a)
311{
312 if (a->index != 0)
313 return -EINVAL;
314 return 0;
295} 315}
296 316
297static struct gemtek_device gemtek_unit; 317static struct gemtek_device gemtek_unit;
@@ -300,7 +320,7 @@ static const struct file_operations gemtek_fops = {
300 .owner = THIS_MODULE, 320 .owner = THIS_MODULE,
301 .open = video_exclusive_open, 321 .open = video_exclusive_open,
302 .release = video_exclusive_release, 322 .release = video_exclusive_release,
303 .ioctl = gemtek_ioctl, 323 .ioctl = video_ioctl2,
304 .compat_ioctl = v4l_compat_ioctl32, 324 .compat_ioctl = v4l_compat_ioctl32,
305 .llseek = no_llseek, 325 .llseek = no_llseek,
306}; 326};
@@ -312,6 +332,18 @@ static struct video_device gemtek_radio=
312 .type = VID_TYPE_TUNER, 332 .type = VID_TYPE_TUNER,
313 .hardware = 0, 333 .hardware = 0,
314 .fops = &gemtek_fops, 334 .fops = &gemtek_fops,
335 .vidioc_querycap = vidioc_querycap,
336 .vidioc_g_tuner = vidioc_g_tuner,
337 .vidioc_s_tuner = vidioc_s_tuner,
338 .vidioc_g_audio = vidioc_g_audio,
339 .vidioc_s_audio = vidioc_s_audio,
340 .vidioc_g_input = vidioc_g_input,
341 .vidioc_s_input = vidioc_s_input,
342 .vidioc_g_frequency = vidioc_g_frequency,
343 .vidioc_s_frequency = vidioc_s_frequency,
344 .vidioc_queryctrl = vidioc_queryctrl,
345 .vidioc_g_ctrl = vidioc_g_ctrl,
346 .vidioc_s_ctrl = vidioc_s_ctrl,
315}; 347};
316 348
317static int __init gemtek_init(void) 349static int __init gemtek_init(void)
diff --git a/drivers/media/radio/radio-maestro.c b/drivers/media/radio/radio-maestro.c
index e67b7f258029..11f80cacd6ed 100644
--- a/drivers/media/radio/radio-maestro.c
+++ b/drivers/media/radio/radio-maestro.c
@@ -75,8 +75,6 @@ static struct v4l2_queryctrl radio_qctrl[] = {
75static int radio_nr = -1; 75static int radio_nr = -1;
76module_param(radio_nr, int, 0); 76module_param(radio_nr, int, 0);
77 77
78static int radio_ioctl(struct inode *inode, struct file *file,
79 unsigned int cmd, unsigned long arg);
80static int maestro_probe(struct pci_dev *pdev, const struct pci_device_id *ent); 78static int maestro_probe(struct pci_dev *pdev, const struct pci_device_id *ent);
81static void maestro_remove(struct pci_dev *pdev); 79static void maestro_remove(struct pci_dev *pdev);
82 80
@@ -102,18 +100,11 @@ static const struct file_operations maestro_fops = {
102 .owner = THIS_MODULE, 100 .owner = THIS_MODULE,
103 .open = video_exclusive_open, 101 .open = video_exclusive_open,
104 .release = video_exclusive_release, 102 .release = video_exclusive_release,
105 .ioctl = radio_ioctl, 103 .ioctl = video_ioctl2,
106 .compat_ioctl = v4l_compat_ioctl32, 104 .compat_ioctl = v4l_compat_ioctl32,
107 .llseek = no_llseek, 105 .llseek = no_llseek,
108}; 106};
109 107
110static struct video_device maestro_radio = {
111 .name = "Maestro radio",
112 .type = VID_TYPE_TUNER,
113 .hardware = 0,
114 .fops = &maestro_fops,
115};
116
117struct radio_device { 108struct radio_device {
118 u16 io, /* base of Maestro card radio io (GPIO_DATA)*/ 109 u16 io, /* base of Maestro card radio io (GPIO_DATA)*/
119 muted, /* VIDEO_AUDIO_MUTE */ 110 muted, /* VIDEO_AUDIO_MUTE */
@@ -190,142 +181,153 @@ static void radio_bits_set(struct radio_device *dev, u32 data)
190 msleep(125); 181 msleep(125);
191} 182}
192 183
193static inline int radio_function(struct inode *inode, struct file *file, 184static int vidioc_querycap(struct file *file, void *priv,
194 unsigned int cmd, void *arg) 185 struct v4l2_capability *v)
186{
187 strlcpy(v->driver, "radio-maestro", sizeof(v->driver));
188 strlcpy(v->card, "Maestro Radio", sizeof(v->card));
189 sprintf(v->bus_info, "PCI");
190 v->version = RADIO_VERSION;
191 v->capabilities = V4L2_CAP_TUNER;
192 return 0;
193}
194
195static int vidioc_g_tuner(struct file *file, void *priv,
196 struct v4l2_tuner *v)
195{ 197{
196 struct video_device *dev = video_devdata(file); 198 struct video_device *dev = video_devdata(file);
197 struct radio_device *card = video_get_drvdata(dev); 199 struct radio_device *card = video_get_drvdata(dev);
198 200
199 switch (cmd) { 201 if (v->index > 0)
200 case VIDIOC_QUERYCAP: 202 return -EINVAL;
201 { 203
202 struct v4l2_capability *v = arg; 204 (void)radio_bits_get(card);
203 memset(v,0,sizeof(*v)); 205
204 strlcpy(v->driver, "radio-maestro", sizeof (v->driver)); 206 strcpy(v->name, "FM");
205 strlcpy(v->card, "Maestro Radio", sizeof (v->card)); 207 v->type = V4L2_TUNER_RADIO;
206 sprintf(v->bus_info,"PCI"); 208 v->rangelow = FREQ_LO;
207 v->version = RADIO_VERSION; 209 v->rangehigh = FREQ_HI;
208 v->capabilities = V4L2_CAP_TUNER; 210 v->rxsubchans = V4L2_TUNER_SUB_MONO|V4L2_TUNER_SUB_STEREO;
209 211 v->capability = V4L2_TUNER_CAP_LOW;
210 return 0; 212 if(card->stereo)
211 } 213 v->audmode = V4L2_TUNER_MODE_STEREO;
212 case VIDIOC_G_TUNER: 214 else
213 { 215 v->audmode = V4L2_TUNER_MODE_MONO;
214 struct v4l2_tuner *v = arg; 216 v->signal = card->tuned;
215 217 return 0;
216 if (v->index > 0) 218}
217 return -EINVAL;
218
219 (void)radio_bits_get(card);
220 219
221 memset(v,0,sizeof(*v)); 220static int vidioc_s_tuner(struct file *file, void *priv,
222 strcpy(v->name, "FM"); 221 struct v4l2_tuner *v)
223 v->type = V4L2_TUNER_RADIO; 222{
223 if (v->index > 0)
224 return -EINVAL;
225 return 0;
226}
224 227
225 v->rangelow = FREQ_LO; 228static int vidioc_s_frequency(struct file *file, void *priv,
226 v->rangehigh = FREQ_HI; 229 struct v4l2_frequency *f)
227 v->rxsubchans =V4L2_TUNER_SUB_MONO|V4L2_TUNER_SUB_STEREO; 230{
228 v->capability=V4L2_TUNER_CAP_LOW; 231 struct video_device *dev = video_devdata(file);
229 if(card->stereo) 232 struct radio_device *card = video_get_drvdata(dev);
230 v->audmode = V4L2_TUNER_MODE_STEREO;
231 else
232 v->audmode = V4L2_TUNER_MODE_MONO;
233 v->signal=card->tuned;
234 233
235 return 0; 234 if (f->frequency < FREQ_LO || f->frequency > FREQ_HI)
236 } 235 return -EINVAL;
237 case VIDIOC_S_TUNER: 236 radio_bits_set(card, FREQ2BITS(f->frequency));
238 { 237 return 0;
239 struct v4l2_tuner *v = arg; 238}
240 239
241 if (v->index > 0) 240static int vidioc_g_frequency(struct file *file, void *priv,
242 return -EINVAL; 241 struct v4l2_frequency *f)
242{
243 struct video_device *dev = video_devdata(file);
244 struct radio_device *card = video_get_drvdata(dev);
243 245
244 return 0; 246 f->type = V4L2_TUNER_RADIO;
245 } 247 f->frequency = BITS2FREQ(radio_bits_get(card));
246 case VIDIOC_S_FREQUENCY: 248 return 0;
247 { 249}
248 struct v4l2_frequency *f = arg;
249 250
250 if (f->frequency < FREQ_LO || f->frequency > FREQ_HI) 251static int vidioc_queryctrl(struct file *file, void *priv,
251 return -EINVAL; 252 struct v4l2_queryctrl *qc)
252 radio_bits_set(card, FREQ2BITS(f->frequency)); 253{
254 int i;
253 255
256 for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
257 if (qc->id && qc->id == radio_qctrl[i].id) {
258 memcpy(qc, &(radio_qctrl[i]),
259 sizeof(*qc));
254 return 0; 260 return 0;
255 } 261 }
256 case VIDIOC_G_FREQUENCY: 262 }
257 { 263 return -EINVAL;
258 struct v4l2_frequency *f = arg; 264}
259 265
260 f->type = V4L2_TUNER_RADIO; 266static int vidioc_g_ctrl(struct file *file, void *priv,
261 f->frequency = BITS2FREQ(radio_bits_get(card)); 267 struct v4l2_control *ctrl)
268{
269 struct video_device *dev = video_devdata(file);
270 struct radio_device *card = video_get_drvdata(dev);
262 271
263 return 0; 272 switch (ctrl->id) {
264 } 273 case V4L2_CID_AUDIO_MUTE:
265 case VIDIOC_QUERYCTRL: 274 ctrl->value = card->muted;
266 { 275 return 0;
267 struct v4l2_queryctrl *qc = arg;
268 int i;
269
270 for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
271 if (qc->id && qc->id == radio_qctrl[i].id) {
272 memcpy(qc, &(radio_qctrl[i]),
273 sizeof(*qc));
274 return (0);
275 }
276 }
277 return -EINVAL;
278 }
279 case VIDIOC_G_CTRL:
280 {
281 struct v4l2_control *ctrl= arg;
282
283 switch (ctrl->id) {
284 case V4L2_CID_AUDIO_MUTE:
285 ctrl->value=card->muted;
286 return (0);
287 }
288 return -EINVAL;
289 }
290 case VIDIOC_S_CTRL:
291 {
292 struct v4l2_control *ctrl= arg;
293
294 switch (ctrl->id) {
295 case V4L2_CID_AUDIO_MUTE:
296 {
297 register u16 io = card->io;
298 register u16 omask = inw(io + IO_MASK);
299 outw(~STR_WREN, io + IO_MASK);
300 outw((card->muted = ctrl->value ) ?
301 STR_WREN : 0, io);
302 udelay(4);
303 outw(omask, io + IO_MASK);
304 msleep(125);
305
306 return (0);
307 }
308 }
309 return -EINVAL;
310 }
311 default:
312 return v4l_compat_translate_ioctl(inode,file,cmd,arg,
313 radio_function);
314 } 276 }
277 return -EINVAL;
315} 278}
316 279
317static int radio_ioctl(struct inode *inode, struct file *file, 280static int vidioc_s_ctrl(struct file *file, void *priv,
318 unsigned int cmd, unsigned long arg) 281 struct v4l2_control *ctrl)
319{ 282{
320 struct video_device *dev = video_devdata(file); 283 struct video_device *dev = video_devdata(file);
321 struct radio_device *card = video_get_drvdata(dev); 284 struct radio_device *card = video_get_drvdata(dev);
322 int ret; 285 register u16 io = card->io;
286 register u16 omask = inw(io + IO_MASK);
287
288 switch (ctrl->id) {
289 case V4L2_CID_AUDIO_MUTE:
290 outw(~STR_WREN, io + IO_MASK);
291 outw((card->muted = ctrl->value ) ?
292 STR_WREN : 0, io);
293 udelay(4);
294 outw(omask, io + IO_MASK);
295 msleep(125);
296 return 0;
297 }
298 return -EINVAL;
299}
323 300
324 mutex_lock(&card->lock); 301static int vidioc_g_audio(struct file *file, void *priv,
325 ret = video_usercopy(inode, file, cmd, arg, radio_function); 302 struct v4l2_audio *a)
326 mutex_unlock(&card->lock); 303{
304 if (a->index > 1)
305 return -EINVAL;
327 306
328 return ret; 307 strcpy(a->name, "Radio");
308 a->capability = V4L2_AUDCAP_STEREO;
309 return 0;
310}
311
312static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
313{
314 *i = 0;
315 return 0;
316}
317
318static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
319{
320 if (i != 0)
321 return -EINVAL;
322 return 0;
323}
324
325static int vidioc_s_audio(struct file *file, void *priv,
326 struct v4l2_audio *a)
327{
328 if (a->index != 0)
329 return -EINVAL;
330 return 0;
329} 331}
330 332
331static u16 __devinit radio_power_on(struct radio_device *dev) 333static u16 __devinit radio_power_on(struct radio_device *dev)
@@ -352,6 +354,24 @@ static u16 __devinit radio_power_on(struct radio_device *dev)
352 return (ofreq == radio_bits_get(dev)); 354 return (ofreq == radio_bits_get(dev));
353} 355}
354 356
357static struct video_device maestro_radio = {
358 .name = "Maestro radio",
359 .type = VID_TYPE_TUNER,
360 .fops = &maestro_fops,
361 .vidioc_querycap = vidioc_querycap,
362 .vidioc_g_tuner = vidioc_g_tuner,
363 .vidioc_s_tuner = vidioc_s_tuner,
364 .vidioc_g_audio = vidioc_g_audio,
365 .vidioc_s_audio = vidioc_s_audio,
366 .vidioc_g_input = vidioc_g_input,
367 .vidioc_s_input = vidioc_s_input,
368 .vidioc_g_frequency = vidioc_g_frequency,
369 .vidioc_s_frequency = vidioc_s_frequency,
370 .vidioc_queryctrl = vidioc_queryctrl,
371 .vidioc_g_ctrl = vidioc_g_ctrl,
372 .vidioc_s_ctrl = vidioc_s_ctrl,
373};
374
355static int __devinit maestro_probe(struct pci_dev *pdev, 375static int __devinit maestro_probe(struct pci_dev *pdev,
356 const struct pci_device_id *ent) 376 const struct pci_device_id *ent)
357{ 377{
diff --git a/drivers/media/radio/radio-rtrack2.c b/drivers/media/radio/radio-rtrack2.c
index f6683872251e..9b493b3298cd 100644
--- a/drivers/media/radio/radio-rtrack2.c
+++ b/drivers/media/radio/radio-rtrack2.c
@@ -122,6 +122,26 @@ static int rt_setfreq(struct rt_device *dev, unsigned long freq)
122 return 0; 122 return 0;
123} 123}
124 124
125static int vidioc_querycap(struct file *file, void *priv,
126 struct v4l2_capability *v)
127{
128 strlcpy(v->driver, "radio-rtrack2", sizeof(v->driver));
129 strlcpy(v->card, "RadioTrack II", sizeof(v->card));
130 sprintf(v->bus_info, "ISA");
131 v->version = RADIO_VERSION;
132 v->capabilities = V4L2_CAP_TUNER;
133 return 0;
134}
135
136static int vidioc_s_tuner(struct file *file, void *priv,
137 struct v4l2_tuner *v)
138{
139 if (v->index > 0)
140 return -EINVAL;
141
142 return 0;
143}
144
125static int rt_getsigstr(struct rt_device *dev) 145static int rt_getsigstr(struct rt_device *dev)
126{ 146{
127 if (inb(io) & 2) /* bit set = no signal present */ 147 if (inb(io) & 2) /* bit set = no signal present */
@@ -129,135 +149,136 @@ static int rt_getsigstr(struct rt_device *dev)
129 return 1; /* signal present */ 149 return 1; /* signal present */
130} 150}
131 151
132static int rt_do_ioctl(struct inode *inode, struct file *file, 152static int vidioc_g_tuner(struct file *file, void *priv,
133 unsigned int cmd, void *arg) 153 struct v4l2_tuner *v)
134{ 154{
135 struct video_device *dev = video_devdata(file); 155 struct video_device *dev = video_devdata(file);
136 struct rt_device *rt=dev->priv; 156 struct rt_device *rt = dev->priv;
137 157
138 switch(cmd) 158 if (v->index > 0)
139 { 159 return -EINVAL;
140 case VIDIOC_QUERYCAP:
141 {
142 struct v4l2_capability *v = arg;
143 memset(v,0,sizeof(*v));
144 strlcpy(v->driver, "radio-rtrack2", sizeof (v->driver));
145 strlcpy(v->card, "RadioTrack II", sizeof (v->card));
146 sprintf(v->bus_info,"ISA");
147 v->version = RADIO_VERSION;
148 v->capabilities = V4L2_CAP_TUNER;
149 160
150 return 0; 161 strcpy(v->name, "FM");
151 } 162 v->type = V4L2_TUNER_RADIO;
152 case VIDIOC_G_TUNER: 163 v->rangelow = (88*16000);
153 { 164 v->rangehigh = (108*16000);
154 struct v4l2_tuner *v = arg; 165 v->rxsubchans = V4L2_TUNER_SUB_MONO;
166 v->capability = V4L2_TUNER_CAP_LOW;
167 v->audmode = V4L2_TUNER_MODE_MONO;
168 v->signal = 0xFFFF*rt_getsigstr(rt);
169 return 0;
170}
155 171
156 if (v->index > 0) 172static int vidioc_s_frequency(struct file *file, void *priv,
157 return -EINVAL; 173 struct v4l2_frequency *f)
174{
175 struct video_device *dev = video_devdata(file);
176 struct rt_device *rt = dev->priv;
158 177
159 memset(v,0,sizeof(*v)); 178 rt->curfreq = f->frequency;
160 strcpy(v->name, "FM"); 179 rt_setfreq(rt, rt->curfreq);
161 v->type = V4L2_TUNER_RADIO; 180 return 0;
181}
162 182
163 v->rangelow=(88*16000); 183static int vidioc_g_frequency(struct file *file, void *priv,
164 v->rangehigh=(108*16000); 184 struct v4l2_frequency *f)
165 v->rxsubchans =V4L2_TUNER_SUB_MONO; 185{
166 v->capability=V4L2_TUNER_CAP_LOW; 186 struct video_device *dev = video_devdata(file);
167 v->audmode = V4L2_TUNER_MODE_MONO; 187 struct rt_device *rt = dev->priv;
168 v->signal=0xFFFF*rt_getsigstr(rt);
169 188
170 return 0; 189 f->type = V4L2_TUNER_RADIO;
171 } 190 f->frequency = rt->curfreq;
172 case VIDIOC_S_TUNER: 191 return 0;
173 { 192}
174 struct v4l2_tuner *v = arg;
175 193
176 if (v->index > 0) 194static int vidioc_queryctrl(struct file *file, void *priv,
177 return -EINVAL; 195 struct v4l2_queryctrl *qc)
196{
197 int i;
178 198
199 for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
200 if (qc->id && qc->id == radio_qctrl[i].id) {
201 memcpy(qc, &(radio_qctrl[i]),
202 sizeof(*qc));
179 return 0; 203 return 0;
180 } 204 }
181 case VIDIOC_S_FREQUENCY: 205 }
182 { 206 return -EINVAL;
183 struct v4l2_frequency *f = arg; 207}
184 208
185 rt->curfreq = f->frequency; 209static int vidioc_g_ctrl(struct file *file, void *priv,
186 rt_setfreq(rt, rt->curfreq); 210 struct v4l2_control *ctrl)
187 return 0; 211{
188 } 212 struct video_device *dev = video_devdata(file);
189 case VIDIOC_G_FREQUENCY: 213 struct rt_device *rt = dev->priv;
190 {
191 struct v4l2_frequency *f = arg;
192 214
193 f->type = V4L2_TUNER_RADIO; 215 switch (ctrl->id) {
194 f->frequency = rt->curfreq; 216 case V4L2_CID_AUDIO_MUTE:
217 ctrl->value = rt->muted;
218 return 0;
219 case V4L2_CID_AUDIO_VOLUME:
220 if (rt->muted)
221 ctrl->value = 0;
222 else
223 ctrl->value = 65535;
224 return 0;
225 }
226 return -EINVAL;
227}
195 228
196 return 0; 229static int vidioc_s_ctrl(struct file *file, void *priv,
197 } 230 struct v4l2_control *ctrl)
198 case VIDIOC_QUERYCTRL: 231{
199 { 232 struct video_device *dev = video_devdata(file);
200 struct v4l2_queryctrl *qc = arg; 233 struct rt_device *rt = dev->priv;
201 int i; 234
202 235 switch (ctrl->id) {
203 for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) { 236 case V4L2_CID_AUDIO_MUTE:
204 if (qc->id && qc->id == radio_qctrl[i].id) { 237 if (ctrl->value)
205 memcpy(qc, &(radio_qctrl[i]), 238 rt_mute(rt);
206 sizeof(*qc)); 239 else
207 return (0); 240 rt_unmute(rt);
208 } 241 return 0;
209 } 242 case V4L2_CID_AUDIO_VOLUME:
210 return -EINVAL; 243 if (ctrl->value)
211 } 244 rt_unmute(rt);
212 case VIDIOC_G_CTRL: 245 else
213 { 246 rt_mute(rt);
214 struct v4l2_control *ctrl= arg; 247 return 0;
215
216 switch (ctrl->id) {
217 case V4L2_CID_AUDIO_MUTE:
218 ctrl->value=rt->muted;
219 return (0);
220 case V4L2_CID_AUDIO_VOLUME:
221 if (rt->muted)
222 ctrl->value=0;
223 else
224 ctrl->value=65535;
225 return (0);
226 }
227 return -EINVAL;
228 }
229 case VIDIOC_S_CTRL:
230 {
231 struct v4l2_control *ctrl= arg;
232
233 switch (ctrl->id) {
234 case V4L2_CID_AUDIO_MUTE:
235 if (ctrl->value) {
236 rt_mute(rt);
237 } else {
238 rt_unmute(rt);
239 }
240 return (0);
241 case V4L2_CID_AUDIO_VOLUME:
242 if (ctrl->value) {
243 rt_unmute(rt);
244 } else {
245 rt_mute(rt);
246 }
247 return (0);
248 }
249 return -EINVAL;
250 }
251 default:
252 return v4l_compat_translate_ioctl(inode,file,cmd,arg,
253 rt_do_ioctl);
254 } 248 }
249 return -EINVAL;
255} 250}
256 251
257static int rt_ioctl(struct inode *inode, struct file *file, 252static int vidioc_g_audio(struct file *file, void *priv,
258 unsigned int cmd, unsigned long arg) 253 struct v4l2_audio *a)
259{ 254{
260 return video_usercopy(inode, file, cmd, arg, rt_do_ioctl); 255 if (a->index > 1)
256 return -EINVAL;
257
258 strcpy(a->name, "Radio");
259 a->capability = V4L2_AUDCAP_STEREO;
260 return 0;
261}
262
263static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
264{
265 *i = 0;
266 return 0;
267}
268
269static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
270{
271 if (i != 0)
272 return -EINVAL;
273 return 0;
274}
275
276static int vidioc_s_audio(struct file *file, void *priv,
277 struct v4l2_audio *a)
278{
279 if (a->index != 0)
280 return -EINVAL;
281 return 0;
261} 282}
262 283
263static struct rt_device rtrack2_unit; 284static struct rt_device rtrack2_unit;
@@ -266,7 +287,7 @@ static const struct file_operations rtrack2_fops = {
266 .owner = THIS_MODULE, 287 .owner = THIS_MODULE,
267 .open = video_exclusive_open, 288 .open = video_exclusive_open,
268 .release = video_exclusive_release, 289 .release = video_exclusive_release,
269 .ioctl = rt_ioctl, 290 .ioctl = video_ioctl2,
270 .compat_ioctl = v4l_compat_ioctl32, 291 .compat_ioctl = v4l_compat_ioctl32,
271 .llseek = no_llseek, 292 .llseek = no_llseek,
272}; 293};
@@ -278,6 +299,18 @@ static struct video_device rtrack2_radio=
278 .type = VID_TYPE_TUNER, 299 .type = VID_TYPE_TUNER,
279 .hardware = 0, 300 .hardware = 0,
280 .fops = &rtrack2_fops, 301 .fops = &rtrack2_fops,
302 .vidioc_querycap = vidioc_querycap,
303 .vidioc_g_tuner = vidioc_g_tuner,
304 .vidioc_s_tuner = vidioc_s_tuner,
305 .vidioc_g_frequency = vidioc_g_frequency,
306 .vidioc_s_frequency = vidioc_s_frequency,
307 .vidioc_queryctrl = vidioc_queryctrl,
308 .vidioc_g_ctrl = vidioc_g_ctrl,
309 .vidioc_s_ctrl = vidioc_s_ctrl,
310 .vidioc_g_audio = vidioc_g_audio,
311 .vidioc_s_audio = vidioc_s_audio,
312 .vidioc_g_input = vidioc_g_input,
313 .vidioc_s_input = vidioc_s_input,
281}; 314};
282 315
283static int __init rtrack2_init(void) 316static int __init rtrack2_init(void)
diff --git a/drivers/media/radio/radio-sf16fmi.c b/drivers/media/radio/radio-sf16fmi.c
index f4619e4dda4f..dc33f19c0e2c 100644
--- a/drivers/media/radio/radio-sf16fmi.c
+++ b/drivers/media/radio/radio-sf16fmi.c
@@ -130,137 +130,155 @@ static inline int fmi_getsigstr(struct fmi_device *dev)
130 return (res & 2) ? 0 : 0xFFFF; 130 return (res & 2) ? 0 : 0xFFFF;
131} 131}
132 132
133static int fmi_do_ioctl(struct inode *inode, struct file *file, 133static int vidioc_querycap(struct file *file, void *priv,
134 unsigned int cmd, void *arg) 134 struct v4l2_capability *v)
135{ 135{
136 strlcpy(v->driver, "radio-sf16fmi", sizeof(v->driver));
137 strlcpy(v->card, "SF16-FMx radio", sizeof(v->card));
138 sprintf(v->bus_info, "ISA");
139 v->version = RADIO_VERSION;
140 v->capabilities = V4L2_CAP_TUNER;
141 return 0;
142}
143
144static int vidioc_g_tuner(struct file *file, void *priv,
145 struct v4l2_tuner *v)
146{
147 int mult;
136 struct video_device *dev = video_devdata(file); 148 struct video_device *dev = video_devdata(file);
137 struct fmi_device *fmi=dev->priv; 149 struct fmi_device *fmi = dev->priv;
138 150
139 switch(cmd) 151 if (v->index > 0)
140 { 152 return -EINVAL;
141 case VIDIOC_QUERYCAP:
142 {
143 struct v4l2_capability *v = arg;
144 memset(v,0,sizeof(*v));
145 strlcpy(v->driver, "radio-sf16fmi", sizeof (v->driver));
146 strlcpy(v->card, "SF16-FMx radio", sizeof (v->card));
147 sprintf(v->bus_info,"ISA");
148 v->version = RADIO_VERSION;
149 v->capabilities = V4L2_CAP_TUNER;
150 153
151 return 0; 154 strcpy(v->name, "FM");
152 } 155 v->type = V4L2_TUNER_RADIO;
153 case VIDIOC_G_TUNER: 156 mult = (fmi->flags & V4L2_TUNER_CAP_LOW) ? 1 : 1000;
154 { 157 v->rangelow = RSF16_MINFREQ/mult;
155 struct v4l2_tuner *v = arg; 158 v->rangehigh = RSF16_MAXFREQ/mult;
156 int mult; 159 v->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_MODE_STEREO;
157 160 v->capability = fmi->flags&V4L2_TUNER_CAP_LOW;
158 if (v->index > 0) 161 v->audmode = V4L2_TUNER_MODE_STEREO;
159 return -EINVAL; 162 v->signal = fmi_getsigstr(fmi);
160 163 return 0;
161 memset(v,0,sizeof(*v)); 164}
162 strcpy(v->name, "FM");
163 v->type = V4L2_TUNER_RADIO;
164
165 mult = (fmi->flags & V4L2_TUNER_CAP_LOW) ? 1 : 1000;
166 v->rangelow = RSF16_MINFREQ/mult;
167 v->rangehigh = RSF16_MAXFREQ/mult;
168 v->rxsubchans =V4L2_TUNER_SUB_MONO | V4L2_TUNER_MODE_STEREO;
169 v->capability=fmi->flags&V4L2_TUNER_CAP_LOW;
170 v->audmode = V4L2_TUNER_MODE_STEREO;
171 v->signal = fmi_getsigstr(fmi);
172 165
173 return 0; 166static int vidioc_s_tuner(struct file *file, void *priv,
174 } 167 struct v4l2_tuner *v)
175 case VIDIOC_S_TUNER: 168{
176 { 169 if (v->index > 0)
177 struct v4l2_tuner *v = arg; 170 return -EINVAL;
171 return 0;
172}
178 173
179 if (v->index > 0) 174static int vidioc_s_frequency(struct file *file, void *priv,
180 return -EINVAL; 175 struct v4l2_frequency *f)
176{
177 struct video_device *dev = video_devdata(file);
178 struct fmi_device *fmi = dev->priv;
181 179
182 return 0; 180 if (!(fmi->flags & V4L2_TUNER_CAP_LOW))
183 } 181 f->frequency *= 1000;
184 case VIDIOC_S_FREQUENCY: 182 if (f->frequency < RSF16_MINFREQ ||
185 { 183 f->frequency > RSF16_MAXFREQ )
186 struct v4l2_frequency *f = arg; 184 return -EINVAL;
187 185 /*rounding in steps of 800 to match th freq
188 if (!(fmi->flags & V4L2_TUNER_CAP_LOW)) 186 that will be used */
189 f->frequency *= 1000; 187 fmi->curfreq = (f->frequency/800)*800;
190 if (f->frequency < RSF16_MINFREQ || 188 fmi_setfreq(fmi);
191 f->frequency > RSF16_MAXFREQ ) 189 return 0;
192 return -EINVAL; 190}
193 /*rounding in steps of 800 to match th freq
194 that will be used */
195 fmi->curfreq = (f->frequency/800)*800;
196 fmi_setfreq(fmi);
197 191
198 return 0; 192static int vidioc_g_frequency(struct file *file, void *priv,
199 } 193 struct v4l2_frequency *f)
200 case VIDIOC_G_FREQUENCY: 194{
201 { 195 struct video_device *dev = video_devdata(file);
202 struct v4l2_frequency *f = arg; 196 struct fmi_device *fmi = dev->priv;
203 197
204 f->type = V4L2_TUNER_RADIO; 198 f->type = V4L2_TUNER_RADIO;
205 f->frequency = fmi->curfreq; 199 f->frequency = fmi->curfreq;
206 if (!(fmi->flags & V4L2_TUNER_CAP_LOW)) 200 if (!(fmi->flags & V4L2_TUNER_CAP_LOW))
207 f->frequency /= 1000; 201 f->frequency /= 1000;
202 return 0;
203}
204
205static int vidioc_queryctrl(struct file *file, void *priv,
206 struct v4l2_queryctrl *qc)
207{
208 int i;
208 209
210 for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
211 if (qc->id && qc->id == radio_qctrl[i].id) {
212 memcpy(qc, &(radio_qctrl[i]),
213 sizeof(*qc));
209 return 0; 214 return 0;
210 } 215 }
211 case VIDIOC_QUERYCTRL:
212 {
213 struct v4l2_queryctrl *qc = arg;
214 int i;
215
216 for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
217 if (qc->id && qc->id == radio_qctrl[i].id) {
218 memcpy(qc, &(radio_qctrl[i]),
219 sizeof(*qc));
220 return (0);
221 }
222 }
223 return -EINVAL;
224 }
225 case VIDIOC_G_CTRL:
226 {
227 struct v4l2_control *ctrl= arg;
228
229 switch (ctrl->id) {
230 case V4L2_CID_AUDIO_MUTE:
231 ctrl->value=fmi->curvol;
232 return (0);
233 }
234 return -EINVAL;
235 }
236 case VIDIOC_S_CTRL:
237 {
238 struct v4l2_control *ctrl= arg;
239
240 switch (ctrl->id) {
241 case V4L2_CID_AUDIO_MUTE:
242 {
243 if (ctrl->value)
244 fmi_mute(fmi->port);
245 else
246 fmi_unmute(fmi->port);
247
248 fmi->curvol=ctrl->value;
249 return (0);
250 }
251 }
252 return -EINVAL;
253 }
254 default:
255 return v4l_compat_translate_ioctl(inode,file,cmd,arg,
256 fmi_do_ioctl);
257 } 216 }
217 return -EINVAL;
218}
219
220static int vidioc_g_ctrl(struct file *file, void *priv,
221 struct v4l2_control *ctrl)
222{
223 struct video_device *dev = video_devdata(file);
224 struct fmi_device *fmi = dev->priv;
225
226 switch (ctrl->id) {
227 case V4L2_CID_AUDIO_MUTE:
228 ctrl->value = fmi->curvol;
229 return 0;
230 }
231 return -EINVAL;
232}
233
234static int vidioc_s_ctrl(struct file *file, void *priv,
235 struct v4l2_control *ctrl)
236{
237 struct video_device *dev = video_devdata(file);
238 struct fmi_device *fmi = dev->priv;
239
240 switch (ctrl->id) {
241 case V4L2_CID_AUDIO_MUTE:
242 if (ctrl->value)
243 fmi_mute(fmi->port);
244 else
245 fmi_unmute(fmi->port);
246 fmi->curvol = ctrl->value;
247 return 0;
248 }
249 return -EINVAL;
258} 250}
259 251
260static int fmi_ioctl(struct inode *inode, struct file *file, 252static int vidioc_g_audio(struct file *file, void *priv,
261 unsigned int cmd, unsigned long arg) 253 struct v4l2_audio *a)
262{ 254{
263 return video_usercopy(inode, file, cmd, arg, fmi_do_ioctl); 255 if (a->index > 1)
256 return -EINVAL;
257
258 strcpy(a->name, "Radio");
259 a->capability = V4L2_AUDCAP_STEREO;
260 return 0;
261}
262
263static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
264{
265 *i = 0;
266 return 0;
267}
268
269static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
270{
271 if (i != 0)
272 return -EINVAL;
273 return 0;
274}
275
276static int vidioc_s_audio(struct file *file, void *priv,
277 struct v4l2_audio *a)
278{
279 if (a->index != 0)
280 return -EINVAL;
281 return 0;
264} 282}
265 283
266static struct fmi_device fmi_unit; 284static struct fmi_device fmi_unit;
@@ -269,7 +287,7 @@ static const struct file_operations fmi_fops = {
269 .owner = THIS_MODULE, 287 .owner = THIS_MODULE,
270 .open = video_exclusive_open, 288 .open = video_exclusive_open,
271 .release = video_exclusive_release, 289 .release = video_exclusive_release,
272 .ioctl = fmi_ioctl, 290 .ioctl = video_ioctl2,
273 .compat_ioctl = v4l_compat_ioctl32, 291 .compat_ioctl = v4l_compat_ioctl32,
274 .llseek = no_llseek, 292 .llseek = no_llseek,
275}; 293};
@@ -281,6 +299,18 @@ static struct video_device fmi_radio=
281 .type = VID_TYPE_TUNER, 299 .type = VID_TYPE_TUNER,
282 .hardware = 0, 300 .hardware = 0,
283 .fops = &fmi_fops, 301 .fops = &fmi_fops,
302 .vidioc_querycap = vidioc_querycap,
303 .vidioc_g_tuner = vidioc_g_tuner,
304 .vidioc_s_tuner = vidioc_s_tuner,
305 .vidioc_g_audio = vidioc_g_audio,
306 .vidioc_s_audio = vidioc_s_audio,
307 .vidioc_g_input = vidioc_g_input,
308 .vidioc_s_input = vidioc_s_input,
309 .vidioc_g_frequency = vidioc_g_frequency,
310 .vidioc_s_frequency = vidioc_s_frequency,
311 .vidioc_queryctrl = vidioc_queryctrl,
312 .vidioc_g_ctrl = vidioc_g_ctrl,
313 .vidioc_s_ctrl = vidioc_s_ctrl,
284}; 314};
285 315
286/* ladis: this is my card. does any other types exist? */ 316/* ladis: this is my card. does any other types exist? */
diff --git a/drivers/media/radio/radio-sf16fmr2.c b/drivers/media/radio/radio-sf16fmr2.c
index b96fafe1f9da..e6c125def5cb 100644
--- a/drivers/media/radio/radio-sf16fmr2.c
+++ b/drivers/media/radio/radio-sf16fmr2.c
@@ -226,186 +226,204 @@ static int fmr2_setvolume(struct fmr2_device *dev)
226 return 0; 226 return 0;
227} 227}
228 228
229static int fmr2_do_ioctl(struct inode *inode, struct file *file, 229static int vidioc_querycap(struct file *file, void *priv,
230 unsigned int cmd, void *arg) 230 struct v4l2_capability *v)
231{ 231{
232 strlcpy(v->driver, "radio-sf16fmr2", sizeof(v->driver));
233 strlcpy(v->card, "SF16-FMR2 radio", sizeof(v->card));
234 sprintf(v->bus_info, "ISA");
235 v->version = RADIO_VERSION;
236 v->capabilities = V4L2_CAP_TUNER;
237 return 0;
238}
239
240static int vidioc_g_tuner(struct file *file, void *priv,
241 struct v4l2_tuner *v)
242{
243 int mult;
232 struct video_device *dev = video_devdata(file); 244 struct video_device *dev = video_devdata(file);
233 struct fmr2_device *fmr2 = dev->priv; 245 struct fmr2_device *fmr2 = dev->priv;
234 debug_print((KERN_DEBUG "freq %ld flags %d vol %d mute %d "
235 "stereo %d type %d\n",
236 fmr2->curfreq, fmr2->flags, fmr2->curvol, fmr2->mute,
237 fmr2->stereo, fmr2->card_type));
238 246
239 switch(cmd) 247 if (v->index > 0)
240 { 248 return -EINVAL;
241 case VIDIOC_QUERYCAP:
242 {
243 struct v4l2_capability *v = arg;
244 memset(v,0,sizeof(*v));
245 strlcpy(v->driver, "radio-sf16fmr2", sizeof (v->driver));
246 strlcpy(v->card, "SF16-FMR2 radio", sizeof (v->card));
247 sprintf(v->bus_info,"ISA");
248 v->version = RADIO_VERSION;
249 v->capabilities = V4L2_CAP_TUNER;
250 249
251 return 0; 250 strcpy(v->name, "FM");
252 } 251 v->type = V4L2_TUNER_RADIO;
253 case VIDIOC_G_TUNER:
254 {
255 struct v4l2_tuner *v = arg;
256 int mult;
257
258 if (v->index > 0)
259 return -EINVAL;
260
261 memset(v,0,sizeof(*v));
262 strcpy(v->name, "FM");
263 v->type = V4L2_TUNER_RADIO;
264
265 mult = (fmr2->flags & V4L2_TUNER_CAP_LOW) ? 1 : 1000;
266 v->rangelow = RSF16_MINFREQ/mult;
267 v->rangehigh = RSF16_MAXFREQ/mult;
268 v->rxsubchans =V4L2_TUNER_SUB_MONO | V4L2_TUNER_MODE_STEREO;
269 v->capability=fmr2->flags&V4L2_TUNER_CAP_LOW;
270
271 v->audmode = fmr2->stereo ? V4L2_TUNER_MODE_STEREO:
272 V4L2_TUNER_MODE_MONO;
273 mutex_lock(&lock);
274 v->signal = fmr2_getsigstr(fmr2);
275 mutex_unlock(&lock);
276 252
277 return 0; 253 mult = (fmr2->flags & V4L2_TUNER_CAP_LOW) ? 1 : 1000;
278 } 254 v->rangelow = RSF16_MINFREQ/mult;
279 case VIDIOC_S_TUNER: 255 v->rangehigh = RSF16_MAXFREQ/mult;
280 { 256 v->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_MODE_STEREO;
281 struct v4l2_tuner *v = arg; 257 v->capability = fmr2->flags&V4L2_TUNER_CAP_LOW;
258 v->audmode = fmr2->stereo ? V4L2_TUNER_MODE_STEREO:
259 V4L2_TUNER_MODE_MONO;
260 mutex_lock(&lock);
261 v->signal = fmr2_getsigstr(fmr2);
262 mutex_unlock(&lock);
263 return 0;
264}
282 265
283 if (v->index > 0) 266static int vidioc_s_tuner(struct file *file, void *priv,
284 return -EINVAL; 267 struct v4l2_tuner *v)
268{
269 if (v->index > 0)
270 return -EINVAL;
271 return 0;
272}
285 273
286 return 0; 274static int vidioc_s_frequency(struct file *file, void *priv,
287 } 275 struct v4l2_frequency *f)
288 case VIDIOC_S_FREQUENCY: 276{
289 { 277 struct video_device *dev = video_devdata(file);
290 struct v4l2_frequency *f = arg; 278 struct fmr2_device *fmr2 = dev->priv;
291
292 if (!(fmr2->flags & V4L2_TUNER_CAP_LOW))
293 f->frequency *= 1000;
294 if (f->frequency < RSF16_MINFREQ ||
295 f->frequency > RSF16_MAXFREQ )
296 return -EINVAL;
297 /*rounding in steps of 200 to match th freq
298 that will be used */
299 fmr2->curfreq = (f->frequency/200)*200;
300
301 /* set card freq (if not muted) */
302 if (fmr2->curvol && !fmr2->mute)
303 {
304 mutex_lock(&lock);
305 fmr2_setfreq(fmr2);
306 mutex_unlock(&lock);
307 }
308 279
309 return 0; 280 if (!(fmr2->flags & V4L2_TUNER_CAP_LOW))
310 } 281 f->frequency *= 1000;
311 case VIDIOC_G_FREQUENCY: 282 if (f->frequency < RSF16_MINFREQ ||
312 { 283 f->frequency > RSF16_MAXFREQ )
313 struct v4l2_frequency *f = arg; 284 return -EINVAL;
285 /*rounding in steps of 200 to match th freq
286 that will be used */
287 fmr2->curfreq = (f->frequency/200)*200;
288
289 /* set card freq (if not muted) */
290 if (fmr2->curvol && !fmr2->mute) {
291 mutex_lock(&lock);
292 fmr2_setfreq(fmr2);
293 mutex_unlock(&lock);
294 }
295 return 0;
296}
297
298static int vidioc_g_frequency(struct file *file, void *priv,
299 struct v4l2_frequency *f)
300{
301 struct video_device *dev = video_devdata(file);
302 struct fmr2_device *fmr2 = dev->priv;
314 303
315 f->type = V4L2_TUNER_RADIO; 304 f->type = V4L2_TUNER_RADIO;
316 f->frequency = fmr2->curfreq; 305 f->frequency = fmr2->curfreq;
317 if (!(fmr2->flags & V4L2_TUNER_CAP_LOW)) 306 if (!(fmr2->flags & V4L2_TUNER_CAP_LOW))
318 f->frequency /= 1000; 307 f->frequency /= 1000;
308 return 0;
309}
319 310
311static int vidioc_queryctrl(struct file *file, void *priv,
312 struct v4l2_queryctrl *qc)
313{
314 int i;
315 struct video_device *dev = video_devdata(file);
316 struct fmr2_device *fmr2 = dev->priv;
317
318 for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
319 if ((fmr2->card_type != 11)
320 && V4L2_CID_AUDIO_VOLUME)
321 radio_qctrl[i].step = 65535;
322 if (qc->id && qc->id == radio_qctrl[i].id) {
323 memcpy(qc, &(radio_qctrl[i]),
324 sizeof(*qc));
320 return 0; 325 return 0;
321 } 326 }
322 case VIDIOC_QUERYCTRL: 327 }
323 { 328 return -EINVAL;
324 struct v4l2_queryctrl *qc = arg; 329}
325 int i; 330
326 331static int vidioc_g_ctrl(struct file *file, void *priv,
327 for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) { 332 struct v4l2_control *ctrl)
328 if ((fmr2->card_type != 11) 333{
329 && V4L2_CID_AUDIO_VOLUME) 334 struct video_device *dev = video_devdata(file);
330 radio_qctrl[i].step=65535; 335 struct fmr2_device *fmr2 = dev->priv;
331 if (qc->id && qc->id == radio_qctrl[i].id) { 336
332 memcpy(qc, &(radio_qctrl[i]), 337 switch (ctrl->id) {
333 sizeof(*qc)); 338 case V4L2_CID_AUDIO_MUTE:
334 return (0); 339 ctrl->value = fmr2->mute;
335 } 340 return 0;
336 } 341 case V4L2_CID_AUDIO_VOLUME:
337 return -EINVAL; 342 ctrl->value = fmr2->curvol;
343 return 0;
344 }
345 return -EINVAL;
346}
347
348static int vidioc_s_ctrl(struct file *file, void *priv,
349 struct v4l2_control *ctrl)
350{
351 struct video_device *dev = video_devdata(file);
352 struct fmr2_device *fmr2 = dev->priv;
353
354 switch (ctrl->id) {
355 case V4L2_CID_AUDIO_MUTE:
356 fmr2->mute = ctrl->value;
357 if (fmr2->card_type != 11) {
358 if (!fmr2->mute)
359 fmr2->curvol = 65535;
360 else
361 fmr2->curvol = 0;
338 } 362 }
339 case VIDIOC_G_CTRL: 363 break;
340 { 364 case V4L2_CID_AUDIO_VOLUME:
341 struct v4l2_control *ctrl= arg; 365 fmr2->curvol = ctrl->value;
342 366 if (fmr2->card_type != 11) {
343 switch (ctrl->id) { 367 if (fmr2->curvol) {
344 case V4L2_CID_AUDIO_MUTE: 368 fmr2->curvol = 65535;
345 ctrl->value=fmr2->mute; 369 fmr2->mute = 0;
346 return (0); 370 } else {
347 case V4L2_CID_AUDIO_VOLUME: 371 fmr2->curvol = 0;
348 ctrl->value=fmr2->curvol; 372 fmr2->mute = 1;
349 return (0);
350 } 373 }
351 return -EINVAL;
352 } 374 }
353 case VIDIOC_S_CTRL: 375 break;
354 { 376 default:
355 struct v4l2_control *ctrl= arg; 377 return -EINVAL;
356 378 }
357 switch (ctrl->id) { 379
358 case V4L2_CID_AUDIO_MUTE:
359 fmr2->mute=ctrl->value;
360 if (fmr2->card_type != 11) {
361 if (!fmr2->mute) {
362 fmr2->curvol = 65535;
363 } else {
364 fmr2->curvol = 0;
365 }
366 }
367 break;
368 case V4L2_CID_AUDIO_VOLUME:
369 fmr2->curvol = ctrl->value;
370 if (fmr2->card_type != 11) {
371 if (fmr2->curvol) {
372 fmr2->curvol = 65535;
373 fmr2->mute = 0;
374 } else {
375 fmr2->curvol = 0;
376 fmr2->mute = 1;
377 }
378 }
379 break;
380 default:
381 return -EINVAL;
382 }
383#ifdef DEBUG 380#ifdef DEBUG
384 if (fmr2->curvol && !fmr2->mute) 381 if (fmr2->curvol && !fmr2->mute)
385 printk(KERN_DEBUG "unmute\n"); 382 printk(KERN_DEBUG "unmute\n");
386 else 383 else
387 printk(KERN_DEBUG "mute\n"); 384 printk(KERN_DEBUG "mute\n");
388#endif 385#endif
389 mutex_lock(&lock);
390 if (fmr2->curvol && !fmr2->mute) {
391 fmr2_setvolume(fmr2);
392 fmr2_setfreq(fmr2);
393 } else
394 fmr2_mute(fmr2->port);
395 mutex_unlock(&lock);
396 return (0);
397 }
398 default:
399 return v4l_compat_translate_ioctl(inode,file,cmd,arg,
400 fmr2_do_ioctl);
401 386
402 } 387 mutex_lock(&lock);
388 if (fmr2->curvol && !fmr2->mute) {
389 fmr2_setvolume(fmr2);
390 fmr2_setfreq(fmr2);
391 } else
392 fmr2_mute(fmr2->port);
393 mutex_unlock(&lock);
394 return 0;
403} 395}
404 396
405static int fmr2_ioctl(struct inode *inode, struct file *file, 397static int vidioc_g_audio(struct file *file, void *priv,
406 unsigned int cmd, unsigned long arg) 398 struct v4l2_audio *a)
407 { 399{
408 return video_usercopy(inode, file, cmd, arg, fmr2_do_ioctl); 400 if (a->index > 1)
401 return -EINVAL;
402
403 strcpy(a->name, "Radio");
404 a->capability = V4L2_AUDCAP_STEREO;
405 return 0;
406}
407
408static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
409{
410 *i = 0;
411 return 0;
412}
413
414static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
415{
416 if (i != 0)
417 return -EINVAL;
418 return 0;
419}
420
421static int vidioc_s_audio(struct file *file, void *priv,
422 struct v4l2_audio *a)
423{
424 if (a->index != 0)
425 return -EINVAL;
426 return 0;
409} 427}
410 428
411static struct fmr2_device fmr2_unit; 429static struct fmr2_device fmr2_unit;
@@ -414,7 +432,7 @@ static const struct file_operations fmr2_fops = {
414 .owner = THIS_MODULE, 432 .owner = THIS_MODULE,
415 .open = video_exclusive_open, 433 .open = video_exclusive_open,
416 .release = video_exclusive_release, 434 .release = video_exclusive_release,
417 .ioctl = fmr2_ioctl, 435 .ioctl = video_ioctl2,
418 .compat_ioctl = v4l_compat_ioctl32, 436 .compat_ioctl = v4l_compat_ioctl32,
419 .llseek = no_llseek, 437 .llseek = no_llseek,
420}; 438};
@@ -426,6 +444,18 @@ static struct video_device fmr2_radio=
426 . type = VID_TYPE_TUNER, 444 . type = VID_TYPE_TUNER,
427 .hardware = 0, 445 .hardware = 0,
428 .fops = &fmr2_fops, 446 .fops = &fmr2_fops,
447 .vidioc_querycap = vidioc_querycap,
448 .vidioc_g_tuner = vidioc_g_tuner,
449 .vidioc_s_tuner = vidioc_s_tuner,
450 .vidioc_g_audio = vidioc_g_audio,
451 .vidioc_s_audio = vidioc_s_audio,
452 .vidioc_g_input = vidioc_g_input,
453 .vidioc_s_input = vidioc_s_input,
454 .vidioc_g_frequency = vidioc_g_frequency,
455 .vidioc_s_frequency = vidioc_s_frequency,
456 .vidioc_queryctrl = vidioc_queryctrl,
457 .vidioc_g_ctrl = vidioc_g_ctrl,
458 .vidioc_s_ctrl = vidioc_s_ctrl,
429}; 459};
430 460
431static int __init fmr2_init(void) 461static int __init fmr2_init(void)
diff --git a/drivers/media/radio/radio-terratec.c b/drivers/media/radio/radio-terratec.c
index d59a27accb84..e43acfd7e533 100644
--- a/drivers/media/radio/radio-terratec.c
+++ b/drivers/media/radio/radio-terratec.c
@@ -205,135 +205,152 @@ static int tt_getsigstr(struct tt_device *dev) /* TODO */
205 return 1; /* signal present */ 205 return 1; /* signal present */
206} 206}
207 207
208static int vidioc_querycap(struct file *file, void *priv,
209 struct v4l2_capability *v)
210{
211 strlcpy(v->driver, "radio-terratec", sizeof(v->driver));
212 strlcpy(v->card, "ActiveRadio", sizeof(v->card));
213 sprintf(v->bus_info, "ISA");
214 v->version = RADIO_VERSION;
215 v->capabilities = V4L2_CAP_TUNER;
216 return 0;
217}
208 218
209/* implement the video4linux api */ 219static int vidioc_g_tuner(struct file *file, void *priv,
210 220 struct v4l2_tuner *v)
211static int tt_do_ioctl(struct inode *inode, struct file *file,
212 unsigned int cmd, void *arg)
213{ 221{
214 struct video_device *dev = video_devdata(file); 222 struct video_device *dev = video_devdata(file);
215 struct tt_device *tt=dev->priv; 223 struct tt_device *tt = dev->priv;
216 224
217 switch(cmd) 225 if (v->index > 0)
218 { 226 return -EINVAL;
219 case VIDIOC_QUERYCAP:
220 {
221 struct v4l2_capability *v = arg;
222 memset(v,0,sizeof(*v));
223 strlcpy(v->driver, "radio-terratec", sizeof (v->driver));
224 strlcpy(v->card, "ActiveRadio", sizeof (v->card));
225 sprintf(v->bus_info,"ISA");
226 v->version = RADIO_VERSION;
227 v->capabilities = V4L2_CAP_TUNER;
228 227
229 return 0; 228 strcpy(v->name, "FM");
230 } 229 v->type = V4L2_TUNER_RADIO;
231 case VIDIOC_G_TUNER: 230 v->rangelow = (87*16000);
232 { 231 v->rangehigh = (108*16000);
233 struct v4l2_tuner *v = arg; 232 v->rxsubchans = V4L2_TUNER_SUB_MONO;
233 v->capability = V4L2_TUNER_CAP_LOW;
234 v->audmode = V4L2_TUNER_MODE_MONO;
235 v->signal = 0xFFFF*tt_getsigstr(tt);
236 return 0;
237}
234 238
235 if (v->index > 0) 239static int vidioc_s_tuner(struct file *file, void *priv,
236 return -EINVAL; 240 struct v4l2_tuner *v)
241{
242 if (v->index > 0)
243 return -EINVAL;
244 return 0;
245}
237 246
238 memset(v,0,sizeof(*v)); 247static int vidioc_s_frequency(struct file *file, void *priv,
239 strcpy(v->name, "FM"); 248 struct v4l2_frequency *f)
240 v->type = V4L2_TUNER_RADIO; 249{
250 struct video_device *dev = video_devdata(file);
251 struct tt_device *tt = dev->priv;
241 252
242 v->rangelow=(87*16000); 253 tt->curfreq = f->frequency;
243 v->rangehigh=(108*16000); 254 tt_setfreq(tt, tt->curfreq);
244 v->rxsubchans =V4L2_TUNER_SUB_MONO; 255 return 0;
245 v->capability=V4L2_TUNER_CAP_LOW; 256}
246 v->audmode = V4L2_TUNER_MODE_MONO;
247 v->signal=0xFFFF*tt_getsigstr(tt);
248 257
249 return 0; 258static int vidioc_g_frequency(struct file *file, void *priv,
250 } 259 struct v4l2_frequency *f)
251 case VIDIOC_S_TUNER: 260{
252 { 261 struct video_device *dev = video_devdata(file);
253 struct v4l2_tuner *v = arg; 262 struct tt_device *tt = dev->priv;
254 263
255 if (v->index > 0) 264 f->type = V4L2_TUNER_RADIO;
256 return -EINVAL; 265 f->frequency = tt->curfreq;
266 return 0;
267}
257 268
258 return 0; 269static int vidioc_queryctrl(struct file *file, void *priv,
259 } 270 struct v4l2_queryctrl *qc)
260 case VIDIOC_S_FREQUENCY: 271{
261 { 272 int i;
262 struct v4l2_frequency *f = arg;
263 273
264 tt->curfreq = f->frequency; 274 for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
265 tt_setfreq(tt, tt->curfreq); 275 if (qc->id && qc->id == radio_qctrl[i].id) {
276 memcpy(qc, &(radio_qctrl[i]),
277 sizeof(*qc));
266 return 0; 278 return 0;
267 } 279 }
268 case VIDIOC_G_FREQUENCY: 280 }
269 { 281 return -EINVAL;
270 struct v4l2_frequency *f = arg; 282}
271 283
272 f->type = V4L2_TUNER_RADIO; 284static int vidioc_g_ctrl(struct file *file, void *priv,
273 f->frequency = tt->curfreq; 285 struct v4l2_control *ctrl)
286{
287 struct video_device *dev = video_devdata(file);
288 struct tt_device *tt = dev->priv;
274 289
275 return 0; 290 switch (ctrl->id) {
276 } 291 case V4L2_CID_AUDIO_MUTE:
277 case VIDIOC_QUERYCTRL: 292 if (tt->muted)
278 { 293 ctrl->value = 1;
279 struct v4l2_queryctrl *qc = arg; 294 else
280 int i; 295 ctrl->value = 0;
281 296 return 0;
282 for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) { 297 case V4L2_CID_AUDIO_VOLUME:
283 if (qc->id && qc->id == radio_qctrl[i].id) { 298 ctrl->value = tt->curvol * 6554;
284 memcpy(qc, &(radio_qctrl[i]), 299 return 0;
285 sizeof(*qc)); 300 }
286 return (0); 301 return -EINVAL;
287 } 302}
288 }
289 return -EINVAL;
290 }
291 case VIDIOC_G_CTRL:
292 {
293 struct v4l2_control *ctrl= arg;
294
295 switch (ctrl->id) {
296 case V4L2_CID_AUDIO_MUTE:
297 if (tt->muted)
298 ctrl->value=1;
299 else
300 ctrl->value=0;
301 return (0);
302 case V4L2_CID_AUDIO_VOLUME:
303 ctrl->value=tt->curvol * 6554;
304 return (0);
305 }
306 return -EINVAL;
307 }
308 case VIDIOC_S_CTRL:
309 {
310 struct v4l2_control *ctrl= arg;
311
312 switch (ctrl->id) {
313 case V4L2_CID_AUDIO_MUTE:
314 if (ctrl->value) {
315 tt_mute(tt);
316 } else {
317 tt_setvol(tt,tt->curvol);
318 }
319 return (0);
320 case V4L2_CID_AUDIO_VOLUME:
321 tt_setvol(tt,ctrl->value);
322 return (0);
323 }
324 return -EINVAL;
325 }
326 303
327 default: 304static int vidioc_s_ctrl(struct file *file, void *priv,
328 return v4l_compat_translate_ioctl(inode,file,cmd,arg, 305 struct v4l2_control *ctrl)
329 tt_do_ioctl); 306{
307 struct video_device *dev = video_devdata(file);
308 struct tt_device *tt = dev->priv;
309
310 switch (ctrl->id) {
311 case V4L2_CID_AUDIO_MUTE:
312 if (ctrl->value)
313 tt_mute(tt);
314 else
315 tt_setvol(tt,tt->curvol);
316 return 0;
317 case V4L2_CID_AUDIO_VOLUME:
318 tt_setvol(tt,ctrl->value);
319 return 0;
330 } 320 }
321 return -EINVAL;
322}
323
324static int vidioc_g_audio(struct file *file, void *priv,
325 struct v4l2_audio *a)
326{
327 if (a->index > 1)
328 return -EINVAL;
329
330 strcpy(a->name, "Radio");
331 a->capability = V4L2_AUDCAP_STEREO;
332 return 0;
333}
334
335static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
336{
337 *i = 0;
338 return 0;
331} 339}
332 340
333static int tt_ioctl(struct inode *inode, struct file *file, 341static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
334 unsigned int cmd, unsigned long arg)
335{ 342{
336 return video_usercopy(inode, file, cmd, arg, tt_do_ioctl); 343 if (i != 0)
344 return -EINVAL;
345 return 0;
346}
347
348static int vidioc_s_audio(struct file *file, void *priv,
349 struct v4l2_audio *a)
350{
351 if (a->index != 0)
352 return -EINVAL;
353 return 0;
337} 354}
338 355
339static struct tt_device terratec_unit; 356static struct tt_device terratec_unit;
@@ -342,7 +359,7 @@ static const struct file_operations terratec_fops = {
342 .owner = THIS_MODULE, 359 .owner = THIS_MODULE,
343 .open = video_exclusive_open, 360 .open = video_exclusive_open,
344 .release = video_exclusive_release, 361 .release = video_exclusive_release,
345 .ioctl = tt_ioctl, 362 .ioctl = video_ioctl2,
346 .compat_ioctl = v4l_compat_ioctl32, 363 .compat_ioctl = v4l_compat_ioctl32,
347 .llseek = no_llseek, 364 .llseek = no_llseek,
348}; 365};
@@ -354,6 +371,18 @@ static struct video_device terratec_radio=
354 .type = VID_TYPE_TUNER, 371 .type = VID_TYPE_TUNER,
355 .hardware = 0, 372 .hardware = 0,
356 .fops = &terratec_fops, 373 .fops = &terratec_fops,
374 .vidioc_querycap = vidioc_querycap,
375 .vidioc_g_tuner = vidioc_g_tuner,
376 .vidioc_s_tuner = vidioc_s_tuner,
377 .vidioc_g_frequency = vidioc_g_frequency,
378 .vidioc_s_frequency = vidioc_s_frequency,
379 .vidioc_queryctrl = vidioc_queryctrl,
380 .vidioc_g_ctrl = vidioc_g_ctrl,
381 .vidioc_s_ctrl = vidioc_s_ctrl,
382 .vidioc_g_audio = vidioc_g_audio,
383 .vidioc_s_audio = vidioc_s_audio,
384 .vidioc_g_input = vidioc_g_input,
385 .vidioc_s_input = vidioc_s_input,
357}; 386};
358 387
359static int __init terratec_init(void) 388static int __init terratec_init(void)
diff --git a/drivers/media/radio/radio-trust.c b/drivers/media/radio/radio-trust.c
index 6d7f1e7116ea..c27c629d99df 100644
--- a/drivers/media/radio/radio-trust.c
+++ b/drivers/media/radio/radio-trust.c
@@ -192,144 +192,154 @@ static void tr_setfreq(unsigned long f)
192 write_i2c(5, TSA6060T_ADDR, (f << 1) | 1, f >> 7, 0x60 | ((f >> 15) & 1), 0); 192 write_i2c(5, TSA6060T_ADDR, (f << 1) | 1, f >> 7, 0x60 | ((f >> 15) & 1), 0);
193} 193}
194 194
195static int tr_do_ioctl(struct inode *inode, struct file *file, 195static int vidioc_querycap(struct file *file, void *priv,
196 unsigned int cmd, void *arg) 196 struct v4l2_capability *v)
197{ 197{
198 switch(cmd) 198 strlcpy(v->driver, "radio-trust", sizeof(v->driver));
199 { 199 strlcpy(v->card, "Trust FM Radio", sizeof(v->card));
200 case VIDIOC_QUERYCAP: 200 sprintf(v->bus_info, "ISA");
201 { 201 v->version = RADIO_VERSION;
202 struct v4l2_capability *v = arg; 202 v->capabilities = V4L2_CAP_TUNER;
203 memset(v,0,sizeof(*v)); 203 return 0;
204 strlcpy(v->driver, "radio-trust", sizeof (v->driver)); 204}
205 strlcpy(v->card, "Trust FM Radio", sizeof (v->card));
206 sprintf(v->bus_info,"ISA");
207 v->version = RADIO_VERSION;
208 v->capabilities = V4L2_CAP_TUNER;
209 205
210 return 0; 206static int vidioc_g_tuner(struct file *file, void *priv,
211 } 207 struct v4l2_tuner *v)
212 case VIDIOC_G_TUNER: 208{
213 { 209 if (v->index > 0)
214 struct v4l2_tuner *v = arg; 210 return -EINVAL;
215
216 if (v->index > 0)
217 return -EINVAL;
218
219 memset(v,0,sizeof(*v));
220 strcpy(v->name, "FM");
221 v->type = V4L2_TUNER_RADIO;
222
223 v->rangelow=(87.5*16000);
224 v->rangehigh=(108*16000);
225 v->rxsubchans =V4L2_TUNER_SUB_MONO|V4L2_TUNER_SUB_STEREO;
226 v->capability=V4L2_TUNER_CAP_LOW;
227 if(tr_getstereo())
228 v->audmode = V4L2_TUNER_MODE_STEREO;
229 else
230 v->audmode = V4L2_TUNER_MODE_MONO;
231 v->signal=tr_getsigstr();
232 211
233 return 0; 212 strcpy(v->name, "FM");
234 } 213 v->type = V4L2_TUNER_RADIO;
235 case VIDIOC_S_TUNER: 214 v->rangelow = (87.5*16000);
236 { 215 v->rangehigh = (108*16000);
237 struct v4l2_tuner *v = arg; 216 v->rxsubchans = V4L2_TUNER_SUB_MONO|V4L2_TUNER_SUB_STEREO;
217 v->capability = V4L2_TUNER_CAP_LOW;
218 if (tr_getstereo())
219 v->audmode = V4L2_TUNER_MODE_STEREO;
220 else
221 v->audmode = V4L2_TUNER_MODE_MONO;
222 v->signal = tr_getsigstr();
223 return 0;
224}
225
226static int vidioc_s_tuner(struct file *file, void *priv,
227 struct v4l2_tuner *v)
228{
229 if (v->index > 0)
230 return -EINVAL;
238 231
239 if (v->index > 0) 232 return 0;
240 return -EINVAL; 233}
241 234
242 return 0; 235static int vidioc_s_frequency(struct file *file, void *priv,
243 } 236 struct v4l2_frequency *f)
244 case VIDIOC_S_FREQUENCY: 237{
245 { 238 curfreq = f->frequency;
246 struct v4l2_frequency *f = arg; 239 tr_setfreq(curfreq);
240 return 0;
241}
247 242
248 curfreq = f->frequency; 243static int vidioc_g_frequency(struct file *file, void *priv,
249 tr_setfreq(curfreq); 244 struct v4l2_frequency *f)
250 return 0; 245{
251 } 246 f->type = V4L2_TUNER_RADIO;
252 case VIDIOC_G_FREQUENCY: 247 f->frequency = curfreq;
253 { 248 return 0;
254 struct v4l2_frequency *f = arg; 249}
255 250
256 f->type = V4L2_TUNER_RADIO; 251static int vidioc_queryctrl(struct file *file, void *priv,
257 f->frequency = curfreq; 252 struct v4l2_queryctrl *qc)
253{
254 int i;
258 255
256 for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
257 if (qc->id && qc->id == radio_qctrl[i].id) {
258 memcpy(qc, &(radio_qctrl[i]),
259 sizeof(*qc));
259 return 0; 260 return 0;
260 } 261 }
261 case VIDIOC_QUERYCTRL: 262 }
262 { 263 return -EINVAL;
263 struct v4l2_queryctrl *qc = arg; 264}
264 int i; 265
265 266static int vidioc_g_ctrl(struct file *file, void *priv,
266 for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) { 267 struct v4l2_control *ctrl)
267 if (qc->id && qc->id == radio_qctrl[i].id) { 268{
268 memcpy(qc, &(radio_qctrl[i]), 269 switch (ctrl->id) {
269 sizeof(*qc)); 270 case V4L2_CID_AUDIO_MUTE:
270 return (0); 271 ctrl->value = curmute;
271 } 272 return 0;
272 } 273 case V4L2_CID_AUDIO_VOLUME:
273 return -EINVAL; 274 ctrl->value = curvol * 2048;
274 } 275 return 0;
275 case VIDIOC_G_CTRL: 276 case V4L2_CID_AUDIO_BASS:
276 { 277 ctrl->value = curbass * 4370;
277 struct v4l2_control *ctrl= arg; 278 return 0;
278 279 case V4L2_CID_AUDIO_TREBLE:
279 switch (ctrl->id) { 280 ctrl->value = curtreble * 4370;
280 case V4L2_CID_AUDIO_MUTE: 281 return 0;
281 ctrl->value=curmute; 282 }
282 return (0); 283 return -EINVAL;
283 case V4L2_CID_AUDIO_VOLUME: 284}
284 ctrl->value= curvol * 2048;
285 return (0);
286 case V4L2_CID_AUDIO_BASS:
287 ctrl->value= curbass * 4370;
288 return (0);
289 case V4L2_CID_AUDIO_TREBLE:
290 ctrl->value= curtreble * 4370;
291 return (0);
292 }
293 return -EINVAL;
294 }
295 case VIDIOC_S_CTRL:
296 {
297 struct v4l2_control *ctrl= arg;
298
299 switch (ctrl->id) {
300 case V4L2_CID_AUDIO_MUTE:
301 tr_setmute(ctrl->value);
302 return 0;
303 case V4L2_CID_AUDIO_VOLUME:
304 tr_setvol(ctrl->value);
305 return 0;
306 case V4L2_CID_AUDIO_BASS:
307 tr_setbass(ctrl->value);
308 return 0;
309 case V4L2_CID_AUDIO_TREBLE:
310 tr_settreble(ctrl->value);
311 return (0);
312 }
313 return -EINVAL;
314 }
315 285
316 default: 286static int vidioc_s_ctrl(struct file *file, void *priv,
317 return v4l_compat_translate_ioctl(inode,file,cmd,arg, 287 struct v4l2_control *ctrl)
318 tr_do_ioctl); 288{
289 switch (ctrl->id) {
290 case V4L2_CID_AUDIO_MUTE:
291 tr_setmute(ctrl->value);
292 return 0;
293 case V4L2_CID_AUDIO_VOLUME:
294 tr_setvol(ctrl->value);
295 return 0;
296 case V4L2_CID_AUDIO_BASS:
297 tr_setbass(ctrl->value);
298 return 0;
299 case V4L2_CID_AUDIO_TREBLE:
300 tr_settreble(ctrl->value);
301 return 0;
319 } 302 }
303 return -EINVAL;
320} 304}
321 305
322static int tr_ioctl(struct inode *inode, struct file *file, 306static int vidioc_g_audio(struct file *file, void *priv,
323 unsigned int cmd, unsigned long arg) 307 struct v4l2_audio *a)
324{ 308{
325 return video_usercopy(inode, file, cmd, arg, tr_do_ioctl); 309 if (a->index > 1)
310 return -EINVAL;
311
312 strcpy(a->name, "Radio");
313 a->capability = V4L2_AUDCAP_STEREO;
314 return 0;
315}
316
317static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
318{
319 *i = 0;
320 return 0;
321}
322
323static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
324{
325 if (i != 0)
326 return -EINVAL;
327 return 0;
328}
329
330static int vidioc_s_audio(struct file *file, void *priv,
331 struct v4l2_audio *a)
332{
333 if (a->index != 0)
334 return -EINVAL;
335 return 0;
326} 336}
327 337
328static const struct file_operations trust_fops = { 338static const struct file_operations trust_fops = {
329 .owner = THIS_MODULE, 339 .owner = THIS_MODULE,
330 .open = video_exclusive_open, 340 .open = video_exclusive_open,
331 .release = video_exclusive_release, 341 .release = video_exclusive_release,
332 .ioctl = tr_ioctl, 342 .ioctl = video_ioctl2,
333 .compat_ioctl = v4l_compat_ioctl32, 343 .compat_ioctl = v4l_compat_ioctl32,
334 .llseek = no_llseek, 344 .llseek = no_llseek,
335}; 345};
@@ -341,6 +351,18 @@ static struct video_device trust_radio=
341 .type = VID_TYPE_TUNER, 351 .type = VID_TYPE_TUNER,
342 .hardware = 0, 352 .hardware = 0,
343 .fops = &trust_fops, 353 .fops = &trust_fops,
354 .vidioc_querycap = vidioc_querycap,
355 .vidioc_g_tuner = vidioc_g_tuner,
356 .vidioc_s_tuner = vidioc_s_tuner,
357 .vidioc_g_frequency = vidioc_g_frequency,
358 .vidioc_s_frequency = vidioc_s_frequency,
359 .vidioc_queryctrl = vidioc_queryctrl,
360 .vidioc_g_ctrl = vidioc_g_ctrl,
361 .vidioc_s_ctrl = vidioc_s_ctrl,
362 .vidioc_g_audio = vidioc_g_audio,
363 .vidioc_s_audio = vidioc_s_audio,
364 .vidioc_g_input = vidioc_g_input,
365 .vidioc_s_input = vidioc_s_input,
344}; 366};
345 367
346static int __init trust_init(void) 368static int __init trust_init(void)
diff --git a/drivers/media/radio/radio-typhoon.c b/drivers/media/radio/radio-typhoon.c
index 3031fef178cb..8ff5a23a9f01 100644
--- a/drivers/media/radio/radio-typhoon.c
+++ b/drivers/media/radio/radio-typhoon.c
@@ -93,8 +93,6 @@ static int typhoon_setfreq(struct typhoon_device *dev, unsigned long frequency);
93static void typhoon_mute(struct typhoon_device *dev); 93static void typhoon_mute(struct typhoon_device *dev);
94static void typhoon_unmute(struct typhoon_device *dev); 94static void typhoon_unmute(struct typhoon_device *dev);
95static int typhoon_setvol(struct typhoon_device *dev, int vol); 95static int typhoon_setvol(struct typhoon_device *dev, int vol);
96static int typhoon_ioctl(struct inode *inode, struct file *file,
97 unsigned int cmd, unsigned long arg);
98#ifdef CONFIG_RADIO_TYPHOON_PROC_FS 96#ifdef CONFIG_RADIO_TYPHOON_PROC_FS
99static int typhoon_get_info(char *buf, char **start, off_t offset, int len); 97static int typhoon_get_info(char *buf, char **start, off_t offset, int len);
100#endif 98#endif
@@ -186,129 +184,148 @@ static int typhoon_setvol(struct typhoon_device *dev, int vol)
186 return 0; 184 return 0;
187} 185}
188 186
187static int vidioc_querycap(struct file *file, void *priv,
188 struct v4l2_capability *v)
189{
190 strlcpy(v->driver, "radio-typhoon", sizeof(v->driver));
191 strlcpy(v->card, "Typhoon Radio", sizeof(v->card));
192 sprintf(v->bus_info, "ISA");
193 v->version = RADIO_VERSION;
194 v->capabilities = V4L2_CAP_TUNER;
195 return 0;
196}
197
198static int vidioc_g_tuner(struct file *file, void *priv,
199 struct v4l2_tuner *v)
200{
201 if (v->index > 0)
202 return -EINVAL;
203
204 strcpy(v->name, "FM");
205 v->type = V4L2_TUNER_RADIO;
206 v->rangelow = (87.5*16000);
207 v->rangehigh = (108*16000);
208 v->rxsubchans = V4L2_TUNER_SUB_MONO;
209 v->capability = V4L2_TUNER_CAP_LOW;
210 v->audmode = V4L2_TUNER_MODE_MONO;
211 v->signal = 0xFFFF; /* We can't get the signal strength */
212 return 0;
213}
189 214
190static int typhoon_do_ioctl(struct inode *inode, struct file *file, 215static int vidioc_s_tuner(struct file *file, void *priv,
191 unsigned int cmd, void *arg) 216 struct v4l2_tuner *v)
217{
218 if (v->index > 0)
219 return -EINVAL;
220
221 return 0;
222}
223
224static int vidioc_s_frequency(struct file *file, void *priv,
225 struct v4l2_frequency *f)
192{ 226{
193 struct video_device *dev = video_devdata(file); 227 struct video_device *dev = video_devdata(file);
194 struct typhoon_device *typhoon = dev->priv; 228 struct typhoon_device *typhoon = dev->priv;
195 229
196 switch (cmd) { 230 typhoon->curfreq = f->frequency;
197 case VIDIOC_QUERYCAP: 231 typhoon_setfreq(typhoon, typhoon->curfreq);
198 { 232 return 0;
199 struct v4l2_capability *v = arg; 233}
200 memset(v,0,sizeof(*v));
201 strlcpy(v->driver, "radio-typhoon", sizeof (v->driver));
202 strlcpy(v->card, "Typhoon Radio", sizeof (v->card));
203 sprintf(v->bus_info,"ISA");
204 v->version = RADIO_VERSION;
205 v->capabilities = V4L2_CAP_TUNER;
206 234
207 return 0; 235static int vidioc_g_frequency(struct file *file, void *priv,
208 } 236 struct v4l2_frequency *f)
209 case VIDIOC_G_TUNER: 237{
210 { 238 struct video_device *dev = video_devdata(file);
211 struct v4l2_tuner *v = arg; 239 struct typhoon_device *typhoon = dev->priv;
212 240
213 if (v->index > 0) 241 f->type = V4L2_TUNER_RADIO;
214 return -EINVAL; 242 f->frequency = typhoon->curfreq;
215 243
216 memset(v,0,sizeof(*v)); 244 return 0;
217 strcpy(v->name, "FM"); 245}
218 v->type = V4L2_TUNER_RADIO;
219 246
220 v->rangelow=(87.5*16000); 247static int vidioc_queryctrl(struct file *file, void *priv,
221 v->rangehigh=(108*16000); 248 struct v4l2_queryctrl *qc)
222 v->rxsubchans =V4L2_TUNER_SUB_MONO; 249{
223 v->capability=V4L2_TUNER_CAP_LOW; 250 int i;
224 v->audmode = V4L2_TUNER_MODE_MONO;
225 v->signal = 0xFFFF; /* We can't get the signal strength */
226 251
252 for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
253 if (qc->id && qc->id == radio_qctrl[i].id) {
254 memcpy(qc, &(radio_qctrl[i]),
255 sizeof(*qc));
227 return 0; 256 return 0;
228 } 257 }
229 case VIDIOC_S_TUNER: 258 }
230 { 259 return -EINVAL;
231 struct v4l2_tuner *v = arg; 260}
232 261
233 if (v->index > 0) 262static int vidioc_g_ctrl(struct file *file, void *priv,
234 return -EINVAL; 263 struct v4l2_control *ctrl)
264{
265 struct video_device *dev = video_devdata(file);
266 struct typhoon_device *typhoon = dev->priv;
235 267
236 return 0; 268 switch (ctrl->id) {
237 } 269 case V4L2_CID_AUDIO_MUTE:
238 case VIDIOC_S_FREQUENCY: 270 ctrl->value = typhoon->muted;
239 { 271 return 0;
240 struct v4l2_frequency *f = arg; 272 case V4L2_CID_AUDIO_VOLUME:
273 ctrl->value = typhoon->curvol;
274 return 0;
275 }
276 return -EINVAL;
277}
241 278
242 typhoon->curfreq = f->frequency; 279static int vidioc_s_ctrl (struct file *file, void *priv,
243 typhoon_setfreq(typhoon, typhoon->curfreq); 280 struct v4l2_control *ctrl)
244 return 0; 281{
245 } 282 struct video_device *dev = video_devdata(file);
246 case VIDIOC_G_FREQUENCY: 283 struct typhoon_device *typhoon = dev->priv;
247 {
248 struct v4l2_frequency *f = arg;
249 284
250 f->type = V4L2_TUNER_RADIO; 285 switch (ctrl->id) {
251 f->frequency = typhoon->curfreq; 286 case V4L2_CID_AUDIO_MUTE:
287 if (ctrl->value)
288 typhoon_mute(typhoon);
289 else
290 typhoon_unmute(typhoon);
291 return 0;
292 case V4L2_CID_AUDIO_VOLUME:
293 typhoon_setvol(typhoon, ctrl->value);
294 return 0;
295 }
296 return -EINVAL;
297}
252 298
253 return 0; 299static int vidioc_g_audio(struct file *file, void *priv,
254 } 300 struct v4l2_audio *a)
255 case VIDIOC_QUERYCTRL: 301{
256 { 302 if (a->index > 1)
257 struct v4l2_queryctrl *qc = arg; 303 return -EINVAL;
258 int i;
259
260 for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
261 if (qc->id && qc->id == radio_qctrl[i].id) {
262 memcpy(qc, &(radio_qctrl[i]),
263 sizeof(*qc));
264 return (0);
265 }
266 }
267 return -EINVAL;
268 }
269 case VIDIOC_G_CTRL:
270 {
271 struct v4l2_control *ctrl= arg;
272
273 switch (ctrl->id) {
274 case V4L2_CID_AUDIO_MUTE:
275 ctrl->value=typhoon->muted;
276 return (0);
277 case V4L2_CID_AUDIO_VOLUME:
278 ctrl->value=typhoon->curvol;
279 return (0);
280 }
281 return -EINVAL;
282 }
283 case VIDIOC_S_CTRL:
284 {
285 struct v4l2_control *ctrl= arg;
286
287 switch (ctrl->id) {
288 case V4L2_CID_AUDIO_MUTE:
289 if (ctrl->value) {
290 typhoon_mute(typhoon);
291 } else {
292 typhoon_unmute(typhoon);
293 }
294 return (0);
295 case V4L2_CID_AUDIO_VOLUME:
296 typhoon_setvol(typhoon, ctrl->value);
297 return (0);
298 }
299 return -EINVAL;
300 }
301 304
302 default: 305 strcpy(a->name, "Radio");
303 return v4l_compat_translate_ioctl(inode,file,cmd,arg, 306 a->capability = V4L2_AUDCAP_STEREO;
304 typhoon_do_ioctl); 307 return 0;
305 } 308}
309
310static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
311{
312 *i = 0;
313 return 0;
314}
315
316static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
317{
318 if (i != 0)
319 return -EINVAL;
320 return 0;
306} 321}
307 322
308static int typhoon_ioctl(struct inode *inode, struct file *file, 323static int vidioc_s_audio(struct file *file, void *priv,
309 unsigned int cmd, unsigned long arg) 324 struct v4l2_audio *a)
310{ 325{
311 return video_usercopy(inode, file, cmd, arg, typhoon_do_ioctl); 326 if (a->index != 0)
327 return -EINVAL;
328 return 0;
312} 329}
313 330
314static struct typhoon_device typhoon_unit = 331static struct typhoon_device typhoon_unit =
@@ -322,7 +339,7 @@ static const struct file_operations typhoon_fops = {
322 .owner = THIS_MODULE, 339 .owner = THIS_MODULE,
323 .open = video_exclusive_open, 340 .open = video_exclusive_open,
324 .release = video_exclusive_release, 341 .release = video_exclusive_release,
325 .ioctl = typhoon_ioctl, 342 .ioctl = video_ioctl2,
326 .compat_ioctl = v4l_compat_ioctl32, 343 .compat_ioctl = v4l_compat_ioctl32,
327 .llseek = no_llseek, 344 .llseek = no_llseek,
328}; 345};
@@ -334,6 +351,18 @@ static struct video_device typhoon_radio =
334 .type = VID_TYPE_TUNER, 351 .type = VID_TYPE_TUNER,
335 .hardware = 0, 352 .hardware = 0,
336 .fops = &typhoon_fops, 353 .fops = &typhoon_fops,
354 .vidioc_querycap = vidioc_querycap,
355 .vidioc_g_tuner = vidioc_g_tuner,
356 .vidioc_s_tuner = vidioc_s_tuner,
357 .vidioc_g_audio = vidioc_g_audio,
358 .vidioc_s_audio = vidioc_s_audio,
359 .vidioc_g_input = vidioc_g_input,
360 .vidioc_s_input = vidioc_s_input,
361 .vidioc_g_frequency = vidioc_g_frequency,
362 .vidioc_s_frequency = vidioc_s_frequency,
363 .vidioc_queryctrl = vidioc_queryctrl,
364 .vidioc_g_ctrl = vidioc_g_ctrl,
365 .vidioc_s_ctrl = vidioc_s_ctrl,
337}; 366};
338 367
339#ifdef CONFIG_RADIO_TYPHOON_PROC_FS 368#ifdef CONFIG_RADIO_TYPHOON_PROC_FS
diff --git a/drivers/media/radio/radio-zoltrix.c b/drivers/media/radio/radio-zoltrix.c
index ec08491fb7c5..a4715901512d 100644
--- a/drivers/media/radio/radio-zoltrix.c
+++ b/drivers/media/radio/radio-zoltrix.c
@@ -230,121 +230,123 @@ static int zol_is_stereo (struct zol_device *dev)
230 return 0; 230 return 0;
231} 231}
232 232
233static int zol_do_ioctl(struct inode *inode, struct file *file, 233static int vidioc_querycap(struct file *file, void *priv,
234 unsigned int cmd, void *arg) 234 struct v4l2_capability *v)
235{
236 strlcpy(v->driver, "radio-zoltrix", sizeof(v->driver));
237 strlcpy(v->card, "Zoltrix Radio", sizeof(v->card));
238 sprintf(v->bus_info, "ISA");
239 v->version = RADIO_VERSION;
240 v->capabilities = V4L2_CAP_TUNER;
241 return 0;
242}
243
244static int vidioc_g_tuner(struct file *file, void *priv,
245 struct v4l2_tuner *v)
235{ 246{
236 struct video_device *dev = video_devdata(file); 247 struct video_device *dev = video_devdata(file);
237 struct zol_device *zol = dev->priv; 248 struct zol_device *zol = dev->priv;
238 249
239 switch (cmd) { 250 if (v->index > 0)
240 case VIDIOC_QUERYCAP: 251 return -EINVAL;
241 {
242 struct v4l2_capability *v = arg;
243 memset(v,0,sizeof(*v));
244 strlcpy(v->driver, "radio-zoltrix", sizeof (v->driver));
245 strlcpy(v->card, "Zoltrix Radio", sizeof (v->card));
246 sprintf(v->bus_info,"ISA");
247 v->version = RADIO_VERSION;
248 v->capabilities = V4L2_CAP_TUNER;
249 252
250 return 0; 253 strcpy(v->name, "FM");
251 } 254 v->type = V4L2_TUNER_RADIO;
252 case VIDIOC_G_TUNER: 255 v->rangelow = (88*16000);
253 { 256 v->rangehigh = (108*16000);
254 struct v4l2_tuner *v = arg; 257 v->rxsubchans = V4L2_TUNER_SUB_MONO|V4L2_TUNER_SUB_STEREO;
255 258 v->capability = V4L2_TUNER_CAP_LOW;
256 if (v->index > 0) 259 if (zol_is_stereo(zol))
257 return -EINVAL; 260 v->audmode = V4L2_TUNER_MODE_STEREO;
258 261 else
259 memset(v,0,sizeof(*v)); 262 v->audmode = V4L2_TUNER_MODE_MONO;
260 strcpy(v->name, "FM"); 263 v->signal = 0xFFFF*zol_getsigstr(zol);
261 v->type = V4L2_TUNER_RADIO; 264 return 0;
262 265}
263 v->rangelow=(88*16000);
264 v->rangehigh=(108*16000);
265 v->rxsubchans =V4L2_TUNER_SUB_MONO|V4L2_TUNER_SUB_STEREO;
266 v->capability=V4L2_TUNER_CAP_LOW;
267 if(zol_is_stereo(zol))
268 v->audmode = V4L2_TUNER_MODE_STEREO;
269 else
270 v->audmode = V4L2_TUNER_MODE_MONO;
271 v->signal=0xFFFF*zol_getsigstr(zol);
272 266
273 return 0; 267static int vidioc_s_tuner(struct file *file, void *priv,
274 } 268 struct v4l2_tuner *v)
275 case VIDIOC_S_TUNER: 269{
276 { 270 if (v->index > 0)
277 struct v4l2_tuner *v = arg; 271 return -EINVAL;
272 return 0;
273}
278 274
279 if (v->index > 0) 275static int vidioc_s_frequency(struct file *file, void *priv,
280 return -EINVAL; 276 struct v4l2_frequency *f)
277{
278 struct video_device *dev = video_devdata(file);
279 struct zol_device *zol = dev->priv;
281 280
282 return 0; 281 zol->curfreq = f->frequency;
283 } 282 zol_setfreq(zol, zol->curfreq);
284 case VIDIOC_S_FREQUENCY: 283 return 0;
285 { 284}
286 struct v4l2_frequency *f = arg;
287 285
288 zol->curfreq = f->frequency; 286static int vidioc_g_frequency(struct file *file, void *priv,
289 zol_setfreq(zol, zol->curfreq); 287 struct v4l2_frequency *f)
290 return 0; 288{
291 } 289 struct video_device *dev = video_devdata(file);
292 case VIDIOC_G_FREQUENCY: 290 struct zol_device *zol = dev->priv;
293 { 291
294 struct v4l2_frequency *f = arg; 292 f->type = V4L2_TUNER_RADIO;
293 f->frequency = zol->curfreq;
294 return 0;
295}
295 296
296 f->type = V4L2_TUNER_RADIO; 297static int vidioc_queryctrl(struct file *file, void *priv,
297 f->frequency = zol->curfreq; 298 struct v4l2_queryctrl *qc)
299{
300 int i;
298 301
302 for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
303 if (qc->id && qc->id == radio_qctrl[i].id) {
304 memcpy(qc, &(radio_qctrl[i]),
305 sizeof(*qc));
299 return 0; 306 return 0;
300 } 307 }
301 case VIDIOC_QUERYCTRL: 308 }
302 { 309 return -EINVAL;
303 struct v4l2_queryctrl *qc = arg; 310}
304 int i; 311
305 312static int vidioc_g_ctrl(struct file *file, void *priv,
306 for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) { 313 struct v4l2_control *ctrl)
307 if (qc->id && qc->id == radio_qctrl[i].id) { 314{
308 memcpy(qc, &(radio_qctrl[i]), 315 struct video_device *dev = video_devdata(file);
309 sizeof(*qc)); 316 struct zol_device *zol = dev->priv;
310 return (0); 317
311 } 318 switch (ctrl->id) {
312 } 319 case V4L2_CID_AUDIO_MUTE:
313 return -EINVAL; 320 ctrl->value = zol->muted;
314 } 321 return 0;
315 case VIDIOC_G_CTRL: 322 case V4L2_CID_AUDIO_VOLUME:
316 { 323 ctrl->value = zol->curvol * 4096;
317 struct v4l2_control *ctrl= arg; 324 return 0;
318 325 }
319 switch (ctrl->id) { 326 return -EINVAL;
320 case V4L2_CID_AUDIO_MUTE: 327}
321 ctrl->value=zol->muted; 328
322 return (0); 329static int vidioc_s_ctrl(struct file *file, void *priv,
323 case V4L2_CID_AUDIO_VOLUME: 330 struct v4l2_control *ctrl)
324 ctrl->value=zol->curvol * 4096; 331{
325 return (0); 332 struct video_device *dev = video_devdata(file);
326 } 333 struct zol_device *zol = dev->priv;
327 return -EINVAL; 334
335 switch (ctrl->id) {
336 case V4L2_CID_AUDIO_MUTE:
337 if (ctrl->value)
338 zol_mute(zol);
339 else {
340 zol_unmute(zol);
341 zol_setvol(zol,zol->curvol);
328 } 342 }
329 case VIDIOC_S_CTRL: 343 return 0;
330 { 344 case V4L2_CID_AUDIO_VOLUME:
331 struct v4l2_control *ctrl= arg; 345 zol_setvol(zol,ctrl->value/4096);
332 346 return 0;
333 switch (ctrl->id) { 347 }
334 case V4L2_CID_AUDIO_MUTE: 348 zol->stereo = 1;
335 if (ctrl->value) { 349 zol_setfreq(zol, zol->curfreq);
336 zol_mute(zol);
337 } else {
338 zol_unmute(zol);
339 zol_setvol(zol,zol->curvol);
340 }
341 return (0);
342 case V4L2_CID_AUDIO_VOLUME:
343 zol_setvol(zol,ctrl->value/4096);
344 return (0);
345 }
346 zol->stereo = 1;
347 zol_setfreq(zol, zol->curfreq);
348#if 0 350#if 0
349/* FIXME: Implement stereo/mono switch on V4L2 */ 351/* FIXME: Implement stereo/mono switch on V4L2 */
350 if (v->mode & VIDEO_SOUND_STEREO) { 352 if (v->mode & VIDEO_SOUND_STEREO) {
@@ -356,19 +358,39 @@ static int zol_do_ioctl(struct inode *inode, struct file *file,
356 zol_setfreq(zol, zol->curfreq); 358 zol_setfreq(zol, zol->curfreq);
357 } 359 }
358#endif 360#endif
359 return -EINVAL; 361 return -EINVAL;
360 } 362}
361 363
362 default: 364static int vidioc_g_audio(struct file *file, void *priv,
363 return v4l_compat_translate_ioctl(inode,file,cmd,arg, 365 struct v4l2_audio *a)
364 zol_do_ioctl); 366{
365 } 367 if (a->index > 1)
368 return -EINVAL;
369
370 strcpy(a->name, "Radio");
371 a->capability = V4L2_AUDCAP_STEREO;
372 return 0;
373}
374
375static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
376{
377 *i = 0;
378 return 0;
366} 379}
367 380
368static int zol_ioctl(struct inode *inode, struct file *file, 381static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
369 unsigned int cmd, unsigned long arg)
370{ 382{
371 return video_usercopy(inode, file, cmd, arg, zol_do_ioctl); 383 if (i != 0)
384 return -EINVAL;
385 return 0;
386}
387
388static int vidioc_s_audio(struct file *file, void *priv,
389 struct v4l2_audio *a)
390{
391 if (a->index != 0)
392 return -EINVAL;
393 return 0;
372} 394}
373 395
374static struct zol_device zoltrix_unit; 396static struct zol_device zoltrix_unit;
@@ -378,7 +400,7 @@ static const struct file_operations zoltrix_fops =
378 .owner = THIS_MODULE, 400 .owner = THIS_MODULE,
379 .open = video_exclusive_open, 401 .open = video_exclusive_open,
380 .release = video_exclusive_release, 402 .release = video_exclusive_release,
381 .ioctl = zol_ioctl, 403 .ioctl = video_ioctl2,
382 .compat_ioctl = v4l_compat_ioctl32, 404 .compat_ioctl = v4l_compat_ioctl32,
383 .llseek = no_llseek, 405 .llseek = no_llseek,
384}; 406};
@@ -390,6 +412,18 @@ static struct video_device zoltrix_radio =
390 .type = VID_TYPE_TUNER, 412 .type = VID_TYPE_TUNER,
391 .hardware = 0, 413 .hardware = 0,
392 .fops = &zoltrix_fops, 414 .fops = &zoltrix_fops,
415 .vidioc_querycap = vidioc_querycap,
416 .vidioc_g_tuner = vidioc_g_tuner,
417 .vidioc_s_tuner = vidioc_s_tuner,
418 .vidioc_g_audio = vidioc_g_audio,
419 .vidioc_s_audio = vidioc_s_audio,
420 .vidioc_g_input = vidioc_g_input,
421 .vidioc_s_input = vidioc_s_input,
422 .vidioc_g_frequency = vidioc_g_frequency,
423 .vidioc_s_frequency = vidioc_s_frequency,
424 .vidioc_queryctrl = vidioc_queryctrl,
425 .vidioc_g_ctrl = vidioc_g_ctrl,
426 .vidioc_s_ctrl = vidioc_s_ctrl,
393}; 427};
394 428
395static int __init zoltrix_init(void) 429static int __init zoltrix_init(void)
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index 7a6105153f23..639e8b6c35b1 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -647,6 +647,8 @@ config VIDEO_HEXIUM_GEMINI
647 647
648source "drivers/media/video/cx88/Kconfig" 648source "drivers/media/video/cx88/Kconfig"
649 649
650source "drivers/media/video/ivtv/Kconfig"
651
650config VIDEO_M32R_AR 652config VIDEO_M32R_AR
651 tristate "AR devices" 653 tristate "AR devices"
652 depends on M32R && VIDEO_V4L1 654 depends on M32R && VIDEO_V4L1
@@ -761,6 +763,18 @@ source "drivers/media/video/zc0301/Kconfig"
761 763
762source "drivers/media/video/pwc/Kconfig" 764source "drivers/media/video/pwc/Kconfig"
763 765
766config USB_ZR364XX
767 tristate "USB ZR364XX Camera support"
768 depends on USB && VIDEO_V4L2
769 ---help---
770 Say Y here if you want to connect this type of camera to your
771 computer's USB port.
772 See <file:Documentation/video4linux/zr364xx.txt> for more info
773 and list of supported cameras.
774
775 To compile this driver as a module, choose M here: the
776 module will be called zr364xx.
777
764endmenu # V4L USB devices 778endmenu # V4L USB devices
765 779
766endmenu 780endmenu
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile
index 44ccaed40b49..9c2de501612f 100644
--- a/drivers/media/video/Makefile
+++ b/drivers/media/video/Makefile
@@ -61,6 +61,7 @@ obj-$(CONFIG_VIDEO_CPIA_USB) += cpia_usb.o
61obj-$(CONFIG_VIDEO_MEYE) += meye.o 61obj-$(CONFIG_VIDEO_MEYE) += meye.o
62obj-$(CONFIG_VIDEO_SAA7134) += ir-kbd-i2c.o saa7134/ 62obj-$(CONFIG_VIDEO_SAA7134) += ir-kbd-i2c.o saa7134/
63obj-$(CONFIG_VIDEO_CX88) += cx88/ 63obj-$(CONFIG_VIDEO_CX88) += cx88/
64obj-$(CONFIG_VIDEO_IVTV) += ivtv/
64obj-$(CONFIG_VIDEO_EM28XX) += em28xx/ 65obj-$(CONFIG_VIDEO_EM28XX) += em28xx/
65obj-$(CONFIG_VIDEO_USBVISION) += usbvision/ 66obj-$(CONFIG_VIDEO_USBVISION) += usbvision/
66obj-$(CONFIG_VIDEO_TVP5150) += tvp5150.o 67obj-$(CONFIG_VIDEO_TVP5150) += tvp5150.o
@@ -99,6 +100,7 @@ obj-$(CONFIG_USB_OV511) += ov511.o
99obj-$(CONFIG_USB_SE401) += se401.o 100obj-$(CONFIG_USB_SE401) += se401.o
100obj-$(CONFIG_USB_STV680) += stv680.o 101obj-$(CONFIG_USB_STV680) += stv680.o
101obj-$(CONFIG_USB_W9968CF) += w9968cf.o 102obj-$(CONFIG_USB_W9968CF) += w9968cf.o
103obj-$(CONFIG_USB_ZR364XX) += zr364xx.o
102 104
103obj-$(CONFIG_USB_SN9C102) += sn9c102/ 105obj-$(CONFIG_USB_SN9C102) += sn9c102/
104obj-$(CONFIG_USB_ET61X251) += et61x251/ 106obj-$(CONFIG_USB_ET61X251) += et61x251/
diff --git a/drivers/media/video/bt8xx/bttv-cards.c b/drivers/media/video/bt8xx/bttv-cards.c
index 6addc42df045..6b31e50fb951 100644
--- a/drivers/media/video/bt8xx/bttv-cards.c
+++ b/drivers/media/video/bt8xx/bttv-cards.c
@@ -291,6 +291,9 @@ static struct CARD {
291 291
292 { 0x15409511, BTTV_BOARD_ACORP_Y878F, "Acorp Y878F" }, 292 { 0x15409511, BTTV_BOARD_ACORP_Y878F, "Acorp Y878F" },
293 293
294 { 0x53534149, BTTV_BOARD_SSAI_SECURITY, "SSAI Security Video Interface" },
295 { 0x5353414a, BTTV_BOARD_SSAI_ULTRASOUND, "SSAI Ultrasound Video Interface" },
296
294 /* likely broken, vendor id doesn't match the other magic views ... 297 /* likely broken, vendor id doesn't match the other magic views ...
295 * { 0xa0fca04f, BTTV_BOARD_MAGICTVIEW063, "Guillemot Maxi TV Video 3" }, */ 298 * { 0xa0fca04f, BTTV_BOARD_MAGICTVIEW063, "Guillemot Maxi TV Video 3" }, */
296 299
@@ -2907,6 +2910,28 @@ struct tvcard bttv_tvcards[] = {
2907 .has_radio = 1, 2910 .has_radio = 1,
2908 .has_remote = 1, 2911 .has_remote = 1,
2909 }, 2912 },
2913 [BTTV_BOARD_SSAI_SECURITY] = {
2914 .name = "SSAI Security Video Interface",
2915 .video_inputs = 4,
2916 .audio_inputs = 0,
2917 .tuner = -1,
2918 .svhs = -1,
2919 .muxsel = { 0, 1, 2, 3 },
2920 .tuner_type = -1,
2921 .tuner_addr = ADDR_UNSET,
2922 .radio_addr = ADDR_UNSET,
2923 },
2924 [BTTV_BOARD_SSAI_ULTRASOUND] = {
2925 .name = "SSAI Ultrasound Video Interface",
2926 .video_inputs = 2,
2927 .audio_inputs = 0,
2928 .tuner = -1,
2929 .svhs = 1,
2930 .muxsel = { 2, 0, 1, 3 },
2931 .tuner_type = -1,
2932 .tuner_addr = ADDR_UNSET,
2933 .radio_addr = ADDR_UNSET,
2934 },
2910}; 2935};
2911 2936
2912static const unsigned int bttv_num_tvcards = ARRAY_SIZE(bttv_tvcards); 2937static const unsigned int bttv_num_tvcards = ARRAY_SIZE(bttv_tvcards);
@@ -2970,20 +2995,20 @@ void __devinit bttv_idcard(struct bttv *btv)
2970 2995
2971 if (UNSET != audiomux[0]) { 2996 if (UNSET != audiomux[0]) {
2972 gpiobits = 0; 2997 gpiobits = 0;
2973 for (i = 0; i < 4; i++) { 2998 for (i = 0; i < ARRAY_SIZE(bttv_tvcards->gpiomux); i++) {
2974 bttv_tvcards[btv->c.type].gpiomux[i] = audiomux[i]; 2999 bttv_tvcards[btv->c.type].gpiomux[i] = audiomux[i];
2975 gpiobits |= audiomux[i]; 3000 gpiobits |= audiomux[i];
2976 } 3001 }
2977 } else { 3002 } else {
2978 gpiobits = audioall; 3003 gpiobits = audioall;
2979 for (i = 0; i < 4; i++) { 3004 for (i = 0; i < ARRAY_SIZE(bttv_tvcards->gpiomux); i++) {
2980 bttv_tvcards[btv->c.type].gpiomux[i] = audioall; 3005 bttv_tvcards[btv->c.type].gpiomux[i] = audioall;
2981 } 3006 }
2982 } 3007 }
2983 bttv_tvcards[btv->c.type].gpiomask = (UNSET != gpiomask) ? gpiomask : gpiobits; 3008 bttv_tvcards[btv->c.type].gpiomask = (UNSET != gpiomask) ? gpiomask : gpiobits;
2984 printk(KERN_INFO "bttv%d: gpio config override: mask=0x%x, mux=", 3009 printk(KERN_INFO "bttv%d: gpio config override: mask=0x%x, mux=",
2985 btv->c.nr,bttv_tvcards[btv->c.type].gpiomask); 3010 btv->c.nr,bttv_tvcards[btv->c.type].gpiomask);
2986 for (i = 0; i < 5; i++) { 3011 for (i = 0; i < ARRAY_SIZE(bttv_tvcards->gpiomux); i++) {
2987 printk("%s0x%x", i ? "," : "", bttv_tvcards[btv->c.type].gpiomux[i]); 3012 printk("%s0x%x", i ? "," : "", bttv_tvcards[btv->c.type].gpiomux[i]);
2988 } 3013 }
2989 printk("\n"); 3014 printk("\n");
@@ -3638,7 +3663,7 @@ static int __devinit pvr_altera_load(struct bttv *btv, u8 *micro, u32 microlen)
3638 3663
3639 for (n = 0; n < microlen; n++) { 3664 for (n = 0; n < microlen; n++) {
3640 bits = micro[n]; 3665 bits = micro[n];
3641 for ( i = 0 ; i < 8 ; i++ ) { 3666 for (i = 0 ; i < 8 ; i++) {
3642 gpio_bits(BTTV_ALT_DCLK,0); 3667 gpio_bits(BTTV_ALT_DCLK,0);
3643 if (bits & 0x01) 3668 if (bits & 0x01)
3644 gpio_bits(BTTV_ALT_DATA,BTTV_ALT_DATA); 3669 gpio_bits(BTTV_ALT_DATA,BTTV_ALT_DATA);
@@ -3691,7 +3716,7 @@ static void __devinit osprey_eeprom(struct bttv *btv)
3691 /* this might be an antique... check for MMAC label in eeprom */ 3716 /* this might be an antique... check for MMAC label in eeprom */
3692 if ((ee[0]=='M') && (ee[1]=='M') && (ee[2]=='A') && (ee[3]=='C')) { 3717 if ((ee[0]=='M') && (ee[1]=='M') && (ee[2]=='A') && (ee[3]=='C')) {
3693 unsigned char checksum = 0; 3718 unsigned char checksum = 0;
3694 for (i =0; i<21; i++) 3719 for (i = 0; i < 21; i++)
3695 checksum += ee[i]; 3720 checksum += ee[i];
3696 if (checksum != ee[21]) 3721 if (checksum != ee[21])
3697 return; 3722 return;
@@ -3703,12 +3728,13 @@ static void __devinit osprey_eeprom(struct bttv *btv)
3703 unsigned short type; 3728 unsigned short type;
3704 int offset = 4*16; 3729 int offset = 4*16;
3705 3730
3706 for(; offset < 8*16; offset += 16) { 3731 for (; offset < 8*16; offset += 16) {
3707 unsigned short checksum = 0; 3732 unsigned short checksum = 0;
3708 /* verify the checksum */ 3733 /* verify the checksum */
3709 for(i = 0; i<14; i++) checksum += ee[i+offset]; 3734 for (i = 0; i < 14; i++)
3710 checksum = ~checksum; /* no idea why */ 3735 checksum += ee[i+offset];
3711 if ((((checksum>>8)&0x0FF) == ee[offset+14]) && 3736 checksum = ~checksum; /* no idea why */
3737 if ((((checksum>>8)&0x0FF) == ee[offset+14]) &&
3712 ((checksum & 0x0FF) == ee[offset+15])) { 3738 ((checksum & 0x0FF) == ee[offset+15])) {
3713 break; 3739 break;
3714 } 3740 }
@@ -3721,7 +3747,6 @@ static void __devinit osprey_eeprom(struct bttv *btv)
3721 type = (ee[offset+4]<<8) | (ee[offset+5]); 3747 type = (ee[offset+4]<<8) | (ee[offset+5]);
3722 3748
3723 switch(type) { 3749 switch(type) {
3724
3725 /* 848 based */ 3750 /* 848 based */
3726 case 0x0004: 3751 case 0x0004:
3727 btv->c.type = BTTV_BOARD_OSPREY1x0_848; 3752 btv->c.type = BTTV_BOARD_OSPREY1x0_848;
@@ -4149,8 +4174,7 @@ static int tea5757_read(struct bttv *btv)
4149 } 4174 }
4150 4175
4151 dprintk("bttv%d: tea5757:",btv->c.nr); 4176 dprintk("bttv%d: tea5757:",btv->c.nr);
4152 for(i = 0; i < 24; i++) 4177 for (i = 0; i < 24; i++) {
4153 {
4154 udelay(5); 4178 udelay(5);
4155 bus_high(btv,btv->mbox_clk); 4179 bus_high(btv,btv->mbox_clk);
4156 udelay(5); 4180 udelay(5);
@@ -4182,8 +4206,7 @@ static int tea5757_write(struct bttv *btv, int value)
4182 dprintk("bttv%d: tea5757: write 0x%X\n", btv->c.nr, value); 4206 dprintk("bttv%d: tea5757: write 0x%X\n", btv->c.nr, value);
4183 bus_low(btv,btv->mbox_clk); 4207 bus_low(btv,btv->mbox_clk);
4184 bus_high(btv,btv->mbox_we); 4208 bus_high(btv,btv->mbox_we);
4185 for(i = 0; i < 25; i++) 4209 for (i = 0; i < 25; i++) {
4186 {
4187 if (reg & 0x1000000) 4210 if (reg & 0x1000000)
4188 bus_high(btv,btv->mbox_data); 4211 bus_high(btv,btv->mbox_data);
4189 else 4212 else
@@ -4755,7 +4778,7 @@ static void kodicom4400r_init(struct bttv *btv)
4755 gpio_write(1 << 9); /* reset MUX */ 4778 gpio_write(1 << 9); /* reset MUX */
4756 gpio_write(0); 4779 gpio_write(0);
4757 /* Preset camera 0 to the 4 controllers */ 4780 /* Preset camera 0 to the 4 controllers */
4758 for (ix=0; ix<4; ix++) { 4781 for (ix = 0; ix < 4; ix++) {
4759 sw_status[ix] = ix; 4782 sw_status[ix] = ix;
4760 kodicom4400r_write(btv, ix, ix, 1); 4783 kodicom4400r_write(btv, ix, ix, 1);
4761 } 4784 }
diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c
index 5720b77ac9a7..1c38723d3169 100644
--- a/drivers/media/video/bt8xx/bttv-driver.c
+++ b/drivers/media/video/bt8xx/bttv-driver.c
@@ -164,6 +164,24 @@ static ssize_t show_card(struct class_device *cd, char *buf)
164static CLASS_DEVICE_ATTR(card, S_IRUGO, show_card, NULL); 164static CLASS_DEVICE_ATTR(card, S_IRUGO, show_card, NULL);
165 165
166/* ----------------------------------------------------------------------- */ 166/* ----------------------------------------------------------------------- */
167/* dvb auto-load setup */
168#if defined(CONFIG_MODULES) && defined(MODULE)
169static void request_module_async(struct work_struct *work)
170{
171 request_module("dvb-bt8xx");
172}
173
174static void request_modules(struct bttv *dev)
175{
176 INIT_WORK(&dev->request_module_wk, request_module_async);
177 schedule_work(&dev->request_module_wk);
178}
179#else
180#define request_modules(dev)
181#endif /* CONFIG_MODULES */
182
183
184/* ----------------------------------------------------------------------- */
167/* static data */ 185/* static data */
168 186
169/* special timing tables from conexant... */ 187/* special timing tables from conexant... */
@@ -4769,9 +4787,11 @@ static int __devinit bttv_probe(struct pci_dev *dev,
4769 disclaim_video_lines(btv); 4787 disclaim_video_lines(btv);
4770 } 4788 }
4771 4789
4772 /* add subdevices */ 4790 /* add subdevices and autoload dvb-bt8xx if needed */
4773 if (bttv_tvcards[btv->c.type].has_dvb) 4791 if (bttv_tvcards[btv->c.type].has_dvb) {
4774 bttv_sub_add_device(&btv->c, "dvb"); 4792 bttv_sub_add_device(&btv->c, "dvb");
4793 request_modules(btv);
4794 }
4775 4795
4776 bttv_input_init(btv); 4796 bttv_input_init(btv);
4777 4797
diff --git a/drivers/media/video/bt8xx/bttv-gpio.c b/drivers/media/video/bt8xx/bttv-gpio.c
index ba081f6f8c82..84154c26f9c5 100644
--- a/drivers/media/video/bt8xx/bttv-gpio.c
+++ b/drivers/media/video/bt8xx/bttv-gpio.c
@@ -71,7 +71,6 @@ struct bus_type bttv_sub_bus_type = {
71 .probe = bttv_sub_probe, 71 .probe = bttv_sub_probe,
72 .remove = bttv_sub_remove, 72 .remove = bttv_sub_remove,
73}; 73};
74EXPORT_SYMBOL(bttv_sub_bus_type);
75 74
76static void release_sub_device(struct device *dev) 75static void release_sub_device(struct device *dev)
77{ 76{
@@ -152,7 +151,6 @@ void bttv_gpio_inout(struct bttv_core *core, u32 mask, u32 outbits)
152 btwrite(data,BT848_GPIO_OUT_EN); 151 btwrite(data,BT848_GPIO_OUT_EN);
153 spin_unlock_irqrestore(&btv->gpio_lock,flags); 152 spin_unlock_irqrestore(&btv->gpio_lock,flags);
154} 153}
155EXPORT_SYMBOL(bttv_gpio_inout);
156 154
157u32 bttv_gpio_read(struct bttv_core *core) 155u32 bttv_gpio_read(struct bttv_core *core)
158{ 156{
@@ -162,7 +160,6 @@ u32 bttv_gpio_read(struct bttv_core *core)
162 value = btread(BT848_GPIO_DATA); 160 value = btread(BT848_GPIO_DATA);
163 return value; 161 return value;
164} 162}
165EXPORT_SYMBOL(bttv_gpio_read);
166 163
167void bttv_gpio_write(struct bttv_core *core, u32 value) 164void bttv_gpio_write(struct bttv_core *core, u32 value)
168{ 165{
@@ -170,7 +167,6 @@ void bttv_gpio_write(struct bttv_core *core, u32 value)
170 167
171 btwrite(value,BT848_GPIO_DATA); 168 btwrite(value,BT848_GPIO_DATA);
172} 169}
173EXPORT_SYMBOL(bttv_gpio_write);
174 170
175void bttv_gpio_bits(struct bttv_core *core, u32 mask, u32 bits) 171void bttv_gpio_bits(struct bttv_core *core, u32 mask, u32 bits)
176{ 172{
@@ -185,7 +181,6 @@ void bttv_gpio_bits(struct bttv_core *core, u32 mask, u32 bits)
185 btwrite(data,BT848_GPIO_DATA); 181 btwrite(data,BT848_GPIO_DATA);
186 spin_unlock_irqrestore(&btv->gpio_lock,flags); 182 spin_unlock_irqrestore(&btv->gpio_lock,flags);
187} 183}
188EXPORT_SYMBOL(bttv_gpio_bits);
189 184
190/* 185/*
191 * Local variables: 186 * Local variables:
diff --git a/drivers/media/video/bt8xx/bttv-i2c.c b/drivers/media/video/bt8xx/bttv-i2c.c
index 62b873076e09..0dfa49b66418 100644
--- a/drivers/media/video/bt8xx/bttv-i2c.c
+++ b/drivers/media/video/bt8xx/bttv-i2c.c
@@ -412,7 +412,7 @@ static void do_i2c_scan(char *name, struct i2c_client *c)
412 unsigned char buf; 412 unsigned char buf;
413 int i,rc; 413 int i,rc;
414 414
415 for (i = 0; i < 128; i++) { 415 for (i = 0; i < ARRAY_SIZE(i2c_devs); i++) {
416 c->addr = i; 416 c->addr = i;
417 rc = i2c_master_recv(c,&buf,0); 417 rc = i2c_master_recv(c,&buf,0);
418 if (rc < 0) 418 if (rc < 0)
diff --git a/drivers/media/video/bt8xx/bttv-if.c b/drivers/media/video/bt8xx/bttv-if.c
index 19b564ab0e92..ecf07988cd33 100644
--- a/drivers/media/video/bt8xx/bttv-if.c
+++ b/drivers/media/video/bt8xx/bttv-if.c
@@ -33,32 +33,16 @@
33 33
34#include "bttvp.h" 34#include "bttvp.h"
35 35
36EXPORT_SYMBOL(bttv_get_cardinfo);
37EXPORT_SYMBOL(bttv_get_pcidev); 36EXPORT_SYMBOL(bttv_get_pcidev);
38EXPORT_SYMBOL(bttv_get_id);
39EXPORT_SYMBOL(bttv_gpio_enable); 37EXPORT_SYMBOL(bttv_gpio_enable);
40EXPORT_SYMBOL(bttv_read_gpio); 38EXPORT_SYMBOL(bttv_read_gpio);
41EXPORT_SYMBOL(bttv_write_gpio); 39EXPORT_SYMBOL(bttv_write_gpio);
42EXPORT_SYMBOL(bttv_get_gpio_queue);
43EXPORT_SYMBOL(bttv_i2c_call);
44 40
45/* ----------------------------------------------------------------------- */ 41/* ----------------------------------------------------------------------- */
46/* Exported functions - for other modules which want to access the */ 42/* Exported functions - for other modules which want to access the */
47/* gpio ports (IR for example) */ 43/* gpio ports (IR for example) */
48/* see bttv.h for comments */ 44/* see bttv.h for comments */
49 45
50int bttv_get_cardinfo(unsigned int card, int *type, unsigned *cardid)
51{
52 printk("The bttv_* interface is obsolete and will go away,\n"
53 "please use the new, sysfs based interface instead.\n");
54 if (card >= bttv_num) {
55 return -1;
56 }
57 *type = bttvs[card].c.type;
58 *cardid = bttvs[card].cardid;
59 return 0;
60}
61
62struct pci_dev* bttv_get_pcidev(unsigned int card) 46struct pci_dev* bttv_get_pcidev(unsigned int card)
63{ 47{
64 if (card >= bttv_num) 48 if (card >= bttv_num)
@@ -66,16 +50,6 @@ struct pci_dev* bttv_get_pcidev(unsigned int card)
66 return bttvs[card].c.pci; 50 return bttvs[card].c.pci;
67} 51}
68 52
69int bttv_get_id(unsigned int card)
70{
71 printk("The bttv_* interface is obsolete and will go away,\n"
72 "please use the new, sysfs based interface instead.\n");
73 if (card >= bttv_num) {
74 return -1;
75 }
76 return bttvs[card].c.type;
77}
78
79 53
80int bttv_gpio_enable(unsigned int card, unsigned long mask, unsigned long data) 54int bttv_gpio_enable(unsigned int card, unsigned long mask, unsigned long data)
81{ 55{
@@ -130,28 +104,6 @@ int bttv_write_gpio(unsigned int card, unsigned long mask, unsigned long data)
130 return 0; 104 return 0;
131} 105}
132 106
133wait_queue_head_t* bttv_get_gpio_queue(unsigned int card)
134{
135 struct bttv *btv;
136
137 if (card >= bttv_num) {
138 return NULL;
139 }
140
141 btv = &bttvs[card];
142 if (bttvs[card].shutdown) {
143 return NULL;
144 }
145 return &btv->gpioq;
146}
147
148void bttv_i2c_call(unsigned int card, unsigned int cmd, void *arg)
149{
150 if (card >= bttv_num)
151 return;
152 bttv_call_i2c_clients(&bttvs[card], cmd, arg);
153}
154
155/* 107/*
156 * Local variables: 108 * Local variables:
157 * c-basic-offset: 8 109 * c-basic-offset: 8
diff --git a/drivers/media/video/bt8xx/bttv.h b/drivers/media/video/bt8xx/bttv.h
index 5491acbdaf63..f821ba69db99 100644
--- a/drivers/media/video/bt8xx/bttv.h
+++ b/drivers/media/video/bt8xx/bttv.h
@@ -168,6 +168,8 @@
168#define BTTV_BOARD_SABRENT_TVFM 0x8e 168#define BTTV_BOARD_SABRENT_TVFM 0x8e
169#define BTTV_BOARD_HAUPPAUGE_IMPACTVCB 0x8f 169#define BTTV_BOARD_HAUPPAUGE_IMPACTVCB 0x8f
170#define BTTV_BOARD_MACHTV_MAGICTV 0x90 170#define BTTV_BOARD_MACHTV_MAGICTV 0x90
171#define BTTV_BOARD_SSAI_SECURITY 0x91
172#define BTTV_BOARD_SSAI_ULTRASOUND 0x92
171 173
172/* more card-specific defines */ 174/* more card-specific defines */
173#define PT2254_L_CHANNEL 0x10 175#define PT2254_L_CHANNEL 0x10
@@ -260,17 +262,8 @@ extern int bttv_handle_chipset(struct bttv *btv);
260/* this obsolete -- please use the sysfs-based 262/* this obsolete -- please use the sysfs-based
261 interface below for new code */ 263 interface below for new code */
262 264
263/* returns card type + card ID (for bt878-based ones)
264 for possible values see lines below beginning with #define BTTV_BOARD_UNKNOWN
265 returns negative value if error occurred
266*/
267extern int bttv_get_cardinfo(unsigned int card, int *type,
268 unsigned int *cardid);
269extern struct pci_dev* bttv_get_pcidev(unsigned int card); 265extern struct pci_dev* bttv_get_pcidev(unsigned int card);
270 266
271/* obsolete, use bttv_get_cardinfo instead */
272extern int bttv_get_id(unsigned int card);
273
274/* sets GPOE register (BT848_GPIO_OUT_EN) to new value: 267/* sets GPOE register (BT848_GPIO_OUT_EN) to new value:
275 data | (current_GPOE_value & ~mask) 268 data | (current_GPOE_value & ~mask)
276 returns negative value if error occurred 269 returns negative value if error occurred
@@ -290,20 +283,6 @@ extern int bttv_read_gpio(unsigned int card, unsigned long *data);
290extern int bttv_write_gpio(unsigned int card, 283extern int bttv_write_gpio(unsigned int card,
291 unsigned long mask, unsigned long data); 284 unsigned long mask, unsigned long data);
292 285
293/* returns pointer to task queue which can be used as parameter to
294 interruptible_sleep_on
295 in interrupt handler if BT848_INT_GPINT bit is set - this queue is activated
296 (wake_up_interruptible) and following call to the function bttv_read_gpio
297 should return new value of GPDATA,
298 returns NULL value if error occurred or queue is not available
299 WARNING: because there is no buffer for GPIO data, one MUST
300 process data ASAP
301*/
302extern wait_queue_head_t* bttv_get_gpio_queue(unsigned int card);
303
304/* call i2c clients
305*/
306extern void bttv_i2c_call(unsigned int card, unsigned int cmd, void *arg);
307 286
308 287
309 288
diff --git a/drivers/media/video/bt8xx/bttvp.h b/drivers/media/video/bt8xx/bttvp.h
index ad79b8d53430..8f44f02029be 100644
--- a/drivers/media/video/bt8xx/bttvp.h
+++ b/drivers/media/video/bt8xx/bttvp.h
@@ -434,6 +434,9 @@ struct bttv {
434 unsigned int users; 434 unsigned int users;
435 struct bttv_fh init; 435 struct bttv_fh init;
436 436
437 /* used to make dvb-bt8xx autoloadable */
438 struct work_struct request_module_wk;
439
437 /* Default (0) and current (1) video capturing and overlay 440 /* Default (0) and current (1) video capturing and overlay
438 cropping parameters in bttv_tvnorm.cropcap units. Protected 441 cropping parameters in bttv_tvnorm.cropcap units. Protected
439 by bttv.lock. */ 442 by bttv.lock. */
diff --git a/drivers/media/video/cafe_ccic.c b/drivers/media/video/cafe_ccic.c
index 710c11a68296..96254dbaf625 100644
--- a/drivers/media/video/cafe_ccic.c
+++ b/drivers/media/video/cafe_ccic.c
@@ -4,6 +4,7 @@
4 * sensor. 4 * sensor.
5 * 5 *
6 * Copyright 2006 One Laptop Per Child Association, Inc. 6 * Copyright 2006 One Laptop Per Child Association, Inc.
7 * Copyright 2006-7 Jonathan Corbet <corbet@lwn.net>
7 * 8 *
8 * Written by Jonathan Corbet, corbet@lwn.net. 9 * Written by Jonathan Corbet, corbet@lwn.net.
9 * 10 *
@@ -22,6 +23,7 @@
22#include <linux/spinlock.h> 23#include <linux/spinlock.h>
23#include <linux/videodev2.h> 24#include <linux/videodev2.h>
24#include <media/v4l2-common.h> 25#include <media/v4l2-common.h>
26#include <media/v4l2-chip-ident.h>
25#include <linux/device.h> 27#include <linux/device.h>
26#include <linux/wait.h> 28#include <linux/wait.h>
27#include <linux/list.h> 29#include <linux/list.h>
@@ -36,7 +38,7 @@
36 38
37#include "cafe_ccic-regs.h" 39#include "cafe_ccic-regs.h"
38 40
39#define CAFE_VERSION 0x000001 41#define CAFE_VERSION 0x000002
40 42
41 43
42/* 44/*
@@ -164,7 +166,7 @@ struct cafe_camera
164 struct tasklet_struct s_tasklet; 166 struct tasklet_struct s_tasklet;
165 167
166 /* Current operating parameters */ 168 /* Current operating parameters */
167 enum v4l2_chip_ident sensor_type; /* Currently ov7670 only */ 169 u32 sensor_type; /* Currently ov7670 only */
168 struct v4l2_pix_format pix_format; 170 struct v4l2_pix_format pix_format;
169 171
170 /* Locks */ 172 /* Locks */
@@ -704,7 +706,13 @@ static void cafe_ctlr_init(struct cafe_camera *cam)
704 cafe_reg_write(cam, REG_GL_CSR, GCSR_SRS|GCSR_MRS); /* Needed? */ 706 cafe_reg_write(cam, REG_GL_CSR, GCSR_SRS|GCSR_MRS); /* Needed? */
705 cafe_reg_write(cam, REG_GL_CSR, GCSR_SRC|GCSR_MRC); 707 cafe_reg_write(cam, REG_GL_CSR, GCSR_SRC|GCSR_MRC);
706 cafe_reg_write(cam, REG_GL_CSR, GCSR_SRC|GCSR_MRS); 708 cafe_reg_write(cam, REG_GL_CSR, GCSR_SRC|GCSR_MRS);
709 /*
710 * Here we must wait a bit for the controller to come around.
711 */
712 spin_unlock_irqrestore(&cam->dev_lock, flags);
707 mdelay(5); /* FIXME revisit this */ 713 mdelay(5); /* FIXME revisit this */
714 spin_lock_irqsave(&cam->dev_lock, flags);
715
708 cafe_reg_write(cam, REG_GL_CSR, GCSR_CCIC_EN|GCSR_SRC|GCSR_MRC); 716 cafe_reg_write(cam, REG_GL_CSR, GCSR_CCIC_EN|GCSR_SRC|GCSR_MRC);
709 cafe_reg_set_bit(cam, REG_GL_IMASK, GIMSK_CCIC_EN); 717 cafe_reg_set_bit(cam, REG_GL_IMASK, GIMSK_CCIC_EN);
710 /* 718 /*
@@ -772,9 +780,9 @@ static void cafe_ctlr_power_up(struct cafe_camera *cam)
772 * Control 1 is power down, set to 0 to operate. 780 * Control 1 is power down, set to 0 to operate.
773 */ 781 */
774 cafe_reg_write(cam, REG_GPR, GPR_C1EN|GPR_C0EN); /* pwr up, reset */ 782 cafe_reg_write(cam, REG_GPR, GPR_C1EN|GPR_C0EN); /* pwr up, reset */
775 mdelay(1); /* Marvell says 1ms will do it */ 783// mdelay(1); /* Marvell says 1ms will do it */
776 cafe_reg_write(cam, REG_GPR, GPR_C1EN|GPR_C0EN|GPR_C0); 784 cafe_reg_write(cam, REG_GPR, GPR_C1EN|GPR_C0EN|GPR_C0);
777 mdelay(1); /* Enough? */ 785// mdelay(1); /* Enough? */
778 spin_unlock_irqrestore(&cam->dev_lock, flags); 786 spin_unlock_irqrestore(&cam->dev_lock, flags);
779} 787}
780 788
@@ -818,6 +826,7 @@ static int __cafe_cam_reset(struct cafe_camera *cam)
818 */ 826 */
819static int cafe_cam_init(struct cafe_camera *cam) 827static int cafe_cam_init(struct cafe_camera *cam)
820{ 828{
829 struct v4l2_chip_ident chip = { V4L2_CHIP_MATCH_I2C_ADDR, 0, 0, 0 };
821 int ret; 830 int ret;
822 831
823 mutex_lock(&cam->s_mutex); 832 mutex_lock(&cam->s_mutex);
@@ -827,9 +836,11 @@ static int cafe_cam_init(struct cafe_camera *cam)
827 ret = __cafe_cam_reset(cam); 836 ret = __cafe_cam_reset(cam);
828 if (ret) 837 if (ret)
829 goto out; 838 goto out;
830 ret = __cafe_cam_cmd(cam, VIDIOC_INT_G_CHIP_IDENT, &cam->sensor_type); 839 chip.match_chip = cam->sensor->addr;
840 ret = __cafe_cam_cmd(cam, VIDIOC_G_CHIP_IDENT, &chip);
831 if (ret) 841 if (ret)
832 goto out; 842 goto out;
843 cam->sensor_type = chip.ident;
833// if (cam->sensor->addr != OV7xx0_SID) { 844// if (cam->sensor->addr != OV7xx0_SID) {
834 if (cam->sensor_type != V4L2_IDENT_OV7670) { 845 if (cam->sensor_type != V4L2_IDENT_OV7670) {
835 cam_err(cam, "Unsupported sensor type %d", cam->sensor->addr); 846 cam_err(cam, "Unsupported sensor type %d", cam->sensor->addr);
@@ -1792,18 +1803,19 @@ static void cafe_frame_tasklet(unsigned long data)
1792 if (list_empty(&cam->sb_avail)) 1803 if (list_empty(&cam->sb_avail))
1793 break; /* Leave it valid, hope for better later */ 1804 break; /* Leave it valid, hope for better later */
1794 clear_bit(bufno, &cam->flags); 1805 clear_bit(bufno, &cam->flags);
1795 /*
1796 * We could perhaps drop the spinlock during this
1797 * big copy. Something to consider.
1798 */
1799 sbuf = list_entry(cam->sb_avail.next, 1806 sbuf = list_entry(cam->sb_avail.next,
1800 struct cafe_sio_buffer, list); 1807 struct cafe_sio_buffer, list);
1808 /*
1809 * Drop the lock during the big copy. This *should* be safe...
1810 */
1811 spin_unlock_irqrestore(&cam->dev_lock, flags);
1801 memcpy(sbuf->buffer, cam->dma_bufs[bufno], 1812 memcpy(sbuf->buffer, cam->dma_bufs[bufno],
1802 cam->pix_format.sizeimage); 1813 cam->pix_format.sizeimage);
1803 sbuf->v4lbuf.bytesused = cam->pix_format.sizeimage; 1814 sbuf->v4lbuf.bytesused = cam->pix_format.sizeimage;
1804 sbuf->v4lbuf.sequence = cam->buf_seq[bufno]; 1815 sbuf->v4lbuf.sequence = cam->buf_seq[bufno];
1805 sbuf->v4lbuf.flags &= ~V4L2_BUF_FLAG_QUEUED; 1816 sbuf->v4lbuf.flags &= ~V4L2_BUF_FLAG_QUEUED;
1806 sbuf->v4lbuf.flags |= V4L2_BUF_FLAG_DONE; 1817 sbuf->v4lbuf.flags |= V4L2_BUF_FLAG_DONE;
1818 spin_lock_irqsave(&cam->dev_lock, flags);
1807 list_move_tail(&sbuf->list, &cam->sb_full); 1819 list_move_tail(&sbuf->list, &cam->sb_full);
1808 } 1820 }
1809 if (! list_empty(&cam->sb_full)) 1821 if (! list_empty(&cam->sb_full))
@@ -2107,6 +2119,7 @@ static int cafe_pci_probe(struct pci_dev *pdev,
2107 cam->v4ldev = cafe_v4l_template; 2119 cam->v4ldev = cafe_v4l_template;
2108 cam->v4ldev.debug = 0; 2120 cam->v4ldev.debug = 0;
2109// cam->v4ldev.debug = V4L2_DEBUG_IOCTL_ARG; 2121// cam->v4ldev.debug = V4L2_DEBUG_IOCTL_ARG;
2122 cam->v4ldev.dev = &pdev->dev;
2110 ret = video_register_device(&cam->v4ldev, VFL_TYPE_GRABBER, -1); 2123 ret = video_register_device(&cam->v4ldev, VFL_TYPE_GRABBER, -1);
2111 if (ret) 2124 if (ret)
2112 goto out_smbus; 2125 goto out_smbus;
@@ -2176,10 +2189,52 @@ static void cafe_pci_remove(struct pci_dev *pdev)
2176} 2189}
2177 2190
2178 2191
2192#ifdef CONFIG_PM
2193/*
2194 * Basic power management.
2195 */
2196static int cafe_pci_suspend(struct pci_dev *pdev, pm_message_t state)
2197{
2198 struct cafe_camera *cam = cafe_find_by_pdev(pdev);
2199 int ret;
2200
2201 ret = pci_save_state(pdev);
2202 if (ret)
2203 return ret;
2204 cafe_ctlr_stop_dma(cam);
2205 cafe_ctlr_power_down(cam);
2206 pci_disable_device(pdev);
2207 return 0;
2208}
2209
2210
2211static int cafe_pci_resume(struct pci_dev *pdev)
2212{
2213 struct cafe_camera *cam = cafe_find_by_pdev(pdev);
2214 int ret = 0;
2215
2216 ret = pci_restore_state(pdev);
2217 if (ret)
2218 return ret;
2219 ret = pci_enable_device(pdev);
2220 if (ret) {
2221 cam_warn(cam, "Unable to re-enable device on resume!\n");
2222 return ret;
2223 }
2224 cafe_ctlr_init(cam);
2225 cafe_ctlr_power_up(cam);
2226 set_bit(CF_CONFIG_NEEDED, &cam->flags);
2227 if (cam->state == S_SPECREAD)
2228 cam->state = S_IDLE; /* Don't bother restarting */
2229 else if (cam->state == S_SINGLEREAD || cam->state == S_STREAMING)
2230 ret = cafe_read_setup(cam, cam->state);
2231 return ret;
2232}
2233
2234#endif /* CONFIG_PM */
2179 2235
2180 2236
2181static struct pci_device_id cafe_ids[] = { 2237static struct pci_device_id cafe_ids[] = {
2182 { PCI_DEVICE(0x1148, 0x4340) }, /* Temporary ID on devel board */
2183 { PCI_DEVICE(0x11ab, 0x4100) }, /* Eventual real ID */ 2238 { PCI_DEVICE(0x11ab, 0x4100) }, /* Eventual real ID */
2184 { PCI_DEVICE(0x11ab, 0x4102) }, /* Really eventual real ID */ 2239 { PCI_DEVICE(0x11ab, 0x4102) }, /* Really eventual real ID */
2185 { 0, } 2240 { 0, }
@@ -2192,6 +2247,10 @@ static struct pci_driver cafe_pci_driver = {
2192 .id_table = cafe_ids, 2247 .id_table = cafe_ids,
2193 .probe = cafe_pci_probe, 2248 .probe = cafe_pci_probe,
2194 .remove = cafe_pci_remove, 2249 .remove = cafe_pci_remove,
2250#ifdef CONFIG_PM
2251 .suspend = cafe_pci_suspend,
2252 .resume = cafe_pci_resume,
2253#endif
2195}; 2254};
2196 2255
2197 2256
diff --git a/drivers/media/video/cpia_pp.c b/drivers/media/video/cpia_pp.c
index b12cec94f4cc..19711aaf9a3e 100644
--- a/drivers/media/video/cpia_pp.c
+++ b/drivers/media/video/cpia_pp.c
@@ -62,7 +62,6 @@ static int cpia_pp_close(void *privdata);
62#define PPCPIA_PARPORT_OFF -2 62#define PPCPIA_PARPORT_OFF -2
63#define PPCPIA_PARPORT_NONE -1 63#define PPCPIA_PARPORT_NONE -1
64 64
65#ifdef MODULE
66static int parport_nr[PARPORT_MAX] = {[0 ... PARPORT_MAX - 1] = PPCPIA_PARPORT_UNSPEC}; 65static int parport_nr[PARPORT_MAX] = {[0 ... PARPORT_MAX - 1] = PPCPIA_PARPORT_UNSPEC};
67static char *parport[PARPORT_MAX] = {NULL,}; 66static char *parport[PARPORT_MAX] = {NULL,};
68 67
@@ -72,11 +71,6 @@ MODULE_LICENSE("GPL");
72 71
73module_param_array(parport, charp, NULL, 0); 72module_param_array(parport, charp, NULL, 0);
74MODULE_PARM_DESC(parport, "'auto' or a list of parallel port numbers. Just like lp."); 73MODULE_PARM_DESC(parport, "'auto' or a list of parallel port numbers. Just like lp.");
75#else
76static int parport_nr[PARPORT_MAX] __initdata =
77 {[0 ... PARPORT_MAX - 1] = PPCPIA_PARPORT_UNSPEC};
78static int parport_ptr = 0;
79#endif
80 74
81struct pp_cam_entry { 75struct pp_cam_entry {
82 struct pardevice *pdev; 76 struct pardevice *pdev;
@@ -141,7 +135,6 @@ static void cpia_pp_run_callback(struct work_struct *work)
141 cam = container_of(work, struct pp_cam_entry, cb_task); 135 cam = container_of(work, struct pp_cam_entry, cb_task);
142 cb_func = cam->cb_func; 136 cb_func = cam->cb_func;
143 cb_data = cam->cb_data; 137 cb_data = cam->cb_data;
144 work_release(work);
145 138
146 cb_func(cb_data); 139 cb_func(cb_data);
147} 140}
@@ -682,7 +675,7 @@ static int cpia_pp_registerCallback(void *privdata, void (*cb)(void *cbdata), vo
682 if(cam->port->irq != PARPORT_IRQ_NONE) { 675 if(cam->port->irq != PARPORT_IRQ_NONE) {
683 cam->cb_func = cb; 676 cam->cb_func = cb;
684 cam->cb_data = cbdata; 677 cam->cb_data = cbdata;
685 INIT_WORK_NAR(&cam->cb_task, cpia_pp_run_callback); 678 INIT_WORK(&cam->cb_task, cpia_pp_run_callback);
686 } else { 679 } else {
687 retval = -1; 680 retval = -1;
688 } 681 }
@@ -820,7 +813,7 @@ static struct parport_driver cpia_pp_driver = {
820 .detach = cpia_pp_detach, 813 .detach = cpia_pp_detach,
821}; 814};
822 815
823static int cpia_pp_init(void) 816static int __init cpia_pp_init(void)
824{ 817{
825 printk(KERN_INFO "%s v%d.%d.%d\n",ABOUT, 818 printk(KERN_INFO "%s v%d.%d.%d\n",ABOUT,
826 CPIA_PP_MAJ_VER,CPIA_PP_MIN_VER,CPIA_PP_PATCH_VER); 819 CPIA_PP_MAJ_VER,CPIA_PP_MIN_VER,CPIA_PP_PATCH_VER);
@@ -839,8 +832,7 @@ static int cpia_pp_init(void)
839 return 0; 832 return 0;
840} 833}
841 834
842#ifdef MODULE 835static int __init cpia_init(void)
843int init_module(void)
844{ 836{
845 if (parport[0]) { 837 if (parport[0]) {
846 /* The user gave some parameters. Let's see what they were. */ 838 /* The user gave some parameters. Let's see what they were. */
@@ -867,38 +859,11 @@ int init_module(void)
867 return cpia_pp_init(); 859 return cpia_pp_init();
868} 860}
869 861
870void cleanup_module(void) 862static void __exit cpia_cleanup(void)
871{ 863{
872 parport_unregister_driver (&cpia_pp_driver); 864 parport_unregister_driver(&cpia_pp_driver);
873 return; 865 return;
874} 866}
875 867
876#else /* !MODULE */ 868module_init(cpia_init);
877 869module_exit(cpia_cleanup);
878static int __init cpia_pp_setup(char *str)
879{
880 int err;
881
882 if (!strncmp(str, "parport", 7)) {
883 int n = simple_strtoul(str + 7, NULL, 10);
884 if (parport_ptr < PARPORT_MAX) {
885 parport_nr[parport_ptr++] = n;
886 } else {
887 LOG("too many ports, %s ignored.\n", str);
888 }
889 } else if (!strcmp(str, "auto")) {
890 parport_nr[0] = PPCPIA_PARPORT_AUTO;
891 } else if (!strcmp(str, "none")) {
892 parport_nr[parport_ptr++] = PPCPIA_PARPORT_NONE;
893 }
894
895 err=cpia_pp_init();
896 if (err)
897 return err;
898
899 return 1;
900}
901
902__setup("cpia_pp=", cpia_pp_setup);
903
904#endif /* !MODULE */
diff --git a/drivers/media/video/cs53l32a.c b/drivers/media/video/cs53l32a.c
index de87247c74ee..a73e285af730 100644
--- a/drivers/media/video/cs53l32a.c
+++ b/drivers/media/video/cs53l32a.c
@@ -28,6 +28,7 @@
28#include <linux/i2c-id.h> 28#include <linux/i2c-id.h>
29#include <linux/videodev.h> 29#include <linux/videodev.h>
30#include <media/v4l2-common.h> 30#include <media/v4l2-common.h>
31#include <media/v4l2-chip-ident.h>
31 32
32MODULE_DESCRIPTION("i2c device driver for cs53l32a Audio ADC"); 33MODULE_DESCRIPTION("i2c device driver for cs53l32a Audio ADC");
33MODULE_AUTHOR("Martin Vaughan"); 34MODULE_AUTHOR("Martin Vaughan");
@@ -103,6 +104,9 @@ static int cs53l32a_command(struct i2c_client *client, unsigned int cmd,
103 cs53l32a_write(client, 0x05, (u8) ctrl->value); 104 cs53l32a_write(client, 0x05, (u8) ctrl->value);
104 break; 105 break;
105 106
107 case VIDIOC_G_CHIP_IDENT:
108 return v4l2_chip_ident_i2c_client(client, arg, V4L2_IDENT_CS53l32A, 0);
109
106 case VIDIOC_LOG_STATUS: 110 case VIDIOC_LOG_STATUS:
107 { 111 {
108 u8 v = cs53l32a_read(client, 0x01); 112 u8 v = cs53l32a_read(client, 0x01);
diff --git a/drivers/media/video/cx2341x.c b/drivers/media/video/cx2341x.c
index d60cd5ecf821..88dbdddeec42 100644
--- a/drivers/media/video/cx2341x.c
+++ b/drivers/media/video/cx2341x.c
@@ -51,6 +51,7 @@ const u32 cx2341x_mpeg_ctrls[] = {
51 V4L2_CID_MPEG_AUDIO_MODE_EXTENSION, 51 V4L2_CID_MPEG_AUDIO_MODE_EXTENSION,
52 V4L2_CID_MPEG_AUDIO_EMPHASIS, 52 V4L2_CID_MPEG_AUDIO_EMPHASIS,
53 V4L2_CID_MPEG_AUDIO_CRC, 53 V4L2_CID_MPEG_AUDIO_CRC,
54 V4L2_CID_MPEG_AUDIO_MUTE,
54 V4L2_CID_MPEG_VIDEO_ENCODING, 55 V4L2_CID_MPEG_VIDEO_ENCODING,
55 V4L2_CID_MPEG_VIDEO_ASPECT, 56 V4L2_CID_MPEG_VIDEO_ASPECT,
56 V4L2_CID_MPEG_VIDEO_B_FRAMES, 57 V4L2_CID_MPEG_VIDEO_B_FRAMES,
@@ -60,6 +61,8 @@ const u32 cx2341x_mpeg_ctrls[] = {
60 V4L2_CID_MPEG_VIDEO_BITRATE, 61 V4L2_CID_MPEG_VIDEO_BITRATE,
61 V4L2_CID_MPEG_VIDEO_BITRATE_PEAK, 62 V4L2_CID_MPEG_VIDEO_BITRATE_PEAK,
62 V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION, 63 V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION,
64 V4L2_CID_MPEG_VIDEO_MUTE,
65 V4L2_CID_MPEG_VIDEO_MUTE_YUV,
63 V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE, 66 V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE,
64 V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER, 67 V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER,
65 V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE, 68 V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE,
@@ -71,6 +74,7 @@ const u32 cx2341x_mpeg_ctrls[] = {
71 V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP, 74 V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP,
72 V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM, 75 V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM,
73 V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP, 76 V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP,
77 V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS,
74 0 78 0
75}; 79};
76 80
@@ -102,6 +106,9 @@ static int cx2341x_get_ctrl(struct cx2341x_mpeg_params *params,
102 case V4L2_CID_MPEG_AUDIO_CRC: 106 case V4L2_CID_MPEG_AUDIO_CRC:
103 ctrl->value = params->audio_crc; 107 ctrl->value = params->audio_crc;
104 break; 108 break;
109 case V4L2_CID_MPEG_AUDIO_MUTE:
110 ctrl->value = params->audio_mute;
111 break;
105 case V4L2_CID_MPEG_VIDEO_ENCODING: 112 case V4L2_CID_MPEG_VIDEO_ENCODING:
106 ctrl->value = params->video_encoding; 113 ctrl->value = params->video_encoding;
107 break; 114 break;
@@ -129,6 +136,12 @@ static int cx2341x_get_ctrl(struct cx2341x_mpeg_params *params,
129 case V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION: 136 case V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION:
130 ctrl->value = params->video_temporal_decimation; 137 ctrl->value = params->video_temporal_decimation;
131 break; 138 break;
139 case V4L2_CID_MPEG_VIDEO_MUTE:
140 ctrl->value = params->video_mute;
141 break;
142 case V4L2_CID_MPEG_VIDEO_MUTE_YUV:
143 ctrl->value = params->video_mute_yuv;
144 break;
132 case V4L2_CID_MPEG_STREAM_TYPE: 145 case V4L2_CID_MPEG_STREAM_TYPE:
133 ctrl->value = params->stream_type; 146 ctrl->value = params->stream_type;
134 break; 147 break;
@@ -168,6 +181,9 @@ static int cx2341x_get_ctrl(struct cx2341x_mpeg_params *params,
168 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM: 181 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM:
169 ctrl->value = params->video_chroma_median_filter_bottom; 182 ctrl->value = params->video_chroma_median_filter_bottom;
170 break; 183 break;
184 case V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS:
185 ctrl->value = params->stream_insert_nav_packets;
186 break;
171 default: 187 default:
172 return -EINVAL; 188 return -EINVAL;
173 } 189 }
@@ -201,6 +217,9 @@ static int cx2341x_set_ctrl(struct cx2341x_mpeg_params *params,
201 case V4L2_CID_MPEG_AUDIO_CRC: 217 case V4L2_CID_MPEG_AUDIO_CRC:
202 params->audio_crc = ctrl->value; 218 params->audio_crc = ctrl->value;
203 break; 219 break;
220 case V4L2_CID_MPEG_AUDIO_MUTE:
221 params->audio_mute = ctrl->value;
222 break;
204 case V4L2_CID_MPEG_VIDEO_ASPECT: 223 case V4L2_CID_MPEG_VIDEO_ASPECT:
205 params->video_aspect = ctrl->value; 224 params->video_aspect = ctrl->value;
206 break; 225 break;
@@ -243,6 +262,12 @@ static int cx2341x_set_ctrl(struct cx2341x_mpeg_params *params,
243 case V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION: 262 case V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION:
244 params->video_temporal_decimation = ctrl->value; 263 params->video_temporal_decimation = ctrl->value;
245 break; 264 break;
265 case V4L2_CID_MPEG_VIDEO_MUTE:
266 params->video_mute = (ctrl->value != 0);
267 break;
268 case V4L2_CID_MPEG_VIDEO_MUTE_YUV:
269 params->video_mute_yuv = ctrl->value;
270 break;
246 case V4L2_CID_MPEG_STREAM_TYPE: 271 case V4L2_CID_MPEG_STREAM_TYPE:
247 params->stream_type = ctrl->value; 272 params->stream_type = ctrl->value;
248 params->video_encoding = 273 params->video_encoding =
@@ -290,6 +315,9 @@ static int cx2341x_set_ctrl(struct cx2341x_mpeg_params *params,
290 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM: 315 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM:
291 params->video_chroma_median_filter_bottom = ctrl->value; 316 params->video_chroma_median_filter_bottom = ctrl->value;
292 break; 317 break;
318 case V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS:
319 params->stream_insert_nav_packets = ctrl->value;
320 break;
293 default: 321 default:
294 return -EINVAL; 322 return -EINVAL;
295 } 323 }
@@ -336,6 +364,9 @@ static int cx2341x_ctrl_query_fill(struct v4l2_queryctrl *qctrl, s32 min, s32 ma
336 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM: 364 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM:
337 name = "Median Chroma Filter Minimum"; 365 name = "Median Chroma Filter Minimum";
338 break; 366 break;
367 case V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS:
368 name = "Insert Navigation Packets";
369 break;
339 370
340 default: 371 default:
341 return v4l2_ctrl_query_fill(qctrl, min, max, step, def); 372 return v4l2_ctrl_query_fill(qctrl, min, max, step, def);
@@ -350,6 +381,12 @@ static int cx2341x_ctrl_query_fill(struct v4l2_queryctrl *qctrl, s32 min, s32 ma
350 min = 0; 381 min = 0;
351 step = 1; 382 step = 1;
352 break; 383 break;
384 case V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS:
385 qctrl->type = V4L2_CTRL_TYPE_BOOLEAN;
386 min = 0;
387 max = 1;
388 step = 1;
389 break;
353 default: 390 default:
354 qctrl->type = V4L2_CTRL_TYPE_INTEGER; 391 qctrl->type = V4L2_CTRL_TYPE_INTEGER;
355 break; 392 break;
@@ -505,6 +542,9 @@ int cx2341x_ctrl_query(struct cx2341x_mpeg_params *params, struct v4l2_queryctrl
505 qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE; 542 qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
506 return 0; 543 return 0;
507 544
545 case V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS:
546 return cx2341x_ctrl_query_fill(qctrl, 0, 1, 1, 0);
547
508 default: 548 default:
509 return v4l2_ctrl_query_fill_std(qctrl); 549 return v4l2_ctrl_query_fill_std(qctrl);
510 550
@@ -656,6 +696,7 @@ void cx2341x_fill_defaults(struct cx2341x_mpeg_params *p)
656 /* stream */ 696 /* stream */
657 .stream_type = V4L2_MPEG_STREAM_TYPE_MPEG2_PS, 697 .stream_type = V4L2_MPEG_STREAM_TYPE_MPEG2_PS,
658 .stream_vbi_fmt = V4L2_MPEG_STREAM_VBI_FMT_NONE, 698 .stream_vbi_fmt = V4L2_MPEG_STREAM_VBI_FMT_NONE,
699 .stream_insert_nav_packets = 0,
659 700
660 /* audio */ 701 /* audio */
661 .audio_sampling_freq = V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000, 702 .audio_sampling_freq = V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000,
@@ -665,6 +706,7 @@ void cx2341x_fill_defaults(struct cx2341x_mpeg_params *p)
665 .audio_mode_extension = V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_4, 706 .audio_mode_extension = V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_4,
666 .audio_emphasis = V4L2_MPEG_AUDIO_EMPHASIS_NONE, 707 .audio_emphasis = V4L2_MPEG_AUDIO_EMPHASIS_NONE,
667 .audio_crc = V4L2_MPEG_AUDIO_CRC_NONE, 708 .audio_crc = V4L2_MPEG_AUDIO_CRC_NONE,
709 .audio_mute = 0,
668 710
669 /* video */ 711 /* video */
670 .video_encoding = V4L2_MPEG_VIDEO_ENCODING_MPEG_2, 712 .video_encoding = V4L2_MPEG_VIDEO_ENCODING_MPEG_2,
@@ -676,6 +718,8 @@ void cx2341x_fill_defaults(struct cx2341x_mpeg_params *p)
676 .video_bitrate = 6000000, 718 .video_bitrate = 6000000,
677 .video_bitrate_peak = 8000000, 719 .video_bitrate_peak = 8000000,
678 .video_temporal_decimation = 0, 720 .video_temporal_decimation = 0,
721 .video_mute = 0,
722 .video_mute_yuv = 0x008080, /* YCbCr value for black */
679 723
680 /* encoding filters */ 724 /* encoding filters */
681 .video_spatial_filter_mode = V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_MANUAL, 725 .video_spatial_filter_mode = V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_MANUAL,
@@ -779,6 +823,10 @@ int cx2341x_update(void *priv, cx2341x_mbox_func func,
779 err = cx2341x_api(priv, func, CX2341X_ENC_SET_AUDIO_PROPERTIES, 1, new->audio_properties); 823 err = cx2341x_api(priv, func, CX2341X_ENC_SET_AUDIO_PROPERTIES, 1, new->audio_properties);
780 if (err) return err; 824 if (err) return err;
781 } 825 }
826 if (old == NULL || old->audio_mute != new->audio_mute) {
827 err = cx2341x_api(priv, func, CX2341X_ENC_MUTE_AUDIO, 1, new->audio_mute);
828 if (err) return err;
829 }
782 if (old == NULL || old->video_bitrate_mode != new->video_bitrate_mode || 830 if (old == NULL || old->video_bitrate_mode != new->video_bitrate_mode ||
783 old->video_bitrate != new->video_bitrate || 831 old->video_bitrate != new->video_bitrate ||
784 old->video_bitrate_peak != new->video_bitrate_peak) { 832 old->video_bitrate_peak != new->video_bitrate_peak) {
@@ -826,6 +874,15 @@ int cx2341x_update(void *priv, cx2341x_mbox_func func,
826 new->video_temporal_decimation); 874 new->video_temporal_decimation);
827 if (err) return err; 875 if (err) return err;
828 } 876 }
877 if (old == NULL || old->video_mute != new->video_mute ||
878 (new->video_mute && old->video_mute_yuv != new->video_mute_yuv)) {
879 err = cx2341x_api(priv, func, CX2341X_ENC_MUTE_VIDEO, 1, new->video_mute | (new->video_mute_yuv << 8));
880 if (err) return err;
881 }
882 if (old == NULL || old->stream_insert_nav_packets != new->stream_insert_nav_packets) {
883 err = cx2341x_api(priv, func, CX2341X_ENC_MISC, 2, 7, new->stream_insert_nav_packets);
884 if (err) return err;
885 }
829 return 0; 886 return 0;
830} 887}
831 888
@@ -854,18 +911,22 @@ void cx2341x_log_status(struct cx2341x_mpeg_params *p, const char *prefix)
854 int temporal = p->video_temporal_filter; 911 int temporal = p->video_temporal_filter;
855 912
856 /* Stream */ 913 /* Stream */
857 printk(KERN_INFO "%s: Stream: %s\n", 914 printk(KERN_INFO "%s: Stream: %s",
858 prefix, 915 prefix,
859 cx2341x_menu_item(p, V4L2_CID_MPEG_STREAM_TYPE)); 916 cx2341x_menu_item(p, V4L2_CID_MPEG_STREAM_TYPE));
917 if (p->stream_insert_nav_packets)
918 printk(" (with navigation packets)");
919 printk("\n");
860 printk(KERN_INFO "%s: VBI Format: %s\n", 920 printk(KERN_INFO "%s: VBI Format: %s\n",
861 prefix, 921 prefix,
862 cx2341x_menu_item(p, V4L2_CID_MPEG_STREAM_VBI_FMT)); 922 cx2341x_menu_item(p, V4L2_CID_MPEG_STREAM_VBI_FMT));
863 923
864 /* Video */ 924 /* Video */
865 printk(KERN_INFO "%s: Video: %dx%d, %d fps\n", 925 printk(KERN_INFO "%s: Video: %dx%d, %d fps%s\n",
866 prefix, 926 prefix,
867 p->width / (is_mpeg1 ? 2 : 1), p->height / (is_mpeg1 ? 2 : 1), 927 p->width / (is_mpeg1 ? 2 : 1), p->height / (is_mpeg1 ? 2 : 1),
868 p->is_50hz ? 25 : 30); 928 p->is_50hz ? 25 : 30,
929 (p->video_mute) ? " (muted)" : "");
869 printk(KERN_INFO "%s: Video: %s, %s, %s, %d", 930 printk(KERN_INFO "%s: Video: %s, %s, %s, %d",
870 prefix, 931 prefix,
871 cx2341x_menu_item(p, V4L2_CID_MPEG_VIDEO_ENCODING), 932 cx2341x_menu_item(p, V4L2_CID_MPEG_VIDEO_ENCODING),
@@ -886,12 +947,13 @@ void cx2341x_log_status(struct cx2341x_mpeg_params *p, const char *prefix)
886 } 947 }
887 948
888 /* Audio */ 949 /* Audio */
889 printk(KERN_INFO "%s: Audio: %s, %s, %s, %s", 950 printk(KERN_INFO "%s: Audio: %s, %s, %s, %s%s",
890 prefix, 951 prefix,
891 cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ), 952 cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ),
892 cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_ENCODING), 953 cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_ENCODING),
893 cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_L2_BITRATE), 954 cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_L2_BITRATE),
894 cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_MODE)); 955 cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_MODE),
956 p->audio_mute ? " (muted)" : "");
895 if (p->audio_mode == V4L2_MPEG_AUDIO_MODE_JOINT_STEREO) { 957 if (p->audio_mode == V4L2_MPEG_AUDIO_MODE_JOINT_STEREO) {
896 printk(", %s", 958 printk(", %s",
897 cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_MODE_EXTENSION)); 959 cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_MODE_EXTENSION));
diff --git a/drivers/media/video/cx25840/cx25840-core.c b/drivers/media/video/cx25840/cx25840-core.c
index 774d2536555b..1757a588970f 100644
--- a/drivers/media/video/cx25840/cx25840-core.c
+++ b/drivers/media/video/cx25840/cx25840-core.c
@@ -35,6 +35,7 @@
35#include <linux/videodev2.h> 35#include <linux/videodev2.h>
36#include <linux/i2c.h> 36#include <linux/i2c.h>
37#include <media/v4l2-common.h> 37#include <media/v4l2-common.h>
38#include <media/v4l2-chip-ident.h>
38#include <media/cx25840.h> 39#include <media/cx25840.h>
39 40
40#include "cx25840-core.h" 41#include "cx25840-core.h"
@@ -827,9 +828,8 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd,
827 cx25840_initialize(client, 0); 828 cx25840_initialize(client, 0);
828 break; 829 break;
829 830
830 case VIDIOC_INT_G_CHIP_IDENT: 831 case VIDIOC_G_CHIP_IDENT:
831 *(enum v4l2_chip_ident *)arg = state->id; 832 return v4l2_chip_ident_i2c_client(client, arg, state->id, state->rev);
832 break;
833 833
834 default: 834 default:
835 return -EINVAL; 835 return -EINVAL;
@@ -847,7 +847,7 @@ static int cx25840_detect_client(struct i2c_adapter *adapter, int address,
847{ 847{
848 struct i2c_client *client; 848 struct i2c_client *client;
849 struct cx25840_state *state; 849 struct cx25840_state *state;
850 enum v4l2_chip_ident id; 850 u32 id;
851 u16 device_id; 851 u16 device_id;
852 852
853 /* Check if the adapter supports the needed features 853 /* Check if the adapter supports the needed features
@@ -902,6 +902,7 @@ static int cx25840_detect_client(struct i2c_adapter *adapter, int address,
902 state->audmode = V4L2_TUNER_MODE_LANG1; 902 state->audmode = V4L2_TUNER_MODE_LANG1;
903 state->vbi_line_offset = 8; 903 state->vbi_line_offset = 8;
904 state->id = id; 904 state->id = id;
905 state->rev = device_id;
905 906
906 i2c_attach_client(client); 907 i2c_attach_client(client);
907 908
diff --git a/drivers/media/video/cx25840/cx25840-core.h b/drivers/media/video/cx25840/cx25840-core.h
index 28049064dd7d..f4b56d2fd6b6 100644
--- a/drivers/media/video/cx25840/cx25840-core.h
+++ b/drivers/media/video/cx25840/cx25840-core.h
@@ -43,7 +43,8 @@ struct cx25840_state {
43 u32 audclk_freq; 43 u32 audclk_freq;
44 int audmode; 44 int audmode;
45 int vbi_line_offset; 45 int vbi_line_offset;
46 enum v4l2_chip_ident id; 46 u32 id;
47 u32 rev;
47 int is_cx25836; 48 int is_cx25836;
48}; 49};
49 50
diff --git a/drivers/media/video/cx25840/cx25840-firmware.c b/drivers/media/video/cx25840/cx25840-firmware.c
index 0e86b9d033ac..e852024a5ea3 100644
--- a/drivers/media/video/cx25840/cx25840-firmware.c
+++ b/drivers/media/video/cx25840/cx25840-firmware.c
@@ -17,7 +17,6 @@
17 17
18#include <linux/module.h> 18#include <linux/module.h>
19#include <linux/i2c.h> 19#include <linux/i2c.h>
20#include <linux/i2c-algo-bit.h>
21#include <linux/firmware.h> 20#include <linux/firmware.h>
22#include <media/v4l2-common.h> 21#include <media/v4l2-common.h>
23#include <media/cx25840.h> 22#include <media/cx25840.h>
diff --git a/drivers/media/video/cx88/Kconfig b/drivers/media/video/cx88/Kconfig
index b2a66ba625f9..0f9d96963618 100644
--- a/drivers/media/video/cx88/Kconfig
+++ b/drivers/media/video/cx88/Kconfig
@@ -53,7 +53,6 @@ config VIDEO_CX88_DVB
53 select DVB_OR51132 if !DVB_FE_CUSTOMISE 53 select DVB_OR51132 if !DVB_FE_CUSTOMISE
54 select DVB_CX22702 if !DVB_FE_CUSTOMISE 54 select DVB_CX22702 if !DVB_FE_CUSTOMISE
55 select DVB_LGDT330X if !DVB_FE_CUSTOMISE 55 select DVB_LGDT330X if !DVB_FE_CUSTOMISE
56 select DVB_TUNER_LGH06XF if !DVB_FE_CUSTOMISE
57 select DVB_NXT200X if !DVB_FE_CUSTOMISE 56 select DVB_NXT200X if !DVB_FE_CUSTOMISE
58 select DVB_CX24123 if !DVB_FE_CUSTOMISE 57 select DVB_CX24123 if !DVB_FE_CUSTOMISE
59 select DVB_ISL6421 if !DVB_FE_CUSTOMISE 58 select DVB_ISL6421 if !DVB_FE_CUSTOMISE
diff --git a/drivers/media/video/cx88/cx88-alsa.c b/drivers/media/video/cx88/cx88-alsa.c
index e4355fdc3b6d..3956c257556c 100644
--- a/drivers/media/video/cx88/cx88-alsa.c
+++ b/drivers/media/video/cx88/cx88-alsa.c
@@ -232,7 +232,8 @@ static void cx8801_aud_irq(snd_cx88_card_t *chip)
232 cx_write(MO_AUD_INTSTAT, status); 232 cx_write(MO_AUD_INTSTAT, status);
233 if (debug > 1 || (status & mask & ~0xff)) 233 if (debug > 1 || (status & mask & ~0xff))
234 cx88_print_irqbits(core->name, "irq aud", 234 cx88_print_irqbits(core->name, "irq aud",
235 cx88_aud_irqs, status, mask); 235 cx88_aud_irqs, ARRAY_SIZE(cx88_aud_irqs),
236 status, mask);
236 /* risc op code error */ 237 /* risc op code error */
237 if (status & (1 << 16)) { 238 if (status & (1 << 16)) {
238 printk(KERN_WARNING "%s/0: audio risc op code error\n",core->name); 239 printk(KERN_WARNING "%s/0: audio risc op code error\n",core->name);
@@ -413,11 +414,9 @@ static int snd_cx88_hw_params(struct snd_pcm_substream * substream,
413 414
414 dprintk(1,"Setting buffer\n"); 415 dprintk(1,"Setting buffer\n");
415 416
416 buf = kmalloc(sizeof(*buf),GFP_KERNEL); 417 buf = kzalloc(sizeof(*buf),GFP_KERNEL);
417 if (NULL == buf) 418 if (NULL == buf)
418 return -ENOMEM; 419 return -ENOMEM;
419 memset(buf,0,sizeof(*buf));
420
421 420
422 buf->vb.memory = V4L2_MEMORY_MMAP; 421 buf->vb.memory = V4L2_MEMORY_MMAP;
423 buf->vb.width = chip->period_size; 422 buf->vb.width = chip->period_size;
@@ -682,7 +681,7 @@ static int __devinit snd_cx88_create(struct snd_card *card,
682 return err; 681 return err;
683 } 682 }
684 683
685 if (!pci_dma_supported(pci,0xffffffff)) { 684 if (!pci_dma_supported(pci,DMA_32BIT_MASK)) {
686 dprintk(0, "%s/1: Oops: no 32bit PCI DMA ???\n",core->name); 685 dprintk(0, "%s/1: Oops: no 32bit PCI DMA ???\n",core->name);
687 err = -EIO; 686 err = -EIO;
688 cx88_core_put(core,pci); 687 cx88_core_put(core,pci);
diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c
index 65e9d8096b74..e61102dc8ad7 100644
--- a/drivers/media/video/cx88/cx88-cards.c
+++ b/drivers/media/video/cx88/cx88-cards.c
@@ -885,6 +885,12 @@ struct cx88_board cx88_boards[] = {
885 .input = {{ 885 .input = {{
886 .type = CX88_VMUX_DVB, 886 .type = CX88_VMUX_DVB,
887 .vmux = 0, 887 .vmux = 0,
888 },{
889 .type = CX88_VMUX_COMPOSITE1,
890 .vmux = 1,
891 },{
892 .type = CX88_VMUX_SVIDEO,
893 .vmux = 2,
888 }}, 894 }},
889 .mpeg = CX88_MPEG_DVB, 895 .mpeg = CX88_MPEG_DVB,
890 }, 896 },
@@ -1537,10 +1543,10 @@ struct cx88_subid cx88_subids[] = {
1537 },{ 1543 },{
1538 .subvendor = 0x17de, 1544 .subvendor = 0x17de,
1539 .subdevice = 0x0840, 1545 .subdevice = 0x0840,
1540 .card = CX88_BOARD_KWORLD_HARDWARE_MPEG_TV_XPERT, 1546 .card = CX88_BOARD_KWORLD_HARDWARE_MPEG_TV_XPERT,
1541 },{ 1547 },{
1542 .subvendor = 0x1421, 1548 .subvendor = 0x1421,
1543 .subdevice = 0x0305, 1549 .subdevice = 0x0305,
1544 .card = CX88_BOARD_KWORLD_HARDWARE_MPEG_TV_XPERT, 1550 .card = CX88_BOARD_KWORLD_HARDWARE_MPEG_TV_XPERT,
1545 },{ 1551 },{
1546 .subvendor = 0x18ac, 1552 .subvendor = 0x18ac,
@@ -1631,6 +1637,10 @@ struct cx88_subid cx88_subids[] = {
1631 .subvendor = 0x0070, 1637 .subvendor = 0x0070,
1632 .subdevice = 0x1402, 1638 .subdevice = 0x1402,
1633 .card = CX88_BOARD_HAUPPAUGE_HVR3000, 1639 .card = CX88_BOARD_HAUPPAUGE_HVR3000,
1640 },{
1641 .subvendor = 0x1421,
1642 .subdevice = 0x0341, /* ADS Tech InstantTV DVB-S */
1643 .card = CX88_BOARD_KWORLD_DVBS_100,
1634 }, 1644 },
1635}; 1645};
1636const unsigned int cx88_idcount = ARRAY_SIZE(cx88_subids); 1646const unsigned int cx88_idcount = ARRAY_SIZE(cx88_subids);
@@ -1786,7 +1796,7 @@ static void dvico_fusionhdtv_hybrid_init(struct cx88_core *core)
1786 { 0x03, 0x0C }, 1796 { 0x03, 0x0C },
1787 }; 1797 };
1788 1798
1789 for (i = 0; i < 13; i++) { 1799 for (i = 0; i < ARRAY_SIZE(init_bufs); i++) {
1790 msg.buf = init_bufs[i]; 1800 msg.buf = init_bufs[i];
1791 msg.len = (i != 12 ? 5 : 2); 1801 msg.len = (i != 12 ? 5 : 2);
1792 err = i2c_transfer(&core->i2c_adap, &msg, 1); 1802 err = i2c_transfer(&core->i2c_adap, &msg, 1);
@@ -1913,12 +1923,21 @@ void cx88_card_setup(struct cx88_core *core)
1913 if (0 == core->i2c_rc) { 1923 if (0 == core->i2c_rc) {
1914 /* enable tuner */ 1924 /* enable tuner */
1915 int i; 1925 int i;
1916 static const u8 buffer [] = { 0x10,0x12,0x13,0x04,0x16,0x00,0x14,0x04,0x017,0x00 }; 1926 static const u8 buffer [][2] = {
1927 {0x10,0x12},
1928 {0x13,0x04},
1929 {0x16,0x00},
1930 {0x14,0x04},
1931 {0x17,0x00}
1932 };
1917 core->i2c_client.addr = 0x0a; 1933 core->i2c_client.addr = 0x0a;
1918 1934
1919 for (i = 0; i < 5; i++) 1935 for (i = 0; i < ARRAY_SIZE(buffer); i++)
1920 if (2 != i2c_master_send(&core->i2c_client,&buffer[i*2],2)) 1936 if (2 != i2c_master_send(&core->i2c_client,
1921 printk(KERN_WARNING "%s: Unable to enable tuner(%i).\n", 1937 buffer[i],2))
1938 printk(KERN_WARNING
1939 "%s: Unable to enable "
1940 "tuner(%i).\n",
1922 core->name, i); 1941 core->name, i);
1923 } 1942 }
1924 break; 1943 break;
diff --git a/drivers/media/video/cx88/cx88-core.c b/drivers/media/video/cx88/cx88-core.c
index d86813be56de..f31ec96924b9 100644
--- a/drivers/media/video/cx88/cx88-core.c
+++ b/drivers/media/video/cx88/cx88-core.c
@@ -489,12 +489,12 @@ static char *cx88_pci_irqs[32] = {
489}; 489};
490 490
491void cx88_print_irqbits(char *name, char *tag, char **strings, 491void cx88_print_irqbits(char *name, char *tag, char **strings,
492 u32 bits, u32 mask) 492 int len, u32 bits, u32 mask)
493{ 493{
494 unsigned int i; 494 unsigned int i;
495 495
496 printk(KERN_DEBUG "%s: %s [0x%x]", name, tag, bits); 496 printk(KERN_DEBUG "%s: %s [0x%x]", name, tag, bits);
497 for (i = 0; i < 32; i++) { 497 for (i = 0; i < len; i++) {
498 if (!(bits & (1 << i))) 498 if (!(bits & (1 << i)))
499 continue; 499 continue;
500 if (strings[i]) 500 if (strings[i])
@@ -520,8 +520,8 @@ int cx88_core_irq(struct cx88_core *core, u32 status)
520 } 520 }
521 if (!handled) 521 if (!handled)
522 cx88_print_irqbits(core->name, "irq pci", 522 cx88_print_irqbits(core->name, "irq pci",
523 cx88_pci_irqs, status, 523 cx88_pci_irqs, ARRAY_SIZE(cx88_pci_irqs),
524 core->pci_irqmask); 524 status, core->pci_irqmask);
525 return handled; 525 return handled;
526} 526}
527 527
diff --git a/drivers/media/video/cx88/cx88-dvb.c b/drivers/media/video/cx88/cx88-dvb.c
index 4f5560285770..dbfe4dc9cf8c 100644
--- a/drivers/media/video/cx88/cx88-dvb.c
+++ b/drivers/media/video/cx88/cx88-dvb.c
@@ -42,7 +42,6 @@
42#include "cx22702.h" 42#include "cx22702.h"
43#include "or51132.h" 43#include "or51132.h"
44#include "lgdt330x.h" 44#include "lgdt330x.h"
45#include "lgh06xf.h"
46#include "nxt200x.h" 45#include "nxt200x.h"
47#include "cx24123.h" 46#include "cx24123.h"
48#include "isl6421.h" 47#include "isl6421.h"
@@ -476,6 +475,8 @@ static int dvb_register(struct cx8802_dev *dev)
476 case CX88_BOARD_WINFAST_DTV2000H: 475 case CX88_BOARD_WINFAST_DTV2000H:
477 case CX88_BOARD_HAUPPAUGE_HVR1100: 476 case CX88_BOARD_HAUPPAUGE_HVR1100:
478 case CX88_BOARD_HAUPPAUGE_HVR1100LP: 477 case CX88_BOARD_HAUPPAUGE_HVR1100LP:
478 case CX88_BOARD_HAUPPAUGE_HVR1300:
479 case CX88_BOARD_HAUPPAUGE_HVR3000:
479 dev->dvb.frontend = dvb_attach(cx22702_attach, 480 dev->dvb.frontend = dvb_attach(cx22702_attach,
480 &hauppauge_hvr_config, 481 &hauppauge_hvr_config,
481 &dev->core->i2c_adap); 482 &dev->core->i2c_adap);
@@ -631,8 +632,9 @@ static int dvb_register(struct cx8802_dev *dev)
631 &fusionhdtv_5_gold, 632 &fusionhdtv_5_gold,
632 &dev->core->i2c_adap); 633 &dev->core->i2c_adap);
633 if (dev->dvb.frontend != NULL) { 634 if (dev->dvb.frontend != NULL) {
634 dvb_attach(lgh06xf_attach, dev->dvb.frontend, 635 dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61,
635 &dev->core->i2c_adap); 636 &dev->core->i2c_adap,
637 &dvb_pll_lg_tdvs_h06xf);
636 } 638 }
637 } 639 }
638 break; 640 break;
@@ -650,8 +652,9 @@ static int dvb_register(struct cx8802_dev *dev)
650 &pchdtv_hd5500, 652 &pchdtv_hd5500,
651 &dev->core->i2c_adap); 653 &dev->core->i2c_adap);
652 if (dev->dvb.frontend != NULL) { 654 if (dev->dvb.frontend != NULL) {
653 dvb_attach(lgh06xf_attach, dev->dvb.frontend, 655 dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61,
654 &dev->core->i2c_adap); 656 &dev->core->i2c_adap,
657 &dvb_pll_lg_tdvs_h06xf);
655 } 658 }
656 } 659 }
657 break; 660 break;
@@ -692,24 +695,6 @@ static int dvb_register(struct cx8802_dev *dev)
692 dev->dvb.frontend->ops.set_voltage = geniatech_dvbs_set_voltage; 695 dev->dvb.frontend->ops.set_voltage = geniatech_dvbs_set_voltage;
693 } 696 }
694 break; 697 break;
695 case CX88_BOARD_HAUPPAUGE_HVR1300:
696 dev->dvb.frontend = dvb_attach(cx22702_attach,
697 &hauppauge_hvr_config,
698 &dev->core->i2c_adap);
699 if (dev->dvb.frontend != NULL) {
700 dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61,
701 &dev->core->i2c_adap, &dvb_pll_fmd1216me);
702 }
703 break;
704 case CX88_BOARD_HAUPPAUGE_HVR3000:
705 dev->dvb.frontend = dvb_attach(cx22702_attach,
706 &hauppauge_hvr_config,
707 &dev->core->i2c_adap);
708 if (dev->dvb.frontend != NULL) {
709 dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61,
710 &dev->core->i2c_adap, &dvb_pll_fmd1216me);
711 }
712 break;
713 default: 698 default:
714 printk("%s: The frontend of your DVB/ATSC card isn't supported yet\n", 699 printk("%s: The frontend of your DVB/ATSC card isn't supported yet\n",
715 dev->core->name); 700 dev->core->name);
diff --git a/drivers/media/video/cx88/cx88-i2c.c b/drivers/media/video/cx88/cx88-i2c.c
index 9830d5c43921..7919a1f9da06 100644
--- a/drivers/media/video/cx88/cx88-i2c.c
+++ b/drivers/media/video/cx88/cx88-i2c.c
@@ -1,3 +1,4 @@
1
1/* 2/*
2 3
3 cx88-i2c.c -- all the i2c code is here 4 cx88-i2c.c -- all the i2c code is here
@@ -195,7 +196,7 @@ static void do_i2c_scan(char *name, struct i2c_client *c)
195 unsigned char buf; 196 unsigned char buf;
196 int i,rc; 197 int i,rc;
197 198
198 for (i = 0; i < 128; i++) { 199 for (i = 0; i < ARRAY_SIZE(i2c_devs); i++) {
199 c->addr = i; 200 c->addr = i;
200 rc = i2c_master_recv(c,&buf,0); 201 rc = i2c_master_recv(c,&buf,0);
201 if (rc < 0) 202 if (rc < 0)
diff --git a/drivers/media/video/cx88/cx88-mpeg.c b/drivers/media/video/cx88/cx88-mpeg.c
index 1fe1a833c7c7..b2eb32e01aee 100644
--- a/drivers/media/video/cx88/cx88-mpeg.c
+++ b/drivers/media/video/cx88/cx88-mpeg.c
@@ -49,6 +49,27 @@ MODULE_PARM_DESC(debug,"enable debug messages [mpeg]");
49#define mpeg_dbg(level,fmt, arg...) if (debug >= level) \ 49#define mpeg_dbg(level,fmt, arg...) if (debug >= level) \
50 printk(KERN_DEBUG "%s/2-mpeg: " fmt, core->name, ## arg) 50 printk(KERN_DEBUG "%s/2-mpeg: " fmt, core->name, ## arg)
51 51
52#if defined(CONFIG_MODULES) && defined(MODULE)
53static void request_module_async(struct work_struct *work)
54{
55 struct cx8802_dev *dev=container_of(work, struct cx8802_dev, request_module_wk);
56
57 if (cx88_boards[dev->core->board].mpeg & CX88_MPEG_DVB)
58 request_module("cx88-dvb");
59 if (cx88_boards[dev->core->board].mpeg & CX88_MPEG_BLACKBIRD)
60 request_module("cx88-blackbird");
61}
62
63static void request_modules(struct cx8802_dev *dev)
64{
65 INIT_WORK(&dev->request_module_wk, request_module_async);
66 schedule_work(&dev->request_module_wk);
67}
68#else
69#define request_modules(dev)
70#endif /* CONFIG_MODULES */
71
72
52static LIST_HEAD(cx8802_devlist); 73static LIST_HEAD(cx8802_devlist);
53/* ------------------------------------------------------------------ */ 74/* ------------------------------------------------------------------ */
54 75
@@ -345,7 +366,8 @@ static void cx8802_mpeg_irq(struct cx8802_dev *dev)
345 366
346 if (debug || (status & mask & ~0xff)) 367 if (debug || (status & mask & ~0xff))
347 cx88_print_irqbits(core->name, "irq mpeg ", 368 cx88_print_irqbits(core->name, "irq mpeg ",
348 cx88_mpeg_irqs, status, mask); 369 cx88_mpeg_irqs, ARRAY_SIZE(cx88_mpeg_irqs),
370 status, mask);
349 371
350 /* risc op code error */ 372 /* risc op code error */
351 if (status & (1 << 16)) { 373 if (status & (1 << 16)) {
@@ -427,7 +449,7 @@ int cx8802_init_common(struct cx8802_dev *dev)
427 if (pci_enable_device(dev->pci)) 449 if (pci_enable_device(dev->pci))
428 return -EIO; 450 return -EIO;
429 pci_set_master(dev->pci); 451 pci_set_master(dev->pci);
430 if (!pci_dma_supported(dev->pci,0xffffffff)) { 452 if (!pci_dma_supported(dev->pci,DMA_32BIT_MASK)) {
431 printk("%s/2: Oops: no 32bit PCI DMA ???\n",dev->core->name); 453 printk("%s/2: Oops: no 32bit PCI DMA ???\n",dev->core->name);
432 return -EIO; 454 return -EIO;
433 } 455 }
@@ -778,6 +800,9 @@ static int __devinit cx8802_probe(struct pci_dev *pci_dev,
778 800
779 /* Maintain a reference so cx88-video can query the 8802 device. */ 801 /* Maintain a reference so cx88-video can query the 8802 device. */
780 core->dvbdev = dev; 802 core->dvbdev = dev;
803
804 /* now autoload cx88-dvb or cx88-blackbird */
805 request_modules(dev);
781 return 0; 806 return 0;
782 807
783 fail_free: 808 fail_free:
diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c
index bdfe2af70124..fbce1d50578b 100644
--- a/drivers/media/video/cx88/cx88-video.c
+++ b/drivers/media/video/cx88/cx88-video.c
@@ -1555,7 +1555,8 @@ static void cx8800_vid_irq(struct cx8800_dev *dev)
1555 cx_write(MO_VID_INTSTAT, status); 1555 cx_write(MO_VID_INTSTAT, status);
1556 if (irq_debug || (status & mask & ~0xff)) 1556 if (irq_debug || (status & mask & ~0xff))
1557 cx88_print_irqbits(core->name, "irq vid", 1557 cx88_print_irqbits(core->name, "irq vid",
1558 cx88_vid_irqs, status, mask); 1558 cx88_vid_irqs, ARRAY_SIZE(cx88_vid_irqs),
1559 status, mask);
1559 1560
1560 /* risc op code error */ 1561 /* risc op code error */
1561 if (status & (1 << 16)) { 1562 if (status & (1 << 16)) {
@@ -1778,7 +1779,7 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev,
1778 dev->pci_lat,(unsigned long long)pci_resource_start(pci_dev,0)); 1779 dev->pci_lat,(unsigned long long)pci_resource_start(pci_dev,0));
1779 1780
1780 pci_set_master(pci_dev); 1781 pci_set_master(pci_dev);
1781 if (!pci_dma_supported(pci_dev,0xffffffff)) { 1782 if (!pci_dma_supported(pci_dev,DMA_32BIT_MASK)) {
1782 printk("%s/0: Oops: no 32bit PCI DMA ???\n",core->name); 1783 printk("%s/0: Oops: no 32bit PCI DMA ???\n",core->name);
1783 err = -EIO; 1784 err = -EIO;
1784 goto fail_core; 1785 goto fail_core;
diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h
index a4f7befda5b0..738d4f20c580 100644
--- a/drivers/media/video/cx88/cx88.h
+++ b/drivers/media/video/cx88/cx88.h
@@ -481,6 +481,8 @@ struct cx8802_dev {
481 481
482 /* List of attached drivers */ 482 /* List of attached drivers */
483 struct cx8802_driver drvlist; 483 struct cx8802_driver drvlist;
484 struct work_struct request_module_wk;
485
484}; 486};
485 487
486/* ----------------------------------------------------------- */ 488/* ----------------------------------------------------------- */
@@ -510,7 +512,7 @@ struct cx8802_dev {
510/* cx88-core.c */ 512/* cx88-core.c */
511 513
512extern void cx88_print_irqbits(char *name, char *tag, char **strings, 514extern void cx88_print_irqbits(char *name, char *tag, char **strings,
513 u32 bits, u32 mask); 515 int len, u32 bits, u32 mask);
514 516
515extern int cx88_core_irq(struct cx88_core *core, u32 status); 517extern int cx88_core_irq(struct cx88_core *core, u32 status);
516extern void cx88_wakeup(struct cx88_core *core, 518extern void cx88_wakeup(struct cx88_core *core,
diff --git a/drivers/media/video/em28xx/em28xx-i2c.c b/drivers/media/video/em28xx/em28xx-i2c.c
index d829d8f8c1f6..563a8319e608 100644
--- a/drivers/media/video/em28xx/em28xx-i2c.c
+++ b/drivers/media/video/em28xx/em28xx-i2c.c
@@ -523,7 +523,7 @@ static void do_i2c_scan(char *name, struct i2c_client *c)
523 unsigned char buf; 523 unsigned char buf;
524 int i, rc; 524 int i, rc;
525 525
526 for (i = 0; i < 128; i++) { 526 for (i = 0; i < ARRAY_SIZE(i2c_devs); i++) {
527 c->addr = i; 527 c->addr = i;
528 rc = i2c_master_recv(c, &buf, 0); 528 rc = i2c_master_recv(c, &buf, 0);
529 if (rc < 0) 529 if (rc < 0)
diff --git a/drivers/media/video/ir-kbd-i2c.c b/drivers/media/video/ir-kbd-i2c.c
index 210582d420f8..ed92b6f7187a 100644
--- a/drivers/media/video/ir-kbd-i2c.c
+++ b/drivers/media/video/ir-kbd-i2c.c
@@ -173,7 +173,7 @@ static int get_key_pinnacle(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw,
173 return -EIO; 173 return -EIO;
174 } 174 }
175 175
176 for (start = 0; start<4; start++) { 176 for (start = 0; start < ARRAY_SIZE(b); start++) {
177 if (b[start] == marker) { 177 if (b[start] == marker) {
178 code=b[(start+parity_offset+1)%4]; 178 code=b[(start+parity_offset+1)%4];
179 parity=b[(start+parity_offset)%4]; 179 parity=b[(start+parity_offset)%4];
diff --git a/drivers/media/video/ivtv/Kconfig b/drivers/media/video/ivtv/Kconfig
new file mode 100644
index 000000000000..e854f3f1b70f
--- /dev/null
+++ b/drivers/media/video/ivtv/Kconfig
@@ -0,0 +1,26 @@
1config VIDEO_IVTV
2 tristate "Conexant cx23416/cx23415 MPEG encoder/decoder support"
3 depends on VIDEO_V4L1 && VIDEO_V4L2 && USB && I2C && EXPERIMENTAL
4 select FW_LOADER
5 select VIDEO_TUNER
6 select VIDEO_TVEEPROM
7 select VIDEO_CX2341X
8 select VIDEO_CX25840
9 select VIDEO_MSP3400
10 select VIDEO_SAA711X
11 select VIDEO_SAA7127
12 select VIDEO_TVAUDIO
13 select VIDEO_CS53L32A
14 select VIDEO_WM8775
15 select VIDEO_WM8739
16 select VIDEO_UPD64031A
17 select VIDEO_UPD64083
18 ---help---
19 This is a video4linux driver for Conexant cx23416 or cx23416 based
20 PCI personal video recorder devices.
21
22 This is used in devices such as the Hauppauge PVR-150/250/350/500
23 cards.
24
25 To compile this driver as a module, choose M here: the
26 module will be called ivtv.
diff --git a/drivers/media/video/ivtv/Makefile b/drivers/media/video/ivtv/Makefile
new file mode 100644
index 000000000000..7e95148fbf4f
--- /dev/null
+++ b/drivers/media/video/ivtv/Makefile
@@ -0,0 +1,7 @@
1ivtv-objs := ivtv-audio.o ivtv-cards.o ivtv-controls.o \
2 ivtv-driver.o ivtv-fileops.o ivtv-firmware.o \
3 ivtv-gpio.o ivtv-i2c.o ivtv-ioctl.o ivtv-irq.o \
4 ivtv-mailbox.o ivtv-queue.o ivtv-streams.o ivtv-udma.o \
5 ivtv-vbi.o ivtv-video.o ivtv-yuv.o
6
7obj-$(CONFIG_VIDEO_IVTV) += ivtv.o
diff --git a/drivers/media/video/ivtv/ivtv-audio.c b/drivers/media/video/ivtv/ivtv-audio.c
new file mode 100644
index 000000000000..d702b8b539a1
--- /dev/null
+++ b/drivers/media/video/ivtv/ivtv-audio.c
@@ -0,0 +1,74 @@
1/*
2 Audio-related ivtv functions.
3 Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
4 Copyright (C) 2005-2007 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#include "ivtv-driver.h"
22#include "ivtv-mailbox.h"
23#include "ivtv-i2c.h"
24#include "ivtv-gpio.h"
25#include "ivtv-cards.h"
26#include "ivtv-audio.h"
27#include <media/msp3400.h>
28#include <linux/videodev.h>
29
30/* Selects the audio input and output according to the current
31 settings. */
32int ivtv_audio_set_io(struct ivtv *itv)
33{
34 struct v4l2_routing route;
35 u32 audio_input;
36 int mux_input;
37
38 /* Determine which input to use */
39 if (test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags)) {
40 audio_input = itv->card->radio_input.audio_input;
41 mux_input = itv->card->radio_input.muxer_input;
42 } else {
43 audio_input = itv->card->audio_inputs[itv->audio_input].audio_input;
44 mux_input = itv->card->audio_inputs[itv->audio_input].muxer_input;
45 }
46
47 /* handle muxer chips */
48 route.input = mux_input;
49 route.output = 0;
50 ivtv_i2c_hw(itv, itv->card->hw_muxer, VIDIOC_INT_S_AUDIO_ROUTING, &route);
51
52 route.input = audio_input;
53 if (itv->card->hw_audio & IVTV_HW_MSP34XX) {
54 route.output = MSP_OUTPUT(MSP_SC_IN_DSP_SCART1);
55 }
56 return ivtv_i2c_hw(itv, itv->card->hw_audio, VIDIOC_INT_S_AUDIO_ROUTING, &route);
57}
58
59void ivtv_audio_set_route(struct ivtv *itv, struct v4l2_routing *route)
60{
61 ivtv_i2c_hw(itv, itv->card->hw_audio, VIDIOC_INT_S_AUDIO_ROUTING, route);
62}
63
64void ivtv_audio_set_audio_clock_freq(struct ivtv *itv, u8 freq)
65{
66 static u32 freqs[3] = { 44100, 48000, 32000 };
67
68 /* The audio clock of the digitizer must match the codec sample
69 rate otherwise you get some very strange effects. */
70 if (freq > 2)
71 return;
72 ivtv_call_i2c_clients(itv, VIDIOC_INT_AUDIO_CLOCK_FREQ, &freqs[freq]);
73}
74
diff --git a/drivers/media/video/ivtv/ivtv-audio.h b/drivers/media/video/ivtv/ivtv-audio.h
new file mode 100644
index 000000000000..9c42846d8124
--- /dev/null
+++ b/drivers/media/video/ivtv/ivtv-audio.h
@@ -0,0 +1,23 @@
1/*
2 Audio-related ivtv functions.
3 Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
4 Copyright (C) 2005-2007 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21int ivtv_audio_set_io(struct ivtv *itv);
22void ivtv_audio_set_route(struct ivtv *itv, struct v4l2_routing *route);
23void ivtv_audio_set_audio_clock_freq(struct ivtv *itv, u8 freq);
diff --git a/drivers/media/video/ivtv/ivtv-cards.c b/drivers/media/video/ivtv/ivtv-cards.c
new file mode 100644
index 000000000000..8eab02083887
--- /dev/null
+++ b/drivers/media/video/ivtv/ivtv-cards.c
@@ -0,0 +1,964 @@
1/*
2 Functions to query card hardware
3 Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
4 Copyright (C) 2005-2007 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#include "ivtv-driver.h"
22#include "ivtv-cards.h"
23#include "ivtv-i2c.h"
24
25#include <media/msp3400.h>
26#include <media/wm8775.h>
27#include <media/cs53l32a.h>
28#include <media/cx25840.h>
29#include <media/upd64031a.h>
30
31#define MSP_TUNER MSP_INPUT(MSP_IN_SCART1, MSP_IN_TUNER1, \
32 MSP_DSP_IN_TUNER, MSP_DSP_IN_TUNER)
33#define MSP_SCART1 MSP_INPUT(MSP_IN_SCART1, MSP_IN_TUNER1, \
34 MSP_DSP_IN_SCART, MSP_DSP_IN_SCART)
35#define MSP_SCART2 MSP_INPUT(MSP_IN_SCART2, MSP_IN_TUNER1, \
36 MSP_DSP_IN_SCART, MSP_DSP_IN_SCART)
37#define MSP_SCART3 MSP_INPUT(MSP_IN_SCART3, MSP_IN_TUNER1, \
38 MSP_DSP_IN_SCART, MSP_DSP_IN_SCART)
39#define MSP_MONO MSP_INPUT(MSP_IN_MONO, MSP_IN_TUNER1, \
40 MSP_DSP_IN_SCART, MSP_DSP_IN_SCART)
41
42/********************** card configuration *******************************/
43
44/* Please add new PCI IDs to: http://pci-ids.ucw.cz/iii
45 This keeps the PCI ID database up to date. Note that the entries
46 must be added under vendor 0x4444 (Conexant) as subsystem IDs.
47 New vendor IDs should still be added to the vendor ID list. */
48
49/* Hauppauge PVR-250 cards */
50
51/* Note: for Hauppauge cards the tveeprom information is used instead of PCI IDs */
52static const struct ivtv_card ivtv_card_pvr250 = {
53 .type = IVTV_CARD_PVR_250,
54 .name = "Hauppauge WinTV PVR-250",
55 .v4l2_capabilities = IVTV_CAP_ENCODER,
56 .hw_video = IVTV_HW_SAA7115,
57 .hw_audio = IVTV_HW_MSP34XX,
58 .hw_audio_ctrl = IVTV_HW_MSP34XX,
59 .hw_all = IVTV_HW_MSP34XX | IVTV_HW_SAA7115 |
60 IVTV_HW_TVEEPROM | IVTV_HW_TUNER,
61 .video_inputs = {
62 { IVTV_CARD_INPUT_VID_TUNER, 0, IVTV_SAA71XX_COMPOSITE4 },
63 { IVTV_CARD_INPUT_SVIDEO1, 1, IVTV_SAA71XX_SVIDEO0 },
64 { IVTV_CARD_INPUT_COMPOSITE1, 1, IVTV_SAA71XX_COMPOSITE0 },
65 { IVTV_CARD_INPUT_SVIDEO2, 2, IVTV_SAA71XX_SVIDEO1 },
66 { IVTV_CARD_INPUT_COMPOSITE2, 2, IVTV_SAA71XX_COMPOSITE1 },
67 { IVTV_CARD_INPUT_COMPOSITE3, 1, IVTV_SAA71XX_COMPOSITE5 },
68 },
69 .audio_inputs = {
70 { IVTV_CARD_INPUT_AUD_TUNER, MSP_TUNER },
71 { IVTV_CARD_INPUT_LINE_IN1, MSP_SCART1 },
72 { IVTV_CARD_INPUT_LINE_IN2, MSP_SCART3 },
73 },
74 .radio_input = { IVTV_CARD_INPUT_AUD_TUNER, MSP_SCART2 },
75};
76
77/* ------------------------------------------------------------------------- */
78
79/* Hauppauge PVR-350 cards */
80
81/* Outputs for Hauppauge PVR350 cards */
82static struct ivtv_card_output ivtv_pvr350_outputs[] = {
83 {
84 .name = "S-Video + Composite",
85 .video_output = 0,
86 }, {
87 .name = "Composite",
88 .video_output = 1,
89 }, {
90 .name = "S-Video",
91 .video_output = 2,
92 }, {
93 .name = "RGB",
94 .video_output = 3,
95 }, {
96 .name = "YUV C",
97 .video_output = 4,
98 }, {
99 .name = "YUV V",
100 .video_output = 5,
101 }
102};
103
104static const struct ivtv_card ivtv_card_pvr350 = {
105 .type = IVTV_CARD_PVR_350,
106 .name = "Hauppauge WinTV PVR-350",
107 .v4l2_capabilities = IVTV_CAP_ENCODER | IVTV_CAP_DECODER,
108 .video_outputs = ivtv_pvr350_outputs,
109 .nof_outputs = ARRAY_SIZE(ivtv_pvr350_outputs),
110 .hw_video = IVTV_HW_SAA7115,
111 .hw_audio = IVTV_HW_MSP34XX,
112 .hw_audio_ctrl = IVTV_HW_MSP34XX,
113 .hw_all = IVTV_HW_MSP34XX | IVTV_HW_SAA7115 |
114 IVTV_HW_SAA7127 | IVTV_HW_TVEEPROM | IVTV_HW_TUNER,
115 .video_inputs = {
116 { IVTV_CARD_INPUT_VID_TUNER, 0, IVTV_SAA71XX_COMPOSITE4 },
117 { IVTV_CARD_INPUT_SVIDEO1, 1, IVTV_SAA71XX_SVIDEO0 },
118 { IVTV_CARD_INPUT_COMPOSITE1, 1, IVTV_SAA71XX_COMPOSITE0 },
119 { IVTV_CARD_INPUT_SVIDEO2, 2, IVTV_SAA71XX_SVIDEO1 },
120 { IVTV_CARD_INPUT_COMPOSITE2, 2, IVTV_SAA71XX_COMPOSITE1 },
121 { IVTV_CARD_INPUT_COMPOSITE3, 1, IVTV_SAA71XX_COMPOSITE5 },
122 },
123 .audio_inputs = {
124 { IVTV_CARD_INPUT_AUD_TUNER, MSP_TUNER },
125 { IVTV_CARD_INPUT_LINE_IN1, MSP_SCART1 },
126 { IVTV_CARD_INPUT_LINE_IN2, MSP_SCART3 },
127 },
128 .radio_input = { IVTV_CARD_INPUT_AUD_TUNER, MSP_SCART2 },
129};
130
131/* PVR-350 V1 boards have a different audio tuner input and use a
132 saa7114 instead of a saa7115.
133 Note that the info below comes from a pre-production model so it may
134 not be correct. Especially the audio behaves strangely (mono only it seems) */
135static const struct ivtv_card ivtv_card_pvr350_v1 = {
136 .type = IVTV_CARD_PVR_350_V1,
137 .name = "Hauppauge WinTV PVR-350 (V1)",
138 .v4l2_capabilities = IVTV_CAP_ENCODER | IVTV_CAP_DECODER,
139 .video_outputs = ivtv_pvr350_outputs,
140 .nof_outputs = ARRAY_SIZE(ivtv_pvr350_outputs),
141 .hw_video = IVTV_HW_SAA7114,
142 .hw_audio = IVTV_HW_MSP34XX,
143 .hw_audio_ctrl = IVTV_HW_MSP34XX,
144 .hw_all = IVTV_HW_MSP34XX | IVTV_HW_SAA7114 |
145 IVTV_HW_SAA7127 | IVTV_HW_TVEEPROM | IVTV_HW_TUNER,
146 .video_inputs = {
147 { IVTV_CARD_INPUT_VID_TUNER, 0, IVTV_SAA71XX_COMPOSITE4 },
148 { IVTV_CARD_INPUT_SVIDEO1, 1, IVTV_SAA71XX_SVIDEO0 },
149 { IVTV_CARD_INPUT_COMPOSITE1, 1, IVTV_SAA71XX_COMPOSITE0 },
150 { IVTV_CARD_INPUT_SVIDEO2, 2, IVTV_SAA71XX_SVIDEO1 },
151 { IVTV_CARD_INPUT_COMPOSITE2, 2, IVTV_SAA71XX_COMPOSITE1 },
152 { IVTV_CARD_INPUT_COMPOSITE3, 1, IVTV_SAA71XX_COMPOSITE5 },
153 },
154 .audio_inputs = {
155 { IVTV_CARD_INPUT_AUD_TUNER, MSP_MONO },
156 { IVTV_CARD_INPUT_LINE_IN1, MSP_SCART1 },
157 { IVTV_CARD_INPUT_LINE_IN2, MSP_SCART3 },
158 },
159 .radio_input = { IVTV_CARD_INPUT_AUD_TUNER, MSP_SCART2 },
160};
161
162/* ------------------------------------------------------------------------- */
163
164/* Hauppauge PVR-150/PVR-500 cards */
165
166static const struct ivtv_card ivtv_card_pvr150 = {
167 .type = IVTV_CARD_PVR_150,
168 .name = "Hauppauge WinTV PVR-150",
169 .v4l2_capabilities = IVTV_CAP_ENCODER,
170 .hw_video = IVTV_HW_CX25840,
171 .hw_audio = IVTV_HW_CX25840,
172 .hw_audio_ctrl = IVTV_HW_CX25840,
173 .hw_muxer = IVTV_HW_WM8775,
174 .hw_all = IVTV_HW_WM8775 | IVTV_HW_CX25840 |
175 IVTV_HW_TVEEPROM | IVTV_HW_TUNER,
176 .video_inputs = {
177 { IVTV_CARD_INPUT_VID_TUNER, 0, CX25840_COMPOSITE7 },
178 { IVTV_CARD_INPUT_SVIDEO1, 1, CX25840_SVIDEO1 },
179 { IVTV_CARD_INPUT_COMPOSITE1, 1, CX25840_COMPOSITE3 },
180 { IVTV_CARD_INPUT_SVIDEO2, 2, CX25840_SVIDEO2 },
181 { IVTV_CARD_INPUT_COMPOSITE2, 2, CX25840_COMPOSITE4 },
182 },
183 .audio_inputs = {
184 { IVTV_CARD_INPUT_AUD_TUNER,
185 CX25840_AUDIO8, WM8775_AIN2 },
186 { IVTV_CARD_INPUT_LINE_IN1,
187 CX25840_AUDIO_SERIAL, WM8775_AIN2 },
188 { IVTV_CARD_INPUT_LINE_IN2,
189 CX25840_AUDIO_SERIAL, WM8775_AIN3 },
190 },
191 .radio_input = { IVTV_CARD_INPUT_AUD_TUNER,
192 CX25840_AUDIO_SERIAL, WM8775_AIN4 },
193 /* apparently needed for the IR blaster */
194 .gpio_init = { .direction = 0x1f01, .initial_value = 0x26f3 },
195};
196
197/* ------------------------------------------------------------------------- */
198
199/* AVerMedia M179 cards */
200
201static const struct ivtv_card_pci_info ivtv_pci_m179[] = {
202 { PCI_DEVICE_ID_IVTV15, IVTV_PCI_ID_AVERMEDIA, 0xa3cf },
203 { PCI_DEVICE_ID_IVTV15, IVTV_PCI_ID_AVERMEDIA, 0xa3ce },
204 { 0, 0, 0 }
205};
206
207static const struct ivtv_card ivtv_card_m179 = {
208 .type = IVTV_CARD_M179,
209 .name = "AVerMedia M179",
210 .v4l2_capabilities = IVTV_CAP_ENCODER,
211 .hw_video = IVTV_HW_SAA7114,
212 .hw_audio = IVTV_HW_GPIO,
213 .hw_audio_ctrl = IVTV_HW_GPIO,
214 .hw_all = IVTV_HW_GPIO | IVTV_HW_SAA7114 | IVTV_HW_TUNER,
215 .video_inputs = {
216 { IVTV_CARD_INPUT_VID_TUNER, 0, IVTV_SAA71XX_COMPOSITE4 },
217 { IVTV_CARD_INPUT_SVIDEO1, 1, IVTV_SAA71XX_SVIDEO0 },
218 { IVTV_CARD_INPUT_COMPOSITE1, 1, IVTV_SAA71XX_COMPOSITE3 },
219 },
220 .audio_inputs = {
221 { IVTV_CARD_INPUT_AUD_TUNER, IVTV_GPIO_TUNER },
222 { IVTV_CARD_INPUT_LINE_IN1, IVTV_GPIO_LINE_IN },
223 },
224 .gpio_init = { .direction = 0xe380, .initial_value = 0x8290 },
225 .gpio_audio_input = { .mask = 0x8040, .tuner = 0x8000, .linein = 0x0000 },
226 .gpio_audio_mute = { .mask = 0x2000, .mute = 0x2000 },
227 .gpio_audio_mode = { .mask = 0x4300, .mono = 0x4000, .stereo = 0x0200,
228 .lang1 = 0x0200, .lang2 = 0x0100, .both = 0x0000 },
229 .gpio_audio_freq = { .mask = 0x0018, .f32000 = 0x0000,
230 .f44100 = 0x0008, .f48000 = 0x0010 },
231 .gpio_audio_detect = { .mask = 0x4000, .stereo = 0x0000 },
232 .tuners = {
233 /* As far as we know all M179 cards use this tuner */
234 { .std = V4L2_STD_ALL, .tuner = TUNER_PHILIPS_NTSC },
235 },
236 .pci_list = ivtv_pci_m179,
237};
238
239/* ------------------------------------------------------------------------- */
240
241/* Yuan MPG600/Kuroutoshikou ITVC16-STVLP cards */
242
243static const struct ivtv_card_pci_info ivtv_pci_mpg600[] = {
244 { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_YUAN1, 0xfff3 },
245 { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_YUAN1, 0xffff },
246 { 0, 0, 0 }
247};
248
249static const struct ivtv_card ivtv_card_mpg600 = {
250 .type = IVTV_CARD_MPG600,
251 .name = "Yuan MPG600, Kuroutoshikou ITVC16-STVLP",
252 .v4l2_capabilities = IVTV_CAP_ENCODER,
253 .hw_video = IVTV_HW_SAA7115,
254 .hw_audio = IVTV_HW_GPIO,
255 .hw_audio_ctrl = IVTV_HW_GPIO,
256 .hw_all = IVTV_HW_GPIO | IVTV_HW_SAA7115 | IVTV_HW_TUNER,
257 .video_inputs = {
258 { IVTV_CARD_INPUT_VID_TUNER, 0, IVTV_SAA71XX_COMPOSITE4 },
259 { IVTV_CARD_INPUT_SVIDEO1, 1, IVTV_SAA71XX_SVIDEO0 },
260 { IVTV_CARD_INPUT_COMPOSITE1, 1, IVTV_SAA71XX_COMPOSITE3 },
261 },
262 .audio_inputs = {
263 { IVTV_CARD_INPUT_AUD_TUNER, IVTV_GPIO_TUNER },
264 { IVTV_CARD_INPUT_LINE_IN1, IVTV_GPIO_LINE_IN },
265 },
266 .gpio_init = { .direction = 0x3080, .initial_value = 0x0004 },
267 .gpio_audio_input = { .mask = 0x3000, .tuner = 0x0000, .linein = 0x2000 },
268 .gpio_audio_mute = { .mask = 0x0001, .mute = 0x0001 },
269 .gpio_audio_mode = { .mask = 0x000e, .mono = 0x0006, .stereo = 0x0004,
270 .lang1 = 0x0004, .lang2 = 0x0000, .both = 0x0008 },
271 .gpio_audio_detect = { .mask = 0x0900, .stereo = 0x0100 },
272 .tuners = {
273 /* The PAL tuner is confirmed */
274 { .std = V4L2_STD_625_50, .tuner = TUNER_PHILIPS_FQ1216ME },
275 { .std = V4L2_STD_ALL, .tuner = TUNER_PHILIPS_FQ1286 },
276 },
277 .pci_list = ivtv_pci_mpg600,
278};
279
280/* ------------------------------------------------------------------------- */
281
282/* Yuan MPG160/Kuroutoshikou ITVC15-STVLP cards */
283
284static const struct ivtv_card_pci_info ivtv_pci_mpg160[] = {
285 { PCI_DEVICE_ID_IVTV15, IVTV_PCI_ID_YUAN1, 0 },
286 { PCI_DEVICE_ID_IVTV15, IVTV_PCI_ID_IODATA, 0x40a0 },
287 { 0, 0, 0 }
288};
289
290static const struct ivtv_card ivtv_card_mpg160 = {
291 .type = IVTV_CARD_MPG160,
292 .name = "YUAN MPG160, Kuroutoshikou ITVC15-STVLP, I/O Data GV-M2TV/PCI",
293 .v4l2_capabilities = IVTV_CAP_ENCODER,
294 .hw_video = IVTV_HW_SAA7114,
295 .hw_audio = IVTV_HW_GPIO,
296 .hw_audio_ctrl = IVTV_HW_GPIO,
297 .hw_all = IVTV_HW_GPIO | IVTV_HW_SAA7114 | IVTV_HW_TUNER,
298 .video_inputs = {
299 { IVTV_CARD_INPUT_VID_TUNER, 0, IVTV_SAA71XX_COMPOSITE4 },
300 { IVTV_CARD_INPUT_SVIDEO1, 1, IVTV_SAA71XX_SVIDEO0 },
301 { IVTV_CARD_INPUT_COMPOSITE1, 1, IVTV_SAA71XX_COMPOSITE3 },
302 },
303 .audio_inputs = {
304 { IVTV_CARD_INPUT_AUD_TUNER, IVTV_GPIO_TUNER },
305 { IVTV_CARD_INPUT_LINE_IN1, IVTV_GPIO_LINE_IN },
306 },
307 .gpio_init = { .direction = 0x7080, .initial_value = 0x400c },
308 .gpio_audio_input = { .mask = 0x3000, .tuner = 0x0000, .linein = 0x2000 },
309 .gpio_audio_mute = { .mask = 0x0001, .mute = 0x0001 },
310 .gpio_audio_mode = { .mask = 0x000e, .mono = 0x0006, .stereo = 0x0004,
311 .lang1 = 0x0004, .lang2 = 0x0000, .both = 0x0008 },
312 .gpio_audio_detect = { .mask = 0x0900, .stereo = 0x0100 },
313 .tuners = {
314 { .std = V4L2_STD_625_50, .tuner = TUNER_PHILIPS_FQ1216ME },
315 { .std = V4L2_STD_ALL, .tuner = TUNER_PHILIPS_FQ1286 },
316 },
317 .pci_list = ivtv_pci_mpg160,
318};
319
320/* ------------------------------------------------------------------------- */
321
322/* Yuan PG600/Diamond PVR-550 cards */
323
324static const struct ivtv_card_pci_info ivtv_pci_pg600[] = {
325 { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_DIAMONDMM, 0x0070 },
326 { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_YUAN3, 0x0600 },
327 { 0, 0, 0 }
328};
329
330static const struct ivtv_card ivtv_card_pg600 = {
331 .type = IVTV_CARD_PG600,
332 .name = "Yuan PG600, Diamond PVR-550",
333 .v4l2_capabilities = IVTV_CAP_ENCODER,
334 .hw_video = IVTV_HW_CX25840,
335 .hw_audio = IVTV_HW_CX25840,
336 .hw_audio_ctrl = IVTV_HW_CX25840,
337 .hw_all = IVTV_HW_CX25840 | IVTV_HW_TUNER,
338 .video_inputs = {
339 { IVTV_CARD_INPUT_VID_TUNER, 0, CX25840_COMPOSITE2 },
340 { IVTV_CARD_INPUT_SVIDEO1, 1,
341 CX25840_SVIDEO_LUMA3 | CX25840_SVIDEO_CHROMA4 },
342 { IVTV_CARD_INPUT_COMPOSITE1, 1, CX25840_COMPOSITE1 },
343 },
344 .audio_inputs = {
345 { IVTV_CARD_INPUT_AUD_TUNER, CX25840_AUDIO5 },
346 { IVTV_CARD_INPUT_LINE_IN1, CX25840_AUDIO_SERIAL },
347 },
348 .tuners = {
349 { .std = V4L2_STD_625_50, .tuner = TUNER_PHILIPS_FQ1216ME },
350 { .std = V4L2_STD_ALL, .tuner = TUNER_PHILIPS_FQ1286 },
351 },
352 .pci_list = ivtv_pci_pg600,
353};
354
355/* ------------------------------------------------------------------------- */
356
357/* Adaptec VideOh! AVC-2410 card */
358
359static const struct ivtv_card_pci_info ivtv_pci_avc2410[] = {
360 { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_ADAPTEC, 0x0093 },
361 { 0, 0, 0 }
362};
363
364static const struct ivtv_card ivtv_card_avc2410 = {
365 .type = IVTV_CARD_AVC2410,
366 .name = "Adaptec VideOh! AVC-2410",
367 .v4l2_capabilities = IVTV_CAP_ENCODER,
368 .hw_video = IVTV_HW_SAA7115,
369 .hw_audio = IVTV_HW_MSP34XX,
370 .hw_audio_ctrl = IVTV_HW_MSP34XX,
371 .hw_muxer = IVTV_HW_CS53L32A,
372 .hw_all = IVTV_HW_MSP34XX | IVTV_HW_CS53L32A |
373 IVTV_HW_SAA7115 | IVTV_HW_TUNER,
374 .video_inputs = {
375 { IVTV_CARD_INPUT_VID_TUNER, 0, IVTV_SAA71XX_COMPOSITE4 },
376 { IVTV_CARD_INPUT_SVIDEO1, 1, IVTV_SAA71XX_SVIDEO0 },
377 { IVTV_CARD_INPUT_COMPOSITE1, 1, IVTV_SAA71XX_COMPOSITE3 },
378 },
379 .audio_inputs = {
380 { IVTV_CARD_INPUT_AUD_TUNER,
381 MSP_TUNER, CS53L32A_IN0 },
382 { IVTV_CARD_INPUT_LINE_IN1,
383 MSP_SCART1, CS53L32A_IN2 },
384 },
385 /* This card has no eeprom and in fact the Windows driver relies
386 on the country/region setting of the user to decide which tuner
387 is available. */
388 .tuners = {
389 /* This tuner has been verified for the AVC2410 */
390 { .std = V4L2_STD_625_50, .tuner = TUNER_PHILIPS_FM1216ME_MK3 },
391 /* This is a good guess, but I'm not totally sure this is
392 the correct tuner for NTSC. */
393 { .std = V4L2_STD_ALL, .tuner = TUNER_PHILIPS_FM1236_MK3 },
394 },
395 .pci_list = ivtv_pci_avc2410,
396};
397
398/* ------------------------------------------------------------------------- */
399
400/* Adaptec VideOh! AVC-2010 card */
401
402static const struct ivtv_card_pci_info ivtv_pci_avc2010[] = {
403 { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_ADAPTEC, 0x0092 },
404 { 0, 0, 0 }
405};
406
407static const struct ivtv_card ivtv_card_avc2010 = {
408 .type = IVTV_CARD_AVC2010,
409 .name = "Adaptec VideOh! AVC-2010",
410 .v4l2_capabilities = IVTV_CAP_ENCODER,
411 .hw_video = IVTV_HW_SAA7115,
412 .hw_audio = IVTV_HW_CS53L32A,
413 .hw_audio_ctrl = IVTV_HW_CS53L32A,
414 .hw_all = IVTV_HW_CS53L32A | IVTV_HW_SAA7115,
415 .video_inputs = {
416 { IVTV_CARD_INPUT_SVIDEO1, 0, IVTV_SAA71XX_SVIDEO0 },
417 { IVTV_CARD_INPUT_COMPOSITE1, 0, IVTV_SAA71XX_COMPOSITE3 },
418 },
419 .audio_inputs = {
420 { IVTV_CARD_INPUT_LINE_IN1, CS53L32A_IN2 },
421 },
422 /* Does not have a tuner */
423 .pci_list = ivtv_pci_avc2010,
424};
425
426/* ------------------------------------------------------------------------- */
427
428/* Nagase Transgear 5000TV card */
429
430static const struct ivtv_card_pci_info ivtv_pci_tg5000tv[] = {
431 { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_AVERMEDIA, 0xbfff },
432 { 0, 0, 0 }
433};
434
435static const struct ivtv_card ivtv_card_tg5000tv = {
436 .type = IVTV_CARD_TG5000TV,
437 .name = "Nagase Transgear 5000TV",
438 .v4l2_capabilities = IVTV_CAP_ENCODER,
439 .hw_video = IVTV_HW_SAA7114 | IVTV_HW_UPD64031A | IVTV_HW_UPD6408X |
440 IVTV_HW_GPIO,
441 .hw_audio = IVTV_HW_GPIO,
442 .hw_audio_ctrl = IVTV_HW_GPIO,
443 .hw_all = IVTV_HW_GPIO | IVTV_HW_SAA7114 | IVTV_HW_TUNER |
444 IVTV_HW_UPD64031A | IVTV_HW_UPD6408X,
445 .video_inputs = {
446 { IVTV_CARD_INPUT_VID_TUNER, 0, IVTV_SAA71XX_SVIDEO0 },
447 { IVTV_CARD_INPUT_SVIDEO1, 1, IVTV_SAA71XX_SVIDEO2 },
448 { IVTV_CARD_INPUT_COMPOSITE1, 1, IVTV_SAA71XX_SVIDEO2 },
449 },
450 .audio_inputs = {
451 { IVTV_CARD_INPUT_AUD_TUNER, IVTV_GPIO_TUNER },
452 { IVTV_CARD_INPUT_LINE_IN1, IVTV_GPIO_LINE_IN },
453 },
454 .gr_config = UPD64031A_VERTICAL_EXTERNAL,
455 .gpio_init = { .direction = 0xe080, .initial_value = 0x8000 },
456 .gpio_audio_input = { .mask = 0x8080, .tuner = 0x8000, .linein = 0x0080 },
457 .gpio_audio_mute = { .mask = 0x6000, .mute = 0x6000 },
458 .gpio_audio_mode = { .mask = 0x4300, .mono = 0x4000, .stereo = 0x0200,
459 .lang1 = 0x0300, .lang2 = 0x0000, .both = 0x0200 },
460 .gpio_video_input = { .mask = 0x0030, .tuner = 0x0000,
461 .composite = 0x0010, .svideo = 0x0020 },
462 .tuners = {
463 { .std = V4L2_STD_525_60, .tuner = TUNER_PHILIPS_FQ1286 },
464 },
465 .pci_list = ivtv_pci_tg5000tv,
466};
467
468/* ------------------------------------------------------------------------- */
469
470/* AOpen VA2000MAX-SNT6 card */
471
472static const struct ivtv_card_pci_info ivtv_pci_va2000[] = {
473 { PCI_DEVICE_ID_IVTV16, 0, 0xff5f },
474 { 0, 0, 0 }
475};
476
477static const struct ivtv_card ivtv_card_va2000 = {
478 .type = IVTV_CARD_VA2000MAX_SNT6,
479 .name = "AOpen VA2000MAX-SNT6",
480 .v4l2_capabilities = IVTV_CAP_ENCODER,
481 .hw_video = IVTV_HW_SAA7115 | IVTV_HW_UPD6408X,
482 .hw_audio = IVTV_HW_MSP34XX,
483 .hw_audio_ctrl = IVTV_HW_MSP34XX,
484 .hw_all = IVTV_HW_MSP34XX | IVTV_HW_SAA7115 |
485 IVTV_HW_UPD6408X | IVTV_HW_TUNER,
486 .video_inputs = {
487 { IVTV_CARD_INPUT_VID_TUNER, 0, IVTV_SAA71XX_SVIDEO0 },
488 },
489 .audio_inputs = {
490 { IVTV_CARD_INPUT_AUD_TUNER, MSP_TUNER },
491 },
492 .tuners = {
493 { .std = V4L2_STD_525_60, .tuner = TUNER_PHILIPS_FQ1286 },
494 },
495 .pci_list = ivtv_pci_va2000,
496};
497
498/* ------------------------------------------------------------------------- */
499
500/* Yuan MPG600GR/Kuroutoshikou CX23416GYC-STVLP cards */
501
502static const struct ivtv_card_pci_info ivtv_pci_cx23416gyc[] = {
503 { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_YUAN1, 0x0600 },
504 { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_YUAN4, 0x0600 },
505 { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_MELCO, 0x0523 },
506 { 0, 0, 0 }
507};
508
509static const struct ivtv_card ivtv_card_cx23416gyc = {
510 .type = IVTV_CARD_CX23416GYC,
511 .name = "Yuan MPG600GR, Kuroutoshikou CX23416GYC-STVLP",
512 .v4l2_capabilities = IVTV_CAP_ENCODER,
513 .hw_video = IVTV_HW_SAA717X | IVTV_HW_GPIO |
514 IVTV_HW_UPD64031A | IVTV_HW_UPD6408X,
515 .hw_audio = IVTV_HW_SAA717X,
516 .hw_audio_ctrl = IVTV_HW_SAA717X,
517 .hw_all = IVTV_HW_GPIO | IVTV_HW_SAA717X | IVTV_HW_TUNER |
518 IVTV_HW_UPD64031A | IVTV_HW_UPD6408X,
519 .video_inputs = {
520 { IVTV_CARD_INPUT_VID_TUNER, 0, IVTV_SAA71XX_SVIDEO3 |
521 IVTV_SAA717X_TUNER_FLAG },
522 { IVTV_CARD_INPUT_SVIDEO1, 1, IVTV_SAA71XX_SVIDEO0 },
523 { IVTV_CARD_INPUT_COMPOSITE1, 1, IVTV_SAA71XX_SVIDEO3 },
524 },
525 .audio_inputs = {
526 { IVTV_CARD_INPUT_AUD_TUNER, IVTV_SAA717X_IN2 },
527 { IVTV_CARD_INPUT_LINE_IN1, IVTV_SAA717X_IN0 },
528 },
529 .gr_config = UPD64031A_VERTICAL_EXTERNAL,
530 .gpio_init = { .direction = 0xf880, .initial_value = 0x8800 },
531 .gpio_video_input = { .mask = 0x0020, .tuner = 0x0000,
532 .composite = 0x0020, .svideo = 0x0020 },
533 .gpio_audio_freq = { .mask = 0xc000, .f32000 = 0x0000,
534 .f44100 = 0x4000, .f48000 = 0x8000 },
535 .tuners = {
536 { .std = V4L2_STD_625_50, .tuner = TUNER_PHILIPS_FM1216ME_MK3 },
537 { .std = V4L2_STD_ALL, .tuner = TUNER_PHILIPS_FM1236_MK3 },
538 },
539 .pci_list = ivtv_pci_cx23416gyc,
540};
541
542static const struct ivtv_card ivtv_card_cx23416gyc_nogr = {
543 .type = IVTV_CARD_CX23416GYC_NOGR,
544 .name = "Yuan MPG600GR, Kuroutoshikou CX23416GYC-STVLP (no GR)",
545 .v4l2_capabilities = IVTV_CAP_ENCODER,
546 .hw_video = IVTV_HW_SAA717X | IVTV_HW_GPIO | IVTV_HW_UPD6408X,
547 .hw_audio = IVTV_HW_SAA717X,
548 .hw_audio_ctrl = IVTV_HW_SAA717X,
549 .hw_all = IVTV_HW_GPIO | IVTV_HW_SAA717X | IVTV_HW_TUNER |
550 IVTV_HW_UPD6408X,
551 .video_inputs = {
552 { IVTV_CARD_INPUT_VID_TUNER, 0, IVTV_SAA71XX_COMPOSITE4 |
553 IVTV_SAA717X_TUNER_FLAG },
554 { IVTV_CARD_INPUT_SVIDEO1, 1, IVTV_SAA71XX_SVIDEO0 },
555 { IVTV_CARD_INPUT_COMPOSITE1, 1, IVTV_SAA71XX_COMPOSITE0 },
556 },
557 .audio_inputs = {
558 { IVTV_CARD_INPUT_AUD_TUNER, IVTV_SAA717X_IN2 },
559 { IVTV_CARD_INPUT_LINE_IN1, IVTV_SAA717X_IN0 },
560 },
561 .gpio_init = { .direction = 0xf880, .initial_value = 0x8800 },
562 .gpio_video_input = { .mask = 0x0020, .tuner = 0x0000,
563 .composite = 0x0020, .svideo = 0x0020 },
564 .gpio_audio_freq = { .mask = 0xc000, .f32000 = 0x0000,
565 .f44100 = 0x4000, .f48000 = 0x8000 },
566 .tuners = {
567 { .std = V4L2_STD_625_50, .tuner = TUNER_PHILIPS_FM1216ME_MK3 },
568 { .std = V4L2_STD_ALL, .tuner = TUNER_PHILIPS_FM1236_MK3 },
569 },
570};
571
572static const struct ivtv_card ivtv_card_cx23416gyc_nogrycs = {
573 .type = IVTV_CARD_CX23416GYC_NOGRYCS,
574 .name = "Yuan MPG600GR, Kuroutoshikou CX23416GYC-STVLP (no GR/YCS)",
575 .v4l2_capabilities = IVTV_CAP_ENCODER,
576 .hw_video = IVTV_HW_SAA717X | IVTV_HW_GPIO,
577 .hw_audio = IVTV_HW_SAA717X,
578 .hw_audio_ctrl = IVTV_HW_SAA717X,
579 .hw_all = IVTV_HW_GPIO | IVTV_HW_SAA717X | IVTV_HW_TUNER,
580 .video_inputs = {
581 { IVTV_CARD_INPUT_VID_TUNER, 0, IVTV_SAA71XX_COMPOSITE4 |
582 IVTV_SAA717X_TUNER_FLAG },
583 { IVTV_CARD_INPUT_SVIDEO1, 1, IVTV_SAA71XX_SVIDEO0 },
584 { IVTV_CARD_INPUT_COMPOSITE1, 1, IVTV_SAA71XX_COMPOSITE0 },
585 },
586 .audio_inputs = {
587 { IVTV_CARD_INPUT_AUD_TUNER, IVTV_SAA717X_IN2 },
588 { IVTV_CARD_INPUT_LINE_IN1, IVTV_SAA717X_IN0 },
589 },
590 .gpio_init = { .direction = 0xf880, .initial_value = 0x8800 },
591 .gpio_video_input = { .mask = 0x0020, .tuner = 0x0000,
592 .composite = 0x0020, .svideo = 0x0020 },
593 .gpio_audio_freq = { .mask = 0xc000, .f32000 = 0x0000,
594 .f44100 = 0x4000, .f48000 = 0x8000 },
595 .tuners = {
596 { .std = V4L2_STD_625_50, .tuner = TUNER_PHILIPS_FM1216ME_MK3 },
597 { .std = V4L2_STD_ALL, .tuner = TUNER_PHILIPS_FM1236_MK3 },
598 },
599};
600
601/* ------------------------------------------------------------------------- */
602
603/* I/O Data GV-MVP/RX & GV-MVP/RX2W (dual tuner) cards */
604
605static const struct ivtv_card_pci_info ivtv_pci_gv_mvprx[] = {
606 { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_IODATA, 0xd01e },
607 { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_IODATA, 0xd038 }, /* 2W unit #1 */
608 { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_IODATA, 0xd039 }, /* 2W unit #2 */
609 { 0, 0, 0 }
610};
611
612static const struct ivtv_card ivtv_card_gv_mvprx = {
613 .type = IVTV_CARD_GV_MVPRX,
614 .name = "I/O Data GV-MVP/RX, GV-MVP/RX2W (dual tuner)",
615 .v4l2_capabilities = IVTV_CAP_ENCODER,
616 .hw_video = IVTV_HW_SAA7115 | IVTV_HW_UPD64031A | IVTV_HW_UPD6408X,
617 .hw_audio = IVTV_HW_GPIO,
618 .hw_audio_ctrl = IVTV_HW_WM8739,
619 .hw_all = IVTV_HW_GPIO | IVTV_HW_SAA7115 | IVTV_HW_TVAUDIO |
620 IVTV_HW_TUNER | IVTV_HW_WM8739 |
621 IVTV_HW_UPD64031A | IVTV_HW_UPD6408X,
622 .video_inputs = {
623 { IVTV_CARD_INPUT_VID_TUNER, 0, IVTV_SAA71XX_SVIDEO0 },
624 { IVTV_CARD_INPUT_SVIDEO1, 1, IVTV_SAA71XX_SVIDEO1 },
625 { IVTV_CARD_INPUT_COMPOSITE1, 1, IVTV_SAA71XX_SVIDEO2 },
626 },
627 .audio_inputs = {
628 { IVTV_CARD_INPUT_AUD_TUNER, IVTV_GPIO_TUNER },
629 { IVTV_CARD_INPUT_LINE_IN1, IVTV_GPIO_LINE_IN },
630 },
631 .gpio_init = { .direction = 0xc301, .initial_value = 0x0200 },
632 .gpio_audio_input = { .mask = 0xffff, .tuner = 0x0200, .linein = 0x0300 },
633 .tuners = {
634 /* This card has the Panasonic VP27 tuner */
635 { .std = V4L2_STD_525_60, .tuner = TUNER_PANASONIC_VP27 },
636 },
637 .pci_list = ivtv_pci_gv_mvprx,
638};
639
640/* ------------------------------------------------------------------------- */
641
642/* I/O Data GV-MVP/RX2E card */
643
644static const struct ivtv_card_pci_info ivtv_pci_gv_mvprx2e[] = {
645 { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_IODATA, 0xd025 },
646 {0, 0, 0}
647};
648
649static const struct ivtv_card ivtv_card_gv_mvprx2e = {
650 .type = IVTV_CARD_GV_MVPRX2E,
651 .name = "I/O Data GV-MVP/RX2E",
652 .v4l2_capabilities = IVTV_CAP_ENCODER,
653 .hw_video = IVTV_HW_SAA7115,
654 .hw_audio = IVTV_HW_GPIO,
655 .hw_audio_ctrl = IVTV_HW_WM8739,
656 .hw_all = IVTV_HW_GPIO | IVTV_HW_SAA7115 | IVTV_HW_TUNER |
657 IVTV_HW_TVAUDIO | IVTV_HW_WM8739,
658 .video_inputs = {
659 { IVTV_CARD_INPUT_VID_TUNER, 0, IVTV_SAA71XX_COMPOSITE4 },
660 { IVTV_CARD_INPUT_SVIDEO1, 1, IVTV_SAA71XX_SVIDEO0 },
661 { IVTV_CARD_INPUT_COMPOSITE1, 1, IVTV_SAA71XX_COMPOSITE3 },
662 },
663 .audio_inputs = {
664 { IVTV_CARD_INPUT_AUD_TUNER, IVTV_GPIO_TUNER },
665 { IVTV_CARD_INPUT_LINE_IN1, IVTV_GPIO_LINE_IN },
666 },
667 .gpio_init = { .direction = 0xc301, .initial_value = 0x0200 },
668 .gpio_audio_input = { .mask = 0xffff, .tuner = 0x0200, .linein = 0x0300 },
669 .tuners = {
670 /* This card has the Panasonic VP27 tuner */
671 { .std = V4L2_STD_525_60, .tuner = TUNER_PANASONIC_VP27 },
672 },
673 .pci_list = ivtv_pci_gv_mvprx2e,
674};
675
676/* ------------------------------------------------------------------------- */
677
678/* GotVIEW PCI DVD card */
679
680static const struct ivtv_card_pci_info ivtv_pci_gotview_pci_dvd[] = {
681 { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_YUAN1, 0x0600 },
682 { 0, 0, 0 }
683};
684
685static const struct ivtv_card ivtv_card_gotview_pci_dvd = {
686 .type = IVTV_CARD_GOTVIEW_PCI_DVD,
687 .name = "GotView PCI DVD",
688 .v4l2_capabilities = IVTV_CAP_ENCODER,
689 .hw_video = IVTV_HW_SAA717X,
690 .hw_audio = IVTV_HW_SAA717X,
691 .hw_audio_ctrl = IVTV_HW_SAA717X,
692 .hw_all = IVTV_HW_SAA717X | IVTV_HW_TUNER,
693 .video_inputs = {
694 { IVTV_CARD_INPUT_VID_TUNER, 0, IVTV_SAA71XX_COMPOSITE1 }, /* pin 116 */
695 { IVTV_CARD_INPUT_SVIDEO1, 1, IVTV_SAA71XX_SVIDEO0 }, /* pin 114/109 */
696 { IVTV_CARD_INPUT_COMPOSITE1, 1, IVTV_SAA71XX_COMPOSITE3 }, /* pin 118 */
697 },
698 .audio_inputs = {
699 { IVTV_CARD_INPUT_AUD_TUNER, IVTV_SAA717X_IN0 },
700 { IVTV_CARD_INPUT_LINE_IN1, IVTV_SAA717X_IN2 },
701 },
702 .gpio_init = { .direction = 0xf000, .initial_value = 0xA000 },
703 .tuners = {
704 /* This card has a Philips FQ1216ME MK3 tuner */
705 { .std = V4L2_STD_625_50, .tuner = TUNER_PHILIPS_FM1216ME_MK3 },
706 },
707 .pci_list = ivtv_pci_gotview_pci_dvd,
708};
709
710/* ------------------------------------------------------------------------- */
711
712/* GotVIEW PCI DVD2 Deluxe card */
713
714static const struct ivtv_card_pci_info ivtv_pci_gotview_pci_dvd2[] = {
715 { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_GOTVIEW1, 0x0600 },
716 { 0, 0, 0 }
717};
718
719static const struct ivtv_card ivtv_card_gotview_pci_dvd2 = {
720 .type = IVTV_CARD_GOTVIEW_PCI_DVD2,
721 .name = "GotView PCI DVD2 Deluxe",
722 .v4l2_capabilities = IVTV_CAP_ENCODER,
723 .hw_video = IVTV_HW_CX25840,
724 .hw_audio = IVTV_HW_CX25840,
725 .hw_audio_ctrl = IVTV_HW_CX25840,
726 .hw_muxer = IVTV_HW_GPIO,
727 .hw_all = IVTV_HW_CX25840 | IVTV_HW_TUNER,
728 .video_inputs = {
729 { IVTV_CARD_INPUT_VID_TUNER, 0, CX25840_COMPOSITE2 },
730 { IVTV_CARD_INPUT_SVIDEO1, 1,
731 CX25840_SVIDEO_LUMA3 | CX25840_SVIDEO_CHROMA4 },
732 { IVTV_CARD_INPUT_COMPOSITE1, 1, CX25840_COMPOSITE1 },
733 },
734 .audio_inputs = {
735 { IVTV_CARD_INPUT_AUD_TUNER, CX25840_AUDIO5, 0 },
736 { IVTV_CARD_INPUT_LINE_IN1, CX25840_AUDIO_SERIAL, 1 },
737 },
738 .radio_input = { IVTV_CARD_INPUT_AUD_TUNER, CX25840_AUDIO_SERIAL, 2 },
739 .gpio_init = { .direction = 0x0800, .initial_value = 0 },
740 .gpio_audio_input = { .mask = 0x0800, .tuner = 0, .linein = 0, .radio = 0x0800 },
741 .tuners = {
742 /* This card has a Philips FQ1216ME MK5 tuner */
743 { .std = V4L2_STD_625_50, .tuner = TUNER_PHILIPS_FM1216ME_MK3 },
744 },
745 .pci_list = ivtv_pci_gotview_pci_dvd2,
746};
747
748/* ------------------------------------------------------------------------- */
749
750/* Yuan MPC622 miniPCI card */
751
752static const struct ivtv_card_pci_info ivtv_pci_yuan_mpc622[] = {
753 { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_YUAN2, 0xd998 },
754 { 0, 0, 0 }
755};
756
757static const struct ivtv_card ivtv_card_yuan_mpc622 = {
758 .type = IVTV_CARD_YUAN_MPC622,
759 .name = "Yuan MPC622",
760 .v4l2_capabilities = IVTV_CAP_ENCODER,
761 .hw_video = IVTV_HW_CX25840,
762 .hw_audio = IVTV_HW_CX25840,
763 .hw_audio_ctrl = IVTV_HW_CX25840,
764 .hw_all = IVTV_HW_CX25840 | IVTV_HW_TUNER,
765 .video_inputs = {
766 { IVTV_CARD_INPUT_VID_TUNER, 0, CX25840_COMPOSITE2 },
767 { IVTV_CARD_INPUT_SVIDEO1, 1,
768 CX25840_SVIDEO_LUMA3 | CX25840_SVIDEO_CHROMA4 },
769 { IVTV_CARD_INPUT_COMPOSITE1, 1, CX25840_COMPOSITE1 },
770 },
771 .audio_inputs = {
772 { IVTV_CARD_INPUT_AUD_TUNER, CX25840_AUDIO5 },
773 { IVTV_CARD_INPUT_LINE_IN1, CX25840_AUDIO_SERIAL },
774 },
775 .gpio_init = { .direction = 0x00ff, .initial_value = 0x0002 },
776 .tuners = {
777 /* This card has the TDA8290/TDA8275 tuner chips */
778 { .std = V4L2_STD_ALL, .tuner = TUNER_PHILIPS_TDA8290 },
779 },
780 .pci_list = ivtv_pci_yuan_mpc622,
781};
782
783/* ------------------------------------------------------------------------- */
784
785/* DIGITAL COWBOY DCT-MTVP1 card */
786
787static const struct ivtv_card_pci_info ivtv_pci_dctmvtvp1[] = {
788 { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_AVERMEDIA, 0xbfff },
789 { 0, 0, 0 }
790};
791
792static const struct ivtv_card ivtv_card_dctmvtvp1 = {
793 .type = IVTV_CARD_DCTMTVP1,
794 .name = "Digital Cowboy DCT-MTVP1",
795 .v4l2_capabilities = IVTV_CAP_ENCODER,
796 .hw_video = IVTV_HW_SAA7115 | IVTV_HW_UPD64031A | IVTV_HW_UPD6408X |
797 IVTV_HW_GPIO,
798 .hw_audio = IVTV_HW_GPIO,
799 .hw_audio_ctrl = IVTV_HW_GPIO,
800 .hw_all = IVTV_HW_GPIO | IVTV_HW_SAA7115 | IVTV_HW_TUNER |
801 IVTV_HW_UPD64031A | IVTV_HW_UPD6408X,
802 .video_inputs = {
803 { IVTV_CARD_INPUT_VID_TUNER, 0, IVTV_SAA71XX_SVIDEO0 },
804 { IVTV_CARD_INPUT_SVIDEO1, 1, IVTV_SAA71XX_SVIDEO2 },
805 { IVTV_CARD_INPUT_COMPOSITE1, 1, IVTV_SAA71XX_SVIDEO2 },
806 },
807 .audio_inputs = {
808 { IVTV_CARD_INPUT_AUD_TUNER, IVTV_GPIO_TUNER },
809 { IVTV_CARD_INPUT_LINE_IN1, IVTV_GPIO_LINE_IN },
810 },
811 .gpio_init = { .direction = 0xe080, .initial_value = 0x8000 },
812 .gpio_audio_input = { .mask = 0x8080, .tuner = 0x8000, .linein = 0x0080 },
813 .gpio_audio_mute = { .mask = 0x6000, .mute = 0x6000 },
814 .gpio_audio_mode = { .mask = 0x4300, .mono = 0x4000, .stereo = 0x0200,
815 .lang1 = 0x0300, .lang2 = 0x0000, .both = 0x0200 },
816 .gpio_video_input = { .mask = 0x0030, .tuner = 0x0000,
817 .composite = 0x0010, .svideo = 0x0020},
818 .tuners = {
819 { .std = V4L2_STD_525_60, .tuner = TUNER_PHILIPS_FQ1286 },
820 },
821 .pci_list = ivtv_pci_dctmvtvp1,
822};
823
824/* ------------------------------------------------------------------------- */
825
826#ifdef HAVE_XC3028
827
828/* Yuan PG600-2/GotView PCI DVD Lite/Club3D ZAP-TV1x01 cards */
829
830static const struct ivtv_card_pci_info ivtv_pci_pg600v2[] = {
831 { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_YUAN3, 0x0600 },
832 { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_GOTVIEW2, 0x0600 },
833 { 0, 0, 0 }
834};
835
836static const struct ivtv_card ivtv_card_pg600v2 = {
837 .type = IVTV_CARD_PG600V2,
838 .name = "Yuan PG600-2, GotView PCI DVD Lite, Club3D ZAP-TV1x01",
839 .v4l2_capabilities = IVTV_CAP_ENCODER,
840 .hw_video = IVTV_HW_CX25840,
841 .hw_audio = IVTV_HW_CX25840,
842 .hw_audio_ctrl = IVTV_HW_CX25840,
843 .hw_all = IVTV_HW_CX25840 | IVTV_HW_TUNER,
844 .video_inputs = {
845 { IVTV_CARD_INPUT_VID_TUNER, 0, CX25840_COMPOSITE2 },
846 { IVTV_CARD_INPUT_SVIDEO1, 1,
847 CX25840_SVIDEO_LUMA3 | CX25840_SVIDEO_CHROMA4 },
848 },
849 .audio_inputs = {
850 { IVTV_CARD_INPUT_AUD_TUNER, CX25840_AUDIO5 },
851 { IVTV_CARD_INPUT_LINE_IN1, CX25840_AUDIO_SERIAL },
852 },
853 .radio_input = { IVTV_CARD_INPUT_AUD_TUNER, CX25840_AUDIO5 },
854 .tuners = {
855 { .std = V4L2_STD_ALL, .tuner = TUNER_XCEIVE_XC3028 },
856 },
857 .gpio_init = { .direction = 0x1000, .initial_value = 0x1000 }, /* tuner reset */
858 .pci_list = ivtv_pci_pg600v2,
859};
860#endif
861
862static const struct ivtv_card *ivtv_card_list[] = {
863 &ivtv_card_pvr250,
864 &ivtv_card_pvr350,
865 &ivtv_card_pvr150,
866 &ivtv_card_m179,
867 &ivtv_card_mpg600,
868 &ivtv_card_mpg160,
869 &ivtv_card_pg600,
870 &ivtv_card_avc2410,
871 &ivtv_card_avc2010,
872 &ivtv_card_tg5000tv,
873 &ivtv_card_va2000,
874 &ivtv_card_cx23416gyc,
875 &ivtv_card_gv_mvprx,
876 &ivtv_card_gv_mvprx2e,
877 &ivtv_card_gotview_pci_dvd,
878 &ivtv_card_gotview_pci_dvd2,
879 &ivtv_card_yuan_mpc622,
880 &ivtv_card_dctmvtvp1,
881#ifdef HAVE_XC3028
882 &ivtv_card_pg600v2,
883#endif
884
885 /* Variations of standard cards but with the same PCI IDs.
886 These cards must come last in this list. */
887 &ivtv_card_pvr350_v1,
888 &ivtv_card_cx23416gyc_nogr,
889 &ivtv_card_cx23416gyc_nogrycs,
890};
891
892const struct ivtv_card *ivtv_get_card(u16 index)
893{
894 if (index >= ARRAY_SIZE(ivtv_card_list))
895 return NULL;
896 return ivtv_card_list[index];
897}
898
899int ivtv_get_input(struct ivtv *itv, u16 index, struct v4l2_input *input)
900{
901 const struct ivtv_card_video_input *card_input = itv->card->video_inputs + index;
902 static const char * const input_strs[] = {
903 "Tuner 1",
904 "S-Video 1",
905 "S-Video 2",
906 "Composite 1",
907 "Composite 2",
908 "Composite 3"
909 };
910
911 memset(input, 0, sizeof(*input));
912 if (index >= itv->nof_inputs)
913 return -EINVAL;
914 input->index = index;
915 strcpy(input->name, input_strs[card_input->video_type - 1]);
916 input->type = (card_input->video_type == IVTV_CARD_INPUT_VID_TUNER ?
917 V4L2_INPUT_TYPE_TUNER : V4L2_INPUT_TYPE_CAMERA);
918 input->audioset = (1 << itv->nof_audio_inputs) - 1;
919 input->std = (input->type == V4L2_INPUT_TYPE_TUNER) ?
920 itv->tuner_std : V4L2_STD_ALL;
921 return 0;
922}
923
924int ivtv_get_output(struct ivtv *itv, u16 index, struct v4l2_output *output)
925{
926 const struct ivtv_card_output *card_output = itv->card->video_outputs + index;
927
928 memset(output, 0, sizeof(*output));
929 if (index >= itv->card->nof_outputs)
930 return -EINVAL;
931 output->index = index;
932 strcpy(output->name, card_output->name);
933 output->type = V4L2_OUTPUT_TYPE_ANALOG;
934 output->audioset = 1;
935 output->std = V4L2_STD_ALL;
936 return 0;
937}
938
939int ivtv_get_audio_input(struct ivtv *itv, u16 index, struct v4l2_audio *audio)
940{
941 const struct ivtv_card_audio_input *aud_input = itv->card->audio_inputs + index;
942 static const char * const input_strs[] = {
943 "Tuner 1",
944 "Line In 1",
945 "Line In 2"
946 };
947
948 memset(audio, 0, sizeof(*audio));
949 if (index >= itv->nof_audio_inputs)
950 return -EINVAL;
951 strcpy(audio->name, input_strs[aud_input->audio_type - 1]);
952 audio->index = index;
953 audio->capability = V4L2_AUDCAP_STEREO;
954 return 0;
955}
956
957int ivtv_get_audio_output(struct ivtv *itv, u16 index, struct v4l2_audioout *aud_output)
958{
959 memset(aud_output, 0, sizeof(*aud_output));
960 if (itv->card->video_outputs == NULL || index != 0)
961 return -EINVAL;
962 strcpy(aud_output->name, "A/V Audio Out");
963 return 0;
964}
diff --git a/drivers/media/video/ivtv/ivtv-cards.h b/drivers/media/video/ivtv/ivtv-cards.h
new file mode 100644
index 000000000000..15012f88b802
--- /dev/null
+++ b/drivers/media/video/ivtv/ivtv-cards.h
@@ -0,0 +1,207 @@
1/*
2 Functions to query card hardware
3 Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
4 Copyright (C) 2005-2007 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21/* hardware flags */
22#define IVTV_HW_CX25840 (1 << 0)
23#define IVTV_HW_SAA7115 (1 << 1)
24#define IVTV_HW_SAA7127 (1 << 2)
25#define IVTV_HW_MSP34XX (1 << 3)
26#define IVTV_HW_TUNER (1 << 4)
27#define IVTV_HW_WM8775 (1 << 5)
28#define IVTV_HW_CS53L32A (1 << 6)
29#define IVTV_HW_TVEEPROM (1 << 7)
30#define IVTV_HW_SAA7114 (1 << 8)
31#define IVTV_HW_TVAUDIO (1 << 9)
32#define IVTV_HW_UPD64031A (1 << 10)
33#define IVTV_HW_UPD6408X (1 << 11)
34#define IVTV_HW_SAA717X (1 << 12)
35#define IVTV_HW_WM8739 (1 << 13)
36#define IVTV_HW_GPIO (1 << 14)
37
38#define IVTV_HW_SAA711X (IVTV_HW_SAA7115 | IVTV_HW_SAA7114)
39
40/* video inputs */
41#define IVTV_CARD_INPUT_VID_TUNER 1
42#define IVTV_CARD_INPUT_SVIDEO1 2
43#define IVTV_CARD_INPUT_SVIDEO2 3
44#define IVTV_CARD_INPUT_COMPOSITE1 4
45#define IVTV_CARD_INPUT_COMPOSITE2 5
46#define IVTV_CARD_INPUT_COMPOSITE3 6
47
48/* audio inputs */
49#define IVTV_CARD_INPUT_AUD_TUNER 1
50#define IVTV_CARD_INPUT_LINE_IN1 2
51#define IVTV_CARD_INPUT_LINE_IN2 3
52
53#define IVTV_CARD_MAX_VIDEO_INPUTS 6
54#define IVTV_CARD_MAX_AUDIO_INPUTS 3
55#define IVTV_CARD_MAX_TUNERS 2
56
57/* SAA71XX HW inputs */
58#define IVTV_SAA71XX_COMPOSITE0 0
59#define IVTV_SAA71XX_COMPOSITE1 1
60#define IVTV_SAA71XX_COMPOSITE2 2
61#define IVTV_SAA71XX_COMPOSITE3 3
62#define IVTV_SAA71XX_COMPOSITE4 4
63#define IVTV_SAA71XX_COMPOSITE5 5
64#define IVTV_SAA71XX_SVIDEO0 6
65#define IVTV_SAA71XX_SVIDEO1 7
66#define IVTV_SAA71XX_SVIDEO2 8
67#define IVTV_SAA71XX_SVIDEO3 9
68
69/* SAA717X needs to mark the tuner input by ORing with this flag */
70#define IVTV_SAA717X_TUNER_FLAG 0x80
71
72/* Dummy HW input */
73#define IVTV_DUMMY_AUDIO 0
74
75/* GPIO HW inputs */
76#define IVTV_GPIO_TUNER 0
77#define IVTV_GPIO_LINE_IN 1
78
79/* SAA717X HW inputs */
80#define IVTV_SAA717X_IN0 0
81#define IVTV_SAA717X_IN1 1
82#define IVTV_SAA717X_IN2 2
83
84/* V4L2 capability aliases */
85#define IVTV_CAP_ENCODER (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_TUNER | \
86 V4L2_CAP_AUDIO | V4L2_CAP_READWRITE | V4L2_CAP_VBI_CAPTURE | \
87 V4L2_CAP_SLICED_VBI_CAPTURE)
88#define IVTV_CAP_DECODER (V4L2_CAP_VBI_OUTPUT | V4L2_CAP_VIDEO_OUTPUT | \
89 V4L2_CAP_SLICED_VBI_OUTPUT | V4L2_CAP_VIDEO_OUTPUT_OVERLAY | V4L2_CAP_VIDEO_OUTPUT_POS)
90
91struct ivtv_card_video_input {
92 u8 video_type; /* video input type */
93 u8 audio_index; /* index in ivtv_card_audio_input array */
94 u16 video_input; /* hardware video input */
95};
96
97struct ivtv_card_audio_input {
98 u8 audio_type; /* audio input type */
99 u32 audio_input; /* hardware audio input */
100 u16 muxer_input; /* hardware muxer input for boards with a
101 multiplexer chip */
102};
103
104struct ivtv_card_output {
105 u8 name[32];
106 u16 video_output; /* hardware video output */
107};
108
109struct ivtv_card_pci_info {
110 u16 device;
111 u16 subsystem_vendor;
112 u16 subsystem_device;
113};
114
115/* GPIO definitions */
116
117/* The mask is the set of bits used by the operation */
118
119struct ivtv_gpio_init { /* set initial GPIO DIR and OUT values */
120 u16 direction; /* DIR setting. Leave to 0 if no init is needed */
121 u16 initial_value;
122};
123
124struct ivtv_gpio_video_input { /* select tuner/line in input */
125 u16 mask; /* leave to 0 if not supported */
126 u16 tuner;
127 u16 composite;
128 u16 svideo;
129};
130
131struct ivtv_gpio_audio_input { /* select tuner/line in input */
132 u16 mask; /* leave to 0 if not supported */
133 u16 tuner;
134 u16 linein;
135 u16 radio;
136};
137
138struct ivtv_gpio_audio_mute {
139 u16 mask; /* leave to 0 if not supported */
140 u16 mute; /* set this value to mute, 0 to unmute */
141};
142
143struct ivtv_gpio_audio_mode {
144 u16 mask; /* leave to 0 if not supported */
145 u16 mono; /* set audio to mono */
146 u16 stereo; /* set audio to stereo */
147 u16 lang1; /* set audio to the first language */
148 u16 lang2; /* set audio to the second language */
149 u16 both; /* both languages are output */
150};
151
152struct ivtv_gpio_audio_freq {
153 u16 mask; /* leave to 0 if not supported */
154 u16 f32000;
155 u16 f44100;
156 u16 f48000;
157};
158
159struct ivtv_gpio_audio_detect {
160 u16 mask; /* leave to 0 if not supported */
161 u16 stereo; /* if the input matches this value then
162 stereo is detected */
163};
164
165struct ivtv_card_tuner {
166 v4l2_std_id std; /* standard for which the tuner is suitable */
167 int tuner; /* tuner ID (from tuner.h) */
168};
169
170/* for card information/parameters */
171struct ivtv_card {
172 int type;
173 char *name;
174 u32 v4l2_capabilities;
175 u32 hw_video; /* hardware used to process video */
176 u32 hw_audio; /* hardware used to process audio */
177 u32 hw_audio_ctrl; /* hardware used for the V4L2 controls (only 1 dev allowed) */
178 u32 hw_muxer; /* hardware used to multiplex audio input */
179 u32 hw_all; /* all hardware used by the board */
180 struct ivtv_card_video_input video_inputs[IVTV_CARD_MAX_VIDEO_INPUTS];
181 struct ivtv_card_audio_input audio_inputs[IVTV_CARD_MAX_AUDIO_INPUTS];
182 struct ivtv_card_audio_input radio_input;
183 int nof_outputs;
184 const struct ivtv_card_output *video_outputs;
185 u8 gr_config; /* config byte for the ghost reduction device */
186
187 /* GPIO card-specific settings */
188 struct ivtv_gpio_init gpio_init;
189 struct ivtv_gpio_video_input gpio_video_input;
190 struct ivtv_gpio_audio_input gpio_audio_input;
191 struct ivtv_gpio_audio_mute gpio_audio_mute;
192 struct ivtv_gpio_audio_mode gpio_audio_mode;
193 struct ivtv_gpio_audio_freq gpio_audio_freq;
194 struct ivtv_gpio_audio_detect gpio_audio_detect;
195
196 struct ivtv_card_tuner tuners[IVTV_CARD_MAX_TUNERS];
197
198 /* list of device and subsystem vendor/devices that
199 correspond to this card type. */
200 const struct ivtv_card_pci_info *pci_list;
201};
202
203int ivtv_get_input(struct ivtv *itv, u16 index, struct v4l2_input *input);
204int ivtv_get_output(struct ivtv *itv, u16 index, struct v4l2_output *output);
205int ivtv_get_audio_input(struct ivtv *itv, u16 index, struct v4l2_audio *input);
206int ivtv_get_audio_output(struct ivtv *itv, u16 index, struct v4l2_audioout *output);
207const struct ivtv_card *ivtv_get_card(u16 index);
diff --git a/drivers/media/video/ivtv/ivtv-controls.c b/drivers/media/video/ivtv/ivtv-controls.c
new file mode 100644
index 000000000000..7a876c3e5b19
--- /dev/null
+++ b/drivers/media/video/ivtv/ivtv-controls.c
@@ -0,0 +1,303 @@
1/*
2 ioctl control functions
3 Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
4 Copyright (C) 2005-2007 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#include "ivtv-driver.h"
22#include "ivtv-cards.h"
23#include "ivtv-ioctl.h"
24#include "ivtv-audio.h"
25#include "ivtv-i2c.h"
26#include "ivtv-mailbox.h"
27#include "ivtv-controls.h"
28
29static const u32 user_ctrls[] = {
30 V4L2_CID_USER_CLASS,
31 V4L2_CID_BRIGHTNESS,
32 V4L2_CID_CONTRAST,
33 V4L2_CID_SATURATION,
34 V4L2_CID_HUE,
35 V4L2_CID_AUDIO_VOLUME,
36 V4L2_CID_AUDIO_BALANCE,
37 V4L2_CID_AUDIO_BASS,
38 V4L2_CID_AUDIO_TREBLE,
39 V4L2_CID_AUDIO_MUTE,
40 V4L2_CID_AUDIO_LOUDNESS,
41 0
42};
43
44static const u32 *ctrl_classes[] = {
45 user_ctrls,
46 cx2341x_mpeg_ctrls,
47 NULL
48};
49
50static int ivtv_queryctrl(struct ivtv *itv, struct v4l2_queryctrl *qctrl)
51{
52 const char *name;
53
54 IVTV_DEBUG_IOCTL("VIDIOC_QUERYCTRL(%08x)\n", qctrl->id);
55
56 qctrl->id = v4l2_ctrl_next(ctrl_classes, qctrl->id);
57 if (qctrl->id == 0)
58 return -EINVAL;
59
60 switch (qctrl->id) {
61 /* Standard V4L2 controls */
62 case V4L2_CID_BRIGHTNESS:
63 case V4L2_CID_HUE:
64 case V4L2_CID_SATURATION:
65 case V4L2_CID_CONTRAST:
66 if (itv->video_dec_func(itv, VIDIOC_QUERYCTRL, qctrl))
67 qctrl->flags |= V4L2_CTRL_FLAG_DISABLED;
68 return 0;
69
70 case V4L2_CID_AUDIO_VOLUME:
71 case V4L2_CID_AUDIO_MUTE:
72 case V4L2_CID_AUDIO_BALANCE:
73 case V4L2_CID_AUDIO_BASS:
74 case V4L2_CID_AUDIO_TREBLE:
75 case V4L2_CID_AUDIO_LOUDNESS:
76 if (ivtv_i2c_hw(itv, itv->card->hw_audio_ctrl, VIDIOC_QUERYCTRL, qctrl))
77 qctrl->flags |= V4L2_CTRL_FLAG_DISABLED;
78 return 0;
79
80 default:
81 if (cx2341x_ctrl_query(&itv->params, qctrl))
82 qctrl->flags |= V4L2_CTRL_FLAG_DISABLED;
83 return 0;
84 }
85 strncpy(qctrl->name, name, sizeof(qctrl->name) - 1);
86 qctrl->name[sizeof(qctrl->name) - 1] = 0;
87 return 0;
88}
89
90static int ivtv_querymenu(struct ivtv *itv, struct v4l2_querymenu *qmenu)
91{
92 struct v4l2_queryctrl qctrl;
93
94 qctrl.id = qmenu->id;
95 ivtv_queryctrl(itv, &qctrl);
96 return v4l2_ctrl_query_menu(qmenu, &qctrl, cx2341x_ctrl_get_menu(qmenu->id));
97}
98
99static int ivtv_s_ctrl(struct ivtv *itv, struct v4l2_control *vctrl)
100{
101 s32 v = vctrl->value;
102
103 IVTV_DEBUG_IOCTL("VIDIOC_S_CTRL(%08x, %x)\n", vctrl->id, v);
104
105 switch (vctrl->id) {
106 /* Standard V4L2 controls */
107 case V4L2_CID_BRIGHTNESS:
108 case V4L2_CID_HUE:
109 case V4L2_CID_SATURATION:
110 case V4L2_CID_CONTRAST:
111 return itv->video_dec_func(itv, VIDIOC_S_CTRL, vctrl);
112
113 case V4L2_CID_AUDIO_VOLUME:
114 case V4L2_CID_AUDIO_MUTE:
115 case V4L2_CID_AUDIO_BALANCE:
116 case V4L2_CID_AUDIO_BASS:
117 case V4L2_CID_AUDIO_TREBLE:
118 case V4L2_CID_AUDIO_LOUDNESS:
119 return ivtv_i2c_hw(itv, itv->card->hw_audio_ctrl, VIDIOC_S_CTRL, vctrl);
120
121 default:
122 IVTV_DEBUG_IOCTL("invalid control %x\n", vctrl->id);
123 return -EINVAL;
124 }
125 return 0;
126}
127
128static int ivtv_g_ctrl(struct ivtv *itv, struct v4l2_control *vctrl)
129{
130 IVTV_DEBUG_IOCTL("VIDIOC_G_CTRL(%08x)\n", vctrl->id);
131
132 switch (vctrl->id) {
133 /* Standard V4L2 controls */
134 case V4L2_CID_BRIGHTNESS:
135 case V4L2_CID_HUE:
136 case V4L2_CID_SATURATION:
137 case V4L2_CID_CONTRAST:
138 return itv->video_dec_func(itv, VIDIOC_G_CTRL, vctrl);
139
140 case V4L2_CID_AUDIO_VOLUME:
141 case V4L2_CID_AUDIO_MUTE:
142 case V4L2_CID_AUDIO_BALANCE:
143 case V4L2_CID_AUDIO_BASS:
144 case V4L2_CID_AUDIO_TREBLE:
145 case V4L2_CID_AUDIO_LOUDNESS:
146 return ivtv_i2c_hw(itv, itv->card->hw_audio_ctrl, VIDIOC_G_CTRL, vctrl);
147 default:
148 IVTV_DEBUG_IOCTL("invalid control %x\n", vctrl->id);
149 return -EINVAL;
150 }
151 return 0;
152}
153
154static int ivtv_setup_vbi_fmt(struct ivtv *itv, enum v4l2_mpeg_stream_vbi_fmt fmt)
155{
156 if (!(itv->v4l2_cap & V4L2_CAP_SLICED_VBI_CAPTURE))
157 return -EINVAL;
158 if (atomic_read(&itv->capturing) > 0)
159 return -EBUSY;
160
161 /* First try to allocate sliced VBI buffers if needed. */
162 if (fmt && itv->vbi.sliced_mpeg_data[0] == NULL) {
163 int i;
164
165 for (i = 0; i < IVTV_VBI_FRAMES; i++) {
166 /* Yuck, hardcoded. Needs to be a define */
167 itv->vbi.sliced_mpeg_data[i] = kmalloc(2049, GFP_KERNEL);
168 if (itv->vbi.sliced_mpeg_data[i] == NULL) {
169 while (--i >= 0) {
170 kfree(itv->vbi.sliced_mpeg_data[i]);
171 itv->vbi.sliced_mpeg_data[i] = NULL;
172 }
173 return -ENOMEM;
174 }
175 }
176 }
177
178 itv->vbi.insert_mpeg = fmt;
179
180 if (itv->vbi.insert_mpeg == 0) {
181 return 0;
182 }
183 /* Need sliced data for mpeg insertion */
184 if (get_service_set(itv->vbi.sliced_in) == 0) {
185 if (itv->is_60hz)
186 itv->vbi.sliced_in->service_set = V4L2_SLICED_CAPTION_525;
187 else
188 itv->vbi.sliced_in->service_set = V4L2_SLICED_WSS_625;
189 expand_service_set(itv->vbi.sliced_in, itv->is_50hz);
190 }
191 return 0;
192}
193
194int ivtv_control_ioctls(struct ivtv *itv, unsigned int cmd, void *arg)
195{
196 struct v4l2_control ctrl;
197
198 switch (cmd) {
199 case VIDIOC_QUERYMENU:
200 IVTV_DEBUG_IOCTL("VIDIOC_QUERYMENU\n");
201 return ivtv_querymenu(itv, arg);
202
203 case VIDIOC_QUERYCTRL:
204 return ivtv_queryctrl(itv, arg);
205
206 case VIDIOC_S_CTRL:
207 return ivtv_s_ctrl(itv, arg);
208
209 case VIDIOC_G_CTRL:
210 return ivtv_g_ctrl(itv, arg);
211
212 case VIDIOC_S_EXT_CTRLS:
213 {
214 struct v4l2_ext_controls *c = arg;
215
216 if (c->ctrl_class == V4L2_CTRL_CLASS_USER) {
217 int i;
218 int err = 0;
219
220 for (i = 0; i < c->count; i++) {
221 ctrl.id = c->controls[i].id;
222 ctrl.value = c->controls[i].value;
223 err = ivtv_s_ctrl(itv, &ctrl);
224 c->controls[i].value = ctrl.value;
225 if (err) {
226 c->error_idx = i;
227 break;
228 }
229 }
230 return err;
231 }
232 IVTV_DEBUG_IOCTL("VIDIOC_S_EXT_CTRLS\n");
233 if (c->ctrl_class == V4L2_CTRL_CLASS_MPEG) {
234 struct cx2341x_mpeg_params p = itv->params;
235 int err = cx2341x_ext_ctrls(&p, arg, cmd);
236
237 if (err)
238 return err;
239
240 if (p.video_encoding != itv->params.video_encoding) {
241 int is_mpeg1 = p.video_encoding ==
242 V4L2_MPEG_VIDEO_ENCODING_MPEG_1;
243 struct v4l2_format fmt;
244
245 /* fix videodecoder resolution */
246 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
247 fmt.fmt.pix.width = itv->params.width / (is_mpeg1 ? 2 : 1);
248 fmt.fmt.pix.height = itv->params.height;
249 itv->video_dec_func(itv, VIDIOC_S_FMT, &fmt);
250 }
251 err = cx2341x_update(itv, ivtv_api_func, &itv->params, &p);
252 if (!err && itv->params.stream_vbi_fmt != p.stream_vbi_fmt) {
253 err = ivtv_setup_vbi_fmt(itv, p.stream_vbi_fmt);
254 }
255 itv->params = p;
256 itv->dualwatch_stereo_mode = p.audio_properties & 0x0300;
257 ivtv_audio_set_audio_clock_freq(itv, p.audio_properties & 0x03);
258 return err;
259 }
260 return -EINVAL;
261 }
262
263 case VIDIOC_G_EXT_CTRLS:
264 {
265 struct v4l2_ext_controls *c = arg;
266
267 if (c->ctrl_class == V4L2_CTRL_CLASS_USER) {
268 int i;
269 int err = 0;
270
271 for (i = 0; i < c->count; i++) {
272 ctrl.id = c->controls[i].id;
273 ctrl.value = c->controls[i].value;
274 err = ivtv_g_ctrl(itv, &ctrl);
275 c->controls[i].value = ctrl.value;
276 if (err) {
277 c->error_idx = i;
278 break;
279 }
280 }
281 return err;
282 }
283 IVTV_DEBUG_IOCTL("VIDIOC_G_EXT_CTRLS\n");
284 if (c->ctrl_class == V4L2_CTRL_CLASS_MPEG)
285 return cx2341x_ext_ctrls(&itv->params, arg, cmd);
286 return -EINVAL;
287 }
288
289 case VIDIOC_TRY_EXT_CTRLS:
290 {
291 struct v4l2_ext_controls *c = arg;
292
293 IVTV_DEBUG_IOCTL("VIDIOC_TRY_EXT_CTRLS\n");
294 if (c->ctrl_class == V4L2_CTRL_CLASS_MPEG)
295 return cx2341x_ext_ctrls(&itv->params, arg, cmd);
296 return -EINVAL;
297 }
298
299 default:
300 return -EINVAL;
301 }
302 return 0;
303}
diff --git a/drivers/media/video/ivtv/ivtv-controls.h b/drivers/media/video/ivtv/ivtv-controls.h
new file mode 100644
index 000000000000..5a11149725ad
--- /dev/null
+++ b/drivers/media/video/ivtv/ivtv-controls.h
@@ -0,0 +1,21 @@
1/*
2 ioctl control functions
3 Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
4 Copyright (C) 2005-2007 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21int ivtv_control_ioctls(struct ivtv *itv, unsigned int cmd, void *arg);
diff --git a/drivers/media/video/ivtv/ivtv-driver.c b/drivers/media/video/ivtv/ivtv-driver.c
new file mode 100644
index 000000000000..45b9328a538f
--- /dev/null
+++ b/drivers/media/video/ivtv/ivtv-driver.c
@@ -0,0 +1,1374 @@
1/*
2 ivtv driver initialization and card probing
3 Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
4 Copyright (C) 2004 Chris Kennedy <c@groovy.org>
5 Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl>
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21
22/* Main Driver file for the ivtv project:
23 * Driver for the Conexant CX23415/CX23416 chip.
24 * Author: Kevin Thayer (nufan_wfk at yahoo.com)
25 * License: GPL
26 * http://www.ivtvdriver.org
27 *
28 * -----
29 * MPG600/MPG160 support by T.Adachi <tadachi@tadachi-net.com>
30 * and Takeru KOMORIYA<komoriya@paken.org>
31 *
32 * AVerMedia M179 GPIO info by Chris Pinkham <cpinkham@bc2va.org>
33 * using information provided by Jiun-Kuei Jung @ AVerMedia.
34 *
35 * Kurouto Sikou CX23416GYC-STVLP tested by K.Ohta <alpha292@bremen.or.jp>
36 * using information from T.Adachi,Takeru KOMORIYA and others :-)
37 *
38 * Nagase TRANSGEAR 5000TV, Aopen VA2000MAX-STN6 and I/O data GV-MVP/RX
39 * version by T.Adachi. Special thanks Mr.Suzuki
40 */
41
42#include "ivtv-driver.h"
43#include "ivtv-version.h"
44#include "ivtv-fileops.h"
45#include "ivtv-i2c.h"
46#include "ivtv-firmware.h"
47#include "ivtv-queue.h"
48#include "ivtv-udma.h"
49#include "ivtv-irq.h"
50#include "ivtv-mailbox.h"
51#include "ivtv-streams.h"
52#include "ivtv-ioctl.h"
53#include "ivtv-cards.h"
54#include "ivtv-vbi.h"
55#include "ivtv-audio.h"
56#include "ivtv-gpio.h"
57#include "ivtv-yuv.h"
58
59#include <linux/vermagic.h>
60#include <media/tveeprom.h>
61#include <media/v4l2-chip-ident.h>
62
63/* var to keep track of the number of array elements in use */
64int ivtv_cards_active = 0;
65
66/* If you have already X v4l cards, then set this to X. This way
67 the device numbers stay matched. Example: you have a WinTV card
68 without radio and a PVR-350 with. Normally this would give a
69 video1 device together with a radio0 device for the PVR. By
70 setting this to 1 you ensure that radio0 is now also radio1. */
71int ivtv_first_minor = 0;
72
73/* Master variable for all ivtv info */
74struct ivtv *ivtv_cards[IVTV_MAX_CARDS];
75
76/* Protects ivtv_cards_active */
77spinlock_t ivtv_cards_lock = SPIN_LOCK_UNLOCKED;
78
79/* add your revision and whatnot here */
80static struct pci_device_id ivtv_pci_tbl[] __devinitdata = {
81 {PCI_VENDOR_ID_ICOMP, PCI_DEVICE_ID_IVTV15,
82 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
83 {PCI_VENDOR_ID_ICOMP, PCI_DEVICE_ID_IVTV16,
84 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
85 {0,}
86};
87
88MODULE_DEVICE_TABLE(pci,ivtv_pci_tbl);
89
90const u32 yuv_offset[4] = {
91 IVTV_YUV_BUFFER_OFFSET,
92 IVTV_YUV_BUFFER_OFFSET_1,
93 IVTV_YUV_BUFFER_OFFSET_2,
94 IVTV_YUV_BUFFER_OFFSET_3
95};
96
97/* Parameter declarations */
98static int cardtype[IVTV_MAX_CARDS];
99static int tuner[IVTV_MAX_CARDS] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 };
100static int radio[IVTV_MAX_CARDS] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 };
101
102static int cardtype_c = 1;
103static int tuner_c = 1;
104static int radio_c = 1;
105static char pal[] = "--";
106static char secam[] = "--";
107static char ntsc[] = "-";
108
109/* Buffers */
110static int enc_mpg_buffers = IVTV_DEFAULT_ENC_MPG_BUFFERS;
111static int enc_yuv_buffers = IVTV_DEFAULT_ENC_YUV_BUFFERS;
112static int enc_vbi_buffers = IVTV_DEFAULT_ENC_VBI_BUFFERS;
113static int enc_pcm_buffers = IVTV_DEFAULT_ENC_PCM_BUFFERS;
114static int dec_mpg_buffers = IVTV_DEFAULT_DEC_MPG_BUFFERS;
115static int dec_yuv_buffers = IVTV_DEFAULT_DEC_YUV_BUFFERS;
116static int dec_vbi_buffers = IVTV_DEFAULT_DEC_VBI_BUFFERS;
117
118static int ivtv_yuv_mode = 0;
119static int ivtv_yuv_threshold=-1;
120static int ivtv_pci_latency = 1;
121
122int ivtv_debug = 0;
123
124static int newi2c = -1;
125
126module_param_array(tuner, int, &tuner_c, 0644);
127module_param_array(radio, bool, &radio_c, 0644);
128module_param_array(cardtype, int, &cardtype_c, 0644);
129module_param_string(pal, pal, sizeof(pal), 0644);
130module_param_string(secam, secam, sizeof(secam), 0644);
131module_param_string(ntsc, ntsc, sizeof(ntsc), 0644);
132module_param_named(debug,ivtv_debug, int, 0644);
133module_param(ivtv_pci_latency, int, 0644);
134module_param(ivtv_yuv_mode, int, 0644);
135module_param(ivtv_yuv_threshold, int, 0644);
136module_param(ivtv_first_minor, int, 0644);
137
138module_param(enc_mpg_buffers, int, 0644);
139module_param(enc_yuv_buffers, int, 0644);
140module_param(enc_vbi_buffers, int, 0644);
141module_param(enc_pcm_buffers, int, 0644);
142module_param(dec_mpg_buffers, int, 0644);
143module_param(dec_yuv_buffers, int, 0644);
144module_param(dec_vbi_buffers, int, 0644);
145
146module_param(newi2c, int, 0644);
147
148MODULE_PARM_DESC(tuner, "Tuner type selection,\n"
149 "\t\t\tsee tuner.h for values");
150MODULE_PARM_DESC(radio,
151 "Enable or disable the radio. Use only if autodetection\n"
152 "\t\t\tfails. 0 = disable, 1 = enable");
153MODULE_PARM_DESC(cardtype,
154 "Only use this option if your card is not detected properly.\n"
155 "\t\tSpecify card type:\n"
156 "\t\t\t 1 = WinTV PVR 250\n"
157 "\t\t\t 2 = WinTV PVR 350\n"
158 "\t\t\t 3 = WinTV PVR-150 or PVR-500\n"
159 "\t\t\t 4 = AVerMedia M179\n"
160 "\t\t\t 5 = YUAN MPG600/Kuroutoshikou iTVC16-STVLP\n"
161 "\t\t\t 6 = YUAN MPG160/Kuroutoshikou iTVC15-STVLP\n"
162 "\t\t\t 7 = YUAN PG600/DIAMONDMM PVR-550 (CX Falcon 2)\n"
163 "\t\t\t 8 = Adaptec AVC-2410\n"
164 "\t\t\t 9 = Adaptec AVC-2010\n"
165 "\t\t\t10 = NAGASE TRANSGEAR 5000TV\n"
166 "\t\t\t11 = AOpen VA2000MAX-STN6\n"
167 "\t\t\t12 = YUAN MPG600GR/Kuroutoshikou CX23416GYC-STVLP\n"
168 "\t\t\t13 = I/O Data GV-MVP/RX\n"
169 "\t\t\t14 = I/O Data GV-MVP/RX2E\n"
170 "\t\t\t15 = GOTVIEW PCI DVD\n"
171 "\t\t\t16 = GOTVIEW PCI DVD2 Deluxe\n"
172 "\t\t\t17 = Yuan MPC622\n"
173 "\t\t\t18 = Digital Cowboy DCT-MTVP1\n"
174#ifdef HAVE_XC3028
175 "\t\t\t19 = Yuan PG600V2/GotView PCI DVD Lite/Club3D ZAP-TV1x01\n"
176#endif
177 "\t\t\t 0 = Autodetect (default)\n"
178 "\t\t\t-1 = Ignore this card\n\t\t");
179MODULE_PARM_DESC(pal, "Set PAL standard: B, G, H, D, K, I, M, N, Nc, 60");
180MODULE_PARM_DESC(secam, "Set SECAM standard: B, G, H, D, K, L, LC");
181MODULE_PARM_DESC(ntsc, "Set NTSC standard: M, J, K");
182MODULE_PARM_DESC(debug,
183 "Debug level (bitmask). Default: errors only\n"
184 "\t\t\t(debug = 511 gives full debugging)");
185MODULE_PARM_DESC(ivtv_pci_latency,
186 "Change the PCI latency to 64 if lower: 0 = No, 1 = Yes,\n"
187 "\t\t\tDefault: Yes");
188MODULE_PARM_DESC(ivtv_yuv_mode,
189 "Specify the yuv playback mode:\n"
190 "\t\t\t0 = interlaced\n\t\t\t1 = progressive\n\t\t\t2 = auto\n"
191 "\t\t\tDefault: 0 (interlaced)");
192MODULE_PARM_DESC(ivtv_yuv_threshold,
193 "If ivtv_yuv_mode is 2 (auto) then playback content as\n\t\tprogressive if src height <= ivtv_yuvthreshold\n"
194 "\t\t\tDefault: 480");;
195MODULE_PARM_DESC(enc_mpg_buffers,
196 "Encoder MPG Buffers (in MB)\n"
197 "\t\t\tDefault: " __stringify(IVTV_DEFAULT_ENC_MPG_BUFFERS));
198MODULE_PARM_DESC(enc_yuv_buffers,
199 "Encoder YUV Buffers (in MB)\n"
200 "\t\t\tDefault: " __stringify(IVTV_DEFAULT_ENC_YUV_BUFFERS));
201MODULE_PARM_DESC(enc_vbi_buffers,
202 "Encoder VBI Buffers (in MB)\n"
203 "\t\t\tDefault: " __stringify(IVTV_DEFAULT_ENC_VBI_BUFFERS));
204MODULE_PARM_DESC(enc_pcm_buffers,
205 "Encoder PCM buffers (in MB)\n"
206 "\t\t\tDefault: " __stringify(IVTV_DEFAULT_ENC_PCM_BUFFERS));
207MODULE_PARM_DESC(dec_mpg_buffers,
208 "Decoder MPG buffers (in MB)\n"
209 "\t\t\tDefault: " __stringify(IVTV_DEFAULT_DEC_MPG_BUFFERS));
210MODULE_PARM_DESC(dec_yuv_buffers,
211 "Decoder YUV buffers (in MB)\n"
212 "\t\t\tDefault: " __stringify(IVTV_DEFAULT_DEC_YUV_BUFFERS));
213MODULE_PARM_DESC(dec_vbi_buffers,
214 "Decoder VBI buffers (in MB)\n"
215 "\t\t\tDefault: " __stringify(IVTV_DEFAULT_DEC_VBI_BUFFERS));
216MODULE_PARM_DESC(newi2c,
217 "Use new I2C implementation\n"
218 "\t\t\t-1 is autodetect, 0 is off, 1 is on\n"
219 "\t\t\tDefault is autodetect");
220
221MODULE_PARM_DESC(ivtv_first_minor, "Set minor assigned to first card");
222
223MODULE_AUTHOR("Kevin Thayer, Chris Kennedy, Hans Verkuil");
224MODULE_DESCRIPTION("CX23415/CX23416 driver");
225MODULE_SUPPORTED_DEVICE
226 ("CX23415/CX23416 MPEG2 encoder (WinTV PVR-150/250/350/500,\n"
227 "\t\t\tYuan MPG series and similar)");
228MODULE_LICENSE("GPL");
229
230MODULE_VERSION(IVTV_VERSION);
231
232void ivtv_clear_irq_mask(struct ivtv *itv, u32 mask)
233{
234 itv->irqmask &= ~mask;
235 write_reg_sync(itv->irqmask, IVTV_REG_IRQMASK);
236}
237
238void ivtv_set_irq_mask(struct ivtv *itv, u32 mask)
239{
240 itv->irqmask |= mask;
241 write_reg_sync(itv->irqmask, IVTV_REG_IRQMASK);
242}
243
244int ivtv_set_output_mode(struct ivtv *itv, int mode)
245{
246 int old_mode;
247
248 spin_lock(&itv->lock);
249 old_mode = itv->output_mode;
250 if (old_mode == 0)
251 itv->output_mode = old_mode = mode;
252 spin_unlock(&itv->lock);
253 return old_mode;
254}
255
256struct ivtv_stream *ivtv_get_output_stream(struct ivtv *itv)
257{
258 switch (itv->output_mode) {
259 case OUT_MPG:
260 return &itv->streams[IVTV_DEC_STREAM_TYPE_MPG];
261 case OUT_YUV:
262 return &itv->streams[IVTV_DEC_STREAM_TYPE_YUV];
263 default:
264 return NULL;
265 }
266}
267
268int ivtv_waitq(wait_queue_head_t *waitq)
269{
270 DEFINE_WAIT(wait);
271
272 prepare_to_wait(waitq, &wait, TASK_INTERRUPTIBLE);
273 schedule();
274 finish_wait(waitq, &wait);
275 return signal_pending(current) ? -EINTR : 0;
276}
277
278/* Generic utility functions */
279int ivtv_sleep_timeout(int timeout, int intr)
280{
281 int ret;
282
283 do {
284 set_current_state(intr ? TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE);
285 timeout = schedule_timeout(timeout);
286 if (intr && (ret = signal_pending(current)))
287 return ret;
288 } while (timeout);
289 return 0;
290}
291
292/* Release ioremapped memory */
293static void ivtv_iounmap(struct ivtv *itv)
294{
295 if (itv == NULL)
296 return;
297
298 /* Release registers memory */
299 if (itv->reg_mem != NULL) {
300 IVTV_DEBUG_INFO("releasing reg_mem\n");
301 iounmap(itv->reg_mem);
302 itv->reg_mem = NULL;
303 }
304 /* Release io memory */
305 if (itv->has_cx23415 && itv->dec_mem != NULL) {
306 IVTV_DEBUG_INFO("releasing dec_mem\n");
307 iounmap(itv->dec_mem);
308 }
309 itv->dec_mem = NULL;
310
311 /* Release io memory */
312 if (itv->enc_mem != NULL) {
313 IVTV_DEBUG_INFO("releasing enc_mem\n");
314 iounmap(itv->enc_mem);
315 itv->enc_mem = NULL;
316 }
317}
318
319/* Hauppauge card? get values from tveeprom */
320void ivtv_read_eeprom(struct ivtv *itv, struct tveeprom *tv)
321{
322 u8 eedata[256];
323
324 itv->i2c_client.addr = 0xA0 >> 1;
325 tveeprom_read(&itv->i2c_client, eedata, sizeof(eedata));
326 tveeprom_hauppauge_analog(&itv->i2c_client, tv, eedata);
327}
328
329static void ivtv_process_eeprom(struct ivtv *itv)
330{
331 struct tveeprom tv;
332 int pci_slot = PCI_SLOT(itv->dev->devfn);
333
334 ivtv_read_eeprom(itv, &tv);
335
336 /* Many thanks to Steven Toth from Hauppauge for providing the
337 model numbers */
338 switch (tv.model) {
339 /* In a few cases the PCI subsystem IDs do not correctly
340 identify the card. A better method is to check the
341 model number from the eeprom instead. */
342 case 32000 ... 32999:
343 case 48000 ... 48099: /* 48??? range are PVR250s with a cx23415 */
344 case 48400 ... 48599:
345 itv->card = ivtv_get_card(IVTV_CARD_PVR_250);
346 break;
347 case 48100 ... 48399:
348 case 48600 ... 48999:
349 itv->card = ivtv_get_card(IVTV_CARD_PVR_350);
350 break;
351 case 23000 ... 23999: /* PVR500 */
352 case 25000 ... 25999: /* Low profile PVR150 */
353 case 26000 ... 26999: /* Regular PVR150 */
354 itv->card = ivtv_get_card(IVTV_CARD_PVR_150);
355 break;
356 case 0:
357 IVTV_ERR("Invalid EEPROM\n");
358 return;
359 default:
360 IVTV_ERR("Unknown model %d, defaulting to PVR-150\n", tv.model);
361 itv->card = ivtv_get_card(IVTV_CARD_PVR_150);
362 break;
363 }
364
365 switch (tv.model) {
366 /* Old style PVR350 (with an saa7114) uses this input for
367 the tuner. */
368 case 48254:
369 itv->card = ivtv_get_card(IVTV_CARD_PVR_350_V1);
370 break;
371 default:
372 break;
373 }
374
375 itv->v4l2_cap = itv->card->v4l2_capabilities;
376 itv->card_name = itv->card->name;
377
378 /* If this is a PVR500 then it should be possible to detect whether it is the
379 first or second unit by looking at the subsystem device ID: is bit 4 is
380 set, then it is the second unit (according to info from Hauppauge).
381
382 However, while this works for most cards, I have seen a few PVR500 cards
383 where both units have the same subsystem ID.
384
385 So instead I look at the reported 'PCI slot' (which is the slot on the PVR500
386 PCI bridge) and if it is 8, then it is assumed to be the first unit, otherwise
387 it is the second unit. It is possible that it is a different slot when ivtv is
388 used in Xen, in that case I ignore this card here. The worst that can happen
389 is that the card presents itself with a non-working radio device.
390
391 This detection is needed since the eeprom reports incorrectly that a radio is
392 present on the second unit. */
393 if (tv.model / 1000 == 23) {
394 itv->card_name = "WinTV PVR 500";
395 if (pci_slot == 8 || pci_slot == 9) {
396 int is_first = (pci_slot & 1) == 0;
397
398 itv->card_name = is_first ? "WinTV PVR 500 (unit #1)" :
399 "WinTV PVR 500 (unit #2)";
400 if (!is_first) {
401 IVTV_INFO("Correcting tveeprom data: no radio present on second unit\n");
402 tv.has_radio = 0;
403 }
404 }
405 }
406 IVTV_INFO("Autodetected %s\n", itv->card_name);
407
408 switch (tv.tuner_hauppauge_model) {
409 case 85:
410 case 99:
411 case 112:
412 itv->pvr150_workaround = 1;
413 break;
414 default:
415 break;
416 }
417 if (tv.tuner_type == TUNER_ABSENT)
418 IVTV_ERR("tveeprom cannot autodetect tuner!");
419
420 if (itv->options.tuner == -1)
421 itv->options.tuner = tv.tuner_type;
422 if (itv->options.radio == -1)
423 itv->options.radio = (tv.has_radio != 0);
424 /* only enable newi2c if an IR blaster is present */
425 /* FIXME: for 2.6.20 the test against 2 should be removed */
426 if (itv->options.newi2c == -1 && tv.has_ir != -1 && tv.has_ir != 2) {
427 itv->options.newi2c = (tv.has_ir & 2) ? 1 : 0;
428 if (itv->options.newi2c) {
429 IVTV_INFO("reopen i2c bus for IR-blaster support\n");
430 exit_ivtv_i2c(itv);
431 init_ivtv_i2c(itv);
432 }
433 }
434
435 if (itv->std != 0)
436 /* user specified tuner standard */
437 return;
438
439 /* autodetect tuner standard */
440 if (tv.tuner_formats & V4L2_STD_PAL) {
441 IVTV_DEBUG_INFO("PAL tuner detected\n");
442 itv->std |= V4L2_STD_PAL_BG | V4L2_STD_PAL_H;
443 } else if (tv.tuner_formats & V4L2_STD_NTSC) {
444 IVTV_DEBUG_INFO("NTSC tuner detected\n");
445 itv->std |= V4L2_STD_NTSC_M;
446 } else if (tv.tuner_formats & V4L2_STD_SECAM) {
447 IVTV_DEBUG_INFO("SECAM tuner detected\n");
448 itv->std |= V4L2_STD_SECAM_L;
449 } else {
450 IVTV_INFO("No tuner detected, default to NTSC-M\n");
451 itv->std |= V4L2_STD_NTSC_M;
452 }
453}
454
455static v4l2_std_id ivtv_parse_std(struct ivtv *itv)
456{
457 switch (pal[0]) {
458 case '6':
459 return V4L2_STD_PAL_60;
460 case 'b':
461 case 'B':
462 case 'g':
463 case 'G':
464 return V4L2_STD_PAL_BG;
465 case 'h':
466 case 'H':
467 return V4L2_STD_PAL_H;
468 case 'n':
469 case 'N':
470 if (pal[1] == 'c' || pal[1] == 'C')
471 return V4L2_STD_PAL_Nc;
472 return V4L2_STD_PAL_N;
473 case 'i':
474 case 'I':
475 return V4L2_STD_PAL_I;
476 case 'd':
477 case 'D':
478 case 'k':
479 case 'K':
480 return V4L2_STD_PAL_DK;
481 case 'M':
482 case 'm':
483 return V4L2_STD_PAL_M;
484 case '-':
485 break;
486 default:
487 IVTV_WARN("pal= argument not recognised\n");
488 return 0;
489 }
490
491 switch (secam[0]) {
492 case 'b':
493 case 'B':
494 case 'g':
495 case 'G':
496 case 'h':
497 case 'H':
498 return V4L2_STD_SECAM_B | V4L2_STD_SECAM_G | V4L2_STD_SECAM_H;
499 case 'd':
500 case 'D':
501 case 'k':
502 case 'K':
503 return V4L2_STD_SECAM_DK;
504 case 'l':
505 case 'L':
506 if (secam[1] == 'C' || secam[1] == 'c')
507 return V4L2_STD_SECAM_LC;
508 return V4L2_STD_SECAM_L;
509 case '-':
510 break;
511 default:
512 IVTV_WARN("secam= argument not recognised\n");
513 return 0;
514 }
515
516 switch (ntsc[0]) {
517 case 'm':
518 case 'M':
519 return V4L2_STD_NTSC_M;
520 case 'j':
521 case 'J':
522 return V4L2_STD_NTSC_M_JP;
523 case 'k':
524 case 'K':
525 return V4L2_STD_NTSC_M_KR;
526 case '-':
527 break;
528 default:
529 IVTV_WARN("ntsc= argument not recognised\n");
530 return 0;
531 }
532
533 /* no match found */
534 return 0;
535}
536
537static void ivtv_process_options(struct ivtv *itv)
538{
539 const char *chipname;
540 int i, j;
541
542 itv->options.megabytes[IVTV_ENC_STREAM_TYPE_MPG] = enc_mpg_buffers;
543 itv->options.megabytes[IVTV_ENC_STREAM_TYPE_YUV] = enc_yuv_buffers;
544 itv->options.megabytes[IVTV_ENC_STREAM_TYPE_VBI] = enc_vbi_buffers;
545 itv->options.megabytes[IVTV_ENC_STREAM_TYPE_PCM] = enc_pcm_buffers;
546 itv->options.megabytes[IVTV_DEC_STREAM_TYPE_MPG] = dec_mpg_buffers;
547 itv->options.megabytes[IVTV_DEC_STREAM_TYPE_YUV] = dec_yuv_buffers;
548 itv->options.megabytes[IVTV_DEC_STREAM_TYPE_VBI] = dec_vbi_buffers;
549 itv->options.cardtype = cardtype[itv->num];
550 itv->options.tuner = tuner[itv->num];
551 itv->options.radio = radio[itv->num];
552 itv->options.newi2c = newi2c;
553
554 itv->std = ivtv_parse_std(itv);
555 itv->has_cx23415 = (itv->dev->device == PCI_DEVICE_ID_IVTV15);
556 chipname = itv->has_cx23415 ? "cx23415" : "cx23416";
557 if (itv->options.cardtype == -1) {
558 IVTV_INFO("Ignore card (detected %s based chip)\n", chipname);
559 return;
560 }
561 if ((itv->card = ivtv_get_card(itv->options.cardtype - 1))) {
562 IVTV_INFO("User specified %s card (detected %s based chip)\n",
563 itv->card->name, chipname);
564 } else if (itv->options.cardtype != 0) {
565 IVTV_ERR("Unknown user specified type, trying to autodetect card\n");
566 }
567 if (itv->card == NULL) {
568 if (itv->dev->subsystem_vendor == IVTV_PCI_ID_HAUPPAUGE ||
569 itv->dev->subsystem_vendor == IVTV_PCI_ID_HAUPPAUGE_ALT1 ||
570 itv->dev->subsystem_vendor == IVTV_PCI_ID_HAUPPAUGE_ALT2) {
571 itv->card = ivtv_get_card(itv->has_cx23415 ? IVTV_CARD_PVR_350 : IVTV_CARD_PVR_150);
572 IVTV_INFO("Autodetected Hauppauge card (%s based)\n",
573 chipname);
574 }
575 }
576 if (itv->card == NULL) {
577 for (i = 0; (itv->card = ivtv_get_card(i)); i++) {
578 if (itv->card->pci_list == NULL)
579 continue;
580 for (j = 0; itv->card->pci_list[j].device; j++) {
581 if (itv->dev->device !=
582 itv->card->pci_list[j].device)
583 continue;
584 if (itv->dev->subsystem_vendor !=
585 itv->card->pci_list[j].subsystem_vendor)
586 continue;
587 if (itv->dev->subsystem_device !=
588 itv->card->pci_list[j].subsystem_device)
589 continue;
590 IVTV_INFO("Autodetected %s card (%s based)\n",
591 itv->card->name, chipname);
592 goto done;
593 }
594 }
595 }
596done:
597
598 if (itv->card == NULL) {
599 itv->card = ivtv_get_card(IVTV_CARD_PVR_150);
600 IVTV_ERR("Unknown card: vendor/device: %04x/%04x\n",
601 itv->dev->vendor, itv->dev->device);
602 IVTV_ERR(" subsystem vendor/device: %04x/%04x\n",
603 itv->dev->subsystem_vendor, itv->dev->subsystem_device);
604 IVTV_ERR(" %s based\n", chipname);
605 IVTV_ERR("Defaulting to %s card\n", itv->card->name);
606 IVTV_ERR("Please mail the vendor/device and subsystem vendor/device IDs and what kind of\n");
607 IVTV_ERR("card you have to the ivtv-devel mailinglist (www.ivtvdriver.org)\n");
608 IVTV_ERR("Prefix your subject line with [UNKNOWN CARD].\n");
609 }
610 itv->v4l2_cap = itv->card->v4l2_capabilities;
611 itv->card_name = itv->card->name;
612}
613
614/* Precondition: the ivtv structure has been memset to 0. Only
615 the dev and num fields have been filled in.
616 No assumptions on the card type may be made here (see ivtv_init_struct2
617 for that).
618 */
619static int __devinit ivtv_init_struct1(struct ivtv *itv)
620{
621 itv->base_addr = pci_resource_start(itv->dev, 0);
622 itv->enc_mbox.max_mbox = 2; /* the encoder has 3 mailboxes (0-2) */
623 itv->dec_mbox.max_mbox = 1; /* the decoder has 2 mailboxes (0-1) */
624
625 mutex_init(&itv->i2c_bus_lock);
626 mutex_init(&itv->udma.lock);
627
628 spin_lock_init(&itv->lock);
629 spin_lock_init(&itv->dma_reg_lock);
630
631 itv->irq_work_queues = create_workqueue(itv->name);
632 if (itv->irq_work_queues == NULL) {
633 IVTV_ERR("Could not create ivtv workqueue\n");
634 return -1;
635 }
636
637 INIT_WORK(&itv->irq_work_queue, ivtv_irq_work_handler);
638
639 /* start counting open_id at 1 */
640 itv->open_id = 1;
641
642 /* Initial settings */
643 cx2341x_fill_defaults(&itv->params);
644 itv->params.port = CX2341X_PORT_MEMORY;
645 itv->params.capabilities = CX2341X_CAP_HAS_SLICED_VBI;
646 init_waitqueue_head(&itv->cap_w);
647 init_waitqueue_head(&itv->event_waitq);
648 init_waitqueue_head(&itv->vsync_waitq);
649 init_waitqueue_head(&itv->dma_waitq);
650 init_timer(&itv->dma_timer);
651 itv->dma_timer.function = ivtv_unfinished_dma;
652 itv->dma_timer.data = (unsigned long)itv;
653
654 itv->cur_dma_stream = -1;
655 itv->audio_stereo_mode = AUDIO_STEREO;
656 itv->audio_bilingual_mode = AUDIO_MONO_LEFT;
657
658 /* Ctrls */
659 itv->speed = 1000;
660
661 /* VBI */
662 itv->vbi.in.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE;
663 itv->vbi.sliced_in = &itv->vbi.in.fmt.sliced;
664
665 /* OSD */
666 itv->osd_global_alpha_state = 1;
667 itv->osd_global_alpha = 255;
668
669 /* YUV */
670 atomic_set(&itv->yuv_info.next_dma_frame, -1);
671 itv->yuv_info.lace_mode = ivtv_yuv_mode;
672 itv->yuv_info.lace_threshold = ivtv_yuv_threshold;
673 return 0;
674}
675
676/* Second initialization part. Here the card type has been
677 autodetected. */
678static void __devinit ivtv_init_struct2(struct ivtv *itv)
679{
680 int i;
681
682 for (i = 0; i < IVTV_CARD_MAX_VIDEO_INPUTS; i++)
683 if (itv->card->video_inputs[i].video_type == 0)
684 break;
685 itv->nof_inputs = i;
686 for (i = 0; i < IVTV_CARD_MAX_AUDIO_INPUTS; i++)
687 if (itv->card->audio_inputs[i].audio_type == 0)
688 break;
689 itv->nof_audio_inputs = i;
690
691 /* 0x00EF = saa7114(239) 0x00F0 = saa7115(240) 0x0106 = micro */
692 if (itv->card->hw_all & (IVTV_HW_SAA7115 | IVTV_HW_SAA717X))
693 itv->digitizer = 0xF1;
694 else if (itv->card->hw_all & IVTV_HW_SAA7114)
695 itv->digitizer = 0xEF;
696 else /* cx25840 */
697 itv->digitizer = 0x140;
698
699 if (itv->card->hw_all & IVTV_HW_CX25840) {
700 itv->vbi.sliced_size = 288; /* multiple of 16, real size = 284 */
701 } else {
702 itv->vbi.sliced_size = 64; /* multiple of 16, real size = 52 */
703 }
704
705 /* Find tuner input */
706 for (i = 0; i < itv->nof_inputs; i++) {
707 if (itv->card->video_inputs[i].video_type ==
708 IVTV_CARD_INPUT_VID_TUNER)
709 break;
710 }
711 if (i == itv->nof_inputs)
712 i = 0;
713 itv->active_input = i;
714 itv->audio_input = itv->card->video_inputs[i].audio_index;
715 if (itv->card->hw_all & IVTV_HW_CX25840)
716 itv->video_dec_func = ivtv_cx25840;
717 else if (itv->card->hw_all & IVTV_HW_SAA717X)
718 itv->video_dec_func = ivtv_saa717x;
719 else
720 itv->video_dec_func = ivtv_saa7115;
721}
722
723static int ivtv_setup_pci(struct ivtv *itv, struct pci_dev *dev,
724 const struct pci_device_id *pci_id)
725{
726 u16 cmd;
727 unsigned char pci_latency;
728
729 IVTV_DEBUG_INFO("Enabling pci device\n");
730
731 if (pci_enable_device(dev)) {
732 IVTV_ERR("Can't enable device %d!\n", itv->num);
733 return -EIO;
734 }
735 if (pci_set_dma_mask(dev, 0xffffffff)) {
736 IVTV_ERR("No suitable DMA available on card %d.\n", itv->num);
737 return -EIO;
738 }
739 if (!request_mem_region(itv->base_addr, IVTV_ENCODER_SIZE, "ivtv encoder")) {
740 IVTV_ERR("Cannot request encoder memory region on card %d.\n", itv->num);
741 return -EIO;
742 }
743
744 if (!request_mem_region(itv->base_addr + IVTV_REG_OFFSET,
745 IVTV_REG_SIZE, "ivtv registers")) {
746 IVTV_ERR("Cannot request register memory region on card %d.\n", itv->num);
747 release_mem_region(itv->base_addr, IVTV_ENCODER_SIZE);
748 return -EIO;
749 }
750
751 if (itv->has_cx23415 &&
752 !request_mem_region(itv->base_addr + IVTV_DECODER_OFFSET,
753 IVTV_DECODER_SIZE, "ivtv decoder")) {
754 IVTV_ERR("Cannot request decoder memory region on card %d.\n", itv->num);
755 release_mem_region(itv->base_addr, IVTV_ENCODER_SIZE);
756 release_mem_region(itv->base_addr + IVTV_REG_OFFSET, IVTV_REG_SIZE);
757 return -EIO;
758 }
759
760 /* Check for bus mastering */
761 pci_read_config_word(dev, PCI_COMMAND, &cmd);
762 if (!(cmd & PCI_COMMAND_MASTER)) {
763 IVTV_DEBUG_INFO("Attempting to enable Bus Mastering\n");
764 pci_set_master(dev);
765 pci_read_config_word(dev, PCI_COMMAND, &cmd);
766 if (!(cmd & PCI_COMMAND_MASTER)) {
767 IVTV_ERR("Bus Mastering is not enabled\n");
768 return -ENXIO;
769 }
770 }
771 IVTV_DEBUG_INFO("Bus Mastering Enabled.\n");
772
773 pci_read_config_byte(dev, PCI_CLASS_REVISION, &itv->card_rev);
774 pci_read_config_byte(dev, PCI_LATENCY_TIMER, &pci_latency);
775
776 if (pci_latency < 64 && ivtv_pci_latency) {
777 IVTV_INFO("Unreasonably low latency timer, "
778 "setting to 64 (was %d)\n", pci_latency);
779 pci_write_config_byte(dev, PCI_LATENCY_TIMER, 64);
780 pci_read_config_byte(dev, PCI_LATENCY_TIMER, &pci_latency);
781 }
782 /* This config space value relates to DMA latencies. The
783 default value 0x8080 is too low however and will lead
784 to DMA errors. 0xffff is the max value which solves
785 these problems. */
786 pci_write_config_dword(dev, 0x40, 0xffff);
787
788 IVTV_DEBUG_INFO("%d (rev %d) at %02x:%02x.%x, "
789 "irq: %d, latency: %d, memory: 0x%lx\n",
790 itv->dev->device, itv->card_rev, dev->bus->number,
791 PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn),
792 itv->dev->irq, pci_latency, (unsigned long)itv->base_addr);
793
794 return 0;
795}
796
797static void ivtv_request_module(struct ivtv *itv, const char *name)
798{
799 if (request_module(name) != 0) {
800 IVTV_ERR("Failed to load module %s\n", name);
801 } else {
802 IVTV_DEBUG_INFO("Loaded module %s\n", name);
803 }
804}
805
806static void ivtv_load_and_init_modules(struct ivtv *itv)
807{
808 struct v4l2_control ctrl;
809 u32 hw = itv->card->hw_all;
810 int i;
811
812 /* load modules */
813#ifndef CONFIG_VIDEO_TUNER
814 if (hw & IVTV_HW_TUNER) {
815 ivtv_request_module(itv, "tuner");
816#ifdef HAVE_XC3028
817 if (itv->options.tuner == TUNER_XCEIVE_XC3028)
818 ivtv_request_module(itv, "xc3028-tuner");
819#endif
820 }
821#endif
822#ifndef CONFIG_VIDEO_CX25840
823 if (hw & IVTV_HW_CX25840)
824 ivtv_request_module(itv, "cx25840");
825#endif
826#ifndef CONFIG_VIDEO_SAA711X
827 if (hw & IVTV_HW_SAA711X)
828 ivtv_request_module(itv, "saa7115");
829#endif
830#ifndef CONFIG_VIDEO_SAA7127
831 if (hw & IVTV_HW_SAA7127)
832 ivtv_request_module(itv, "saa7127");
833#endif
834 if (hw & IVTV_HW_SAA717X)
835 ivtv_request_module(itv, "saa717x");
836#ifndef CONFIG_VIDEO_UPD64031A
837 if (hw & IVTV_HW_UPD64031A)
838 ivtv_request_module(itv, "upd64031a");
839#endif
840#ifndef CONFIG_VIDEO_UPD64083
841 if (hw & IVTV_HW_UPD6408X)
842 ivtv_request_module(itv, "upd64083");
843#endif
844#ifndef CONFIG_VIDEO_MSP3400
845 if (hw & IVTV_HW_MSP34XX)
846 ivtv_request_module(itv, "msp3400");
847#endif
848 if (hw & IVTV_HW_TVAUDIO)
849 ivtv_request_module(itv, "tvaudio");
850#ifndef CONFIG_VIDEO_WM8775
851 if (hw & IVTV_HW_WM8775)
852 ivtv_request_module(itv, "wm8775");
853#endif
854#ifndef CONFIG_VIDEO_WM8739
855 if (hw & IVTV_HW_WM8739)
856 ivtv_request_module(itv, "wm8739");
857#endif
858#ifndef CONFIG_VIDEO_CS53L32A
859 if (hw & IVTV_HW_CS53L32A)
860 ivtv_request_module(itv, "cs53l32a");
861#endif
862
863 /* check which i2c devices are actually found */
864 for (i = 0; i < 32; i++) {
865 u32 device = 1 << i;
866
867 if (!(device & hw))
868 continue;
869 if (device == IVTV_HW_GPIO) {
870 /* GPIO is always available */
871 itv->hw_flags |= IVTV_HW_GPIO;
872 continue;
873 }
874 if (ivtv_i2c_hw_addr(itv, device) > 0)
875 itv->hw_flags |= device;
876 }
877
878 hw = itv->hw_flags;
879
880 if (itv->card->type == IVTV_CARD_CX23416GYC) {
881 /* Several variations of this card exist, detect which card
882 type should be used. */
883 if ((hw & (IVTV_HW_UPD64031A | IVTV_HW_UPD6408X)) == 0)
884 itv->card = ivtv_get_card(IVTV_CARD_CX23416GYC_NOGRYCS);
885 else if ((hw & IVTV_HW_UPD64031A) == 0)
886 itv->card = ivtv_get_card(IVTV_CARD_CX23416GYC_NOGR);
887 }
888
889 if (hw & IVTV_HW_CX25840) {
890 /* CX25840_CID_ENABLE_PVR150_WORKAROUND */
891 ctrl.id = V4L2_CID_PRIVATE_BASE;
892 ctrl.value = itv->pvr150_workaround;
893 itv->video_dec_func(itv, VIDIOC_S_CTRL, &ctrl);
894
895 itv->vbi.raw_decoder_line_size = 1444;
896 itv->vbi.raw_decoder_sav_odd_field = 0x20;
897 itv->vbi.raw_decoder_sav_even_field = 0x60;
898 itv->vbi.sliced_decoder_line_size = 272;
899 itv->vbi.sliced_decoder_sav_odd_field = 0xB0;
900 itv->vbi.sliced_decoder_sav_even_field = 0xF0;
901 }
902
903 if (hw & IVTV_HW_SAA711X) {
904 struct v4l2_chip_ident v = { V4L2_CHIP_MATCH_I2C_DRIVER, I2C_DRIVERID_SAA711X };
905
906 /* determine the exact saa711x model */
907 itv->hw_flags &= ~IVTV_HW_SAA711X;
908
909 ivtv_saa7115(itv, VIDIOC_G_CHIP_IDENT, &v);
910 if (v.ident == V4L2_IDENT_SAA7114) {
911 itv->hw_flags |= IVTV_HW_SAA7114;
912 /* VBI is not yet supported by the saa7114 driver. */
913 itv->v4l2_cap &= ~(V4L2_CAP_SLICED_VBI_CAPTURE|V4L2_CAP_VBI_CAPTURE);
914 }
915 else {
916 itv->hw_flags |= IVTV_HW_SAA7115;
917 }
918 itv->vbi.raw_decoder_line_size = 1443;
919 itv->vbi.raw_decoder_sav_odd_field = 0x25;
920 itv->vbi.raw_decoder_sav_even_field = 0x62;
921 itv->vbi.sliced_decoder_line_size = 51;
922 itv->vbi.sliced_decoder_sav_odd_field = 0xAB;
923 itv->vbi.sliced_decoder_sav_even_field = 0xEC;
924 }
925
926 if (hw & IVTV_HW_SAA717X) {
927 itv->vbi.raw_decoder_line_size = 1443;
928 itv->vbi.raw_decoder_sav_odd_field = 0x25;
929 itv->vbi.raw_decoder_sav_even_field = 0x62;
930 itv->vbi.sliced_decoder_line_size = 51;
931 itv->vbi.sliced_decoder_sav_odd_field = 0xAB;
932 itv->vbi.sliced_decoder_sav_even_field = 0xEC;
933 }
934}
935
936static int __devinit ivtv_probe(struct pci_dev *dev,
937 const struct pci_device_id *pci_id)
938{
939 int retval = 0;
940 int video_input;
941 int yuv_buf_size;
942 int vbi_buf_size;
943 int fw_retry_count = 3;
944 struct ivtv *itv;
945 struct v4l2_frequency vf;
946
947 spin_lock(&ivtv_cards_lock);
948
949 /* Make sure we've got a place for this card */
950 if (ivtv_cards_active == IVTV_MAX_CARDS) {
951 printk(KERN_ERR "ivtv: Maximum number of cards detected (%d).\n",
952 ivtv_cards_active);
953 spin_unlock(&ivtv_cards_lock);
954 return -ENOMEM;
955 }
956
957 itv = kzalloc(sizeof(struct ivtv), GFP_ATOMIC);
958 if (itv == 0) {
959 spin_unlock(&ivtv_cards_lock);
960 return -ENOMEM;
961 }
962 ivtv_cards[ivtv_cards_active] = itv;
963 itv->dev = dev;
964 itv->num = ivtv_cards_active++;
965 snprintf(itv->name, sizeof(itv->name) - 1, "ivtv%d", itv->num);
966 if (itv->num) {
967 printk(KERN_INFO "ivtv: ====================== NEXT CARD ======================\n");
968 }
969
970 spin_unlock(&ivtv_cards_lock);
971
972 ivtv_process_options(itv);
973 if (itv->options.cardtype == -1) {
974 retval = -ENODEV;
975 goto err;
976 }
977 if (ivtv_init_struct1(itv)) {
978 retval = -ENOMEM;
979 goto err;
980 }
981
982 IVTV_DEBUG_INFO("base addr: 0x%08x\n", itv->base_addr);
983
984 /* PCI Device Setup */
985 if ((retval = ivtv_setup_pci(itv, dev, pci_id)) != 0) {
986 if (retval == -EIO)
987 goto free_workqueue;
988 else if (retval == -ENXIO)
989 goto free_mem;
990 }
991 /* save itv in the pci struct for later use */
992 pci_set_drvdata(dev, itv);
993
994 /* map io memory */
995 IVTV_DEBUG_INFO("attempting ioremap at 0x%08x len 0x%08x\n",
996 itv->base_addr + IVTV_ENCODER_OFFSET, IVTV_ENCODER_SIZE);
997 itv->enc_mem = ioremap_nocache(itv->base_addr + IVTV_ENCODER_OFFSET,
998 IVTV_ENCODER_SIZE);
999 if (!itv->enc_mem) {
1000 IVTV_ERR("ioremap failed, perhaps increasing __VMALLOC_RESERVE in page.h\n");
1001 IVTV_ERR("or disabling CONFIG_HIMEM4G into the kernel would help\n");
1002 retval = -ENOMEM;
1003 goto free_mem;
1004 }
1005
1006 if (itv->has_cx23415) {
1007 IVTV_DEBUG_INFO("attempting ioremap at 0x%08x len 0x%08x\n",
1008 itv->base_addr + IVTV_DECODER_OFFSET, IVTV_DECODER_SIZE);
1009 itv->dec_mem = ioremap_nocache(itv->base_addr + IVTV_DECODER_OFFSET,
1010 IVTV_DECODER_SIZE);
1011 if (!itv->dec_mem) {
1012 IVTV_ERR("ioremap failed, perhaps increasing __VMALLOC_RESERVE in page.h\n");
1013 IVTV_ERR("or disabling CONFIG_HIMEM4G into the kernel would help\n");
1014 retval = -ENOMEM;
1015 goto free_mem;
1016 }
1017 }
1018 else {
1019 itv->dec_mem = itv->enc_mem;
1020 }
1021
1022 /* map registers memory */
1023 IVTV_DEBUG_INFO("attempting ioremap at 0x%08x len 0x%08x\n",
1024 itv->base_addr + IVTV_REG_OFFSET, IVTV_REG_SIZE);
1025 itv->reg_mem =
1026 ioremap_nocache(itv->base_addr + IVTV_REG_OFFSET, IVTV_REG_SIZE);
1027 if (!itv->reg_mem) {
1028 IVTV_ERR("ioremap failed, perhaps increasing __VMALLOC_RESERVE in page.h\n");
1029 IVTV_ERR("or disabling CONFIG_HIMEM4G into the kernel would help\n");
1030 retval = -ENOMEM;
1031 goto free_io;
1032 }
1033
1034 while (--fw_retry_count > 0) {
1035 /* load firmware */
1036 if (ivtv_firmware_init(itv) == 0)
1037 break;
1038 if (fw_retry_count > 1)
1039 IVTV_WARN("Retry loading firmware\n");
1040 }
1041 if (fw_retry_count == 0) {
1042 IVTV_ERR("Error initializing firmware\n");
1043 goto free_i2c;
1044 }
1045
1046 /* Try and get firmware versions */
1047 IVTV_DEBUG_INFO("Getting firmware version..\n");
1048 ivtv_firmware_versions(itv);
1049
1050 /* Check yuv output filter table */
1051 if (itv->has_cx23415) ivtv_yuv_filter_check(itv);
1052
1053 ivtv_gpio_init(itv);
1054
1055 /* active i2c */
1056 IVTV_DEBUG_INFO("activating i2c...\n");
1057 if (init_ivtv_i2c(itv)) {
1058 IVTV_ERR("Could not initialize i2c\n");
1059 goto free_irq;
1060 }
1061
1062 IVTV_DEBUG_INFO("Active card count: %d.\n", ivtv_cards_active);
1063
1064 if (itv->card->hw_all & IVTV_HW_TVEEPROM) {
1065#ifdef CONFIG_VIDEO_TVEEPROM_MODULE
1066 ivtv_request_module(itv, "tveeprom");
1067#endif
1068 /* Based on the model number the cardtype may be changed.
1069 The PCI IDs are not always reliable. */
1070 ivtv_process_eeprom(itv);
1071 }
1072
1073 if (itv->std == 0) {
1074 itv->std = V4L2_STD_NTSC_M;
1075 }
1076
1077 if (itv->options.tuner == -1) {
1078 int i;
1079
1080 for (i = 0; i < IVTV_CARD_MAX_TUNERS; i++) {
1081 if ((itv->std & itv->card->tuners[i].std) == 0)
1082 continue;
1083 itv->options.tuner = itv->card->tuners[i].tuner;
1084 break;
1085 }
1086 }
1087 /* if no tuner was found, then pick the first tuner in the card list */
1088 if (itv->options.tuner == -1 && itv->card->tuners[0].std) {
1089 itv->std = itv->card->tuners[0].std;
1090 itv->options.tuner = itv->card->tuners[0].tuner;
1091 }
1092 if (itv->options.radio == -1)
1093 itv->options.radio = (itv->card->radio_input.audio_type != 0);
1094
1095 /* The card is now fully identified, continue with card-specific
1096 initialization. */
1097 ivtv_init_struct2(itv);
1098
1099 ivtv_load_and_init_modules(itv);
1100
1101 if (itv->std & V4L2_STD_525_60) {
1102 itv->is_60hz = 1;
1103 itv->is_out_60hz = 1;
1104 } else {
1105 itv->is_50hz = 1;
1106 itv->is_out_50hz = 1;
1107 }
1108 itv->params.video_gop_size = itv->is_60hz ? 15 : 12;
1109
1110 itv->stream_buf_size[IVTV_ENC_STREAM_TYPE_MPG] = 0x08000;
1111 itv->stream_buf_size[IVTV_ENC_STREAM_TYPE_PCM] = 0x01200;
1112 itv->stream_buf_size[IVTV_DEC_STREAM_TYPE_MPG] = 0x10000;
1113
1114 /* 0x15180 == 720 * 480 / 4, 0x19500 == 720 * 576 / 4 */
1115 yuv_buf_size = itv->is_60hz ? 0x15180 : 0x19500;
1116 itv->stream_buf_size[IVTV_DEC_STREAM_TYPE_YUV] = yuv_buf_size / 2;
1117 itv->stream_buf_size[IVTV_ENC_STREAM_TYPE_YUV] = yuv_buf_size / 8;
1118
1119 /* Setup VBI Raw Size. Should be big enough to hold PAL.
1120 It is possible to switch between PAL and NTSC, so we need to
1121 take the largest size here. */
1122 /* 1456 is multiple of 16, real size = 1444 */
1123 itv->vbi.raw_size = 1456;
1124 /* We use a buffer size of 1/2 of the total size needed for a
1125 frame. This is actually very useful, since we now receive
1126 a field at a time and that makes 'compressing' the raw data
1127 down to size by stripping off the SAV codes a lot easier.
1128 Note: having two different buffer sizes prevents standard
1129 switching on the fly. We need to find a better solution... */
1130 vbi_buf_size = itv->vbi.raw_size * (itv->is_60hz ? 24 : 36) / 2;
1131 itv->stream_buf_size[IVTV_ENC_STREAM_TYPE_VBI] = vbi_buf_size;
1132 itv->stream_buf_size[IVTV_DEC_STREAM_TYPE_VBI] = sizeof(struct v4l2_sliced_vbi_data) * 36;
1133
1134 if (itv->options.radio > 0)
1135 itv->v4l2_cap |= V4L2_CAP_RADIO;
1136
1137 if (itv->options.tuner > -1) {
1138 struct tuner_setup setup;
1139
1140 setup.addr = ADDR_UNSET;
1141 setup.type = itv->options.tuner;
1142 setup.mode_mask = T_ANALOG_TV; /* matches TV tuners */
1143#ifdef HAVE_XC3028
1144 setup.initmode = V4L2_TUNER_ANALOG_TV;
1145 if (itv->options.tuner == TUNER_XCEIVE_XC3028) {
1146 setup.gpio_write = ivtv_reset_tuner_gpio;
1147 setup.gpio_priv = itv;
1148 }
1149#endif
1150 ivtv_call_i2c_clients(itv, TUNER_SET_TYPE_ADDR, &setup);
1151 }
1152
1153 vf.tuner = 0;
1154 vf.type = V4L2_TUNER_ANALOG_TV;
1155 vf.frequency = 6400; /* the tuner 'baseline' frequency */
1156 if (itv->std & V4L2_STD_NTSC_M) {
1157 /* Why on earth? */
1158 vf.frequency = 1076; /* ch. 4 67250*16/1000 */
1159 }
1160
1161 /* The tuner is fixed to the standard. The other inputs (e.g. S-Video)
1162 are not. */
1163 itv->tuner_std = itv->std;
1164
1165 video_input = itv->active_input;
1166 itv->active_input++; /* Force update of input */
1167 ivtv_v4l2_ioctls(itv, NULL, VIDIOC_S_INPUT, &video_input);
1168
1169 /* Let the VIDIOC_S_STD ioctl do all the work, keeps the code
1170 in one place. */
1171 itv->std++; /* Force full standard initialization */
1172 itv->std_out = itv->std;
1173 ivtv_v4l2_ioctls(itv, NULL, VIDIOC_S_FREQUENCY, &vf);
1174
1175 retval = ivtv_streams_setup(itv);
1176 if (retval) {
1177 IVTV_ERR("Error %d setting up streams\n", retval);
1178 goto free_i2c;
1179 }
1180
1181 if (itv->card->v4l2_capabilities & V4L2_CAP_VIDEO_OUTPUT) {
1182 ivtv_init_mpeg_decoder(itv);
1183 }
1184 ivtv_v4l2_ioctls(itv, NULL, VIDIOC_S_STD, &itv->tuner_std);
1185
1186 IVTV_DEBUG_IRQ("Masking interrupts\n");
1187 /* clear interrupt mask, effectively disabling interrupts */
1188 ivtv_set_irq_mask(itv, 0xffffffff);
1189
1190 /* Register IRQ */
1191 retval = request_irq(itv->dev->irq, ivtv_irq_handler,
1192 IRQF_SHARED | IRQF_DISABLED, itv->name, (void *)itv);
1193 if (retval) {
1194 IVTV_ERR("Failed to register irq %d\n", retval);
1195 goto free_streams;
1196 }
1197
1198 /* On a cx23416 this seems to be able to enable DMA to the chip? */
1199 if (!itv->has_cx23415)
1200 write_reg_sync(0x03, IVTV_REG_DMACONTROL);
1201
1202 /* Default interrupts enabled. For the PVR350 this includes the
1203 decoder VSYNC interrupt, which is always on. It is not only used
1204 during decoding but also by the OSD.
1205 Some old PVR250 cards had a cx23415, so testing for that is too
1206 general. Instead test if the card has video output capability. */
1207 if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)
1208 ivtv_clear_irq_mask(itv, IVTV_IRQ_MASK_INIT | IVTV_IRQ_DEC_VSYNC);
1209 else
1210 ivtv_clear_irq_mask(itv, IVTV_IRQ_MASK_INIT);
1211
1212 if (itv->has_cx23415)
1213 ivtv_set_osd_alpha(itv);
1214
1215 IVTV_INFO("Initialized %s, card #%d\n", itv->card_name, itv->num);
1216
1217 return 0;
1218
1219 free_irq:
1220 free_irq(itv->dev->irq, (void *)itv);
1221 free_streams:
1222 ivtv_streams_cleanup(itv);
1223 free_i2c:
1224 exit_ivtv_i2c(itv);
1225 free_io:
1226 ivtv_iounmap(itv);
1227 free_mem:
1228 release_mem_region(itv->base_addr, IVTV_ENCODER_SIZE);
1229 release_mem_region(itv->base_addr + IVTV_REG_OFFSET, IVTV_REG_SIZE);
1230 if (itv->has_cx23415)
1231 release_mem_region(itv->base_addr + IVTV_DECODER_OFFSET, IVTV_DECODER_SIZE);
1232 free_workqueue:
1233 destroy_workqueue(itv->irq_work_queues);
1234 err:
1235 if (retval == 0)
1236 retval = -ENODEV;
1237 IVTV_ERR("Error %d on initialization\n", retval);
1238
1239 kfree(ivtv_cards[ivtv_cards_active]);
1240 ivtv_cards[ivtv_cards_active] = NULL;
1241 return retval;
1242}
1243
1244static void ivtv_remove(struct pci_dev *pci_dev)
1245{
1246 struct ivtv *itv = pci_get_drvdata(pci_dev);
1247
1248 IVTV_DEBUG_INFO("Removing Card #%d.\n", itv->num);
1249
1250 /* Stop all captures */
1251 IVTV_DEBUG_INFO(" Stopping all streams.\n");
1252 if (atomic_read(&itv->capturing) > 0)
1253 ivtv_stop_all_captures(itv);
1254
1255 /* Stop all decoding */
1256 IVTV_DEBUG_INFO(" Stopping decoding.\n");
1257 if (atomic_read(&itv->decoding) > 0) {
1258 int type;
1259
1260 if (test_bit(IVTV_F_I_DEC_YUV, &itv->i_flags))
1261 type = IVTV_DEC_STREAM_TYPE_YUV;
1262 else
1263 type = IVTV_DEC_STREAM_TYPE_MPG;
1264 ivtv_stop_v4l2_decode_stream(&itv->streams[type],
1265 VIDEO_CMD_STOP_TO_BLACK | VIDEO_CMD_STOP_IMMEDIATELY, 0);
1266 }
1267
1268 /* Interrupts */
1269 IVTV_DEBUG_INFO(" Disabling interrupts.\n");
1270 ivtv_set_irq_mask(itv, 0xffffffff);
1271 del_timer_sync(&itv->dma_timer);
1272
1273 /* Stop all Work Queues */
1274 IVTV_DEBUG_INFO(" Stop Work Queues.\n");
1275 flush_workqueue(itv->irq_work_queues);
1276 destroy_workqueue(itv->irq_work_queues);
1277
1278 IVTV_DEBUG_INFO(" Stopping Firmware.\n");
1279 ivtv_halt_firmware(itv);
1280
1281 IVTV_DEBUG_INFO(" Unregistering v4l devices.\n");
1282 ivtv_streams_cleanup(itv);
1283 IVTV_DEBUG_INFO(" Freeing dma resources.\n");
1284 ivtv_udma_free(itv);
1285
1286 exit_ivtv_i2c(itv);
1287
1288 IVTV_DEBUG_INFO(" Releasing irq.\n");
1289 free_irq(itv->dev->irq, (void *)itv);
1290
1291 if (itv->dev) {
1292 ivtv_iounmap(itv);
1293 }
1294
1295 IVTV_DEBUG_INFO(" Releasing mem.\n");
1296 release_mem_region(itv->base_addr, IVTV_ENCODER_SIZE);
1297 release_mem_region(itv->base_addr + IVTV_REG_OFFSET, IVTV_REG_SIZE);
1298 if (itv->has_cx23415)
1299 release_mem_region(itv->base_addr + IVTV_DECODER_OFFSET, IVTV_DECODER_SIZE);
1300
1301 pci_disable_device(itv->dev);
1302
1303 IVTV_INFO("Removed %s, card #%d\n", itv->card_name, itv->num);
1304}
1305
1306/* define a pci_driver for card detection */
1307static struct pci_driver ivtv_pci_driver = {
1308 .name = "ivtv",
1309 .id_table = ivtv_pci_tbl,
1310 .probe = ivtv_probe,
1311 .remove = ivtv_remove,
1312};
1313
1314static int module_start(void)
1315{
1316 printk(KERN_INFO "ivtv: ==================== START INIT IVTV ====================\n");
1317 printk(KERN_INFO "ivtv: version %s (" VERMAGIC_STRING ") loading\n", IVTV_VERSION);
1318
1319 memset(ivtv_cards, 0, sizeof(ivtv_cards));
1320
1321 /* Validate parameters */
1322 if (ivtv_first_minor < 0 || ivtv_first_minor >= IVTV_MAX_CARDS) {
1323 printk(KERN_ERR "ivtv: ivtv_first_minor must be between 0 and %d. Exiting...\n",
1324 IVTV_MAX_CARDS - 1);
1325 return -1;
1326 }
1327
1328 if (ivtv_debug < 0 || ivtv_debug > 511) {
1329 ivtv_debug = 0;
1330 printk(KERN_INFO "ivtv: debug value must be >= 0 and <= 511!\n");
1331 }
1332
1333 if (pci_register_driver(&ivtv_pci_driver)) {
1334 printk(KERN_ERR "ivtv: Error detecting PCI card\n");
1335 return -ENODEV;
1336 }
1337 printk(KERN_INFO "ivtv: ==================== END INIT IVTV ====================\n");
1338 return 0;
1339}
1340
1341static void module_cleanup(void)
1342{
1343 int i, j;
1344
1345 pci_unregister_driver(&ivtv_pci_driver);
1346
1347 for (i = 0; i < ivtv_cards_active; i++) {
1348 if (ivtv_cards[i] == NULL)
1349 continue;
1350 for (j = 0; j < IVTV_VBI_FRAMES; j++) {
1351 kfree(ivtv_cards[i]->vbi.sliced_mpeg_data[j]);
1352 }
1353 kfree(ivtv_cards[i]);
1354 }
1355}
1356
1357/* Note: These symbols are exported because they are used by the ivtv-fb
1358 framebuffer module and an infrared module for the IR-blaster. */
1359EXPORT_SYMBOL(ivtv_set_irq_mask);
1360EXPORT_SYMBOL(ivtv_cards_active);
1361EXPORT_SYMBOL(ivtv_cards);
1362EXPORT_SYMBOL(ivtv_api);
1363EXPORT_SYMBOL(ivtv_vapi);
1364EXPORT_SYMBOL(ivtv_vapi_result);
1365EXPORT_SYMBOL(ivtv_clear_irq_mask);
1366EXPORT_SYMBOL(ivtv_debug);
1367EXPORT_SYMBOL(ivtv_reset_ir_gpio);
1368EXPORT_SYMBOL(ivtv_udma_setup);
1369EXPORT_SYMBOL(ivtv_udma_unmap);
1370EXPORT_SYMBOL(ivtv_udma_alloc);
1371EXPORT_SYMBOL(ivtv_udma_prepare);
1372
1373module_init(module_start);
1374module_exit(module_cleanup);
diff --git a/drivers/media/video/ivtv/ivtv-driver.h b/drivers/media/video/ivtv/ivtv-driver.h
new file mode 100644
index 000000000000..9a412d6c6d06
--- /dev/null
+++ b/drivers/media/video/ivtv/ivtv-driver.h
@@ -0,0 +1,868 @@
1/*
2 ivtv driver internal defines and structures
3 Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
4 Copyright (C) 2004 Chris Kennedy <c@groovy.org>
5 Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl>
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21
22#ifndef IVTV_DRIVER_H
23#define IVTV_DRIVER_H
24
25/* Internal header for ivtv project:
26 * Driver for the cx23415/6 chip.
27 * Author: Kevin Thayer (nufan_wfk at yahoo.com)
28 * License: GPL
29 * http://www.ivtvdriver.org
30 *
31 * -----
32 * MPG600/MPG160 support by T.Adachi <tadachi@tadachi-net.com>
33 * and Takeru KOMORIYA<komoriya@paken.org>
34 *
35 * AVerMedia M179 GPIO info by Chris Pinkham <cpinkham@bc2va.org>
36 * using information provided by Jiun-Kuei Jung @ AVerMedia.
37 */
38
39#include <linux/version.h>
40#include <linux/module.h>
41#include <linux/moduleparam.h>
42#include <linux/init.h>
43#include <linux/delay.h>
44#include <linux/sched.h>
45#include <linux/fs.h>
46#include <linux/pci.h>
47#include <linux/interrupt.h>
48#include <linux/spinlock.h>
49#include <linux/i2c.h>
50#include <linux/i2c-algo-bit.h>
51#include <linux/list.h>
52#include <linux/unistd.h>
53#include <linux/byteorder/swab.h>
54#include <linux/pagemap.h>
55#include <linux/workqueue.h>
56#include <linux/mutex.h>
57#include <asm/uaccess.h>
58#include <asm/system.h>
59
60#include <linux/dvb/video.h>
61#include <linux/dvb/audio.h>
62#include <media/v4l2-common.h>
63#include <media/tuner.h>
64#include <media/cx2341x.h>
65
66/* #define HAVE_XC3028 1 */
67
68#include <media/ivtv.h>
69
70#ifdef CONFIG_LIRC_I2C
71# error "This driver is not compatible with the LIRC I2C kernel configuration option."
72#endif /* CONFIG_LIRC_I2C */
73
74#ifndef CONFIG_PCI
75# error "This driver requires kernel PCI support."
76#endif /* CONFIG_PCI */
77
78#define IVTV_ENCODER_OFFSET 0x00000000
79#define IVTV_ENCODER_SIZE 0x00800000 /* Last half isn't needed 0x01000000 */
80
81#define IVTV_DECODER_OFFSET 0x01000000
82#define IVTV_DECODER_SIZE 0x00800000 /* Last half isn't needed 0x01000000 */
83
84#define IVTV_REG_OFFSET 0x02000000
85#define IVTV_REG_SIZE 0x00010000
86
87/* Buffers on hardware offsets */
88#define IVTV_YUV_BUFFER_OFFSET 0x001a8600 /* First YUV Buffer */
89#define IVTV_YUV_BUFFER_OFFSET_1 0x00240400 /* Second YUV Buffer */
90#define IVTV_YUV_BUFFER_OFFSET_2 0x002d8200 /* Third YUV Buffer */
91#define IVTV_YUV_BUFFER_OFFSET_3 0x00370000 /* Fourth YUV Buffer */
92#define IVTV_YUV_BUFFER_UV_OFFSET 0x65400 /* Offset to UV Buffer */
93
94/* Offset to filter table in firmware */
95#define IVTV_YUV_HORIZONTAL_FILTER_OFFSET 0x025d8
96#define IVTV_YUV_VERTICAL_FILTER_OFFSET 0x03358
97
98extern const u32 yuv_offset[4];
99
100/* Maximum ivtv driver instances.
101 Based on 6 PVR500s each with two PVR15s...
102 TODO: make this dynamic. I believe it is only a global in order to support
103 ivtv-fb. There must be a better way to do that. */
104#define IVTV_MAX_CARDS 12
105
106/* Supported cards */
107#define IVTV_CARD_PVR_250 0 /* WinTV PVR 250 */
108#define IVTV_CARD_PVR_350 1 /* encoder, decoder, tv-out */
109#define IVTV_CARD_PVR_150 2 /* WinTV PVR 150 and PVR 500 (really just two
110 PVR150s on one PCI board) */
111#define IVTV_CARD_M179 3 /* AVerMedia M179 (encoder only) */
112#define IVTV_CARD_MPG600 4 /* Kuroutoshikou ITVC16-STVLP/YUAN MPG600, encoder only */
113#define IVTV_CARD_MPG160 5 /* Kuroutoshikou ITVC15-STVLP/YUAN MPG160
114 cx23415 based, but does not have tv-out */
115#define IVTV_CARD_PG600 6 /* YUAN PG600/DIAMONDMM PVR-550 based on the CX Falcon 2 */
116#define IVTV_CARD_AVC2410 7 /* Adaptec AVC-2410 */
117#define IVTV_CARD_AVC2010 8 /* Adaptec AVD-2010 (No Tuner) */
118#define IVTV_CARD_TG5000TV 9 /* NAGASE TRANSGEAR 5000TV, encoder only */
119#define IVTV_CARD_VA2000MAX_SNT6 10 /* VA2000MAX-STN6 */
120#define IVTV_CARD_CX23416GYC 11 /* Kuroutoshikou CX23416GYC-STVLP (Yuan MPG600GR OEM) */
121#define IVTV_CARD_GV_MVPRX 12 /* I/O Data GV-MVP/RX, RX2, RX2W */
122#define IVTV_CARD_GV_MVPRX2E 13 /* I/O Data GV-MVP/RX2E */
123#define IVTV_CARD_GOTVIEW_PCI_DVD 14 /* GotView PCI DVD */
124#define IVTV_CARD_GOTVIEW_PCI_DVD2 15 /* GotView PCI DVD2 */
125#define IVTV_CARD_YUAN_MPC622 16 /* Yuan MPC622 miniPCI */
126#define IVTV_CARD_DCTMTVP1 17 /* DIGITAL COWBOY DCT-MTVP1 */
127#ifdef HAVE_XC3028
128#define IVTV_CARD_PG600V2 18 /* Yuan PG600V2/GotView PCI DVD Lite/Club3D ZAP-TV1x01 */
129#define IVTV_CARD_LAST 18
130#else
131#define IVTV_CARD_LAST 17
132#endif
133
134/* Variants of existing cards but with the same PCI IDs. The driver
135 detects these based on other device information.
136 These cards must always come last.
137 New cards must be inserted above, and the indices of the cards below
138 must be adjusted accordingly. */
139
140/* PVR-350 V1 (uses saa7114) */
141#define IVTV_CARD_PVR_350_V1 (IVTV_CARD_LAST+1)
142/* 2 variants of Kuroutoshikou CX23416GYC-STVLP (Yuan MPG600GR OEM) */
143#define IVTV_CARD_CX23416GYC_NOGR (IVTV_CARD_LAST+2)
144#define IVTV_CARD_CX23416GYC_NOGRYCS (IVTV_CARD_LAST+3)
145
146#define IVTV_ENC_STREAM_TYPE_MPG 0
147#define IVTV_ENC_STREAM_TYPE_YUV 1
148#define IVTV_ENC_STREAM_TYPE_VBI 2
149#define IVTV_ENC_STREAM_TYPE_PCM 3
150#define IVTV_ENC_STREAM_TYPE_RAD 4
151#define IVTV_DEC_STREAM_TYPE_MPG 5
152#define IVTV_DEC_STREAM_TYPE_VBI 6
153#define IVTV_DEC_STREAM_TYPE_VOUT 7
154#define IVTV_DEC_STREAM_TYPE_YUV 8
155#define IVTV_MAX_STREAMS 9
156
157#define IVTV_V4L2_DEC_MPG_OFFSET 16 /* offset from 0 to register decoder mpg v4l2 minors on */
158#define IVTV_V4L2_ENC_PCM_OFFSET 24 /* offset from 0 to register pcm v4l2 minors on */
159#define IVTV_V4L2_ENC_YUV_OFFSET 32 /* offset from 0 to register yuv v4l2 minors on */
160#define IVTV_V4L2_DEC_YUV_OFFSET 48 /* offset from 0 to register decoder yuv v4l2 minors on */
161#define IVTV_V4L2_DEC_VBI_OFFSET 8 /* offset from 0 to register decoder vbi input v4l2 minors on */
162#define IVTV_V4L2_DEC_VOUT_OFFSET 16 /* offset from 0 to register vbi output v4l2 minors on */
163
164#define IVTV_ENC_MEM_START 0x00000000
165#define IVTV_DEC_MEM_START 0x01000000
166
167/* system vendor and device IDs */
168#define PCI_VENDOR_ID_ICOMP 0x4444
169#define PCI_DEVICE_ID_IVTV15 0x0803
170#define PCI_DEVICE_ID_IVTV16 0x0016
171
172/* subsystem vendor ID */
173#define IVTV_PCI_ID_HAUPPAUGE 0x0070
174#define IVTV_PCI_ID_HAUPPAUGE_ALT1 0x0270
175#define IVTV_PCI_ID_HAUPPAUGE_ALT2 0x4070
176#define IVTV_PCI_ID_ADAPTEC 0x9005
177#define IVTV_PCI_ID_AVERMEDIA 0x1461
178#define IVTV_PCI_ID_YUAN1 0x12ab
179#define IVTV_PCI_ID_YUAN2 0xff01
180#define IVTV_PCI_ID_YUAN3 0xffab
181#define IVTV_PCI_ID_YUAN4 0xfbab
182#define IVTV_PCI_ID_DIAMONDMM 0xff92
183#define IVTV_PCI_ID_IODATA 0x10fc
184#define IVTV_PCI_ID_MELCO 0x1154
185#define IVTV_PCI_ID_GOTVIEW1 0xffac
186#define IVTV_PCI_ID_GOTVIEW2 0xffad
187
188/* Decoder Buffer hardware size on Chip */
189#define IVTV_DEC_MAX_BUF 0x00100000 /* max bytes in decoder buffer */
190#define IVTV_DEC_MIN_BUF 0x00010000 /* min bytes in dec buffer */
191
192/* ======================================================================== */
193/* ========================== START USER SETTABLE DMA VARIABLES =========== */
194/* ======================================================================== */
195
196#define IVTV_DMA_SG_OSD_ENT (2883584/PAGE_SIZE) /* sg entities */
197
198/* DMA Buffers, Default size in MB allocated */
199#define IVTV_DEFAULT_ENC_MPG_BUFFERS 4
200#define IVTV_DEFAULT_ENC_YUV_BUFFERS 2
201#define IVTV_DEFAULT_ENC_VBI_BUFFERS 1
202#define IVTV_DEFAULT_ENC_PCM_BUFFERS 1
203#define IVTV_DEFAULT_DEC_MPG_BUFFERS 1
204#define IVTV_DEFAULT_DEC_YUV_BUFFERS 1
205#define IVTV_DEFAULT_DEC_VBI_BUFFERS 1
206
207/* ======================================================================== */
208/* ========================== END USER SETTABLE DMA VARIABLES ============= */
209/* ======================================================================== */
210
211/* Decoder Status Register */
212#define IVTV_DMA_ERR_LIST 0x00000010
213#define IVTV_DMA_ERR_WRITE 0x00000008
214#define IVTV_DMA_ERR_READ 0x00000004
215#define IVTV_DMA_SUCCESS_WRITE 0x00000002
216#define IVTV_DMA_SUCCESS_READ 0x00000001
217#define IVTV_DMA_READ_ERR (IVTV_DMA_ERR_LIST | IVTV_DMA_ERR_READ)
218#define IVTV_DMA_WRITE_ERR (IVTV_DMA_ERR_LIST | IVTV_DMA_ERR_WRITE)
219#define IVTV_DMA_ERR (IVTV_DMA_ERR_LIST | IVTV_DMA_ERR_WRITE | IVTV_DMA_ERR_READ)
220
221/* DMA Registers */
222#define IVTV_REG_DMAXFER (0x0000)
223#define IVTV_REG_DMASTATUS (0x0004)
224#define IVTV_REG_DECDMAADDR (0x0008)
225#define IVTV_REG_ENCDMAADDR (0x000c)
226#define IVTV_REG_DMACONTROL (0x0010)
227#define IVTV_REG_IRQSTATUS (0x0040)
228#define IVTV_REG_IRQMASK (0x0048)
229
230/* Setup Registers */
231#define IVTV_REG_ENC_SDRAM_REFRESH (0x07F8)
232#define IVTV_REG_ENC_SDRAM_PRECHARGE (0x07FC)
233#define IVTV_REG_DEC_SDRAM_REFRESH (0x08F8)
234#define IVTV_REG_DEC_SDRAM_PRECHARGE (0x08FC)
235#define IVTV_REG_VDM (0x2800)
236#define IVTV_REG_AO (0x2D00)
237#define IVTV_REG_BYTEFLUSH (0x2D24)
238#define IVTV_REG_SPU (0x9050)
239#define IVTV_REG_HW_BLOCKS (0x9054)
240#define IVTV_REG_VPU (0x9058)
241#define IVTV_REG_APU (0xA064)
242
243#define IVTV_IRQ_ENC_START_CAP (0x1 << 31)
244#define IVTV_IRQ_ENC_EOS (0x1 << 30)
245#define IVTV_IRQ_ENC_VBI_CAP (0x1 << 29)
246#define IVTV_IRQ_ENC_VIM_RST (0x1 << 28)
247#define IVTV_IRQ_ENC_DMA_COMPLETE (0x1 << 27)
248#define IVTV_IRQ_DEC_AUD_MODE_CHG (0x1 << 24)
249#define IVTV_IRQ_DEC_DATA_REQ (0x1 << 22)
250#define IVTV_IRQ_DEC_DMA_COMPLETE (0x1 << 20)
251#define IVTV_IRQ_DEC_VBI_RE_INSERT (0x1 << 19)
252#define IVTV_IRQ_DMA_ERR (0x1 << 18)
253#define IVTV_IRQ_DMA_WRITE (0x1 << 17)
254#define IVTV_IRQ_DMA_READ (0x1 << 16)
255#define IVTV_IRQ_DEC_VSYNC (0x1 << 10)
256
257/* IRQ Masks */
258#define IVTV_IRQ_MASK_INIT (IVTV_IRQ_DMA_ERR|IVTV_IRQ_ENC_DMA_COMPLETE|IVTV_IRQ_DMA_READ)
259
260#define IVTV_IRQ_MASK_CAPTURE (IVTV_IRQ_ENC_START_CAP | IVTV_IRQ_ENC_EOS)
261#define IVTV_IRQ_MASK_DECODE (IVTV_IRQ_DEC_DATA_REQ|IVTV_IRQ_DEC_AUD_MODE_CHG)
262
263/* i2c stuff */
264#define I2C_CLIENTS_MAX 16
265
266/* debugging */
267
268#define IVTV_DBGFLG_WARN (1 << 0)
269#define IVTV_DBGFLG_INFO (1 << 1)
270#define IVTV_DBGFLG_API (1 << 2)
271#define IVTV_DBGFLG_DMA (1 << 3)
272#define IVTV_DBGFLG_IOCTL (1 << 4)
273#define IVTV_DBGFLG_I2C (1 << 5)
274#define IVTV_DBGFLG_IRQ (1 << 6)
275#define IVTV_DBGFLG_DEC (1 << 7)
276#define IVTV_DBGFLG_YUV (1 << 8)
277
278/* NOTE: extra space before comma in 'itv->num , ## args' is required for
279 gcc-2.95, otherwise it won't compile. */
280#define IVTV_DEBUG(x, type, fmt, args...) \
281 do { \
282 if ((x) & ivtv_debug) \
283 printk(KERN_INFO "ivtv%d " type ": " fmt, itv->num , ## args); \
284 } while (0)
285#define IVTV_DEBUG_WARN(fmt, args...) IVTV_DEBUG(IVTV_DBGFLG_WARN, "warning", fmt , ## args)
286#define IVTV_DEBUG_INFO(fmt, args...) IVTV_DEBUG(IVTV_DBGFLG_INFO, "info",fmt , ## args)
287#define IVTV_DEBUG_API(fmt, args...) IVTV_DEBUG(IVTV_DBGFLG_API, "api", fmt , ## args)
288#define IVTV_DEBUG_DMA(fmt, args...) IVTV_DEBUG(IVTV_DBGFLG_DMA, "dma", fmt , ## args)
289#define IVTV_DEBUG_IOCTL(fmt, args...) IVTV_DEBUG(IVTV_DBGFLG_IOCTL, "ioctl", fmt , ## args)
290#define IVTV_DEBUG_I2C(fmt, args...) IVTV_DEBUG(IVTV_DBGFLG_I2C, "i2c", fmt , ## args)
291#define IVTV_DEBUG_IRQ(fmt, args...) IVTV_DEBUG(IVTV_DBGFLG_IRQ, "irq", fmt , ## args)
292#define IVTV_DEBUG_DEC(fmt, args...) IVTV_DEBUG(IVTV_DBGFLG_DEC, "dec", fmt , ## args)
293#define IVTV_DEBUG_YUV(fmt, args...) IVTV_DEBUG(IVTV_DBGFLG_YUV, "yuv", fmt , ## args)
294
295#define IVTV_FB_DEBUG(x, type, fmt, args...) \
296 do { \
297 if ((x) & ivtv_debug) \
298 printk(KERN_INFO "ivtv%d-fb " type ": " fmt, itv->num , ## args); \
299 } while (0)
300#define IVTV_FB_DEBUG_WARN(fmt, args...) IVTV_FB_DEBUG(IVTV_DBGFLG_WARN, "warning", fmt , ## args)
301#define IVTV_FB_DEBUG_INFO(fmt, args...) IVTV_FB_DEBUG(IVTV_DBGFLG_INFO, "info", fmt , ## args)
302#define IVTV_FB_DEBUG_API(fmt, args...) IVTV_FB_DEBUG(IVTV_DBGFLG_API, "api", fmt , ## args)
303#define IVTV_FB_DEBUG_DMA(fmt, args...) IVTV_FB_DEBUG(IVTV_DBGFLG_DMA, "dma", fmt , ## args)
304#define IVTV_FB_DEBUG_IOCTL(fmt, args...) IVTV_FB_DEBUG(IVTV_DBGFLG_IOCTL, "ioctl", fmt , ## args)
305#define IVTV_FB_DEBUG_I2C(fmt, args...) IVTV_FB_DEBUG(IVTV_DBGFLG_I2C, "i2c", fmt , ## args)
306#define IVTV_FB_DEBUG_IRQ(fmt, args...) IVTV_FB_DEBUG(IVTV_DBGFLG_IRQ, "irq", fmt , ## args)
307#define IVTV_FB_DEBUG_DEC(fmt, args...) IVTV_FB_DEBUG(IVTV_DBGFLG_DEC, "dec", fmt , ## args)
308#define IVTV_FB_DEBUG_YUV(fmt, args...) IVTV_FB_DEBUG(IVTV_DBGFLG_YUV, "yuv", fmt , ## args)
309
310/* Standard kernel messages */
311#define IVTV_ERR(fmt, args...) printk(KERN_ERR "ivtv%d: " fmt, itv->num , ## args)
312#define IVTV_WARN(fmt, args...) printk(KERN_WARNING "ivtv%d: " fmt, itv->num , ## args)
313#define IVTV_INFO(fmt, args...) printk(KERN_INFO "ivtv%d: " fmt, itv->num , ## args)
314#define IVTV_FB_ERR(fmt, args...) printk(KERN_ERR "ivtv%d-fb: " fmt, itv->num , ## args)
315#define IVTV_FB_WARN(fmt, args...) printk(KERN_WARNING "ivtv%d-fb: " fmt, itv->num , ## args)
316#define IVTV_FB_INFO(fmt, args...) printk(KERN_INFO "ivtv%d-fb: " fmt, itv->num , ## args)
317
318/* Values for IVTV_API_DEC_PLAYBACK_SPEED mpeg_frame_type_mask parameter: */
319#define MPEG_FRAME_TYPE_IFRAME 1
320#define MPEG_FRAME_TYPE_IFRAME_PFRAME 3
321#define MPEG_FRAME_TYPE_ALL 7
322
323/* output modes (cx23415 only) */
324#define OUT_NONE 0
325#define OUT_MPG 1
326#define OUT_YUV 2
327#define OUT_UDMA_YUV 3
328#define OUT_PASSTHROUGH 4
329
330#define IVTV_MAX_PGM_INDEX (400)
331
332extern int ivtv_debug;
333
334
335struct ivtv_options {
336 int megabytes[IVTV_MAX_STREAMS]; /* Size in megabytes of each stream */
337 int cardtype; /* force card type on load */
338 int tuner; /* set tuner on load */
339 int radio; /* enable/disable radio */
340 int newi2c; /* New I2C algorithm */
341};
342
343#define IVTV_MBOX_DMA_START 6
344#define IVTV_MBOX_DMA_END 8
345#define IVTV_MBOX_DMA 9
346#define IVTV_MBOX_FIELD_DISPLAYED 8
347
348/* ivtv-specific mailbox template */
349struct ivtv_mailbox {
350 u32 flags;
351 u32 cmd;
352 u32 retval;
353 u32 timeout;
354 u32 data[CX2341X_MBOX_MAX_DATA];
355};
356
357struct ivtv_api_cache {
358 unsigned long last_jiffies; /* when last command was issued */
359 u32 data[CX2341X_MBOX_MAX_DATA]; /* last sent api data */
360};
361
362struct ivtv_mailbox_data {
363 volatile struct ivtv_mailbox __iomem *mbox;
364 /* Bits 0-2 are for the encoder mailboxes, 0-1 are for the decoder mailboxes.
365 If the bit is set, then the corresponding mailbox is in use by the driver. */
366 unsigned long busy;
367 u8 max_mbox;
368};
369
370/* per-buffer bit flags */
371#define IVTV_F_B_NEED_BUF_SWAP 0 /* this buffer should be byte swapped */
372
373/* per-stream, s_flags */
374#define IVTV_F_S_DMA_PENDING 0 /* this stream has pending DMA */
375#define IVTV_F_S_DMA_HAS_VBI 1 /* the current DMA request also requests VBI data */
376#define IVTV_F_S_NEEDS_DATA 2 /* this decoding stream needs more data */
377
378#define IVTV_F_S_CLAIMED 3 /* this stream is claimed */
379#define IVTV_F_S_STREAMING 4 /* the fw is decoding/encoding this stream */
380#define IVTV_F_S_INTERNAL_USE 5 /* this stream is used internally (sliced VBI processing) */
381#define IVTV_F_S_PASSTHROUGH 6 /* this stream is in passthrough mode */
382#define IVTV_F_S_STREAMOFF 7 /* signal end of stream EOS */
383#define IVTV_F_S_APPL_IO 8 /* this stream is used read/written by an application */
384
385/* per-ivtv, i_flags */
386#define IVTV_F_I_DMA 0 /* DMA in progress */
387#define IVTV_F_I_UDMA 1 /* UDMA in progress */
388#define IVTV_F_I_UDMA_PENDING 2 /* UDMA pending */
389#define IVTV_F_I_SPEED_CHANGE 3 /* A speed change is in progress */
390#define IVTV_F_I_EOS 4 /* End of encoder stream reached */
391#define IVTV_F_I_RADIO_USER 5 /* The radio tuner is selected */
392#define IVTV_F_I_DIG_RST 6 /* Reset digitizer */
393#define IVTV_F_I_DEC_YUV 7 /* YUV instead of MPG is being decoded */
394#define IVTV_F_I_ENC_VBI 8 /* VBI DMA */
395#define IVTV_F_I_UPDATE_CC 9 /* CC should be updated */
396#define IVTV_F_I_UPDATE_WSS 10 /* WSS should be updated */
397#define IVTV_F_I_UPDATE_VPS 11 /* VPS should be updated */
398#define IVTV_F_I_DECODING_YUV 12 /* this stream is YUV frame decoding */
399#define IVTV_F_I_ENC_PAUSED 13 /* the encoder is paused */
400#define IVTV_F_I_VALID_DEC_TIMINGS 14 /* last_dec_timing is valid */
401#define IVTV_F_I_WORK_HANDLER_VBI 15 /* there is work to be done for VBI */
402#define IVTV_F_I_WORK_HANDLER_YUV 16 /* there is work to be done for YUV */
403
404/* Event notifications */
405#define IVTV_F_I_EV_DEC_STOPPED 28 /* decoder stopped event */
406#define IVTV_F_I_EV_VSYNC 29 /* VSYNC event */
407#define IVTV_F_I_EV_VSYNC_FIELD 30 /* VSYNC event field (0 = first, 1 = second field) */
408#define IVTV_F_I_EV_VSYNC_ENABLED 31 /* VSYNC event enabled */
409
410/* Scatter-Gather array element, used in DMA transfers */
411struct ivtv_SG_element {
412 u32 src;
413 u32 dst;
414 u32 size;
415};
416
417struct ivtv_user_dma {
418 struct mutex lock;
419 int page_count;
420 struct page *map[IVTV_DMA_SG_OSD_ENT];
421
422 /* Base Dev SG Array for cx23415/6 */
423 struct ivtv_SG_element SGarray[IVTV_DMA_SG_OSD_ENT];
424 dma_addr_t SG_handle;
425 int SG_length;
426
427 /* SG List of Buffers */
428 struct scatterlist SGlist[IVTV_DMA_SG_OSD_ENT];
429};
430
431struct ivtv_dma_page_info {
432 unsigned long uaddr;
433 unsigned long first;
434 unsigned long last;
435 unsigned int offset;
436 unsigned int tail;
437 int page_count;
438};
439
440struct ivtv_buffer {
441 struct list_head list;
442 dma_addr_t dma_handle;
443 unsigned long b_flags;
444 char *buf;
445
446 u32 bytesused;
447 u32 readpos;
448};
449
450struct ivtv_queue {
451 struct list_head list;
452 u32 buffers;
453 u32 length;
454 u32 bytesused;
455};
456
457struct ivtv; /* forward reference */
458
459struct ivtv_stream {
460 /* These first four fields are always set, even if the stream
461 is not actually created. */
462 struct video_device *v4l2dev; /* NULL when stream not created */
463 struct ivtv *itv; /* for ease of use */
464 const char *name; /* name of the stream */
465 int type; /* stream type */
466
467 u32 id;
468 spinlock_t qlock; /* locks access to the queues */
469 unsigned long s_flags; /* status flags, see above */
470 int dma; /* can be PCI_DMA_TODEVICE,
471 PCI_DMA_FROMDEVICE or
472 PCI_DMA_NONE */
473 u32 dma_offset;
474 u32 dma_backup;
475 u64 dma_pts;
476
477 int subtype;
478 wait_queue_head_t waitq;
479 u32 dma_last_offset;
480
481 /* Buffer Stats */
482 u32 buffers;
483 u32 buf_size;
484 u32 buffers_stolen;
485
486 /* Buffer Queues */
487 struct ivtv_queue q_free; /* free buffers */
488 struct ivtv_queue q_full; /* full buffers */
489 struct ivtv_queue q_io; /* waiting for I/O */
490 struct ivtv_queue q_dma; /* waiting for DMA */
491 struct ivtv_queue q_predma; /* waiting for DMA */
492
493 /* Base Dev SG Array for cx23415/6 */
494 struct ivtv_SG_element *SGarray;
495 dma_addr_t SG_handle;
496 int SG_length;
497
498 /* SG List of Buffers */
499 struct scatterlist *SGlist;
500};
501
502struct ivtv_open_id {
503 u32 open_id;
504 int type;
505 enum v4l2_priority prio;
506 struct ivtv *itv;
507};
508
509#define IVTV_YUV_UPDATE_HORIZONTAL 0x01
510#define IVTV_YUV_UPDATE_VERTICAL 0x02
511
512struct yuv_frame_info
513{
514 u32 update;
515 int src_x;
516 int src_y;
517 unsigned int src_w;
518 unsigned int src_h;
519 int dst_x;
520 int dst_y;
521 unsigned int dst_w;
522 unsigned int dst_h;
523 int pan_x;
524 int pan_y;
525 u32 vis_w;
526 u32 vis_h;
527 u32 interlaced_y;
528 u32 interlaced_uv;
529 int tru_x;
530 u32 tru_w;
531 u32 tru_h;
532 u32 offset_y;
533};
534
535#define IVTV_YUV_MODE_INTERLACED 0x00
536#define IVTV_YUV_MODE_PROGRESSIVE 0x01
537#define IVTV_YUV_MODE_AUTO 0x02
538#define IVTV_YUV_MODE_MASK 0x03
539
540#define IVTV_YUV_SYNC_EVEN 0x00
541#define IVTV_YUV_SYNC_ODD 0x04
542#define IVTV_YUV_SYNC_MASK 0x04
543
544struct yuv_playback_info
545{
546 u32 reg_2834;
547 u32 reg_2838;
548 u32 reg_283c;
549 u32 reg_2840;
550 u32 reg_2844;
551 u32 reg_2848;
552 u32 reg_2854;
553 u32 reg_285c;
554 u32 reg_2864;
555
556 u32 reg_2870;
557 u32 reg_2874;
558 u32 reg_2890;
559 u32 reg_2898;
560 u32 reg_289c;
561
562 u32 reg_2918;
563 u32 reg_291c;
564 u32 reg_2920;
565 u32 reg_2924;
566 u32 reg_2928;
567 u32 reg_292c;
568 u32 reg_2930;
569
570 u32 reg_2934;
571
572 u32 reg_2938;
573 u32 reg_293c;
574 u32 reg_2940;
575 u32 reg_2944;
576 u32 reg_2948;
577 u32 reg_294c;
578 u32 reg_2950;
579 u32 reg_2954;
580 u32 reg_2958;
581 u32 reg_295c;
582 u32 reg_2960;
583 u32 reg_2964;
584 u32 reg_2968;
585 u32 reg_296c;
586
587 u32 reg_2970;
588
589 int v_filter_1;
590 int v_filter_2;
591 int h_filter;
592
593 u32 osd_x_offset;
594 u32 osd_y_offset;
595
596 u32 osd_x_pan;
597 u32 osd_y_pan;
598
599 u32 osd_vis_w;
600 u32 osd_vis_h;
601
602 int decode_height;
603
604 int frame_interlaced;
605 int frame_interlaced_last;
606
607 int lace_mode;
608 int lace_threshold;
609 int lace_sync_field;
610
611 atomic_t next_dma_frame;
612 atomic_t next_fill_frame;
613
614 u32 yuv_forced_update;
615 int update_frame;
616 struct yuv_frame_info new_frame_info[4];
617 struct yuv_frame_info old_frame_info;
618 struct yuv_frame_info old_frame_info_args;
619
620 void *blanking_ptr;
621 dma_addr_t blanking_dmaptr;
622};
623
624#define IVTV_VBI_FRAMES 32
625
626/* VBI data */
627struct vbi_info {
628 u32 dec_start;
629 u32 enc_start, enc_size;
630 int fpi;
631 u32 frame;
632 u32 dma_offset;
633 u8 cc_data_odd[256];
634 u8 cc_data_even[256];
635 int cc_pos;
636 u8 cc_no_update;
637 u8 vps[5];
638 u8 vps_found;
639 int wss;
640 u8 wss_found;
641 u8 wss_no_update;
642 u32 raw_decoder_line_size;
643 u8 raw_decoder_sav_odd_field;
644 u8 raw_decoder_sav_even_field;
645 u32 sliced_decoder_line_size;
646 u8 sliced_decoder_sav_odd_field;
647 u8 sliced_decoder_sav_even_field;
648 struct v4l2_format in;
649 /* convenience pointer to sliced struct in vbi_in union */
650 struct v4l2_sliced_vbi_format *sliced_in;
651 u32 service_set_in;
652 u32 service_set_out;
653 int insert_mpeg;
654
655 /* Buffer for the maximum of 2 * 18 * packet_size sliced VBI lines.
656 One for /dev/vbi0 and one for /dev/vbi8 */
657 struct v4l2_sliced_vbi_data sliced_data[36];
658 struct v4l2_sliced_vbi_data sliced_dec_data[36];
659
660 /* Buffer for VBI data inserted into MPEG stream.
661 The first byte is a dummy byte that's never used.
662 The next 16 bytes contain the MPEG header for the VBI data,
663 the remainder is the actual VBI data.
664 The max size accepted by the MPEG VBI reinsertion turns out
665 to be 1552 bytes, which happens to be 4 + (1 + 42) * (2 * 18) bytes,
666 where 4 is a four byte header, 42 is the max sliced VBI payload, 1 is
667 a single line header byte and 2 * 18 is the number of VBI lines per frame.
668
669 However, it seems that the data must be 1K aligned, so we have to
670 pad the data until the 1 or 2 K boundary.
671
672 This pointer array will allocate 2049 bytes to store each VBI frame. */
673 u8 *sliced_mpeg_data[IVTV_VBI_FRAMES];
674 u32 sliced_mpeg_size[IVTV_VBI_FRAMES];
675 struct ivtv_buffer sliced_mpeg_buf;
676 u32 inserted_frame;
677
678 u32 start[2], count;
679 u32 raw_size;
680 u32 sliced_size;
681};
682
683/* forward declaration of struct defined in ivtv-cards.h */
684struct ivtv_card;
685
686/* Struct to hold info about ivtv cards */
687struct ivtv {
688 int num; /* board number, -1 during init! */
689 char name[8]; /* board name for printk and interrupts (e.g. 'ivtv0') */
690 struct pci_dev *dev; /* PCI device */
691 const struct ivtv_card *card; /* card information */
692 const char *card_name; /* full name of the card */
693 u8 has_cx23415; /* 1 if it is a cx23415 based card, 0 for cx23416 */
694 u8 is_50hz;
695 u8 is_60hz;
696 u8 is_out_50hz;
697 u8 is_out_60hz;
698 u8 pvr150_workaround; /* 1 if the cx25840 needs to workaround a PVR150 bug */
699 u8 nof_inputs; /* number of video inputs */
700 u8 nof_audio_inputs; /* number of audio inputs */
701 u32 v4l2_cap; /* V4L2 capabilities of card */
702 u32 hw_flags; /* Hardware description of the board */
703
704 /* controlling Video decoder function */
705 int (*video_dec_func)(struct ivtv *, unsigned int, void *);
706
707 struct ivtv_options options; /* User options */
708 int stream_buf_size[IVTV_MAX_STREAMS]; /* Stream buffer size */
709 struct ivtv_stream streams[IVTV_MAX_STREAMS]; /* Stream data */
710 int speed;
711 u8 speed_mute_audio;
712 unsigned long i_flags; /* global ivtv flags */
713 atomic_t capturing; /* count number of active capture streams */
714 atomic_t decoding; /* count number of active decoding streams */
715 u32 irq_rr_idx; /* Round-robin stream index */
716 int cur_dma_stream; /* index of stream doing DMA */
717 u32 dma_data_req_offset;
718 u32 dma_data_req_size;
719 int output_mode; /* NONE, MPG, YUV, UDMA YUV, passthrough */
720 spinlock_t lock; /* lock access to this struct */
721 int search_pack_header;
722
723 spinlock_t dma_reg_lock; /* lock access to DMA engine registers */
724
725 /* User based DMA for OSD */
726 struct ivtv_user_dma udma;
727
728 int open_id; /* incremented each time an open occurs, used as unique ID.
729 starts at 1, so 0 can be used as uninitialized value
730 in the stream->id. */
731
732 u32 base_addr;
733 u32 irqmask;
734
735 struct v4l2_prio_state prio;
736 struct workqueue_struct *irq_work_queues;
737 struct work_struct irq_work_queue;
738 struct timer_list dma_timer; /* Timer used to catch unfinished DMAs */
739
740 struct vbi_info vbi;
741
742 struct ivtv_mailbox_data enc_mbox;
743 struct ivtv_mailbox_data dec_mbox;
744 struct ivtv_api_cache api_cache[256]; /* Cached API Commands */
745
746 u8 card_rev;
747 volatile void __iomem *enc_mem, *dec_mem, *reg_mem;
748
749 u32 pgm_info_offset;
750 u32 pgm_info_num;
751 u32 pgm_info_write_idx;
752 u32 pgm_info_read_idx;
753 struct v4l2_enc_idx_entry pgm_info[IVTV_MAX_PGM_INDEX];
754
755 u64 mpg_data_received;
756 u64 vbi_data_inserted;
757
758 wait_queue_head_t cap_w;
759 /* when the next decoder event arrives this queue is woken up */
760 wait_queue_head_t event_waitq;
761 /* when the next decoder vsync arrives this queue is woken up */
762 wait_queue_head_t vsync_waitq;
763 /* when the current DMA is finished this queue is woken up */
764 wait_queue_head_t dma_waitq;
765
766 /* OSD support */
767 unsigned long osd_video_pbase;
768 int osd_global_alpha_state; /* 0=off : 1=on */
769 int osd_local_alpha_state; /* 0=off : 1=on */
770 int osd_color_key_state; /* 0=off : 1=on */
771 u8 osd_global_alpha; /* Current global alpha */
772 u32 osd_color_key; /* Current color key */
773 u32 osd_pixelformat; /* Current pixel format */
774 struct v4l2_rect osd_rect; /* Current OSD position and size */
775 struct v4l2_rect main_rect; /* Current Main window position and size */
776
777 u32 last_dec_timing[3]; /* Store last retrieved pts/scr/frame values */
778
779 /* i2c */
780 struct i2c_adapter i2c_adap;
781 struct i2c_algo_bit_data i2c_algo;
782 struct i2c_client i2c_client;
783 struct mutex i2c_bus_lock;
784 int i2c_state;
785 struct i2c_client *i2c_clients[I2C_CLIENTS_MAX];
786
787 /* v4l2 and User settings */
788
789 /* codec settings */
790 struct cx2341x_mpeg_params params;
791 u32 audio_input;
792 u32 active_input;
793 u32 active_output;
794 v4l2_std_id std;
795 v4l2_std_id std_out;
796 v4l2_std_id tuner_std; /* The norm of the tuner (fixed) */
797 u8 audio_stereo_mode;
798 u8 audio_bilingual_mode;
799
800 /* dualwatch */
801 unsigned long dualwatch_jiffies;
802 u16 dualwatch_stereo_mode;
803
804 /* Digitizer type */
805 int digitizer; /* 0x00EF = saa7114 0x00FO = saa7115 0x0106 = mic */
806
807 u32 lastVsyncFrame;
808
809 struct yuv_playback_info yuv_info;
810 struct osd_info *osd_info;
811};
812
813/* Globals */
814extern struct ivtv *ivtv_cards[];
815extern int ivtv_cards_active;
816extern int ivtv_first_minor;
817extern spinlock_t ivtv_cards_lock;
818
819/*==============Prototypes==================*/
820
821/* Hardware/IRQ */
822void ivtv_set_irq_mask(struct ivtv *itv, u32 mask);
823void ivtv_clear_irq_mask(struct ivtv *itv, u32 mask);
824
825/* try to set output mode, return current mode. */
826int ivtv_set_output_mode(struct ivtv *itv, int mode);
827
828/* return current output stream based on current mode */
829struct ivtv_stream *ivtv_get_output_stream(struct ivtv *itv);
830
831/* Return non-zero if a signal is pending */
832int ivtv_sleep_timeout(int timeout, int intr);
833
834/* Wait on queue, returns -EINTR if interrupted */
835int ivtv_waitq(wait_queue_head_t *waitq);
836
837/* Read Hauppauge eeprom */
838struct tveeprom; /* forward reference */
839void ivtv_read_eeprom(struct ivtv *itv, struct tveeprom *tv);
840
841/* This is a PCI post thing, where if the pci register is not read, then
842 the write doesn't always take effect right away. By reading back the
843 register any pending PCI writes will be performed (in order), and so
844 you can be sure that the writes are guaranteed to be done.
845
846 Rarely needed, only in some timing sensitive cases.
847 Apparently if this is not done some motherboards seem
848 to kill the firmware and get into the broken state until computer is
849 rebooted. */
850#define write_sync(val, reg) \
851 do { writel(val, reg); readl(reg); } while (0)
852
853#define read_reg(reg) readl(itv->reg_mem + (reg))
854#define write_reg(val, reg) writel(val, itv->reg_mem + (reg))
855#define write_reg_sync(val, reg) \
856 do { write_reg(val, reg); read_reg(reg); } while (0)
857
858#define read_enc(addr) readl(itv->enc_mem + (u32)(addr))
859#define write_enc(val, addr) writel(val, itv->enc_mem + (u32)(addr))
860#define write_enc_sync(val, addr) \
861 do { write_enc(val, addr); read_enc(addr); } while (0)
862
863#define read_dec(addr) readl(itv->dec_mem + (u32)(addr))
864#define write_dec(val, addr) writel(val, itv->dec_mem + (u32)(addr))
865#define write_dec_sync(val, addr) \
866 do { write_dec(val, addr); read_dec(addr); } while (0)
867
868#endif /* IVTV_DRIVER_H */
diff --git a/drivers/media/video/ivtv/ivtv-fileops.c b/drivers/media/video/ivtv/ivtv-fileops.c
new file mode 100644
index 000000000000..1637097ddec7
--- /dev/null
+++ b/drivers/media/video/ivtv/ivtv-fileops.c
@@ -0,0 +1,921 @@
1/*
2 file operation functions
3 Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
4 Copyright (C) 2004 Chris Kennedy <c@groovy.org>
5 Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl>
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21
22#include "ivtv-driver.h"
23#include "ivtv-fileops.h"
24#include "ivtv-i2c.h"
25#include "ivtv-queue.h"
26#include "ivtv-udma.h"
27#include "ivtv-irq.h"
28#include "ivtv-vbi.h"
29#include "ivtv-mailbox.h"
30#include "ivtv-audio.h"
31#include "ivtv-streams.h"
32#include "ivtv-yuv.h"
33#include "ivtv-controls.h"
34#include "ivtv-ioctl.h"
35
36/* This function tries to claim the stream for a specific file descriptor.
37 If no one else is using this stream then the stream is claimed and
38 associated VBI streams are also automatically claimed.
39 Possible error returns: -EBUSY if someone else has claimed
40 the stream or 0 on success. */
41int ivtv_claim_stream(struct ivtv_open_id *id, int type)
42{
43 struct ivtv *itv = id->itv;
44 struct ivtv_stream *s = &itv->streams[type];
45 struct ivtv_stream *s_vbi;
46 int vbi_type;
47
48 if (test_and_set_bit(IVTV_F_S_CLAIMED, &s->s_flags)) {
49 /* someone already claimed this stream */
50 if (s->id == id->open_id) {
51 /* yes, this file descriptor did. So that's OK. */
52 return 0;
53 }
54 if (s->id == -1 && (type == IVTV_DEC_STREAM_TYPE_VBI ||
55 type == IVTV_ENC_STREAM_TYPE_VBI)) {
56 /* VBI is handled already internally, now also assign
57 the file descriptor to this stream for external
58 reading of the stream. */
59 s->id = id->open_id;
60 IVTV_DEBUG_INFO("Start Read VBI\n");
61 return 0;
62 }
63 /* someone else is using this stream already */
64 IVTV_DEBUG_INFO("Stream %d is busy\n", type);
65 return -EBUSY;
66 }
67 s->id = id->open_id;
68 if (type == IVTV_DEC_STREAM_TYPE_VBI) {
69 /* Enable reinsertion interrupt */
70 ivtv_clear_irq_mask(itv, IVTV_IRQ_DEC_VBI_RE_INSERT);
71 }
72
73 /* IVTV_DEC_STREAM_TYPE_MPG needs to claim IVTV_DEC_STREAM_TYPE_VBI,
74 IVTV_ENC_STREAM_TYPE_MPG needs to claim IVTV_ENC_STREAM_TYPE_VBI
75 (provided VBI insertion is on and sliced VBI is selected), for all
76 other streams we're done */
77 if (type == IVTV_DEC_STREAM_TYPE_MPG) {
78 vbi_type = IVTV_DEC_STREAM_TYPE_VBI;
79 } else if (type == IVTV_ENC_STREAM_TYPE_MPG &&
80 itv->vbi.insert_mpeg && itv->vbi.sliced_in->service_set) {
81 vbi_type = IVTV_ENC_STREAM_TYPE_VBI;
82 } else {
83 return 0;
84 }
85 s_vbi = &itv->streams[vbi_type];
86
87 if (!test_and_set_bit(IVTV_F_S_CLAIMED, &s_vbi->s_flags)) {
88 /* Enable reinsertion interrupt */
89 if (vbi_type == IVTV_DEC_STREAM_TYPE_VBI)
90 ivtv_clear_irq_mask(itv, IVTV_IRQ_DEC_VBI_RE_INSERT);
91 }
92 /* mark that it is used internally */
93 set_bit(IVTV_F_S_INTERNAL_USE, &s_vbi->s_flags);
94 return 0;
95}
96
97/* This function releases a previously claimed stream. It will take into
98 account associated VBI streams. */
99void ivtv_release_stream(struct ivtv_stream *s)
100{
101 struct ivtv *itv = s->itv;
102 struct ivtv_stream *s_vbi;
103
104 s->id = -1;
105 if ((s->type == IVTV_DEC_STREAM_TYPE_VBI || s->type == IVTV_ENC_STREAM_TYPE_VBI) &&
106 test_bit(IVTV_F_S_INTERNAL_USE, &s->s_flags)) {
107 /* this stream is still in use internally */
108 return;
109 }
110 if (!test_and_clear_bit(IVTV_F_S_CLAIMED, &s->s_flags)) {
111 IVTV_DEBUG_WARN("Release stream %s not in use!\n", s->name);
112 return;
113 }
114
115 ivtv_flush_queues(s);
116
117 /* disable reinsertion interrupt */
118 if (s->type == IVTV_DEC_STREAM_TYPE_VBI)
119 ivtv_set_irq_mask(itv, IVTV_IRQ_DEC_VBI_RE_INSERT);
120
121 /* IVTV_DEC_STREAM_TYPE_MPG needs to release IVTV_DEC_STREAM_TYPE_VBI,
122 IVTV_ENC_STREAM_TYPE_MPG needs to release IVTV_ENC_STREAM_TYPE_VBI,
123 for all other streams we're done */
124 if (s->type == IVTV_DEC_STREAM_TYPE_MPG)
125 s_vbi = &itv->streams[IVTV_DEC_STREAM_TYPE_VBI];
126 else if (s->type == IVTV_ENC_STREAM_TYPE_MPG)
127 s_vbi = &itv->streams[IVTV_ENC_STREAM_TYPE_VBI];
128 else
129 return;
130
131 /* clear internal use flag */
132 if (!test_and_clear_bit(IVTV_F_S_INTERNAL_USE, &s_vbi->s_flags)) {
133 /* was already cleared */
134 return;
135 }
136 if (s_vbi->id != -1) {
137 /* VBI stream still claimed by a file descriptor */
138 return;
139 }
140 /* disable reinsertion interrupt */
141 if (s_vbi->type == IVTV_DEC_STREAM_TYPE_VBI)
142 ivtv_set_irq_mask(itv, IVTV_IRQ_DEC_VBI_RE_INSERT);
143 clear_bit(IVTV_F_S_CLAIMED, &s_vbi->s_flags);
144 ivtv_flush_queues(s_vbi);
145}
146
147static void ivtv_dualwatch(struct ivtv *itv)
148{
149 struct v4l2_tuner vt;
150 u16 new_bitmap;
151 u16 new_stereo_mode;
152 const u16 stereo_mask = 0x0300;
153 const u16 dual = 0x0200;
154
155 new_stereo_mode = itv->params.audio_properties & stereo_mask;
156 memset(&vt, 0, sizeof(vt));
157 ivtv_call_i2c_clients(itv, VIDIOC_G_TUNER, &vt);
158 if (vt.audmode == V4L2_TUNER_MODE_LANG1_LANG2 && (vt.rxsubchans & V4L2_TUNER_SUB_LANG2))
159 new_stereo_mode = dual;
160
161 if (new_stereo_mode == itv->dualwatch_stereo_mode)
162 return;
163
164 new_bitmap = new_stereo_mode | (itv->params.audio_properties & ~stereo_mask);
165
166 IVTV_DEBUG_INFO("dualwatch: change stereo flag from 0x%x to 0x%x. new audio_bitmask=0x%ux\n",
167 itv->dualwatch_stereo_mode, new_stereo_mode, new_bitmap);
168
169 if (ivtv_vapi(itv, CX2341X_ENC_SET_AUDIO_PROPERTIES, 1, new_bitmap) == 0) {
170 itv->dualwatch_stereo_mode = new_stereo_mode;
171 return;
172 }
173 IVTV_DEBUG_INFO("dualwatch: changing stereo flag failed\n");
174}
175
176static void ivtv_update_pgm_info(struct ivtv *itv)
177{
178 u32 wr_idx = (read_enc(itv->pgm_info_offset) - itv->pgm_info_offset - 4) / 24;
179 int cnt;
180 int i = 0;
181
182 if (wr_idx >= itv->pgm_info_num) {
183 IVTV_DEBUG_WARN("Invalid PGM index %d (>= %d)\n", wr_idx, itv->pgm_info_num);
184 return;
185 }
186 cnt = (wr_idx + itv->pgm_info_num - itv->pgm_info_write_idx) % itv->pgm_info_num;
187 while (i < cnt) {
188 int idx = (itv->pgm_info_write_idx + i) % itv->pgm_info_num;
189 struct v4l2_enc_idx_entry *e = itv->pgm_info + idx;
190 u32 addr = itv->pgm_info_offset + 4 + idx * 24;
191 const int mapping[] = { V4L2_ENC_IDX_FRAME_P, V4L2_ENC_IDX_FRAME_I, V4L2_ENC_IDX_FRAME_B, 0 };
192
193 e->offset = read_enc(addr + 4) + ((u64)read_enc(addr + 8) << 32);
194 if (e->offset > itv->mpg_data_received) {
195 break;
196 }
197 e->offset += itv->vbi_data_inserted;
198 e->length = read_enc(addr);
199 e->pts = read_enc(addr + 16) + ((u64)(read_enc(addr + 20) & 1) << 32);
200 e->flags = mapping[read_enc(addr + 12) & 3];
201 i++;
202 }
203 itv->pgm_info_write_idx = (itv->pgm_info_write_idx + i) % itv->pgm_info_num;
204}
205
206static struct ivtv_buffer *ivtv_get_buffer(struct ivtv_stream *s, int non_block, int *err)
207{
208 struct ivtv *itv = s->itv;
209 struct ivtv_stream *s_vbi = &itv->streams[IVTV_ENC_STREAM_TYPE_VBI];
210 struct ivtv_buffer *buf;
211 DEFINE_WAIT(wait);
212
213 *err = 0;
214 while (1) {
215 if (s->type == IVTV_ENC_STREAM_TYPE_MPG) {
216 /* Process pending program info updates and pending VBI data */
217 ivtv_update_pgm_info(itv);
218
219 if (jiffies - itv->dualwatch_jiffies > HZ) {
220 itv->dualwatch_jiffies = jiffies;
221 ivtv_dualwatch(itv);
222 }
223
224 if (test_bit(IVTV_F_S_INTERNAL_USE, &s_vbi->s_flags) &&
225 !test_bit(IVTV_F_S_APPL_IO, &s_vbi->s_flags)) {
226 while ((buf = ivtv_dequeue(s_vbi, &s_vbi->q_full))) {
227 /* byteswap and process VBI data */
228 ivtv_process_vbi_data(itv, buf, s_vbi->dma_pts, s_vbi->type);
229 ivtv_enqueue(s_vbi, buf, &s_vbi->q_free);
230 }
231 }
232 buf = &itv->vbi.sliced_mpeg_buf;
233 if (buf->readpos != buf->bytesused) {
234 return buf;
235 }
236 }
237
238 /* do we have leftover data? */
239 buf = ivtv_dequeue(s, &s->q_io);
240 if (buf)
241 return buf;
242
243 /* do we have new data? */
244 buf = ivtv_dequeue(s, &s->q_full);
245 if (buf) {
246 if (!test_and_clear_bit(IVTV_F_B_NEED_BUF_SWAP, &buf->b_flags))
247 return buf;
248 if (s->type == IVTV_ENC_STREAM_TYPE_MPG)
249 /* byteswap MPG data */
250 ivtv_buf_swap(buf);
251 else if (s->type != IVTV_DEC_STREAM_TYPE_VBI) {
252 /* byteswap and process VBI data */
253 ivtv_process_vbi_data(itv, buf, s->dma_pts, s->type);
254 }
255 return buf;
256 }
257 /* return if file was opened with O_NONBLOCK */
258 if (non_block) {
259 *err = -EAGAIN;
260 return NULL;
261 }
262
263 /* return if end of stream */
264 if (s->type != IVTV_DEC_STREAM_TYPE_VBI && !test_bit(IVTV_F_S_STREAMING, &s->s_flags)) {
265 clear_bit(IVTV_F_S_STREAMOFF, &s->s_flags);
266 IVTV_DEBUG_INFO("EOS %s\n", s->name);
267 return NULL;
268 }
269
270 /* wait for more data to arrive */
271 prepare_to_wait(&s->waitq, &wait, TASK_INTERRUPTIBLE);
272 /* New buffers might have become available before we were added to the waitqueue */
273 if (!s->q_full.buffers)
274 schedule();
275 finish_wait(&s->waitq, &wait);
276 if (signal_pending(current)) {
277 /* return if a signal was received */
278 IVTV_DEBUG_INFO("User stopped %s\n", s->name);
279 *err = -EINTR;
280 return NULL;
281 }
282 }
283}
284
285static void ivtv_setup_sliced_vbi_buf(struct ivtv *itv)
286{
287 int idx = itv->vbi.inserted_frame % IVTV_VBI_FRAMES;
288
289 itv->vbi.sliced_mpeg_buf.buf = itv->vbi.sliced_mpeg_data[idx];
290 itv->vbi.sliced_mpeg_buf.bytesused = itv->vbi.sliced_mpeg_size[idx];
291 itv->vbi.sliced_mpeg_buf.readpos = 0;
292}
293
294static size_t ivtv_copy_buf_to_user(struct ivtv_stream *s, struct ivtv_buffer *buf,
295 char __user *ubuf, size_t ucount)
296{
297 struct ivtv *itv = s->itv;
298 size_t len = buf->bytesused - buf->readpos;
299
300 if (len > ucount) len = ucount;
301 if (itv->vbi.insert_mpeg && s->type == IVTV_ENC_STREAM_TYPE_MPG &&
302 itv->vbi.sliced_in->service_set && buf != &itv->vbi.sliced_mpeg_buf) {
303 const char *start = buf->buf + buf->readpos;
304 const char *p = start + 1;
305 const u8 *q;
306 u8 ch = itv->search_pack_header ? 0xba : 0xe0;
307 int stuffing, i;
308
309 while (start + len > p && (q = memchr(p, 0, start + len - p))) {
310 p = q + 1;
311 if ((char *)q + 15 >= buf->buf + buf->bytesused ||
312 q[1] != 0 || q[2] != 1 || q[3] != ch) {
313 continue;
314 }
315 if (!itv->search_pack_header) {
316 if ((q[6] & 0xc0) != 0x80)
317 continue;
318 if (((q[7] & 0xc0) == 0x80 && (q[9] & 0xf0) == 0x20) ||
319 ((q[7] & 0xc0) == 0xc0 && (q[9] & 0xf0) == 0x30)) {
320 ch = 0xba;
321 itv->search_pack_header = 1;
322 p = q + 9;
323 }
324 continue;
325 }
326 stuffing = q[13] & 7;
327 /* all stuffing bytes must be 0xff */
328 for (i = 0; i < stuffing; i++)
329 if (q[14 + i] != 0xff)
330 break;
331 if (i == stuffing && (q[4] & 0xc4) == 0x44 && (q[12] & 3) == 3 &&
332 q[14 + stuffing] == 0 && q[15 + stuffing] == 0 &&
333 q[16 + stuffing] == 1) {
334 itv->search_pack_header = 0;
335 len = (char *)q - start;
336 ivtv_setup_sliced_vbi_buf(itv);
337 break;
338 }
339 }
340 }
341 if (copy_to_user(ubuf, (u8 *)buf->buf + buf->readpos, len)) {
342 IVTV_DEBUG_WARN("copy %zd bytes to user failed for %s\n", len, s->name);
343 return -EFAULT;
344 }
345 /*IVTV_INFO("copied %lld %d %d %d %d %d vbi %d\n", itv->mpg_data_received, len, ucount,
346 buf->readpos, buf->bytesused, buf->bytesused - buf->readpos - len,
347 buf == &itv->vbi.sliced_mpeg_buf); */
348 buf->readpos += len;
349 if (s->type == IVTV_ENC_STREAM_TYPE_MPG && buf != &itv->vbi.sliced_mpeg_buf)
350 itv->mpg_data_received += len;
351 return len;
352}
353
354static ssize_t ivtv_read(struct ivtv_stream *s, char __user *ubuf, size_t tot_count, int non_block)
355{
356 struct ivtv *itv = s->itv;
357 size_t tot_written = 0;
358 int single_frame = 0;
359
360 if (atomic_read(&itv->capturing) == 0 && s->id == -1) {
361 /* shouldn't happen */
362 IVTV_DEBUG_WARN("Stream %s not initialized before read\n", s->name);
363 return -EIO;
364 }
365
366 /* Each VBI buffer is one frame, the v4l2 API says that for VBI the frames should
367 arrive one-by-one, so make sure we never output more than one VBI frame at a time */
368 if (s->type == IVTV_DEC_STREAM_TYPE_VBI ||
369 (s->type == IVTV_ENC_STREAM_TYPE_VBI && itv->vbi.sliced_in->service_set))
370 single_frame = 1;
371
372 for (;;) {
373 struct ivtv_buffer *buf;
374 int rc;
375
376 buf = ivtv_get_buffer(s, non_block, &rc);
377 if (buf == NULL && rc == -EAGAIN && tot_written)
378 break;
379 if (buf == NULL)
380 return rc;
381 rc = ivtv_copy_buf_to_user(s, buf, ubuf + tot_written, tot_count - tot_written);
382 if (buf != &itv->vbi.sliced_mpeg_buf) {
383 ivtv_enqueue(s, buf, (buf->readpos == buf->bytesused) ? &s->q_free : &s->q_io);
384 }
385 else if (buf->readpos == buf->bytesused) {
386 int idx = itv->vbi.inserted_frame % IVTV_VBI_FRAMES;
387 itv->vbi.sliced_mpeg_size[idx] = 0;
388 itv->vbi.inserted_frame++;
389 itv->vbi_data_inserted += buf->bytesused;
390 }
391 if (rc < 0)
392 return rc;
393 tot_written += rc;
394
395 if (tot_written == tot_count || single_frame)
396 break;
397 }
398 return tot_written;
399}
400
401static ssize_t ivtv_read_pos(struct ivtv_stream *s, char __user *ubuf, size_t count,
402 loff_t *pos, int non_block)
403{
404 ssize_t rc = count ? ivtv_read(s, ubuf, count, non_block) : 0;
405 struct ivtv *itv = s->itv;
406
407 IVTV_DEBUG_INFO("read %zd from %s, got %zd\n", count, s->name, rc);
408 if (rc > 0)
409 pos += rc;
410 return rc;
411}
412
413int ivtv_start_capture(struct ivtv_open_id *id)
414{
415 struct ivtv *itv = id->itv;
416 struct ivtv_stream *s = &itv->streams[id->type];
417 struct ivtv_stream *s_vbi;
418
419 if (s->type == IVTV_ENC_STREAM_TYPE_RAD ||
420 s->type == IVTV_DEC_STREAM_TYPE_MPG ||
421 s->type == IVTV_DEC_STREAM_TYPE_YUV ||
422 s->type == IVTV_DEC_STREAM_TYPE_VOUT) {
423 /* you cannot read from these stream types. */
424 return -EPERM;
425 }
426
427 /* Try to claim this stream. */
428 if (ivtv_claim_stream(id, s->type))
429 return -EBUSY;
430
431 /* This stream does not need to start capturing */
432 if (s->type == IVTV_DEC_STREAM_TYPE_VBI) {
433 set_bit(IVTV_F_S_APPL_IO, &s->s_flags);
434 return 0;
435 }
436
437 /* If capture is already in progress, then we also have to
438 do nothing extra. */
439 if (test_bit(IVTV_F_S_STREAMOFF, &s->s_flags) || test_and_set_bit(IVTV_F_S_STREAMING, &s->s_flags)) {
440 set_bit(IVTV_F_S_APPL_IO, &s->s_flags);
441 return 0;
442 }
443
444 /* Start VBI capture if required */
445 s_vbi = &itv->streams[IVTV_ENC_STREAM_TYPE_VBI];
446 if (s->type == IVTV_ENC_STREAM_TYPE_MPG &&
447 test_bit(IVTV_F_S_INTERNAL_USE, &s_vbi->s_flags) &&
448 !test_and_set_bit(IVTV_F_S_STREAMING, &s_vbi->s_flags)) {
449 /* Note: the IVTV_ENC_STREAM_TYPE_VBI is claimed
450 automatically when the MPG stream is claimed.
451 We only need to start the VBI capturing. */
452 if (ivtv_start_v4l2_encode_stream(s_vbi)) {
453 IVTV_DEBUG_WARN("VBI capture start failed\n");
454
455 /* Failure, clean up and return an error */
456 clear_bit(IVTV_F_S_STREAMING, &s_vbi->s_flags);
457 clear_bit(IVTV_F_S_STREAMING, &s->s_flags);
458 /* also releases the associated VBI stream */
459 ivtv_release_stream(s);
460 return -EIO;
461 }
462 IVTV_DEBUG_INFO("VBI insertion started\n");
463 }
464
465 /* Tell the card to start capturing */
466 if (!ivtv_start_v4l2_encode_stream(s)) {
467 /* We're done */
468 set_bit(IVTV_F_S_APPL_IO, &s->s_flags);
469 /* Resume a possibly paused encoder */
470 if (test_and_clear_bit(IVTV_F_I_ENC_PAUSED, &itv->i_flags))
471 ivtv_vapi(itv, CX2341X_ENC_PAUSE_ENCODER, 1, 1);
472 return 0;
473 }
474
475 /* failure, clean up */
476 IVTV_DEBUG_WARN("Failed to start capturing for stream %s\n", s->name);
477
478 /* Note: the IVTV_ENC_STREAM_TYPE_VBI is released
479 automatically when the MPG stream is released.
480 We only need to stop the VBI capturing. */
481 if (s->type == IVTV_ENC_STREAM_TYPE_MPG &&
482 test_bit(IVTV_F_S_STREAMING, &s_vbi->s_flags)) {
483 ivtv_stop_v4l2_encode_stream(s_vbi, 0);
484 clear_bit(IVTV_F_S_STREAMING, &s_vbi->s_flags);
485 }
486 clear_bit(IVTV_F_S_STREAMING, &s->s_flags);
487 ivtv_release_stream(s);
488 return -EIO;
489}
490
491ssize_t ivtv_v4l2_read(struct file * filp, char __user *buf, size_t count, loff_t * pos)
492{
493 struct ivtv_open_id *id = filp->private_data;
494 struct ivtv *itv = id->itv;
495 struct ivtv_stream *s = &itv->streams[id->type];
496 int rc;
497
498 IVTV_DEBUG_IOCTL("read %zd bytes from %s\n", count, s->name);
499
500 rc = ivtv_start_capture(id);
501 if (rc)
502 return rc;
503 return ivtv_read_pos(s, buf, count, pos, filp->f_flags & O_NONBLOCK);
504}
505
506int ivtv_start_decoding(struct ivtv_open_id *id, int speed)
507{
508 struct ivtv *itv = id->itv;
509 struct ivtv_stream *s = &itv->streams[id->type];
510
511 if (atomic_read(&itv->decoding) == 0) {
512 if (ivtv_claim_stream(id, s->type)) {
513 /* someone else is using this stream already */
514 IVTV_DEBUG_WARN("start decode, stream already claimed\n");
515 return -EBUSY;
516 }
517 ivtv_start_v4l2_decode_stream(s, 0);
518 }
519 if (s->type == IVTV_DEC_STREAM_TYPE_MPG)
520 return ivtv_set_speed(itv, speed);
521 return 0;
522}
523
524ssize_t ivtv_v4l2_write(struct file *filp, const char __user *user_buf, size_t count, loff_t *pos)
525{
526 struct ivtv_open_id *id = filp->private_data;
527 struct ivtv *itv = id->itv;
528 struct ivtv_stream *s = &itv->streams[id->type];
529 struct ivtv_buffer *buf;
530 struct ivtv_queue q;
531 int bytes_written = 0;
532 int mode;
533 int rc;
534 DEFINE_WAIT(wait);
535
536 IVTV_DEBUG_IOCTL("write %zd bytes to %s\n", count, s->name);
537
538 if (s->type != IVTV_DEC_STREAM_TYPE_MPG &&
539 s->type != IVTV_DEC_STREAM_TYPE_YUV &&
540 s->type != IVTV_DEC_STREAM_TYPE_VOUT)
541 /* not decoder streams */
542 return -EPERM;
543
544 /* Try to claim this stream */
545 if (ivtv_claim_stream(id, s->type))
546 return -EBUSY;
547
548 /* This stream does not need to start any decoding */
549 if (s->type == IVTV_DEC_STREAM_TYPE_VOUT) {
550 set_bit(IVTV_F_S_APPL_IO, &s->s_flags);
551 return ivtv_write_vbi(itv, user_buf, count);
552 }
553
554 mode = s->type == IVTV_DEC_STREAM_TYPE_MPG ? OUT_MPG : OUT_YUV;
555
556 if (ivtv_set_output_mode(itv, mode) != mode) {
557 ivtv_release_stream(s);
558 return -EBUSY;
559 }
560 ivtv_queue_init(&q);
561 set_bit(IVTV_F_S_APPL_IO, &s->s_flags);
562
563retry:
564 for (;;) {
565 /* Gather buffers */
566 while (q.length - q.bytesused < count && (buf = ivtv_dequeue(s, &s->q_io)))
567 ivtv_enqueue(s, buf, &q);
568 while (q.length - q.bytesused < count && (buf = ivtv_dequeue(s, &s->q_free))) {
569 ivtv_enqueue(s, buf, &q);
570 }
571 if (q.buffers)
572 break;
573 if (filp->f_flags & O_NONBLOCK)
574 return -EAGAIN;
575 prepare_to_wait(&s->waitq, &wait, TASK_INTERRUPTIBLE);
576 /* New buffers might have become free before we were added to the waitqueue */
577 if (!s->q_free.buffers)
578 schedule();
579 finish_wait(&s->waitq, &wait);
580 if (signal_pending(current)) {
581 IVTV_DEBUG_INFO("User stopped %s\n", s->name);
582 return -EINTR;
583 }
584 }
585
586 /* copy user data into buffers */
587 while ((buf = ivtv_dequeue(s, &q))) {
588 /* Make sure we really got all the user data */
589 rc = ivtv_buf_copy_from_user(s, buf, user_buf, count);
590
591 if (rc < 0) {
592 ivtv_queue_move(s, &q, NULL, &s->q_free, 0);
593 return rc;
594 }
595 user_buf += rc;
596 count -= rc;
597 bytes_written += rc;
598
599 if (buf->bytesused != s->buf_size) {
600 /* incomplete, leave in q_io for next time */
601 ivtv_enqueue(s, buf, &s->q_io);
602 break;
603 }
604 /* Byteswap MPEG buffer */
605 if (s->type == IVTV_DEC_STREAM_TYPE_MPG)
606 ivtv_buf_swap(buf);
607 ivtv_enqueue(s, buf, &s->q_full);
608 }
609
610 /* Start decoder (returns 0 if already started) */
611 rc = ivtv_start_decoding(id, itv->speed);
612 if (rc) {
613 IVTV_DEBUG_WARN("Failed start decode stream %s\n", s->name);
614
615 /* failure, clean up */
616 clear_bit(IVTV_F_S_STREAMING, &s->s_flags);
617 clear_bit(IVTV_F_S_APPL_IO, &s->s_flags);
618 return rc;
619 }
620 if (test_bit(IVTV_F_S_NEEDS_DATA, &s->s_flags)) {
621 if (s->q_full.length >= itv->dma_data_req_size) {
622 int got_sig;
623
624 prepare_to_wait(&itv->dma_waitq, &wait, TASK_INTERRUPTIBLE);
625 while (!(got_sig = signal_pending(current)) &&
626 test_bit(IVTV_F_S_DMA_PENDING, &s->s_flags)) {
627 schedule();
628 }
629 finish_wait(&itv->dma_waitq, &wait);
630 if (got_sig) {
631 IVTV_DEBUG_INFO("User interrupted %s\n", s->name);
632 return -EINTR;
633 }
634
635 clear_bit(IVTV_F_S_NEEDS_DATA, &s->s_flags);
636 ivtv_queue_move(s, &s->q_full, NULL, &s->q_predma, itv->dma_data_req_size);
637 ivtv_dma_stream_dec_prepare(s, itv->dma_data_req_offset + IVTV_DECODER_OFFSET, 1);
638 }
639 }
640 /* more user data is available, wait until buffers become free
641 to transfer the rest. */
642 if (count && !(filp->f_flags & O_NONBLOCK))
643 goto retry;
644 IVTV_DEBUG_INFO("Wrote %d bytes to %s (%d)\n", bytes_written, s->name, s->q_full.bytesused);
645 return bytes_written;
646}
647
648unsigned int ivtv_v4l2_dec_poll(struct file *filp, poll_table *wait)
649{
650 struct ivtv_open_id *id = filp->private_data;
651 struct ivtv *itv = id->itv;
652 struct ivtv_stream *s = &itv->streams[id->type];
653 int res = 0;
654
655 /* add stream's waitq to the poll list */
656 poll_wait(filp, &s->waitq, wait);
657
658 set_bit(IVTV_F_I_EV_VSYNC_ENABLED, &itv->i_flags);
659 if (test_bit(IVTV_F_I_EV_VSYNC, &itv->i_flags) ||
660 test_bit(IVTV_F_I_EV_DEC_STOPPED, &itv->i_flags))
661 res = POLLPRI;
662
663 /* Allow write if buffers are available for writing */
664 if (s->q_free.buffers)
665 res |= POLLOUT | POLLWRNORM;
666 return res;
667}
668
669unsigned int ivtv_v4l2_enc_poll(struct file *filp, poll_table * wait)
670{
671 struct ivtv_open_id *id = filp->private_data;
672 struct ivtv *itv = id->itv;
673 struct ivtv_stream *s = &itv->streams[id->type];
674 int eof = test_bit(IVTV_F_S_STREAMOFF, &s->s_flags);
675
676 /* Start a capture if there is none */
677 if (!eof && !test_bit(IVTV_F_S_STREAMING, &s->s_flags)) {
678 int rc = ivtv_start_capture(id);
679
680 if (rc) {
681 IVTV_DEBUG_INFO("Could not start capture for %s (%d)\n",
682 s->name, rc);
683 return POLLERR;
684 }
685 }
686
687 /* add stream's waitq to the poll list */
688 poll_wait(filp, &s->waitq, wait);
689
690 if (eof || s->q_full.length)
691 return POLLIN | POLLRDNORM;
692 return 0;
693}
694
695void ivtv_stop_capture(struct ivtv_open_id *id, int gop_end)
696{
697 struct ivtv *itv = id->itv;
698 struct ivtv_stream *s = &itv->streams[id->type];
699
700 IVTV_DEBUG_IOCTL("close() of %s\n", s->name);
701
702 /* 'Unclaim' this stream */
703
704 /* Stop capturing */
705 if (test_bit(IVTV_F_S_STREAMING, &s->s_flags)) {
706 struct ivtv_stream *s_vbi = &itv->streams[IVTV_ENC_STREAM_TYPE_VBI];
707
708 IVTV_DEBUG_INFO("close stopping capture\n");
709 /* Special case: a running VBI capture for VBI insertion
710 in the mpeg stream. Need to stop that too. */
711 if (id->type == IVTV_ENC_STREAM_TYPE_MPG &&
712 test_bit(IVTV_F_S_STREAMING, &s_vbi->s_flags) &&
713 !test_bit(IVTV_F_S_APPL_IO, &s_vbi->s_flags)) {
714 IVTV_DEBUG_INFO("close stopping embedded VBI capture\n");
715 ivtv_stop_v4l2_encode_stream(s_vbi, 0);
716 }
717 if ((id->type == IVTV_DEC_STREAM_TYPE_VBI ||
718 id->type == IVTV_ENC_STREAM_TYPE_VBI) &&
719 test_bit(IVTV_F_S_INTERNAL_USE, &s->s_flags)) {
720 /* Also used internally, don't stop capturing */
721 s->id = -1;
722 }
723 else {
724 ivtv_stop_v4l2_encode_stream(s, gop_end);
725 }
726 }
727 clear_bit(IVTV_F_S_APPL_IO, &s->s_flags);
728 clear_bit(IVTV_F_S_STREAMOFF, &s->s_flags);
729
730 ivtv_release_stream(s);
731}
732
733static void ivtv_stop_decoding(struct ivtv_open_id *id, int flags, u64 pts)
734{
735 struct ivtv *itv = id->itv;
736 struct ivtv_stream *s = &itv->streams[id->type];
737
738 IVTV_DEBUG_IOCTL("close() of %s\n", s->name);
739
740 /* Stop decoding */
741 if (test_bit(IVTV_F_S_STREAMING, &s->s_flags)) {
742 IVTV_DEBUG_INFO("close stopping decode\n");
743
744 ivtv_stop_v4l2_decode_stream(s, flags, pts);
745 }
746 clear_bit(IVTV_F_S_APPL_IO, &s->s_flags);
747 clear_bit(IVTV_F_S_STREAMOFF, &s->s_flags);
748 if (id->type == IVTV_DEC_STREAM_TYPE_YUV && test_bit(IVTV_F_I_DECODING_YUV, &itv->i_flags)) {
749 /* Restore registers we've changed & clean up any mess we've made */
750 ivtv_yuv_close(itv);
751 }
752 if (s->type == IVTV_DEC_STREAM_TYPE_YUV && itv->output_mode == OUT_YUV)
753 itv->output_mode = OUT_NONE;
754 else if (s->type == IVTV_DEC_STREAM_TYPE_MPG && itv->output_mode == OUT_MPG)
755 itv->output_mode = OUT_NONE;
756
757 itv->speed = 0;
758 ivtv_release_stream(s);
759}
760
761int ivtv_v4l2_close(struct inode *inode, struct file *filp)
762{
763 struct ivtv_open_id *id = filp->private_data;
764 struct ivtv *itv = id->itv;
765 struct ivtv_stream *s = &itv->streams[id->type];
766
767 IVTV_DEBUG_IOCTL("close() of %s\n", s->name);
768
769 v4l2_prio_close(&itv->prio, &id->prio);
770
771 /* Easy case first: this stream was never claimed by us */
772 if (s->id != id->open_id) {
773 kfree(id);
774 return 0;
775 }
776
777 /* 'Unclaim' this stream */
778
779 /* Stop radio */
780 if (id->type == IVTV_ENC_STREAM_TYPE_RAD) {
781 /* Closing radio device, return to TV mode */
782 ivtv_mute(itv);
783 /* Mark that the radio is no longer in use */
784 clear_bit(IVTV_F_I_RADIO_USER, &itv->i_flags);
785 /* Switch tuner to TV */
786 ivtv_call_i2c_clients(itv, VIDIOC_S_STD, &itv->std);
787 /* Select correct audio input (i.e. TV tuner or Line in) */
788 ivtv_audio_set_io(itv);
789 /* Done! Unmute and continue. */
790 ivtv_unmute(itv);
791 ivtv_release_stream(s);
792 } else if (s->type >= IVTV_DEC_STREAM_TYPE_MPG) {
793 ivtv_stop_decoding(id, VIDEO_CMD_STOP_TO_BLACK | VIDEO_CMD_STOP_IMMEDIATELY, 0);
794 } else {
795 ivtv_stop_capture(id, 0);
796 }
797 kfree(id);
798 return 0;
799}
800
801int ivtv_v4l2_open(struct inode *inode, struct file *filp)
802{
803 int x, y = 0;
804 struct ivtv_open_id *item;
805 struct ivtv *itv = NULL;
806 struct ivtv_stream *s = NULL;
807 int minor = MINOR(inode->i_rdev);
808
809 /* Find which card this open was on */
810 spin_lock(&ivtv_cards_lock);
811 for (x = 0; itv == NULL && x < ivtv_cards_active; x++) {
812 /* find out which stream this open was on */
813 for (y = 0; y < IVTV_MAX_STREAMS; y++) {
814 s = &ivtv_cards[x]->streams[y];
815 if (s->v4l2dev && s->v4l2dev->minor == minor) {
816 itv = ivtv_cards[x];
817 break;
818 }
819 }
820 }
821 spin_unlock(&ivtv_cards_lock);
822
823 if (itv == NULL) {
824 /* Couldn't find a device registered
825 on that minor, shouldn't happen! */
826 printk(KERN_WARNING "ivtv: no ivtv device found on minor %d\n", minor);
827 return -ENXIO;
828 }
829
830 if (y == IVTV_DEC_STREAM_TYPE_MPG &&
831 test_bit(IVTV_F_S_CLAIMED, &itv->streams[IVTV_DEC_STREAM_TYPE_YUV].s_flags))
832 return -EBUSY;
833
834 if (y == IVTV_DEC_STREAM_TYPE_YUV &&
835 test_bit(IVTV_F_S_CLAIMED, &itv->streams[IVTV_DEC_STREAM_TYPE_MPG].s_flags))
836 return -EBUSY;
837
838 if (y == IVTV_DEC_STREAM_TYPE_YUV) {
839 if (read_reg(0x82c) == 0) {
840 IVTV_ERR("Tried to open YUV output device but need to send data to mpeg decoder before it can be used\n");
841 /* return -ENODEV; */
842 }
843 ivtv_udma_alloc(itv);
844 }
845
846 /* Allocate memory */
847 item = kmalloc(sizeof(struct ivtv_open_id), GFP_KERNEL);
848 if (NULL == item) {
849 IVTV_DEBUG_WARN("nomem on v4l2 open\n");
850 return -ENOMEM;
851 }
852 item->itv = itv;
853 item->type = y;
854 v4l2_prio_open(&itv->prio, &item->prio);
855
856 item->open_id = itv->open_id++;
857 filp->private_data = item;
858
859 if (item->type == IVTV_ENC_STREAM_TYPE_RAD) {
860 /* Try to claim this stream */
861 if (ivtv_claim_stream(item, item->type)) {
862 /* No, it's already in use */
863 kfree(item);
864 return -EBUSY;
865 }
866
867 /* We have the radio */
868 ivtv_mute(itv);
869 /* Switch tuner to radio */
870 ivtv_call_i2c_clients(itv, AUDC_SET_RADIO, NULL);
871 /* Mark that the radio is being used. */
872 set_bit(IVTV_F_I_RADIO_USER, &itv->i_flags);
873 /* Select the correct audio input (i.e. radio tuner) */
874 ivtv_audio_set_io(itv);
875 /* Done! Unmute and continue. */
876 ivtv_unmute(itv);
877 }
878
879 /* YUV or MPG Decoding Mode? */
880 if (y == IVTV_DEC_STREAM_TYPE_MPG)
881 clear_bit(IVTV_F_I_DEC_YUV, &itv->i_flags);
882 else if (y == IVTV_DEC_STREAM_TYPE_YUV)
883 {
884 set_bit(IVTV_F_I_DEC_YUV, &itv->i_flags);
885 }
886
887 return 0;
888}
889
890void ivtv_mute(struct ivtv *itv)
891{
892 struct v4l2_control ctrl = { V4L2_CID_AUDIO_MUTE, 1 };
893
894 /* Mute sound to avoid pop */
895 ivtv_control_ioctls(itv, VIDIOC_S_CTRL, &ctrl);
896
897 if (atomic_read(&itv->capturing))
898 ivtv_vapi(itv, CX2341X_ENC_MUTE_AUDIO, 1, 1);
899
900 IVTV_DEBUG_INFO("Mute\n");
901}
902
903void ivtv_unmute(struct ivtv *itv)
904{
905 struct v4l2_control ctrl = { V4L2_CID_AUDIO_MUTE, 0 };
906
907 /* initialize or refresh input */
908 if (atomic_read(&itv->capturing) == 0)
909 ivtv_vapi(itv, CX2341X_ENC_INITIALIZE_INPUT, 0);
910
911 ivtv_sleep_timeout(HZ / 10, 0);
912
913 if (atomic_read(&itv->capturing)) {
914 ivtv_vapi(itv, CX2341X_ENC_MISC, 1, 12);
915 ivtv_vapi(itv, CX2341X_ENC_MUTE_AUDIO, 1, 0);
916 }
917
918 /* Unmute */
919 ivtv_control_ioctls(itv, VIDIOC_S_CTRL, &ctrl);
920 IVTV_DEBUG_INFO("Unmute\n");
921}
diff --git a/drivers/media/video/ivtv/ivtv-fileops.h b/drivers/media/video/ivtv/ivtv-fileops.h
new file mode 100644
index 000000000000..74a1745fabbc
--- /dev/null
+++ b/drivers/media/video/ivtv/ivtv-fileops.h
@@ -0,0 +1,44 @@
1/*
2 file operation functions
3 Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
4 Copyright (C) 2005-2007 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21/* Testing/Debugging */
22int ivtv_v4l2_open(struct inode *inode, struct file *filp);
23ssize_t ivtv_v4l2_read(struct file *filp, char __user *buf, size_t count,
24 loff_t * pos);
25ssize_t ivtv_v4l2_write(struct file *filp, const char __user *buf, size_t count,
26 loff_t * pos);
27int ivtv_v4l2_close(struct inode *inode, struct file *filp);
28unsigned int ivtv_v4l2_enc_poll(struct file *filp, poll_table * wait);
29unsigned int ivtv_v4l2_dec_poll(struct file *filp, poll_table * wait);
30int ivtv_start_capture(struct ivtv_open_id *id);
31void ivtv_stop_capture(struct ivtv_open_id *id, int gop_end);
32int ivtv_start_decoding(struct ivtv_open_id *id, int speed);
33void ivtv_mute(struct ivtv *itv);
34void ivtv_unmute(struct ivtv *itv);
35
36/* Utilities */
37
38/* Try to claim a stream for the filehandle. Return 0 on success,
39 -EBUSY if stream already claimed. Once a stream is claimed, it
40 remains claimed until the associated filehandle is closed. */
41int ivtv_claim_stream(struct ivtv_open_id *id, int type);
42
43/* Release a previously claimed stream. */
44void ivtv_release_stream(struct ivtv_stream *s);
diff --git a/drivers/media/video/ivtv/ivtv-firmware.c b/drivers/media/video/ivtv/ivtv-firmware.c
new file mode 100644
index 000000000000..d4c910b782af
--- /dev/null
+++ b/drivers/media/video/ivtv/ivtv-firmware.c
@@ -0,0 +1,272 @@
1/*
2 ivtv firmware functions.
3 Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
4 Copyright (C) 2004 Chris Kennedy <c@groovy.org>
5 Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl>
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21
22#include "ivtv-driver.h"
23#include "ivtv-mailbox.h"
24#include "ivtv-firmware.h"
25#include <linux/firmware.h>
26
27#define IVTV_MASK_SPU_ENABLE 0xFFFFFFFE
28#define IVTV_MASK_VPU_ENABLE15 0xFFFFFFF6
29#define IVTV_MASK_VPU_ENABLE16 0xFFFFFFFB
30#define IVTV_CMD_VDM_STOP 0x00000000
31#define IVTV_CMD_AO_STOP 0x00000005
32#define IVTV_CMD_APU_PING 0x00000000
33#define IVTV_CMD_VPU_STOP15 0xFFFFFFFE
34#define IVTV_CMD_VPU_STOP16 0xFFFFFFEE
35#define IVTV_CMD_HW_BLOCKS_RST 0xFFFFFFFF
36#define IVTV_CMD_SPU_STOP 0x00000001
37#define IVTV_CMD_SDRAM_PRECHARGE_INIT 0x0000001A
38#define IVTV_CMD_SDRAM_REFRESH_INIT 0x80000640
39#define IVTV_SDRAM_SLEEPTIME (60 * HZ / 100) /* 600 ms */
40
41#define IVTV_DECODE_INIT_MPEG_FILENAME "v4l-cx2341x-init.mpg"
42#define IVTV_DECODE_INIT_MPEG_SIZE (152*1024)
43
44/* Encoder/decoder firmware sizes */
45#define IVTV_FW_ENC_SIZE (376836)
46#define IVTV_FW_DEC_SIZE (256*1024)
47
48static int load_fw_direct(const char *fn, volatile u8 __iomem *mem, struct ivtv *itv, long size)
49{
50 const struct firmware *fw = NULL;
51 int retries = 3;
52
53retry:
54 if (retries && request_firmware(&fw, fn, &itv->dev->dev) == 0) {
55 int i;
56 volatile u32 __iomem *dst = (volatile u32 __iomem *)mem;
57 const u32 *src = (const u32 *)fw->data;
58
59 /* temporarily allow 256 KB encoding firmwares as well for
60 compatibility with blackbird cards */
61 if (fw->size != size && fw->size != 256 * 1024) {
62 /* Due to race conditions in firmware loading (esp. with udev <0.95)
63 the wrong file was sometimes loaded. So we check filesizes to
64 see if at least the right-sized file was loaded. If not, then we
65 retry. */
66 IVTV_INFO("retry: file loaded was not %s (expected size %ld, got %zd)\n", fn, size, fw->size);
67 release_firmware(fw);
68 retries--;
69 goto retry;
70 }
71 for (i = 0; i < fw->size; i += 4) {
72 /* no need for endianness conversion on the ppc */
73 __raw_writel(*src, dst);
74 dst++;
75 src++;
76 }
77 release_firmware(fw);
78 IVTV_INFO("loaded %s firmware (%zd bytes)\n", fn, fw->size);
79 return size;
80 }
81 IVTV_ERR("unable to open firmware %s (must be %ld bytes)\n", fn, size);
82 IVTV_ERR("did you put the firmware in the hotplug firmware directory?\n");
83 return -ENOMEM;
84}
85
86void ivtv_halt_firmware(struct ivtv *itv)
87{
88 IVTV_DEBUG_INFO("Preparing for firmware halt.\n");
89 if (itv->has_cx23415 && itv->dec_mbox.mbox)
90 ivtv_vapi(itv, CX2341X_DEC_HALT_FW, 0);
91 if (itv->enc_mbox.mbox)
92 ivtv_vapi(itv, CX2341X_ENC_HALT_FW, 0);
93
94 ivtv_sleep_timeout(HZ / 100, 0);
95 itv->enc_mbox.mbox = itv->dec_mbox.mbox = NULL;
96
97 IVTV_DEBUG_INFO("Stopping VDM\n");
98 write_reg(IVTV_CMD_VDM_STOP, IVTV_REG_VDM);
99
100 IVTV_DEBUG_INFO("Stopping AO\n");
101 write_reg(IVTV_CMD_AO_STOP, IVTV_REG_AO);
102
103 IVTV_DEBUG_INFO("pinging (?) APU\n");
104 write_reg(IVTV_CMD_APU_PING, IVTV_REG_APU);
105
106 IVTV_DEBUG_INFO("Stopping VPU\n");
107 if (!itv->has_cx23415)
108 write_reg(IVTV_CMD_VPU_STOP16, IVTV_REG_VPU);
109 else
110 write_reg(IVTV_CMD_VPU_STOP15, IVTV_REG_VPU);
111
112 IVTV_DEBUG_INFO("Resetting Hw Blocks\n");
113 write_reg(IVTV_CMD_HW_BLOCKS_RST, IVTV_REG_HW_BLOCKS);
114
115 IVTV_DEBUG_INFO("Stopping SPU\n");
116 write_reg(IVTV_CMD_SPU_STOP, IVTV_REG_SPU);
117
118 ivtv_sleep_timeout(HZ / 100, 0);
119
120 IVTV_DEBUG_INFO("init Encoder SDRAM pre-charge\n");
121 write_reg(IVTV_CMD_SDRAM_PRECHARGE_INIT, IVTV_REG_ENC_SDRAM_PRECHARGE);
122
123 IVTV_DEBUG_INFO("init Encoder SDRAM refresh to 1us\n");
124 write_reg(IVTV_CMD_SDRAM_REFRESH_INIT, IVTV_REG_ENC_SDRAM_REFRESH);
125
126 if (itv->has_cx23415) {
127 IVTV_DEBUG_INFO("init Decoder SDRAM pre-charge\n");
128 write_reg(IVTV_CMD_SDRAM_PRECHARGE_INIT, IVTV_REG_DEC_SDRAM_PRECHARGE);
129
130 IVTV_DEBUG_INFO("init Decoder SDRAM refresh to 1us\n");
131 write_reg(IVTV_CMD_SDRAM_REFRESH_INIT, IVTV_REG_DEC_SDRAM_REFRESH);
132 }
133
134 IVTV_DEBUG_INFO("Sleeping for %dms (600 recommended)\n",
135 (int)(IVTV_SDRAM_SLEEPTIME * 1000 / HZ));
136 ivtv_sleep_timeout(IVTV_SDRAM_SLEEPTIME, 0);
137}
138
139void ivtv_firmware_versions(struct ivtv *itv)
140{
141 u32 data[CX2341X_MBOX_MAX_DATA];
142
143 /* Encoder */
144 ivtv_vapi_result(itv, data, CX2341X_ENC_GET_VERSION, 0);
145 IVTV_INFO("Encoder revision: 0x%08x\n", data[0]);
146
147 if (data[0] != 0x02060039)
148 IVTV_WARN("Recommended firmware version is 0x02060039.\n");
149
150 if (itv->has_cx23415) {
151 /* Decoder */
152 ivtv_vapi_result(itv, data, CX2341X_DEC_GET_VERSION, 0);
153 IVTV_INFO("Decoder revision: 0x%08x\n", data[0]);
154 }
155}
156
157static int ivtv_firmware_copy(struct ivtv *itv)
158{
159 IVTV_DEBUG_INFO("Loading encoder image\n");
160 if (load_fw_direct(CX2341X_FIRM_ENC_FILENAME,
161 itv->enc_mem, itv, IVTV_FW_ENC_SIZE) != IVTV_FW_ENC_SIZE) {
162 IVTV_DEBUG_WARN("failed loading encoder firmware\n");
163 return -3;
164 }
165 if (!itv->has_cx23415)
166 return 0;
167
168 IVTV_DEBUG_INFO("Loading decoder image\n");
169 if (load_fw_direct(CX2341X_FIRM_DEC_FILENAME,
170 itv->dec_mem, itv, IVTV_FW_DEC_SIZE) != IVTV_FW_DEC_SIZE) {
171 IVTV_DEBUG_WARN("failed loading decoder firmware\n");
172 return -1;
173 }
174 return 0;
175}
176
177static volatile struct ivtv_mailbox __iomem *ivtv_search_mailbox(const volatile u8 __iomem *mem, u32 size)
178{
179 int i;
180
181 /* mailbox is preceeded by a 16 byte 'magic cookie' starting at a 256-byte
182 address boundary */
183 for (i = 0; i < size; i += 0x100) {
184 if (readl(mem + i) == 0x12345678 &&
185 readl(mem + i + 4) == 0x34567812 &&
186 readl(mem + i + 8) == 0x56781234 &&
187 readl(mem + i + 12) == 0x78123456) {
188 return (volatile struct ivtv_mailbox __iomem *)(mem + i + 16);
189 }
190 }
191 return NULL;
192}
193
194int ivtv_firmware_init(struct ivtv *itv)
195{
196 int err;
197
198 ivtv_halt_firmware(itv);
199
200 /* load firmware */
201 err = ivtv_firmware_copy(itv);
202 if (err) {
203 IVTV_DEBUG_WARN("Error %d loading firmware\n", err);
204 return err;
205 }
206
207 /* start firmware */
208 write_reg(read_reg(IVTV_REG_SPU) & IVTV_MASK_SPU_ENABLE, IVTV_REG_SPU);
209 ivtv_sleep_timeout(HZ / 10, 0);
210 if (itv->has_cx23415)
211 write_reg(read_reg(IVTV_REG_VPU) & IVTV_MASK_VPU_ENABLE15, IVTV_REG_VPU);
212 else
213 write_reg(read_reg(IVTV_REG_VPU) & IVTV_MASK_VPU_ENABLE16, IVTV_REG_VPU);
214 ivtv_sleep_timeout(HZ / 10, 0);
215
216 /* find mailboxes and ping firmware */
217 itv->enc_mbox.mbox = ivtv_search_mailbox(itv->enc_mem, IVTV_ENCODER_SIZE);
218 if (itv->enc_mbox.mbox == NULL)
219 IVTV_ERR("Encoder mailbox not found\n");
220 else if (ivtv_vapi(itv, CX2341X_ENC_PING_FW, 0)) {
221 IVTV_ERR("Encoder firmware dead!\n");
222 itv->enc_mbox.mbox = NULL;
223 }
224 if (itv->enc_mbox.mbox == NULL)
225 return -ENODEV;
226
227 if (!itv->has_cx23415)
228 return 0;
229
230 itv->dec_mbox.mbox = ivtv_search_mailbox(itv->dec_mem, IVTV_DECODER_SIZE);
231 if (itv->dec_mbox.mbox == NULL)
232 IVTV_ERR("Decoder mailbox not found\n");
233 else if (itv->has_cx23415 && ivtv_vapi(itv, CX2341X_DEC_PING_FW, 0)) {
234 IVTV_ERR("Decoder firmware dead!\n");
235 itv->dec_mbox.mbox = NULL;
236 }
237 return itv->dec_mbox.mbox ? 0 : -ENODEV;
238}
239
240void ivtv_init_mpeg_decoder(struct ivtv *itv)
241{
242 u32 data[CX2341X_MBOX_MAX_DATA];
243 long readbytes;
244 volatile u8 __iomem *mem_offset;
245
246 data[0] = 0;
247 data[1] = itv->params.width; /* YUV source width */
248 data[2] = itv->params.height;
249 data[3] = itv->params.audio_properties; /* Audio settings to use,
250 bitmap. see docs. */
251 if (ivtv_api(itv, CX2341X_DEC_SET_DECODER_SOURCE, 4, data)) {
252 IVTV_ERR("ivtv_init_mpeg_decoder failed to set decoder source\n");
253 return;
254 }
255
256 if (ivtv_vapi(itv, CX2341X_DEC_START_PLAYBACK, 2, 0, 1) != 0) {
257 IVTV_ERR("ivtv_init_mpeg_decoder failed to start playback\n");
258 return;
259 }
260 ivtv_api_get_data(&itv->dec_mbox, IVTV_MBOX_DMA, data);
261 mem_offset = itv->dec_mem + data[1];
262
263 if ((readbytes = load_fw_direct(IVTV_DECODE_INIT_MPEG_FILENAME,
264 mem_offset, itv, IVTV_DECODE_INIT_MPEG_SIZE)) <= 0) {
265 IVTV_DEBUG_WARN("failed to read mpeg decoder initialisation file %s\n",
266 IVTV_DECODE_INIT_MPEG_FILENAME);
267 } else {
268 ivtv_vapi(itv, CX2341X_DEC_SCHED_DMA_FROM_HOST, 3, 0, readbytes, 0);
269 ivtv_sleep_timeout(HZ / 10, 0);
270 }
271 ivtv_vapi(itv, CX2341X_DEC_STOP_PLAYBACK, 4, 0, 0, 0, 1);
272}
diff --git a/drivers/media/video/ivtv/ivtv-firmware.h b/drivers/media/video/ivtv/ivtv-firmware.h
new file mode 100644
index 000000000000..8b2ffe658905
--- /dev/null
+++ b/drivers/media/video/ivtv/ivtv-firmware.h
@@ -0,0 +1,25 @@
1/*
2 ivtv firmware functions.
3 Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
4 Copyright (C) 2004 Chris Kennedy <c@groovy.org>
5 Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl>
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21
22int ivtv_firmware_init(struct ivtv *itv);
23void ivtv_firmware_versions(struct ivtv *itv);
24void ivtv_halt_firmware(struct ivtv *itv);
25void ivtv_init_mpeg_decoder(struct ivtv *itv);
diff --git a/drivers/media/video/ivtv/ivtv-gpio.c b/drivers/media/video/ivtv/ivtv-gpio.c
new file mode 100644
index 000000000000..bc8f8ca2961f
--- /dev/null
+++ b/drivers/media/video/ivtv/ivtv-gpio.c
@@ -0,0 +1,307 @@
1/*
2 gpio functions.
3 Merging GPIO support into driver:
4 Copyright (C) 2004 Chris Kennedy <c@groovy.org>
5 Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl>
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21
22#include "ivtv-driver.h"
23#include "ivtv-cards.h"
24#include "ivtv-gpio.h"
25#include <media/tuner.h>
26
27/*
28 * GPIO assignment of Yuan MPG600/MPG160
29 *
30 * bit 15 14 13 12 | 11 10 9 8 | 7 6 5 4 | 3 2 1 0
31 * OUTPUT IN1 IN0 AM3 AM2 AM1 AM0
32 * INPUT DM1 DM0
33 *
34 * IN* : Input selection
35 * IN1 IN0
36 * 1 1 N/A
37 * 1 0 Line
38 * 0 1 N/A
39 * 0 0 Tuner
40 *
41 * AM* : Audio Mode
42 * AM3 0: Normal 1: Mixed(Sub+Main channel)
43 * AM2 0: Subchannel 1: Main channel
44 * AM1 0: Stereo 1: Mono
45 * AM0 0: Normal 1: Mute
46 *
47 * DM* : Detected tuner audio Mode
48 * DM1 0: Stereo 1: Mono
49 * DM0 0: Multiplex 1: Normal
50 *
51 * GPIO Initial Settings
52 * MPG600 MPG160
53 * DIR 0x3080 0x7080
54 * OUTPUT 0x000C 0x400C
55 *
56 * Special thanks to Makoto Iguchi <iguchi@tahoo.org> and Mr. Anonymous
57 * for analyzing GPIO of MPG160.
58 *
59 *****************************************************************************
60 *
61 * GPIO assignment of Avermedia M179 (per information direct from AVerMedia)
62 *
63 * bit 15 14 13 12 | 11 10 9 8 | 7 6 5 4 | 3 2 1 0
64 * OUTPUT IN0 AM0 IN1 AM1 AM2 IN2 BR0 BR1
65 * INPUT
66 *
67 * IN* : Input selection
68 * IN0 IN1 IN2
69 * * 1 * Mute
70 * 0 0 0 Line-In
71 * 1 0 0 TV Tuner Audio
72 * 0 0 1 FM Audio
73 * 1 0 1 Mute
74 *
75 * AM* : Audio Mode
76 * AM0 AM1 AM2
77 * 0 0 0 TV Tuner Audio: L_OUT=(L+R)/2, R_OUT=SAP
78 * 0 0 1 TV Tuner Audio: L_OUT=R_OUT=SAP (SAP)
79 * 0 1 0 TV Tuner Audio: L_OUT=L, R_OUT=R (stereo)
80 * 0 1 1 TV Tuner Audio: mute
81 * 1 * * TV Tuner Audio: L_OUT=R_OUT=(L+R)/2 (mono)
82 *
83 * BR* : Audio Sample Rate (BR stands for bitrate for some reason)
84 * BR0 BR1
85 * 0 0 32 kHz
86 * 0 1 44.1 kHz
87 * 1 0 48 kHz
88 *
89 * DM* : Detected tuner audio Mode
90 * Unknown currently
91 *
92 * Special thanks to AVerMedia Technologies, Inc. and Jiun-Kuei Jung at
93 * AVerMedia for providing the GPIO information used to add support
94 * for the M179 cards.
95 */
96
97/********************* GPIO stuffs *********************/
98
99/* GPIO registers */
100#define IVTV_REG_GPIO_IN 0x9008
101#define IVTV_REG_GPIO_OUT 0x900c
102#define IVTV_REG_GPIO_DIR 0x9020
103
104void ivtv_reset_ir_gpio(struct ivtv *itv)
105{
106 int curdir, curout;
107
108 if (itv->card->type != IVTV_CARD_PVR_150)
109 return;
110 IVTV_DEBUG_INFO("Resetting PVR150 IR\n");
111 curout = read_reg(IVTV_REG_GPIO_OUT);
112 curdir = read_reg(IVTV_REG_GPIO_DIR);
113 curdir |= 0x80;
114 write_reg(curdir, IVTV_REG_GPIO_DIR);
115 curout = (curout & ~0xF) | 1;
116 write_reg(curout, IVTV_REG_GPIO_OUT);
117 /* We could use something else for smaller time */
118 current->state = TASK_INTERRUPTIBLE;
119 schedule_timeout(1);
120 curout |= 2;
121 write_reg(curout, IVTV_REG_GPIO_OUT);
122 curdir &= ~0x80;
123 write_reg(curdir, IVTV_REG_GPIO_DIR);
124}
125
126#ifdef HAVE_XC3028
127int ivtv_reset_tuner_gpio(enum v4l2_tuner_type mode, void *priv, int ptr)
128{
129 int curdir, curout;
130 struct ivtv *itv = (struct ivtv *) priv;
131
132 if (itv->card->type != IVTV_CARD_PG600V2 || itv->options.tuner != TUNER_XCEIVE_XC3028)
133 return -EINVAL;
134 IVTV_INFO("Resetting tuner.\n");
135 curout = read_reg(IVTV_REG_GPIO_OUT);
136 curdir = read_reg(IVTV_REG_GPIO_DIR);
137 curdir |= (1 << 12); /* GPIO bit 12 */
138
139 curout &= ~(1 << 12);
140 write_reg(curout, IVTV_REG_GPIO_OUT);
141 current->state = TASK_INTERRUPTIBLE;
142 schedule_timeout(1);
143
144 curout |= (1 << 12);
145 write_reg(curout, IVTV_REG_GPIO_OUT);
146 current->state = TASK_INTERRUPTIBLE;
147 schedule_timeout(1);
148
149 return 0;
150}
151#endif
152
153void ivtv_gpio_init(struct ivtv *itv)
154{
155 if (itv->card->gpio_init.direction == 0)
156 return;
157
158 IVTV_DEBUG_INFO("GPIO initial dir: %08x out: %08x\n",
159 read_reg(IVTV_REG_GPIO_DIR), read_reg(IVTV_REG_GPIO_OUT));
160
161 /* init output data then direction */
162 write_reg(itv->card->gpio_init.initial_value, IVTV_REG_GPIO_OUT);
163 write_reg(itv->card->gpio_init.direction, IVTV_REG_GPIO_DIR);
164}
165
166static struct v4l2_queryctrl gpio_ctrl_mute = {
167 .id = V4L2_CID_AUDIO_MUTE,
168 .type = V4L2_CTRL_TYPE_BOOLEAN,
169 .name = "Mute",
170 .minimum = 0,
171 .maximum = 1,
172 .step = 1,
173 .default_value = 1,
174 .flags = 0,
175};
176
177int ivtv_gpio(struct ivtv *itv, unsigned int command, void *arg)
178{
179 struct v4l2_tuner *tuner = arg;
180 struct v4l2_control *ctrl = arg;
181 struct v4l2_routing *route = arg;
182 u16 mask, data;
183
184 switch (command) {
185 case VIDIOC_INT_AUDIO_CLOCK_FREQ:
186 mask = itv->card->gpio_audio_freq.mask;
187 switch (*(u32 *)arg) {
188 case 32000:
189 data = itv->card->gpio_audio_freq.f32000;
190 break;
191 case 44100:
192 data = itv->card->gpio_audio_freq.f44100;
193 break;
194 case 48000:
195 default:
196 data = itv->card->gpio_audio_freq.f48000;
197 break;
198 }
199 break;
200
201 case VIDIOC_G_TUNER:
202 mask = itv->card->gpio_audio_detect.mask;
203 if (mask == 0 || (read_reg(IVTV_REG_GPIO_IN) & mask))
204 tuner->rxsubchans = V4L2_TUNER_MODE_STEREO |
205 V4L2_TUNER_MODE_LANG1 | V4L2_TUNER_MODE_LANG2;
206 else
207 tuner->rxsubchans = V4L2_TUNER_SUB_MONO;
208 return 0;
209
210 case VIDIOC_S_TUNER:
211 mask = itv->card->gpio_audio_mode.mask;
212 switch (tuner->audmode) {
213 case V4L2_TUNER_MODE_LANG1:
214 data = itv->card->gpio_audio_mode.lang1;
215 break;
216 case V4L2_TUNER_MODE_LANG2:
217 data = itv->card->gpio_audio_mode.lang2;
218 break;
219 case V4L2_TUNER_MODE_MONO:
220 data = itv->card->gpio_audio_mode.mono;
221 break;
222 case V4L2_TUNER_MODE_STEREO:
223 case V4L2_TUNER_MODE_LANG1_LANG2:
224 default:
225 data = itv->card->gpio_audio_mode.stereo;
226 break;
227 }
228 break;
229
230 case AUDC_SET_RADIO:
231 mask = itv->card->gpio_audio_input.mask;
232 data = itv->card->gpio_audio_input.radio;
233 break;
234
235 case VIDIOC_S_STD:
236 mask = itv->card->gpio_audio_input.mask;
237 data = itv->card->gpio_audio_input.tuner;
238 break;
239
240 case VIDIOC_INT_S_AUDIO_ROUTING:
241 if (route->input > 2)
242 return -EINVAL;
243 mask = itv->card->gpio_audio_input.mask;
244 switch (route->input) {
245 case 0:
246 data = itv->card->gpio_audio_input.tuner;
247 break;
248 case 1:
249 data = itv->card->gpio_audio_input.linein;
250 break;
251 case 2:
252 default:
253 data = itv->card->gpio_audio_input.radio;
254 break;
255 }
256 break;
257
258 case VIDIOC_G_CTRL:
259 if (ctrl->id != V4L2_CID_AUDIO_MUTE)
260 return -EINVAL;
261 mask = itv->card->gpio_audio_mute.mask;
262 data = itv->card->gpio_audio_mute.mute;
263 ctrl->value = (read_reg(IVTV_REG_GPIO_OUT) & mask) == data;
264 return 0;
265
266 case VIDIOC_S_CTRL:
267 if (ctrl->id != V4L2_CID_AUDIO_MUTE)
268 return -EINVAL;
269 mask = itv->card->gpio_audio_mute.mask;
270 data = ctrl->value ? itv->card->gpio_audio_mute.mute : 0;
271 break;
272
273 case VIDIOC_QUERYCTRL:
274 {
275 struct v4l2_queryctrl *qc = arg;
276
277 if (qc->id != V4L2_CID_AUDIO_MUTE)
278 return -EINVAL;
279 *qc = gpio_ctrl_mute;
280 return 0;
281 }
282
283 case VIDIOC_LOG_STATUS:
284 IVTV_INFO("GPIO status: DIR=0x%04x OUT=0x%04x IN=0x%04x\n",
285 read_reg(IVTV_REG_GPIO_DIR), read_reg(IVTV_REG_GPIO_OUT),
286 read_reg(IVTV_REG_GPIO_IN));
287 return 0;
288
289 case VIDIOC_INT_S_VIDEO_ROUTING:
290 if (route->input > 2) /* 0:Tuner 1:Composite 2:S-Video */
291 return -EINVAL;
292 mask = itv->card->gpio_video_input.mask;
293 if (route->input == 0)
294 data = itv->card->gpio_video_input.tuner;
295 else if (route->input == 1)
296 data = itv->card->gpio_video_input.composite;
297 else
298 data = itv->card->gpio_video_input.svideo;
299 break;
300
301 default:
302 return -EINVAL;
303 }
304 if (mask)
305 write_reg((read_reg(IVTV_REG_GPIO_OUT) & ~mask) | (data & mask), IVTV_REG_GPIO_OUT);
306 return 0;
307}
diff --git a/drivers/media/video/ivtv/ivtv-gpio.h b/drivers/media/video/ivtv/ivtv-gpio.h
new file mode 100644
index 000000000000..c301d2a39346
--- /dev/null
+++ b/drivers/media/video/ivtv/ivtv-gpio.h
@@ -0,0 +1,25 @@
1/*
2 gpio functions.
3 Copyright (C) 2004 Chris Kennedy <c@groovy.org>
4 Copyright (C) 2005-2007 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21/* GPIO stuff */
22void ivtv_gpio_init(struct ivtv *itv);
23void ivtv_reset_ir_gpio(struct ivtv *itv);
24int ivtv_reset_tuner_gpio(enum v4l2_tuner_type mode, void *priv, int ptr);
25int ivtv_gpio(struct ivtv *itv, unsigned int command, void *arg);
diff --git a/drivers/media/video/ivtv/ivtv-i2c.c b/drivers/media/video/ivtv/ivtv-i2c.c
new file mode 100644
index 000000000000..50624c6a62a5
--- /dev/null
+++ b/drivers/media/video/ivtv/ivtv-i2c.c
@@ -0,0 +1,748 @@
1/*
2 I2C functions
3 Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
4 Copyright (C) 2005-2007 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21/*
22 This file includes an i2c implementation that was reverse engineered
23 from the Hauppauge windows driver. Older ivtv versions used i2c-algo-bit,
24 which whilst fine under most circumstances, had trouble with the Zilog
25 CPU on the PVR-150 which handles IR functions (occasional inability to
26 communicate with the chip until it was reset) and also with the i2c
27 bus being completely unreachable when multiple PVR cards were present.
28
29 The implementation is very similar to i2c-algo-bit, but there are enough
30 subtle differences that the two are hard to merge. The general strategy
31 employed by i2c-algo-bit is to use udelay() to implement the timing
32 when putting out bits on the scl/sda lines. The general strategy taken
33 here is to poll the lines for state changes (see ivtv_waitscl and
34 ivtv_waitsda). In addition there are small delays at various locations
35 which poll the SCL line 5 times (ivtv_scldelay). I would guess that
36 since this is memory mapped I/O that the length of those delays is tied
37 to the PCI bus clock. There is some extra code to do with recovery
38 and retries. Since it is not known what causes the actual i2c problems
39 in the first place, the only goal if one was to attempt to use
40 i2c-algo-bit would be to try to make it follow the same code path.
41 This would be a lot of work, and I'm also not convinced that it would
42 provide a generic benefit to i2c-algo-bit. Therefore consider this
43 an engineering solution -- not pretty, but it works.
44
45 Some more general comments about what we are doing:
46
47 The i2c bus is a 2 wire serial bus, with clock (SCL) and data (SDA)
48 lines. To communicate on the bus (as a master, we don't act as a slave),
49 we first initiate a start condition (ivtv_start). We then write the
50 address of the device that we want to communicate with, along with a flag
51 that indicates whether this is a read or a write. The slave then issues
52 an ACK signal (ivtv_ack), which tells us that it is ready for reading /
53 writing. We then proceed with reading or writing (ivtv_read/ivtv_write),
54 and finally issue a stop condition (ivtv_stop) to make the bus available
55 to other masters.
56
57 There is an additional form of transaction where a write may be
58 immediately followed by a read. In this case, there is no intervening
59 stop condition. (Only the msp3400 chip uses this method of data transfer).
60 */
61
62#include "ivtv-driver.h"
63#include "ivtv-cards.h"
64#include "ivtv-gpio.h"
65#include "ivtv-i2c.h"
66
67#include <media/ir-kbd-i2c.h>
68
69/* i2c implementation for cx23415/6 chip, ivtv project.
70 * Author: Kevin Thayer (nufan_wfk at yahoo.com)
71 */
72/* i2c stuff */
73#define IVTV_REG_I2C_SETSCL_OFFSET 0x7000
74#define IVTV_REG_I2C_SETSDA_OFFSET 0x7004
75#define IVTV_REG_I2C_GETSCL_OFFSET 0x7008
76#define IVTV_REG_I2C_GETSDA_OFFSET 0x700c
77
78#ifndef I2C_ADAP_CLASS_TV_ANALOG
79#define I2C_ADAP_CLASS_TV_ANALOG I2C_CLASS_TV_ANALOG
80#endif /* I2C_ADAP_CLASS_TV_ANALOG */
81
82#define IVTV_CS53L32A_I2C_ADDR 0x11
83#define IVTV_CX25840_I2C_ADDR 0x44
84#define IVTV_SAA7115_I2C_ADDR 0x21
85#define IVTV_SAA7127_I2C_ADDR 0x44
86#define IVTV_SAA717x_I2C_ADDR 0x21
87#define IVTV_MSP3400_I2C_ADDR 0x40
88#define IVTV_HAUPPAUGE_I2C_ADDR 0x50
89#define IVTV_WM8739_I2C_ADDR 0x1a
90#define IVTV_WM8775_I2C_ADDR 0x1b
91#define IVTV_TEA5767_I2C_ADDR 0x60
92#define IVTV_UPD64031A_I2C_ADDR 0x12
93#define IVTV_UPD64083_I2C_ADDR 0x5c
94#define IVTV_TDA985X_I2C_ADDR 0x5b
95
96/* This array should match the IVTV_HW_ defines */
97static const u8 hw_driverids[] = {
98 I2C_DRIVERID_CX25840,
99 I2C_DRIVERID_SAA711X,
100 I2C_DRIVERID_SAA7127,
101 I2C_DRIVERID_MSP3400,
102 I2C_DRIVERID_TUNER,
103 I2C_DRIVERID_WM8775,
104 I2C_DRIVERID_CS53L32A,
105 I2C_DRIVERID_TVEEPROM,
106 I2C_DRIVERID_SAA711X,
107 I2C_DRIVERID_TVAUDIO,
108 I2C_DRIVERID_UPD64031A,
109 I2C_DRIVERID_UPD64083,
110 I2C_DRIVERID_SAA717X,
111 I2C_DRIVERID_WM8739,
112 0 /* IVTV_HW_GPIO dummy driver ID */
113};
114
115/* This array should match the IVTV_HW_ defines */
116static const char * const hw_drivernames[] = {
117 "cx2584x",
118 "saa7115",
119 "saa7127",
120 "msp3400",
121 "tuner",
122 "wm8775",
123 "cs53l32a",
124 "tveeprom",
125 "saa7114",
126 "tvaudio",
127 "upd64031a",
128 "upd64083",
129 "saa717x",
130 "wm8739",
131 "gpio",
132};
133
134static int attach_inform(struct i2c_client *client)
135{
136 struct ivtv *itv = (struct ivtv *)i2c_get_adapdata(client->adapter);
137 int i;
138
139 IVTV_DEBUG_I2C("i2c client attach\n");
140 for (i = 0; i < I2C_CLIENTS_MAX; i++) {
141 if (itv->i2c_clients[i] == NULL) {
142 itv->i2c_clients[i] = client;
143 break;
144 }
145 }
146 if (i == I2C_CLIENTS_MAX) {
147 IVTV_ERR("insufficient room for new I2C client!\n");
148 }
149 return 0;
150}
151
152static int detach_inform(struct i2c_client *client)
153{
154 int i;
155 struct ivtv *itv = (struct ivtv *)i2c_get_adapdata(client->adapter);
156
157 IVTV_DEBUG_I2C("i2c client detach\n");
158 for (i = 0; i < I2C_CLIENTS_MAX; i++) {
159 if (itv->i2c_clients[i] == client) {
160 itv->i2c_clients[i] = NULL;
161 break;
162 }
163 }
164 IVTV_DEBUG_I2C("i2c detach [client=%s,%s]\n",
165 client->name, (i < I2C_CLIENTS_MAX) ? "ok" : "failed");
166
167 return 0;
168}
169
170/* Set the serial clock line to the desired state */
171static void ivtv_setscl(struct ivtv *itv, int state)
172{
173 /* write them out */
174 /* write bits are inverted */
175 write_reg(~state, IVTV_REG_I2C_SETSCL_OFFSET);
176}
177
178/* Set the serial data line to the desired state */
179static void ivtv_setsda(struct ivtv *itv, int state)
180{
181 /* write them out */
182 /* write bits are inverted */
183 write_reg(~state & 1, IVTV_REG_I2C_SETSDA_OFFSET);
184}
185
186/* Read the serial clock line */
187static int ivtv_getscl(struct ivtv *itv)
188{
189 return read_reg(IVTV_REG_I2C_GETSCL_OFFSET) & 1;
190}
191
192/* Read the serial data line */
193static int ivtv_getsda(struct ivtv *itv)
194{
195 return read_reg(IVTV_REG_I2C_GETSDA_OFFSET) & 1;
196}
197
198/* Implement a short delay by polling the serial clock line */
199static void ivtv_scldelay(struct ivtv *itv)
200{
201 int i;
202
203 for (i = 0; i < 5; ++i)
204 ivtv_getscl(itv);
205}
206
207/* Wait for the serial clock line to become set to a specific value */
208static int ivtv_waitscl(struct ivtv *itv, int val)
209{
210 int i;
211
212 ivtv_scldelay(itv);
213 for (i = 0; i < 1000; ++i) {
214 if (ivtv_getscl(itv) == val)
215 return 1;
216 }
217 return 0;
218}
219
220/* Wait for the serial data line to become set to a specific value */
221static int ivtv_waitsda(struct ivtv *itv, int val)
222{
223 int i;
224
225 ivtv_scldelay(itv);
226 for (i = 0; i < 1000; ++i) {
227 if (ivtv_getsda(itv) == val)
228 return 1;
229 }
230 return 0;
231}
232
233/* Wait for the slave to issue an ACK */
234static int ivtv_ack(struct ivtv *itv)
235{
236 int ret = 0;
237
238 if (ivtv_getscl(itv) == 1) {
239 IVTV_DEBUG_I2C("SCL was high starting an ack\n");
240 ivtv_setscl(itv, 0);
241 if (!ivtv_waitscl(itv, 0)) {
242 IVTV_DEBUG_I2C("Could not set SCL low starting an ack\n");
243 return -EREMOTEIO;
244 }
245 }
246 ivtv_setsda(itv, 1);
247 ivtv_scldelay(itv);
248 ivtv_setscl(itv, 1);
249 if (!ivtv_waitsda(itv, 0)) {
250 IVTV_DEBUG_I2C("Slave did not ack\n");
251 ret = -EREMOTEIO;
252 }
253 ivtv_setscl(itv, 0);
254 if (!ivtv_waitscl(itv, 0)) {
255 IVTV_DEBUG_I2C("Failed to set SCL low after ACK\n");
256 ret = -EREMOTEIO;
257 }
258 return ret;
259}
260
261/* Write a single byte to the i2c bus and wait for the slave to ACK */
262static int ivtv_sendbyte(struct ivtv *itv, unsigned char byte)
263{
264 int i, bit;
265
266 IVTV_DEBUG_I2C("write %x\n",byte);
267 for (i = 0; i < 8; ++i, byte<<=1) {
268 ivtv_setscl(itv, 0);
269 if (!ivtv_waitscl(itv, 0)) {
270 IVTV_DEBUG_I2C("Error setting SCL low\n");
271 return -EREMOTEIO;
272 }
273 bit = (byte>>7)&1;
274 ivtv_setsda(itv, bit);
275 if (!ivtv_waitsda(itv, bit)) {
276 IVTV_DEBUG_I2C("Error setting SDA\n");
277 return -EREMOTEIO;
278 }
279 ivtv_setscl(itv, 1);
280 if (!ivtv_waitscl(itv, 1)) {
281 IVTV_DEBUG_I2C("Slave not ready for bit\n");
282 return -EREMOTEIO;
283 }
284 }
285 ivtv_setscl(itv, 0);
286 if (!ivtv_waitscl(itv, 0)) {
287 IVTV_DEBUG_I2C("Error setting SCL low\n");
288 return -EREMOTEIO;
289 }
290 return ivtv_ack(itv);
291}
292
293/* Read a byte from the i2c bus and send a NACK if applicable (i.e. for the
294 final byte) */
295static int ivtv_readbyte(struct ivtv *itv, unsigned char *byte, int nack)
296{
297 int i;
298
299 *byte = 0;
300
301 ivtv_setsda(itv, 1);
302 ivtv_scldelay(itv);
303 for (i = 0; i < 8; ++i) {
304 ivtv_setscl(itv, 0);
305 ivtv_scldelay(itv);
306 ivtv_setscl(itv, 1);
307 if (!ivtv_waitscl(itv, 1)) {
308 IVTV_DEBUG_I2C("Error setting SCL high\n");
309 return -EREMOTEIO;
310 }
311 *byte = ((*byte)<<1)|ivtv_getsda(itv);
312 }
313 ivtv_setscl(itv, 0);
314 ivtv_scldelay(itv);
315 ivtv_setsda(itv, nack);
316 ivtv_scldelay(itv);
317 ivtv_setscl(itv, 1);
318 ivtv_scldelay(itv);
319 ivtv_setscl(itv, 0);
320 ivtv_scldelay(itv);
321 IVTV_DEBUG_I2C("read %x\n",*byte);
322 return 0;
323}
324
325/* Issue a start condition on the i2c bus to alert slaves to prepare for
326 an address write */
327static int ivtv_start(struct ivtv *itv)
328{
329 int sda;
330
331 sda = ivtv_getsda(itv);
332 if (sda != 1) {
333 IVTV_DEBUG_I2C("SDA was low at start\n");
334 ivtv_setsda(itv, 1);
335 if (!ivtv_waitsda(itv, 1)) {
336 IVTV_DEBUG_I2C("SDA stuck low\n");
337 return -EREMOTEIO;
338 }
339 }
340 if (ivtv_getscl(itv) != 1) {
341 ivtv_setscl(itv, 1);
342 if (!ivtv_waitscl(itv, 1)) {
343 IVTV_DEBUG_I2C("SCL stuck low at start\n");
344 return -EREMOTEIO;
345 }
346 }
347 ivtv_setsda(itv, 0);
348 ivtv_scldelay(itv);
349 return 0;
350}
351
352/* Issue a stop condition on the i2c bus to release it */
353static int ivtv_stop(struct ivtv *itv)
354{
355 int i;
356
357 if (ivtv_getscl(itv) != 0) {
358 IVTV_DEBUG_I2C("SCL not low when stopping\n");
359 ivtv_setscl(itv, 0);
360 if (!ivtv_waitscl(itv, 0)) {
361 IVTV_DEBUG_I2C("SCL could not be set low\n");
362 }
363 }
364 ivtv_setsda(itv, 0);
365 ivtv_scldelay(itv);
366 ivtv_setscl(itv, 1);
367 if (!ivtv_waitscl(itv, 1)) {
368 IVTV_DEBUG_I2C("SCL could not be set high\n");
369 return -EREMOTEIO;
370 }
371 ivtv_scldelay(itv);
372 ivtv_setsda(itv, 1);
373 if (!ivtv_waitsda(itv, 1)) {
374 IVTV_DEBUG_I2C("resetting I2C\n");
375 for (i = 0; i < 16; ++i) {
376 ivtv_setscl(itv, 0);
377 ivtv_scldelay(itv);
378 ivtv_setscl(itv, 1);
379 ivtv_scldelay(itv);
380 ivtv_setsda(itv, 1);
381 }
382 ivtv_waitsda(itv, 1);
383 return -EREMOTEIO;
384 }
385 return 0;
386}
387
388/* Write a message to the given i2c slave. do_stop may be 0 to prevent
389 issuing the i2c stop condition (when following with a read) */
390static int ivtv_write(struct ivtv *itv, unsigned char addr, unsigned char *data, u32 len, int do_stop)
391{
392 int retry, ret = -EREMOTEIO;
393 u32 i;
394
395 for (retry = 0; ret != 0 && retry < 8; ++retry) {
396 ret = ivtv_start(itv);
397
398 if (ret == 0) {
399 ret = ivtv_sendbyte(itv, addr<<1);
400 for (i = 0; ret == 0 && i < len; ++i)
401 ret = ivtv_sendbyte(itv, data[i]);
402 }
403 if (ret != 0 || do_stop) {
404 ivtv_stop(itv);
405 }
406 }
407 if (ret)
408 IVTV_DEBUG_I2C("i2c write to %x failed\n", addr);
409 return ret;
410}
411
412/* Read data from the given i2c slave. A stop condition is always issued. */
413static int ivtv_read(struct ivtv *itv, unsigned char addr, unsigned char *data, u32 len)
414{
415 int retry, ret = -EREMOTEIO;
416 u32 i;
417
418 for (retry = 0; ret != 0 && retry < 8; ++retry) {
419 ret = ivtv_start(itv);
420 if (ret == 0)
421 ret = ivtv_sendbyte(itv, (addr << 1) | 1);
422 for (i = 0; ret == 0 && i < len; ++i) {
423 ret = ivtv_readbyte(itv, &data[i], i == len - 1);
424 }
425 ivtv_stop(itv);
426 }
427 if (ret)
428 IVTV_DEBUG_I2C("i2c read from %x failed\n", addr);
429 return ret;
430}
431
432/* Kernel i2c transfer implementation. Takes a number of messages to be read
433 or written. If a read follows a write, this will occur without an
434 intervening stop condition */
435static int ivtv_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, int num)
436{
437 struct ivtv *itv = i2c_get_adapdata(i2c_adap);
438 int retval;
439 int i;
440
441 mutex_lock(&itv->i2c_bus_lock);
442 for (i = retval = 0; retval == 0 && i < num; i++) {
443 if (msgs[i].flags & I2C_M_RD)
444 retval = ivtv_read(itv, msgs[i].addr, msgs[i].buf, msgs[i].len);
445 else {
446 /* if followed by a read, don't stop */
447 int stop = !(i + 1 < num && msgs[i + 1].flags == I2C_M_RD);
448
449 retval = ivtv_write(itv, msgs[i].addr, msgs[i].buf, msgs[i].len, stop);
450 }
451 }
452 mutex_unlock(&itv->i2c_bus_lock);
453 return retval ? retval : num;
454}
455
456/* Kernel i2c capabilities */
457static u32 ivtv_functionality(struct i2c_adapter *adap)
458{
459 return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
460}
461
462static struct i2c_algorithm ivtv_algo = {
463 .master_xfer = ivtv_xfer,
464 .functionality = ivtv_functionality,
465};
466
467/* template for our-bit banger */
468static struct i2c_adapter ivtv_i2c_adap_hw_template = {
469 .name = "ivtv i2c driver",
470 .id = I2C_HW_B_CX2341X,
471 .algo = &ivtv_algo,
472 .algo_data = NULL, /* filled from template */
473 .client_register = attach_inform,
474 .client_unregister = detach_inform,
475 .owner = THIS_MODULE,
476#ifdef I2C_ADAP_CLASS_TV_ANALOG
477 .class = I2C_ADAP_CLASS_TV_ANALOG,
478#endif
479};
480
481static void ivtv_setscl_old(void *data, int state)
482{
483 struct ivtv *itv = (struct ivtv *)data;
484
485 if (state)
486 itv->i2c_state |= 0x01;
487 else
488 itv->i2c_state &= ~0x01;
489
490 /* write them out */
491 /* write bits are inverted */
492 write_reg(~itv->i2c_state, IVTV_REG_I2C_SETSCL_OFFSET);
493}
494
495static void ivtv_setsda_old(void *data, int state)
496{
497 struct ivtv *itv = (struct ivtv *)data;
498
499 if (state)
500 itv->i2c_state |= 0x01;
501 else
502 itv->i2c_state &= ~0x01;
503
504 /* write them out */
505 /* write bits are inverted */
506 write_reg(~itv->i2c_state, IVTV_REG_I2C_SETSDA_OFFSET);
507}
508
509static int ivtv_getscl_old(void *data)
510{
511 struct ivtv *itv = (struct ivtv *)data;
512
513 return read_reg(IVTV_REG_I2C_GETSCL_OFFSET) & 1;
514}
515
516static int ivtv_getsda_old(void *data)
517{
518 struct ivtv *itv = (struct ivtv *)data;
519
520 return read_reg(IVTV_REG_I2C_GETSDA_OFFSET) & 1;
521}
522
523/* template for i2c-bit-algo */
524static struct i2c_adapter ivtv_i2c_adap_template = {
525 .name = "ivtv i2c driver",
526 .id = I2C_HW_B_CX2341X, /* algo-bit is OR'd with this */
527 .algo = NULL, /* set by i2c-algo-bit */
528 .algo_data = NULL, /* filled from template */
529 .client_register = attach_inform,
530 .client_unregister = detach_inform,
531 .owner = THIS_MODULE,
532#ifdef I2C_ADAP_CLASS_TV_ANALOG
533 .class = I2C_ADAP_CLASS_TV_ANALOG,
534#endif
535};
536
537static struct i2c_algo_bit_data ivtv_i2c_algo_template = {
538 NULL, /* ?? */
539 ivtv_setsda_old, /* setsda function */
540 ivtv_setscl_old, /* " */
541 ivtv_getsda_old, /* " */
542 ivtv_getscl_old, /* " */
543 10, /* udelay */
544 200 /* timeout */
545};
546
547static struct i2c_client ivtv_i2c_client_template = {
548 .name = "ivtv internal",
549};
550
551int ivtv_call_i2c_client(struct ivtv *itv, int addr, unsigned int cmd, void *arg)
552{
553 struct i2c_client *client;
554 int retval;
555 int i;
556
557 IVTV_DEBUG_I2C("call_i2c_client addr=%02x\n", addr);
558 for (i = 0; i < I2C_CLIENTS_MAX; i++) {
559 client = itv->i2c_clients[i];
560 if (client == NULL) {
561 continue;
562 }
563 if (client->driver->command == NULL) {
564 continue;
565 }
566 if (addr == client->addr) {
567 retval = client->driver->command(client, cmd, arg);
568 return retval;
569 }
570 }
571 if (cmd != VIDIOC_G_CHIP_IDENT)
572 IVTV_ERR("i2c addr 0x%02x not found for command 0x%x!\n", addr, cmd);
573 return -ENODEV;
574}
575
576/* Find the i2c device based on the driver ID and return
577 its i2c address or -ENODEV if no matching device was found. */
578static int ivtv_i2c_id_addr(struct ivtv *itv, u32 id)
579{
580 struct i2c_client *client;
581 int retval = -ENODEV;
582 int i;
583
584 for (i = 0; i < I2C_CLIENTS_MAX; i++) {
585 client = itv->i2c_clients[i];
586 if (client == NULL)
587 continue;
588 if (id == client->driver->id) {
589 retval = client->addr;
590 break;
591 }
592 }
593 return retval;
594}
595
596/* Find the i2c device name matching the DRIVERID */
597static const char *ivtv_i2c_id_name(u32 id)
598{
599 int i;
600
601 for (i = 0; i < ARRAY_SIZE(hw_driverids); i++)
602 if (hw_driverids[i] == id)
603 return hw_drivernames[i];
604 return "unknown device";
605}
606
607/* Find the i2c device name matching the IVTV_HW_ flag */
608static const char *ivtv_i2c_hw_name(u32 hw)
609{
610 int i;
611
612 for (i = 0; i < ARRAY_SIZE(hw_driverids); i++)
613 if (1 << i == hw)
614 return hw_drivernames[i];
615 return "unknown device";
616}
617
618/* Find the i2c device matching the IVTV_HW_ flag and return
619 its i2c address or -ENODEV if no matching device was found. */
620int ivtv_i2c_hw_addr(struct ivtv *itv, u32 hw)
621{
622 int i;
623
624 for (i = 0; i < ARRAY_SIZE(hw_driverids); i++)
625 if (1 << i == hw)
626 return ivtv_i2c_id_addr(itv, hw_driverids[i]);
627 return -ENODEV;
628}
629
630/* Calls i2c device based on IVTV_HW_ flag. If hw == 0, then do nothing.
631 If hw == IVTV_HW_GPIO then call the gpio handler. */
632int ivtv_i2c_hw(struct ivtv *itv, u32 hw, unsigned int cmd, void *arg)
633{
634 int addr;
635
636 if (hw == IVTV_HW_GPIO)
637 return ivtv_gpio(itv, cmd, arg);
638 if (hw == 0)
639 return 0;
640
641 addr = ivtv_i2c_hw_addr(itv, hw);
642 if (addr < 0) {
643 IVTV_ERR("i2c hardware 0x%08x (%s) not found for command 0x%x!\n",
644 hw, ivtv_i2c_hw_name(hw), cmd);
645 return addr;
646 }
647 return ivtv_call_i2c_client(itv, addr, cmd, arg);
648}
649
650/* Calls i2c device based on I2C driver ID. */
651int ivtv_i2c_id(struct ivtv *itv, u32 id, unsigned int cmd, void *arg)
652{
653 int addr;
654
655 addr = ivtv_i2c_id_addr(itv, id);
656 if (addr < 0) {
657 if (cmd != VIDIOC_G_CHIP_IDENT)
658 IVTV_ERR("i2c ID 0x%08x (%s) not found for command 0x%x!\n",
659 id, ivtv_i2c_id_name(id), cmd);
660 return addr;
661 }
662 return ivtv_call_i2c_client(itv, addr, cmd, arg);
663}
664
665int ivtv_cx25840(struct ivtv *itv, unsigned int cmd, void *arg)
666{
667 return ivtv_call_i2c_client(itv, IVTV_CX25840_I2C_ADDR, cmd, arg);
668}
669
670int ivtv_saa7115(struct ivtv *itv, unsigned int cmd, void *arg)
671{
672 return ivtv_call_i2c_client(itv, IVTV_SAA7115_I2C_ADDR, cmd, arg);
673}
674
675int ivtv_saa7127(struct ivtv *itv, unsigned int cmd, void *arg)
676{
677 return ivtv_call_i2c_client(itv, IVTV_SAA7127_I2C_ADDR, cmd, arg);
678}
679
680int ivtv_saa717x(struct ivtv *itv, unsigned int cmd, void *arg)
681{
682 return ivtv_call_i2c_client(itv, IVTV_SAA717x_I2C_ADDR, cmd, arg);
683}
684
685int ivtv_upd64031a(struct ivtv *itv, unsigned int cmd, void *arg)
686{
687 return ivtv_call_i2c_client(itv, IVTV_UPD64031A_I2C_ADDR, cmd, arg);
688}
689
690int ivtv_upd64083(struct ivtv *itv, unsigned int cmd, void *arg)
691{
692 return ivtv_call_i2c_client(itv, IVTV_UPD64083_I2C_ADDR, cmd, arg);
693}
694
695/* broadcast cmd for all I2C clients and for the gpio subsystem */
696void ivtv_call_i2c_clients(struct ivtv *itv, unsigned int cmd, void *arg)
697{
698 if (itv->i2c_adap.algo == NULL) {
699 IVTV_ERR("adapter is not set");
700 return;
701 }
702 i2c_clients_command(&itv->i2c_adap, cmd, arg);
703 if (itv->hw_flags & IVTV_HW_GPIO)
704 ivtv_gpio(itv, cmd, arg);
705}
706
707/* init + register i2c algo-bit adapter */
708int __devinit init_ivtv_i2c(struct ivtv *itv)
709{
710 IVTV_DEBUG_I2C("i2c init\n");
711
712 if (itv->options.newi2c > 0) {
713 memcpy(&itv->i2c_adap, &ivtv_i2c_adap_hw_template,
714 sizeof(struct i2c_adapter));
715 } else {
716 memcpy(&itv->i2c_adap, &ivtv_i2c_adap_template,
717 sizeof(struct i2c_adapter));
718 memcpy(&itv->i2c_algo, &ivtv_i2c_algo_template,
719 sizeof(struct i2c_algo_bit_data));
720 itv->i2c_algo.data = itv;
721 itv->i2c_adap.algo_data = &itv->i2c_algo;
722 }
723
724 sprintf(itv->i2c_adap.name + strlen(itv->i2c_adap.name), " #%d",
725 itv->num);
726 i2c_set_adapdata(&itv->i2c_adap, itv);
727
728 memcpy(&itv->i2c_client, &ivtv_i2c_client_template,
729 sizeof(struct i2c_client));
730 itv->i2c_client.adapter = &itv->i2c_adap;
731 itv->i2c_adap.dev.parent = &itv->dev->dev;
732
733 IVTV_DEBUG_I2C("setting scl and sda to 1\n");
734 ivtv_setscl(itv, 1);
735 ivtv_setsda(itv, 1);
736
737 if (itv->options.newi2c > 0)
738 return i2c_add_adapter(&itv->i2c_adap);
739 else
740 return i2c_bit_add_bus(&itv->i2c_adap);
741}
742
743void __devexit exit_ivtv_i2c(struct ivtv *itv)
744{
745 IVTV_DEBUG_I2C("i2c exit\n");
746
747 i2c_del_adapter(&itv->i2c_adap);
748}
diff --git a/drivers/media/video/ivtv/ivtv-i2c.h b/drivers/media/video/ivtv/ivtv-i2c.h
new file mode 100644
index 000000000000..5d210adb5c52
--- /dev/null
+++ b/drivers/media/video/ivtv/ivtv-i2c.h
@@ -0,0 +1,36 @@
1/*
2 I2C functions
3 Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
4 Copyright (C) 2005-2007 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21int ivtv_cx25840(struct ivtv *itv, unsigned int cmd, void *arg);
22int ivtv_saa7115(struct ivtv *itv, unsigned int cmd, void *arg);
23int ivtv_saa7127(struct ivtv *itv, unsigned int cmd, void *arg);
24int ivtv_saa717x(struct ivtv *itv, unsigned int cmd, void *arg);
25int ivtv_upd64031a(struct ivtv *itv, unsigned int cmd, void *arg);
26int ivtv_upd64083(struct ivtv *itv, unsigned int cmd, void *arg);
27
28int ivtv_i2c_hw_addr(struct ivtv *itv, u32 hw);
29int ivtv_i2c_hw(struct ivtv *itv, u32 hw, unsigned int cmd, void *arg);
30int ivtv_i2c_id(struct ivtv *itv, u32 id, unsigned int cmd, void *arg);
31int ivtv_call_i2c_client(struct ivtv *itv, int addr, unsigned int cmd, void *arg);
32void ivtv_call_i2c_clients(struct ivtv *itv, unsigned int cmd, void *arg);
33
34/* init + register i2c algo-bit adapter */
35int __devinit init_ivtv_i2c(struct ivtv *itv);
36void __devexit exit_ivtv_i2c(struct ivtv *itv);
diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c
new file mode 100644
index 000000000000..794a6a02f82f
--- /dev/null
+++ b/drivers/media/video/ivtv/ivtv-ioctl.c
@@ -0,0 +1,1567 @@
1/*
2 ioctl system call
3 Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
4 Copyright (C) 2005-2007 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#include "ivtv-driver.h"
22#include "ivtv-version.h"
23#include "ivtv-mailbox.h"
24#include "ivtv-i2c.h"
25#include "ivtv-queue.h"
26#include "ivtv-fileops.h"
27#include "ivtv-vbi.h"
28#include "ivtv-audio.h"
29#include "ivtv-video.h"
30#include "ivtv-streams.h"
31#include "ivtv-yuv.h"
32#include "ivtv-ioctl.h"
33#include "ivtv-gpio.h"
34#include "ivtv-controls.h"
35#include "ivtv-cards.h"
36#include <media/saa7127.h>
37#include <media/tveeprom.h>
38#include <media/v4l2-chip-ident.h>
39#include <linux/dvb/audio.h>
40#include <linux/i2c-id.h>
41
42u16 service2vbi(int type)
43{
44 switch (type) {
45 case V4L2_SLICED_TELETEXT_B:
46 return IVTV_SLICED_TYPE_TELETEXT_B;
47 case V4L2_SLICED_CAPTION_525:
48 return IVTV_SLICED_TYPE_CAPTION_525;
49 case V4L2_SLICED_WSS_625:
50 return IVTV_SLICED_TYPE_WSS_625;
51 case V4L2_SLICED_VPS:
52 return IVTV_SLICED_TYPE_VPS;
53 default:
54 return 0;
55 }
56}
57
58static int valid_service_line(int field, int line, int is_pal)
59{
60 return (is_pal && line >= 6 && (line != 23 || field == 0)) ||
61 (!is_pal && line >= 10 && line < 22);
62}
63
64static u16 select_service_from_set(int field, int line, u16 set, int is_pal)
65{
66 u16 valid_set = (is_pal ? V4L2_SLICED_VBI_625 : V4L2_SLICED_VBI_525);
67 int i;
68
69 set = set & valid_set;
70 if (set == 0 || !valid_service_line(field, line, is_pal)) {
71 return 0;
72 }
73 if (!is_pal) {
74 if (line == 21 && (set & V4L2_SLICED_CAPTION_525))
75 return V4L2_SLICED_CAPTION_525;
76 }
77 else {
78 if (line == 16 && field == 0 && (set & V4L2_SLICED_VPS))
79 return V4L2_SLICED_VPS;
80 if (line == 23 && field == 0 && (set & V4L2_SLICED_WSS_625))
81 return V4L2_SLICED_WSS_625;
82 if (line == 23)
83 return 0;
84 }
85 for (i = 0; i < 32; i++) {
86 if ((1 << i) & set)
87 return 1 << i;
88 }
89 return 0;
90}
91
92void expand_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal)
93{
94 u16 set = fmt->service_set;
95 int f, l;
96
97 fmt->service_set = 0;
98 for (f = 0; f < 2; f++) {
99 for (l = 0; l < 24; l++) {
100 fmt->service_lines[f][l] = select_service_from_set(f, l, set, is_pal);
101 }
102 }
103}
104
105static int check_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal)
106{
107 int f, l;
108 u16 set = 0;
109
110 for (f = 0; f < 2; f++) {
111 for (l = 0; l < 24; l++) {
112 fmt->service_lines[f][l] = select_service_from_set(f, l, fmt->service_lines[f][l], is_pal);
113 set |= fmt->service_lines[f][l];
114 }
115 }
116 return set != 0;
117}
118
119u16 get_service_set(struct v4l2_sliced_vbi_format *fmt)
120{
121 int f, l;
122 u16 set = 0;
123
124 for (f = 0; f < 2; f++) {
125 for (l = 0; l < 24; l++) {
126 set |= fmt->service_lines[f][l];
127 }
128 }
129 return set;
130}
131
132static const struct {
133 v4l2_std_id std;
134 char *name;
135} enum_stds[] = {
136 { V4L2_STD_PAL_BG | V4L2_STD_PAL_H, "PAL-BGH" },
137 { V4L2_STD_PAL_DK, "PAL-DK" },
138 { V4L2_STD_PAL_I, "PAL-I" },
139 { V4L2_STD_PAL_M, "PAL-M" },
140 { V4L2_STD_PAL_N, "PAL-N" },
141 { V4L2_STD_PAL_Nc, "PAL-Nc" },
142 { V4L2_STD_SECAM_B | V4L2_STD_SECAM_G | V4L2_STD_SECAM_H, "SECAM-BGH" },
143 { V4L2_STD_SECAM_DK, "SECAM-DK" },
144 { V4L2_STD_SECAM_L, "SECAM-L" },
145 { V4L2_STD_SECAM_LC, "SECAM-L'" },
146 { V4L2_STD_NTSC_M, "NTSC-M" },
147 { V4L2_STD_NTSC_M_JP, "NTSC-J" },
148 { V4L2_STD_NTSC_M_KR, "NTSC-K" },
149};
150
151static const struct v4l2_standard ivtv_std_60hz =
152{
153 .frameperiod = {.numerator = 1001, .denominator = 30000},
154 .framelines = 525,
155};
156
157static const struct v4l2_standard ivtv_std_50hz =
158{
159 .frameperiod = {.numerator = 1, .denominator = 25},
160 .framelines = 625,
161};
162
163void ivtv_set_osd_alpha(struct ivtv *itv)
164{
165 ivtv_vapi(itv, CX2341X_OSD_SET_GLOBAL_ALPHA, 3,
166 itv->osd_global_alpha_state, itv->osd_global_alpha, !itv->osd_local_alpha_state);
167 ivtv_vapi(itv, CX2341X_OSD_SET_CHROMA_KEY, 2, itv->osd_color_key_state, itv->osd_color_key);
168}
169
170int ivtv_set_speed(struct ivtv *itv, int speed)
171{
172 u32 data[CX2341X_MBOX_MAX_DATA];
173 struct ivtv_stream *s;
174 int single_step = (speed == 1 || speed == -1);
175 DEFINE_WAIT(wait);
176
177 if (speed == 0) speed = 1000;
178
179 /* No change? */
180 if (speed == itv->speed && !single_step)
181 return 0;
182
183 s = &itv->streams[IVTV_DEC_STREAM_TYPE_MPG];
184
185 if (single_step && (speed < 0) == (itv->speed < 0)) {
186 /* Single step video and no need to change direction */
187 ivtv_vapi(itv, CX2341X_DEC_STEP_VIDEO, 1, 0);
188 itv->speed = speed;
189 return 0;
190 }
191 if (single_step)
192 /* Need to change direction */
193 speed = speed < 0 ? -1000 : 1000;
194
195 data[0] = (speed > 1000 || speed < -1000) ? 0x80000000 : 0;
196 data[0] |= (speed > 1000 || speed < -1500) ? 0x40000000 : 0;
197 data[1] = (speed < 0);
198 data[2] = speed < 0 ? 3 : 7;
199 data[3] = itv->params.video_b_frames;
200 data[4] = (speed == 1500 || speed == 500) ? itv->speed_mute_audio : 0;
201 data[5] = 0;
202 data[6] = 0;
203
204 if (speed == 1500 || speed == -1500) data[0] |= 1;
205 else if (speed == 2000 || speed == -2000) data[0] |= 2;
206 else if (speed > -1000 && speed < 0) data[0] |= (-1000 / speed);
207 else if (speed < 1000 && speed > 0) data[0] |= (1000 / speed);
208
209 /* If not decoding, just change speed setting */
210 if (atomic_read(&itv->decoding) > 0) {
211 int got_sig = 0;
212
213 /* Stop all DMA and decoding activity */
214 ivtv_vapi(itv, CX2341X_DEC_PAUSE_PLAYBACK, 1, 0);
215
216 /* Wait for any DMA to finish */
217 prepare_to_wait(&itv->dma_waitq, &wait, TASK_INTERRUPTIBLE);
218 while (itv->i_flags & IVTV_F_I_DMA) {
219 got_sig = signal_pending(current);
220 if (got_sig)
221 break;
222 got_sig = 0;
223 schedule();
224 }
225 finish_wait(&itv->dma_waitq, &wait);
226 if (got_sig)
227 return -EINTR;
228
229 /* Change Speed safely */
230 ivtv_api(itv, CX2341X_DEC_SET_PLAYBACK_SPEED, 7, data);
231 IVTV_DEBUG_INFO("Setting Speed to 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n",
232 data[0], data[1], data[2], data[3], data[4], data[5], data[6]);
233 }
234 if (single_step) {
235 speed = (speed < 0) ? -1 : 1;
236 ivtv_vapi(itv, CX2341X_DEC_STEP_VIDEO, 1, 0);
237 }
238 itv->speed = speed;
239 return 0;
240}
241
242static int ivtv_validate_speed(int cur_speed, int new_speed)
243{
244 int fact = new_speed < 0 ? -1 : 1;
245 int s;
246
247 if (new_speed < 0) new_speed = -new_speed;
248 if (cur_speed < 0) cur_speed = -cur_speed;
249
250 if (cur_speed <= new_speed) {
251 if (new_speed > 1500) return fact * 2000;
252 if (new_speed > 1000) return fact * 1500;
253 }
254 else {
255 if (new_speed >= 2000) return fact * 2000;
256 if (new_speed >= 1500) return fact * 1500;
257 if (new_speed >= 1000) return fact * 1000;
258 }
259 if (new_speed == 0) return 1000;
260 if (new_speed == 1 || new_speed == 1000) return fact * new_speed;
261
262 s = new_speed;
263 new_speed = 1000 / new_speed;
264 if (1000 / cur_speed == new_speed)
265 new_speed += (cur_speed < s) ? -1 : 1;
266 if (new_speed > 60) return 1000 / (fact * 60);
267 return 1000 / (fact * new_speed);
268}
269
270static int ivtv_video_command(struct ivtv *itv, struct ivtv_open_id *id,
271 struct video_command *vc, int try)
272{
273 struct ivtv_stream *s = &itv->streams[IVTV_DEC_STREAM_TYPE_MPG];
274
275 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
276 return -EINVAL;
277
278 switch (vc->cmd) {
279 case VIDEO_CMD_PLAY: {
280 vc->flags = 0;
281 vc->play.speed = ivtv_validate_speed(itv->speed, vc->play.speed);
282 if (vc->play.speed < 0)
283 vc->play.format = VIDEO_PLAY_FMT_GOP;
284 if (try) break;
285
286 if (ivtv_set_output_mode(itv, OUT_MPG) != OUT_MPG)
287 return -EBUSY;
288 return ivtv_start_decoding(id, vc->play.speed);
289 }
290
291 case VIDEO_CMD_STOP:
292 vc->flags &= VIDEO_CMD_STOP_IMMEDIATELY|VIDEO_CMD_STOP_TO_BLACK;
293 if (vc->flags & VIDEO_CMD_STOP_IMMEDIATELY)
294 vc->stop.pts = 0;
295 if (try) break;
296 if (atomic_read(&itv->decoding) == 0)
297 return 0;
298 if (itv->output_mode != OUT_MPG)
299 return -EBUSY;
300
301 itv->output_mode = OUT_NONE;
302 return ivtv_stop_v4l2_decode_stream(s, vc->flags, vc->stop.pts);
303
304 case VIDEO_CMD_FREEZE:
305 vc->flags &= VIDEO_CMD_FREEZE_TO_BLACK;
306 if (try) break;
307 if (itv->output_mode != OUT_MPG)
308 return -EBUSY;
309 if (atomic_read(&itv->decoding) > 0) {
310 ivtv_vapi(itv, CX2341X_DEC_PAUSE_PLAYBACK, 1,
311 (vc->flags & VIDEO_CMD_FREEZE_TO_BLACK) ? 1 : 0);
312 }
313 break;
314
315 case VIDEO_CMD_CONTINUE:
316 vc->flags = 0;
317 if (try) break;
318 if (itv->output_mode != OUT_MPG)
319 return -EBUSY;
320 if (atomic_read(&itv->decoding) > 0) {
321 ivtv_vapi(itv, CX2341X_DEC_START_PLAYBACK, 2, 0, 0);
322 }
323 break;
324
325 default:
326 return -EINVAL;
327 }
328 return 0;
329}
330
331static int ivtv_itvc(struct ivtv *itv, unsigned int cmd, void *arg)
332{
333 struct v4l2_register *regs = arg;
334 unsigned long flags;
335 volatile u8 __iomem *reg_start;
336
337 if (!capable(CAP_SYS_ADMIN))
338 return -EPERM;
339 if (regs->reg >= IVTV_REG_OFFSET && regs->reg < IVTV_REG_OFFSET + IVTV_REG_SIZE)
340 reg_start = itv->reg_mem - IVTV_REG_OFFSET;
341 else if (itv->has_cx23415 && regs->reg >= IVTV_DECODER_OFFSET &&
342 regs->reg < IVTV_DECODER_OFFSET + IVTV_DECODER_SIZE)
343 reg_start = itv->dec_mem - IVTV_DECODER_OFFSET;
344 else if (regs->reg >= 0 && regs->reg < IVTV_ENCODER_SIZE)
345 reg_start = itv->enc_mem;
346 else
347 return -EINVAL;
348
349 spin_lock_irqsave(&ivtv_cards_lock, flags);
350 if (cmd == VIDIOC_DBG_G_REGISTER) {
351 regs->val = readl(regs->reg + reg_start);
352 } else {
353 writel(regs->val, regs->reg + reg_start);
354 }
355 spin_unlock_irqrestore(&ivtv_cards_lock, flags);
356 return 0;
357}
358
359static int ivtv_get_fmt(struct ivtv *itv, int streamtype, struct v4l2_format *fmt)
360{
361 switch (fmt->type) {
362 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
363 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
364 return -EINVAL;
365 fmt->fmt.pix.left = itv->main_rect.left;
366 fmt->fmt.pix.top = itv->main_rect.top;
367 fmt->fmt.pix.width = itv->main_rect.width;
368 fmt->fmt.pix.height = itv->main_rect.height;
369 fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
370 fmt->fmt.pix.field = V4L2_FIELD_INTERLACED;
371 if (itv->output_mode == OUT_UDMA_YUV) {
372 switch (itv->yuv_info.lace_mode & IVTV_YUV_MODE_MASK) {
373 case IVTV_YUV_MODE_INTERLACED:
374 fmt->fmt.pix.field = (itv->yuv_info.lace_mode & IVTV_YUV_SYNC_MASK) ?
375 V4L2_FIELD_INTERLACED_BT : V4L2_FIELD_INTERLACED_TB;
376 break;
377 case IVTV_YUV_MODE_PROGRESSIVE:
378 fmt->fmt.pix.field = V4L2_FIELD_NONE;
379 break;
380 default:
381 fmt->fmt.pix.field = V4L2_FIELD_ANY;
382 break;
383 }
384 fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_HM12;
385 /* YUV size is (Y=(h*w) + UV=(h*(w/2))) */
386 fmt->fmt.pix.sizeimage =
387 fmt->fmt.pix.height * fmt->fmt.pix.width +
388 fmt->fmt.pix.height * (fmt->fmt.pix.width / 2);
389 }
390 else if (itv->output_mode == OUT_YUV ||
391 streamtype == IVTV_ENC_STREAM_TYPE_YUV ||
392 streamtype == IVTV_DEC_STREAM_TYPE_YUV) {
393 fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_HM12;
394 /* YUV size is (Y=(h*w) + UV=(h*(w/2))) */
395 fmt->fmt.pix.sizeimage =
396 fmt->fmt.pix.height * fmt->fmt.pix.width +
397 fmt->fmt.pix.height * (fmt->fmt.pix.width / 2);
398 } else {
399 fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
400 fmt->fmt.pix.sizeimage = 128 * 1024;
401 }
402 break;
403
404 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
405 fmt->fmt.pix.left = 0;
406 fmt->fmt.pix.top = 0;
407 fmt->fmt.pix.width = itv->params.width;
408 fmt->fmt.pix.height = itv->params.height;
409 fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
410 fmt->fmt.pix.field = V4L2_FIELD_INTERLACED;
411 if (streamtype == IVTV_ENC_STREAM_TYPE_YUV ||
412 streamtype == IVTV_DEC_STREAM_TYPE_YUV) {
413 fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_HM12;
414 /* YUV size is (Y=(h*w) + UV=(h*(w/2))) */
415 fmt->fmt.pix.sizeimage =
416 fmt->fmt.pix.height * fmt->fmt.pix.width +
417 fmt->fmt.pix.height * (fmt->fmt.pix.width / 2);
418 } else {
419 fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
420 fmt->fmt.pix.sizeimage = 128 * 1024;
421 }
422 break;
423
424 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
425 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
426 return -EINVAL;
427 fmt->fmt.win.chromakey = itv->osd_color_key;
428 fmt->fmt.win.global_alpha = itv->osd_global_alpha;
429 break;
430
431 case V4L2_BUF_TYPE_VBI_CAPTURE:
432 fmt->fmt.vbi.sampling_rate = 27000000;
433 fmt->fmt.vbi.offset = 248;
434 fmt->fmt.vbi.samples_per_line = itv->vbi.raw_decoder_line_size - 4;
435 fmt->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY;
436 fmt->fmt.vbi.start[0] = itv->vbi.start[0];
437 fmt->fmt.vbi.start[1] = itv->vbi.start[1];
438 fmt->fmt.vbi.count[0] = fmt->fmt.vbi.count[1] = itv->vbi.count;
439 break;
440
441 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
442 {
443 struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
444
445 if (!(itv->v4l2_cap & V4L2_CAP_SLICED_VBI_OUTPUT))
446 return -EINVAL;
447 vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36;
448 memset(vbifmt->reserved, 0, sizeof(vbifmt->reserved));
449 memset(vbifmt->service_lines, 0, sizeof(vbifmt->service_lines));
450 if (itv->is_60hz) {
451 vbifmt->service_lines[0][21] = V4L2_SLICED_CAPTION_525;
452 vbifmt->service_lines[1][21] = V4L2_SLICED_CAPTION_525;
453 } else {
454 vbifmt->service_lines[0][23] = V4L2_SLICED_WSS_625;
455 vbifmt->service_lines[0][16] = V4L2_SLICED_VPS;
456 }
457 vbifmt->service_set = get_service_set(vbifmt);
458 break;
459 }
460
461 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
462 {
463 struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
464
465 vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36;
466 memset(vbifmt->reserved, 0, sizeof(vbifmt->reserved));
467 memset(vbifmt->service_lines, 0, sizeof(vbifmt->service_lines));
468
469 if (streamtype == IVTV_DEC_STREAM_TYPE_VBI) {
470 vbifmt->service_set = itv->is_50hz ? V4L2_SLICED_VBI_625 :
471 V4L2_SLICED_VBI_525;
472 expand_service_set(vbifmt, itv->is_50hz);
473 break;
474 }
475
476 itv->video_dec_func(itv, VIDIOC_G_FMT, fmt);
477 vbifmt->service_set = get_service_set(vbifmt);
478 break;
479 }
480 case V4L2_BUF_TYPE_VBI_OUTPUT:
481 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
482 default:
483 return -EINVAL;
484 }
485 return 0;
486}
487
488static int ivtv_try_or_set_fmt(struct ivtv *itv, int streamtype,
489 struct v4l2_format *fmt, int set_fmt)
490{
491 struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
492 u16 set;
493
494 if (fmt->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
495 struct v4l2_rect r;
496 int field;
497
498 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
499 return -EINVAL;
500 field = fmt->fmt.pix.field;
501 r.top = fmt->fmt.pix.top;
502 r.left = fmt->fmt.pix.left;
503 r.width = fmt->fmt.pix.width;
504 r.height = fmt->fmt.pix.height;
505 ivtv_get_fmt(itv, streamtype, fmt);
506 if (itv->output_mode != OUT_UDMA_YUV) {
507 /* TODO: would setting the rect also be valid for this mode? */
508 fmt->fmt.pix.top = r.top;
509 fmt->fmt.pix.left = r.left;
510 fmt->fmt.pix.width = r.width;
511 fmt->fmt.pix.height = r.height;
512 }
513 if (itv->output_mode == OUT_UDMA_YUV) {
514 /* TODO: add checks for validity */
515 fmt->fmt.pix.field = field;
516 }
517 if (set_fmt) {
518 if (itv->output_mode == OUT_UDMA_YUV) {
519 switch (field) {
520 case V4L2_FIELD_NONE:
521 itv->yuv_info.lace_mode = IVTV_YUV_MODE_PROGRESSIVE;
522 break;
523 case V4L2_FIELD_ANY:
524 itv->yuv_info.lace_mode = IVTV_YUV_MODE_AUTO;
525 break;
526 case V4L2_FIELD_INTERLACED_BT:
527 itv->yuv_info.lace_mode =
528 IVTV_YUV_MODE_INTERLACED|IVTV_YUV_SYNC_ODD;
529 break;
530 case V4L2_FIELD_INTERLACED_TB:
531 default:
532 itv->yuv_info.lace_mode = IVTV_YUV_MODE_INTERLACED;
533 break;
534 }
535 itv->yuv_info.lace_sync_field = (itv->yuv_info.lace_mode & IVTV_YUV_SYNC_MASK) == IVTV_YUV_SYNC_EVEN ? 0 : 1;
536
537 /* Force update of yuv registers */
538 itv->yuv_info.yuv_forced_update = 1;
539 return 0;
540 }
541 if (!ivtv_vapi(itv, CX2341X_OSD_SET_FRAMEBUFFER_WINDOW, 4,
542 r.width, r.height, r.left, r.top))
543 itv->main_rect = r;
544 else
545 return -EINVAL;
546 }
547 return 0;
548 }
549
550 if (fmt->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY) {
551 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
552 return -EINVAL;
553 if (set_fmt) {
554 itv->osd_color_key = fmt->fmt.win.chromakey;
555 itv->osd_global_alpha = fmt->fmt.win.global_alpha;
556 ivtv_set_osd_alpha(itv);
557 }
558 return 0;
559 }
560
561 /* set window size */
562 if (fmt->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
563 int w = fmt->fmt.pix.width;
564 int h = fmt->fmt.pix.height;
565
566 if (w > 720) w = 720;
567 else if (w < 1) w = 1;
568 if (h > (itv->is_50hz ? 576 : 480)) h = (itv->is_50hz ? 576 : 480);
569 else if (h < 2) h = 2;
570 ivtv_get_fmt(itv, streamtype, fmt);
571 fmt->fmt.pix.width = w;
572 fmt->fmt.pix.height = h;
573
574 if (!set_fmt || (itv->params.width == w && itv->params.height == h))
575 return 0;
576 if (atomic_read(&itv->capturing) > 0)
577 return -EBUSY;
578
579 itv->params.width = w;
580 itv->params.height = h;
581 if (w != 720 || h != (itv->is_50hz ? 576 : 480))
582 itv->params.video_temporal_filter = 0;
583 else
584 itv->params.video_temporal_filter = 8;
585 itv->video_dec_func(itv, VIDIOC_S_FMT, fmt);
586 return ivtv_get_fmt(itv, streamtype, fmt);
587 }
588
589 /* set raw VBI format */
590 if (fmt->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
591 if (set_fmt && streamtype == IVTV_ENC_STREAM_TYPE_VBI &&
592 itv->vbi.sliced_in->service_set &&
593 atomic_read(&itv->capturing) > 0) {
594 return -EBUSY;
595 }
596 if (set_fmt) {
597 itv->vbi.sliced_in->service_set = 0;
598 itv->video_dec_func(itv, VIDIOC_S_FMT, &itv->vbi.in);
599 }
600 return ivtv_get_fmt(itv, streamtype, fmt);
601 }
602
603 /* set sliced VBI output
604 In principle the user could request that only certain
605 VBI types are output and that the others are ignored.
606 I.e., suppress CC in the even fields or only output
607 WSS and no VPS. Currently though there is no choice. */
608 if (fmt->type == V4L2_BUF_TYPE_SLICED_VBI_OUTPUT)
609 return ivtv_get_fmt(itv, streamtype, fmt);
610
611 /* any else but sliced VBI capture is an error */
612 if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE)
613 return -EINVAL;
614
615 if (streamtype == IVTV_DEC_STREAM_TYPE_VBI)
616 return ivtv_get_fmt(itv, streamtype, fmt);
617
618 /* set sliced VBI capture format */
619 vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36;
620 memset(vbifmt->reserved, 0, sizeof(vbifmt->reserved));
621
622 if (vbifmt->service_set)
623 expand_service_set(vbifmt, itv->is_50hz);
624 set = check_service_set(vbifmt, itv->is_50hz);
625 vbifmt->service_set = get_service_set(vbifmt);
626
627 if (!set_fmt)
628 return 0;
629 if (set == 0)
630 return -EINVAL;
631 if (atomic_read(&itv->capturing) > 0 && itv->vbi.sliced_in->service_set == 0) {
632 return -EBUSY;
633 }
634 itv->video_dec_func(itv, VIDIOC_S_FMT, fmt);
635 memcpy(itv->vbi.sliced_in, vbifmt, sizeof(*itv->vbi.sliced_in));
636 return 0;
637}
638
639static int ivtv_debug_ioctls(struct file *filp, unsigned int cmd, void *arg)
640{
641 struct ivtv_open_id *id = (struct ivtv_open_id *)filp->private_data;
642 struct ivtv *itv = id->itv;
643 struct v4l2_register *reg = arg;
644
645 switch (cmd) {
646 /* ioctls to allow direct access to the encoder registers for testing */
647 case VIDIOC_DBG_G_REGISTER:
648 if (v4l2_chip_match_host(reg->match_type, reg->match_chip))
649 return ivtv_itvc(itv, cmd, arg);
650 if (reg->match_type == V4L2_CHIP_MATCH_I2C_DRIVER)
651 return ivtv_i2c_id(itv, reg->match_chip, cmd, arg);
652 return ivtv_call_i2c_client(itv, reg->match_chip, cmd, arg);
653
654 case VIDIOC_DBG_S_REGISTER:
655 if (v4l2_chip_match_host(reg->match_type, reg->match_chip))
656 return ivtv_itvc(itv, cmd, arg);
657 if (reg->match_type == V4L2_CHIP_MATCH_I2C_DRIVER)
658 return ivtv_i2c_id(itv, reg->match_chip, cmd, arg);
659 return ivtv_call_i2c_client(itv, reg->match_chip, cmd, arg);
660
661 case VIDIOC_G_CHIP_IDENT: {
662 struct v4l2_chip_ident *chip = arg;
663
664 chip->ident = V4L2_IDENT_NONE;
665 chip->revision = 0;
666 if (reg->match_type == V4L2_CHIP_MATCH_HOST) {
667 if (v4l2_chip_match_host(reg->match_type, reg->match_chip)) {
668 struct v4l2_chip_ident *chip = arg;
669
670 chip->ident = itv->has_cx23415 ? V4L2_IDENT_CX23415 : V4L2_IDENT_CX23416;
671 }
672 return 0;
673 }
674 if (reg->match_type == V4L2_CHIP_MATCH_I2C_DRIVER)
675 return ivtv_i2c_id(itv, reg->match_chip, cmd, arg);
676 if (reg->match_type == V4L2_CHIP_MATCH_I2C_ADDR)
677 return ivtv_call_i2c_client(itv, reg->match_chip, cmd, arg);
678 return -EINVAL;
679 }
680
681 case VIDIOC_INT_S_AUDIO_ROUTING: {
682 struct v4l2_routing *route = arg;
683
684 ivtv_audio_set_route(itv, route);
685 break;
686 }
687
688 case VIDIOC_INT_RESET:
689 ivtv_reset_ir_gpio(itv);
690 break;
691
692 default:
693 return -EINVAL;
694 }
695 return 0;
696}
697
698int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void *arg)
699{
700 struct ivtv_open_id *id = NULL;
701
702 if (filp) id = (struct ivtv_open_id *)filp->private_data;
703
704 switch (cmd) {
705 case VIDIOC_G_PRIORITY:
706 {
707 enum v4l2_priority *p = arg;
708
709 *p = v4l2_prio_max(&itv->prio);
710 break;
711 }
712
713 case VIDIOC_S_PRIORITY:
714 {
715 enum v4l2_priority *prio = arg;
716
717 return v4l2_prio_change(&itv->prio, &id->prio, *prio);
718 }
719
720 case VIDIOC_QUERYCAP:{
721 struct v4l2_capability *vcap = arg;
722
723 memset(vcap, 0, sizeof(*vcap));
724 strcpy(vcap->driver, IVTV_DRIVER_NAME); /* driver name */
725 strcpy(vcap->card, itv->card_name); /* card type */
726 strcpy(vcap->bus_info, pci_name(itv->dev)); /* bus info... */
727 vcap->version = IVTV_DRIVER_VERSION; /* version */
728 vcap->capabilities = itv->v4l2_cap; /* capabilities */
729
730 /* reserved.. must set to 0! */
731 vcap->reserved[0] = vcap->reserved[1] =
732 vcap->reserved[2] = vcap->reserved[3] = 0;
733 break;
734 }
735
736 case VIDIOC_ENUMAUDIO:{
737 struct v4l2_audio *vin = arg;
738
739 return ivtv_get_audio_input(itv, vin->index, vin);
740 }
741
742 case VIDIOC_G_AUDIO:{
743 struct v4l2_audio *vin = arg;
744
745 vin->index = itv->audio_input;
746 return ivtv_get_audio_input(itv, vin->index, vin);
747 }
748
749 case VIDIOC_S_AUDIO:{
750 struct v4l2_audio *vout = arg;
751
752 if (vout->index >= itv->nof_audio_inputs)
753 return -EINVAL;
754 itv->audio_input = vout->index;
755 ivtv_audio_set_io(itv);
756 break;
757 }
758
759 case VIDIOC_ENUMAUDOUT:{
760 struct v4l2_audioout *vin = arg;
761
762 /* set it to defaults from our table */
763 return ivtv_get_audio_output(itv, vin->index, vin);
764 }
765
766 case VIDIOC_G_AUDOUT:{
767 struct v4l2_audioout *vin = arg;
768
769 vin->index = 0;
770 return ivtv_get_audio_output(itv, vin->index, vin);
771 }
772
773 case VIDIOC_S_AUDOUT:{
774 struct v4l2_audioout *vout = arg;
775
776 return ivtv_get_audio_output(itv, vout->index, vout);
777 }
778
779 case VIDIOC_ENUMINPUT:{
780 struct v4l2_input *vin = arg;
781
782 /* set it to defaults from our table */
783 return ivtv_get_input(itv, vin->index, vin);
784 }
785
786 case VIDIOC_ENUMOUTPUT:{
787 struct v4l2_output *vout = arg;
788
789 return ivtv_get_output(itv, vout->index, vout);
790 }
791
792 case VIDIOC_TRY_FMT:
793 case VIDIOC_S_FMT: {
794 struct v4l2_format *fmt = arg;
795
796 return ivtv_try_or_set_fmt(itv, id->type, fmt, cmd == VIDIOC_S_FMT);
797 }
798
799 case VIDIOC_G_FMT: {
800 struct v4l2_format *fmt = arg;
801 int type = fmt->type;
802
803 memset(fmt, 0, sizeof(*fmt));
804 fmt->type = type;
805 return ivtv_get_fmt(itv, id->type, fmt);
806 }
807
808 case VIDIOC_S_CROP: {
809 struct v4l2_crop *crop = arg;
810
811 if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
812 return -EINVAL;
813 return itv->video_dec_func(itv, VIDIOC_S_CROP, arg);
814 }
815
816 case VIDIOC_G_CROP: {
817 struct v4l2_crop *crop = arg;
818
819 if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
820 return -EINVAL;
821 return itv->video_dec_func(itv, VIDIOC_G_CROP, arg);
822 }
823
824 case VIDIOC_ENUM_FMT: {
825 static struct v4l2_fmtdesc formats[] = {
826 { 0, 0, 0,
827 "HM12 (YUV 4:1:1)", V4L2_PIX_FMT_HM12,
828 { 0, 0, 0, 0 }
829 },
830 { 1, 0, V4L2_FMT_FLAG_COMPRESSED,
831 "MPEG", V4L2_PIX_FMT_MPEG,
832 { 0, 0, 0, 0 }
833 }
834 };
835 struct v4l2_fmtdesc *fmt = arg;
836 enum v4l2_buf_type type = fmt->type;
837
838 switch (type) {
839 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
840 break;
841 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
842 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
843 return -EINVAL;
844 break;
845 default:
846 return -EINVAL;
847 }
848 if (fmt->index > 1)
849 return -EINVAL;
850 *fmt = formats[fmt->index];
851 fmt->type = type;
852 return 0;
853 }
854
855 case VIDIOC_G_INPUT:{
856 *(int *)arg = itv->active_input;
857 break;
858 }
859
860 case VIDIOC_S_INPUT:{
861 int inp = *(int *)arg;
862
863 if (inp < 0 || inp >= itv->nof_inputs)
864 return -EINVAL;
865
866 if (inp == itv->active_input) {
867 IVTV_DEBUG_INFO("Input unchanged\n");
868 break;
869 }
870 IVTV_DEBUG_INFO("Changing input from %d to %d\n",
871 itv->active_input, inp);
872
873 itv->active_input = inp;
874 /* Set the audio input to whatever is appropriate for the
875 input type. */
876 itv->audio_input = itv->card->video_inputs[inp].audio_index;
877
878 /* prevent others from messing with the streams until
879 we're finished changing inputs. */
880 ivtv_mute(itv);
881 ivtv_video_set_io(itv);
882 ivtv_audio_set_io(itv);
883 ivtv_unmute(itv);
884 break;
885 }
886
887 case VIDIOC_G_OUTPUT:{
888 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
889 return -EINVAL;
890 *(int *)arg = itv->active_output;
891 break;
892 }
893
894 case VIDIOC_S_OUTPUT:{
895 int outp = *(int *)arg;
896 struct v4l2_routing route;
897
898 if (outp >= itv->card->nof_outputs)
899 return -EINVAL;
900
901 if (outp == itv->active_output) {
902 IVTV_DEBUG_INFO("Output unchanged\n");
903 break;
904 }
905 IVTV_DEBUG_INFO("Changing output from %d to %d\n",
906 itv->active_output, outp);
907
908 itv->active_output = outp;
909 route.input = SAA7127_INPUT_TYPE_NORMAL;
910 route.output = itv->card->video_outputs[outp].video_output;
911 ivtv_saa7127(itv, VIDIOC_INT_S_VIDEO_ROUTING, &route);
912 break;
913 }
914
915 case VIDIOC_G_FREQUENCY:{
916 struct v4l2_frequency *vf = arg;
917
918 if (vf->tuner != 0)
919 return -EINVAL;
920 ivtv_call_i2c_clients(itv, cmd, arg);
921 break;
922 }
923
924 case VIDIOC_S_FREQUENCY:{
925 struct v4l2_frequency vf = *(struct v4l2_frequency *)arg;
926
927 if (vf.tuner != 0)
928 return -EINVAL;
929
930 ivtv_mute(itv);
931 IVTV_DEBUG_INFO("v4l2 ioctl: set frequency %d\n", vf.frequency);
932 ivtv_call_i2c_clients(itv, cmd, &vf);
933 ivtv_unmute(itv);
934 break;
935 }
936
937 case VIDIOC_ENUMSTD:{
938 struct v4l2_standard *vs = arg;
939 int idx = vs->index;
940
941 if (idx < 0 || idx >= ARRAY_SIZE(enum_stds))
942 return -EINVAL;
943
944 *vs = (enum_stds[idx].std & V4L2_STD_525_60) ?
945 ivtv_std_60hz : ivtv_std_50hz;
946 vs->index = idx;
947 vs->id = enum_stds[idx].std;
948 strcpy(vs->name, enum_stds[idx].name);
949 break;
950 }
951
952 case VIDIOC_G_STD:{
953 *(v4l2_std_id *) arg = itv->std;
954 break;
955 }
956
957 case VIDIOC_S_STD: {
958 v4l2_std_id std = *(v4l2_std_id *) arg;
959
960 if ((std & V4L2_STD_ALL) == 0)
961 return -EINVAL;
962
963 if (std == itv->std)
964 break;
965
966 if (test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags) ||
967 atomic_read(&itv->capturing) > 0 ||
968 atomic_read(&itv->decoding) > 0) {
969 /* Switching standard would turn off the radio or mess
970 with already running streams, prevent that by
971 returning EBUSY. */
972 return -EBUSY;
973 }
974
975 itv->std = std;
976 itv->is_60hz = (std & V4L2_STD_525_60) ? 1 : 0;
977 itv->params.is_50hz = itv->is_50hz = !itv->is_60hz;
978 itv->params.width = 720;
979 itv->params.height = itv->is_50hz ? 576 : 480;
980 itv->vbi.count = itv->is_50hz ? 18 : 12;
981 itv->vbi.start[0] = itv->is_50hz ? 6 : 10;
982 itv->vbi.start[1] = itv->is_50hz ? 318 : 273;
983 if (itv->hw_flags & IVTV_HW_CX25840) {
984 itv->vbi.sliced_decoder_line_size = itv->is_60hz ? 272 : 284;
985 }
986 IVTV_DEBUG_INFO("Switching standard to %llx.\n", itv->std);
987
988 /* Tuner */
989 ivtv_call_i2c_clients(itv, VIDIOC_S_STD, &itv->std);
990
991 if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) {
992 /* set display standard */
993 itv->std_out = std;
994 itv->is_out_60hz = itv->is_60hz;
995 itv->is_out_50hz = itv->is_50hz;
996 ivtv_call_i2c_clients(itv, VIDIOC_INT_S_STD_OUTPUT, &itv->std_out);
997 ivtv_vapi(itv, CX2341X_DEC_SET_STANDARD, 1, itv->is_out_50hz);
998 itv->main_rect.left = itv->main_rect.top = 0;
999 itv->main_rect.width = 720;
1000 itv->main_rect.height = itv->params.height;
1001 ivtv_vapi(itv, CX2341X_OSD_SET_FRAMEBUFFER_WINDOW, 4,
1002 720, itv->main_rect.height, 0, 0);
1003 }
1004 break;
1005 }
1006
1007 case VIDIOC_S_TUNER: { /* Setting tuner can only set audio mode */
1008 struct v4l2_tuner *vt = arg;
1009
1010 if (vt->index != 0)
1011 return -EINVAL;
1012
1013 ivtv_call_i2c_clients(itv, VIDIOC_S_TUNER, vt);
1014 break;
1015 }
1016
1017 case VIDIOC_G_TUNER: {
1018 struct v4l2_tuner *vt = arg;
1019
1020 if (vt->index != 0)
1021 return -EINVAL;
1022
1023 memset(vt, 0, sizeof(*vt));
1024 ivtv_call_i2c_clients(itv, VIDIOC_G_TUNER, vt);
1025
1026 if (test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags)) {
1027 strcpy(vt->name, "ivtv Radio Tuner");
1028 vt->type = V4L2_TUNER_RADIO;
1029 } else {
1030 strcpy(vt->name, "ivtv TV Tuner");
1031 vt->type = V4L2_TUNER_ANALOG_TV;
1032 }
1033 break;
1034 }
1035
1036 case VIDIOC_G_SLICED_VBI_CAP: {
1037 struct v4l2_sliced_vbi_cap *cap = arg;
1038 int set = itv->is_50hz ? V4L2_SLICED_VBI_625 : V4L2_SLICED_VBI_525;
1039 int f, l;
1040 enum v4l2_buf_type type = cap->type;
1041
1042 memset(cap, 0, sizeof(*cap));
1043 cap->type = type;
1044 if (type == V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) {
1045 for (f = 0; f < 2; f++) {
1046 for (l = 0; l < 24; l++) {
1047 if (valid_service_line(f, l, itv->is_50hz)) {
1048 cap->service_lines[f][l] = set;
1049 }
1050 }
1051 }
1052 return 0;
1053 }
1054 if (type == V4L2_BUF_TYPE_SLICED_VBI_OUTPUT) {
1055 if (!(itv->v4l2_cap & V4L2_CAP_SLICED_VBI_OUTPUT))
1056 return -EINVAL;
1057 if (itv->is_60hz) {
1058 cap->service_lines[0][21] = V4L2_SLICED_CAPTION_525;
1059 cap->service_lines[1][21] = V4L2_SLICED_CAPTION_525;
1060 } else {
1061 cap->service_lines[0][23] = V4L2_SLICED_WSS_625;
1062 cap->service_lines[0][16] = V4L2_SLICED_VPS;
1063 }
1064 return 0;
1065 }
1066 return -EINVAL;
1067 }
1068
1069 case VIDIOC_G_ENC_INDEX: {
1070 struct v4l2_enc_idx *idx = arg;
1071 int i;
1072
1073 idx->entries = (itv->pgm_info_write_idx + IVTV_MAX_PGM_INDEX - itv->pgm_info_read_idx) %
1074 IVTV_MAX_PGM_INDEX;
1075 if (idx->entries > V4L2_ENC_IDX_ENTRIES)
1076 idx->entries = V4L2_ENC_IDX_ENTRIES;
1077 for (i = 0; i < idx->entries; i++) {
1078 idx->entry[i] = itv->pgm_info[(itv->pgm_info_read_idx + i) % IVTV_MAX_PGM_INDEX];
1079 }
1080 itv->pgm_info_read_idx = (itv->pgm_info_read_idx + idx->entries) % IVTV_MAX_PGM_INDEX;
1081 break;
1082 }
1083
1084 case VIDIOC_ENCODER_CMD:
1085 case VIDIOC_TRY_ENCODER_CMD: {
1086 struct v4l2_encoder_cmd *enc = arg;
1087 int try = cmd == VIDIOC_TRY_ENCODER_CMD;
1088
1089 memset(&enc->raw, 0, sizeof(enc->raw));
1090 switch (enc->cmd) {
1091 case V4L2_ENC_CMD_START:
1092 enc->flags = 0;
1093 if (try)
1094 return 0;
1095 return ivtv_start_capture(id);
1096
1097 case V4L2_ENC_CMD_STOP:
1098 enc->flags &= V4L2_ENC_CMD_STOP_AT_GOP_END;
1099 if (try)
1100 return 0;
1101 ivtv_stop_capture(id, enc->flags & V4L2_ENC_CMD_STOP_AT_GOP_END);
1102 return 0;
1103
1104 case V4L2_ENC_CMD_PAUSE:
1105 enc->flags = 0;
1106 if (try)
1107 return 0;
1108 if (!atomic_read(&itv->capturing))
1109 return -EPERM;
1110 if (test_and_set_bit(IVTV_F_I_ENC_PAUSED, &itv->i_flags))
1111 return 0;
1112 ivtv_mute(itv);
1113 ivtv_vapi(itv, CX2341X_ENC_PAUSE_ENCODER, 1, 0);
1114 break;
1115
1116 case V4L2_ENC_CMD_RESUME:
1117 enc->flags = 0;
1118 if (try)
1119 return 0;
1120 if (!atomic_read(&itv->capturing))
1121 return -EPERM;
1122 if (!test_and_clear_bit(IVTV_F_I_ENC_PAUSED, &itv->i_flags))
1123 return 0;
1124 ivtv_vapi(itv, CX2341X_ENC_PAUSE_ENCODER, 1, 1);
1125 ivtv_unmute(itv);
1126 break;
1127 default:
1128 return -EINVAL;
1129 }
1130 break;
1131 }
1132
1133 case VIDIOC_G_FBUF: {
1134 struct v4l2_framebuffer *fb = arg;
1135
1136 memset(fb, 0, sizeof(*fb));
1137 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY))
1138 break;
1139 fb->capability = V4L2_FBUF_CAP_EXTERNOVERLAY | V4L2_FBUF_CAP_CHROMAKEY |
1140 V4L2_FBUF_CAP_LOCAL_ALPHA | V4L2_FBUF_CAP_GLOBAL_ALPHA;
1141 fb->fmt.pixelformat = itv->osd_pixelformat;
1142 fb->fmt.width = itv->osd_rect.width;
1143 fb->fmt.height = itv->osd_rect.height;
1144 fb->fmt.left = itv->osd_rect.left;
1145 fb->fmt.top = itv->osd_rect.top;
1146 fb->base = (void *)itv->osd_video_pbase;
1147 if (itv->osd_global_alpha_state)
1148 fb->flags |= V4L2_FBUF_FLAG_GLOBAL_ALPHA;
1149 if (itv->osd_local_alpha_state)
1150 fb->flags |= V4L2_FBUF_FLAG_LOCAL_ALPHA;
1151 if (itv->osd_color_key_state)
1152 fb->flags |= V4L2_FBUF_FLAG_CHROMAKEY;
1153 break;
1154 }
1155
1156 case VIDIOC_S_FBUF: {
1157 struct v4l2_framebuffer *fb = arg;
1158
1159 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY))
1160 break;
1161 itv->osd_global_alpha_state = (fb->flags & V4L2_FBUF_FLAG_GLOBAL_ALPHA) != 0;
1162 itv->osd_local_alpha_state = (fb->flags & V4L2_FBUF_FLAG_LOCAL_ALPHA) != 0;
1163 itv->osd_color_key_state = (fb->flags & V4L2_FBUF_FLAG_CHROMAKEY) != 0;
1164 break;
1165 }
1166
1167 case VIDIOC_LOG_STATUS:
1168 {
1169 int has_output = itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT;
1170 struct v4l2_input vidin;
1171 struct v4l2_audio audin;
1172 int i;
1173
1174 IVTV_INFO("================= START STATUS CARD #%d =================\n", itv->num);
1175 if (itv->hw_flags & IVTV_HW_TVEEPROM) {
1176 struct tveeprom tv;
1177
1178 ivtv_read_eeprom(itv, &tv);
1179 }
1180 ivtv_call_i2c_clients(itv, VIDIOC_LOG_STATUS, NULL);
1181 ivtv_get_input(itv, itv->active_input, &vidin);
1182 ivtv_get_audio_input(itv, itv->audio_input, &audin);
1183 IVTV_INFO("Video Input: %s\n", vidin.name);
1184 IVTV_INFO("Audio Input: %s\n", audin.name);
1185 if (has_output) {
1186 struct v4l2_output vidout;
1187 struct v4l2_audioout audout;
1188 int mode = itv->output_mode;
1189 static const char * const output_modes[] = {
1190 "None",
1191 "MPEG Streaming",
1192 "YUV Streaming",
1193 "YUV Frames",
1194 "Passthrough",
1195 };
1196
1197 ivtv_get_output(itv, itv->active_output, &vidout);
1198 ivtv_get_audio_output(itv, 0, &audout);
1199 IVTV_INFO("Video Output: %s\n", vidout.name);
1200 IVTV_INFO("Audio Output: %s\n", audout.name);
1201 if (mode < 0 || mode > OUT_PASSTHROUGH)
1202 mode = OUT_NONE;
1203 IVTV_INFO("Output Mode: %s\n", output_modes[mode]);
1204 }
1205 IVTV_INFO("Tuner: %s\n",
1206 test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags) ? "Radio" : "TV");
1207 cx2341x_log_status(&itv->params, itv->name);
1208 IVTV_INFO("Status flags: 0x%08lx\n", itv->i_flags);
1209 for (i = 0; i < IVTV_MAX_STREAMS; i++) {
1210 struct ivtv_stream *s = &itv->streams[i];
1211
1212 if (s->v4l2dev == NULL || s->buffers == 0)
1213 continue;
1214 IVTV_INFO("Stream %s: status 0x%04lx, %d%% of %d KiB (%d buffers) in use\n", s->name, s->s_flags,
1215 (s->buffers - s->q_free.buffers) * 100 / s->buffers,
1216 (s->buffers * s->buf_size) / 1024, s->buffers);
1217 }
1218 IVTV_INFO("Read MPEG/VBI: %lld/%lld bytes\n", itv->mpg_data_received, itv->vbi_data_inserted);
1219 IVTV_INFO("================== END STATUS CARD #%d ==================\n", itv->num);
1220 break;
1221 }
1222
1223 default:
1224 return -EINVAL;
1225 }
1226 return 0;
1227}
1228
1229static int ivtv_decoder_ioctls(struct file *filp, unsigned int cmd, void *arg)
1230{
1231 struct ivtv_open_id *id = (struct ivtv_open_id *)filp->private_data;
1232 struct ivtv *itv = id->itv;
1233 int nonblocking = filp->f_flags & O_NONBLOCK;
1234 struct ivtv_stream *s = &itv->streams[id->type];
1235
1236 switch (cmd) {
1237 case IVTV_IOC_DMA_FRAME: {
1238 struct ivtv_dma_frame *args = arg;
1239
1240 IVTV_DEBUG_IOCTL("IVTV_IOC_DMA_FRAME\n");
1241 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1242 return -EINVAL;
1243 if (args->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
1244 return -EINVAL;
1245 if (itv->output_mode == OUT_UDMA_YUV && args->y_source == NULL)
1246 return 0;
1247 if (ivtv_claim_stream(id, id->type)) {
1248 return -EBUSY;
1249 }
1250 if (ivtv_set_output_mode(itv, OUT_UDMA_YUV) != OUT_UDMA_YUV) {
1251 ivtv_release_stream(s);
1252 return -EBUSY;
1253 }
1254 if (args->y_source == NULL)
1255 return 0;
1256 return ivtv_yuv_prep_frame(itv, args);
1257 }
1258
1259 case VIDEO_GET_PTS: {
1260 u32 data[CX2341X_MBOX_MAX_DATA];
1261 u64 *pts = arg;
1262
1263 IVTV_DEBUG_IOCTL("VIDEO_GET_PTS\n");
1264 if (s->type < IVTV_DEC_STREAM_TYPE_MPG) {
1265 *pts = s->dma_pts;
1266 break;
1267 }
1268 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1269 return -EINVAL;
1270
1271 if (test_bit(IVTV_F_I_VALID_DEC_TIMINGS, &itv->i_flags)) {
1272 *pts = (u64) ((u64)itv->last_dec_timing[2] << 32) |
1273 (u64)itv->last_dec_timing[1];
1274 break;
1275 }
1276 *pts = 0;
1277 if (atomic_read(&itv->decoding)) {
1278 if (ivtv_api(itv, CX2341X_DEC_GET_TIMING_INFO, 5, data)) {
1279 IVTV_DEBUG_WARN("GET_TIMING: couldn't read clock\n");
1280 return -EIO;
1281 }
1282 memcpy(itv->last_dec_timing, data, sizeof(itv->last_dec_timing));
1283 set_bit(IVTV_F_I_VALID_DEC_TIMINGS, &itv->i_flags);
1284 *pts = (u64) ((u64) data[2] << 32) | (u64) data[1];
1285 /*timing->scr = (u64) (((u64) data[4] << 32) | (u64) (data[3]));*/
1286 }
1287 break;
1288 }
1289
1290 case VIDEO_GET_FRAME_COUNT: {
1291 u32 data[CX2341X_MBOX_MAX_DATA];
1292 u64 *frame = arg;
1293
1294 IVTV_DEBUG_IOCTL("VIDEO_GET_FRAME_COUNT\n");
1295 if (s->type < IVTV_DEC_STREAM_TYPE_MPG) {
1296 *frame = 0;
1297 break;
1298 }
1299 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1300 return -EINVAL;
1301
1302 if (test_bit(IVTV_F_I_VALID_DEC_TIMINGS, &itv->i_flags)) {
1303 *frame = itv->last_dec_timing[0];
1304 break;
1305 }
1306 *frame = 0;
1307 if (atomic_read(&itv->decoding)) {
1308 if (ivtv_api(itv, CX2341X_DEC_GET_TIMING_INFO, 5, data)) {
1309 IVTV_DEBUG_WARN("GET_TIMING: couldn't read clock\n");
1310 return -EIO;
1311 }
1312 memcpy(itv->last_dec_timing, data, sizeof(itv->last_dec_timing));
1313 set_bit(IVTV_F_I_VALID_DEC_TIMINGS, &itv->i_flags);
1314 *frame = data[0];
1315 }
1316 break;
1317 }
1318
1319 case VIDEO_PLAY: {
1320 struct video_command vc;
1321
1322 IVTV_DEBUG_IOCTL("VIDEO_PLAY\n");
1323 memset(&vc, 0, sizeof(vc));
1324 vc.cmd = VIDEO_CMD_PLAY;
1325 return ivtv_video_command(itv, id, &vc, 0);
1326 }
1327
1328 case VIDEO_STOP: {
1329 struct video_command vc;
1330
1331 IVTV_DEBUG_IOCTL("VIDEO_STOP\n");
1332 memset(&vc, 0, sizeof(vc));
1333 vc.cmd = VIDEO_CMD_STOP;
1334 vc.flags = VIDEO_CMD_STOP_TO_BLACK | VIDEO_CMD_STOP_IMMEDIATELY;
1335 return ivtv_video_command(itv, id, &vc, 0);
1336 }
1337
1338 case VIDEO_FREEZE: {
1339 struct video_command vc;
1340
1341 IVTV_DEBUG_IOCTL("VIDEO_FREEZE\n");
1342 memset(&vc, 0, sizeof(vc));
1343 vc.cmd = VIDEO_CMD_FREEZE;
1344 return ivtv_video_command(itv, id, &vc, 0);
1345 }
1346
1347 case VIDEO_CONTINUE: {
1348 struct video_command vc;
1349
1350 IVTV_DEBUG_IOCTL("VIDEO_CONTINUE\n");
1351 memset(&vc, 0, sizeof(vc));
1352 vc.cmd = VIDEO_CMD_CONTINUE;
1353 return ivtv_video_command(itv, id, &vc, 0);
1354 }
1355
1356 case VIDEO_COMMAND:
1357 case VIDEO_TRY_COMMAND: {
1358 struct video_command *vc = arg;
1359 int try = (cmd == VIDEO_TRY_COMMAND);
1360
1361 if (try)
1362 IVTV_DEBUG_IOCTL("VIDEO_TRY_COMMAND\n");
1363 else
1364 IVTV_DEBUG_IOCTL("VIDEO_COMMAND\n");
1365 return ivtv_video_command(itv, id, vc, try);
1366 }
1367
1368 case VIDEO_GET_EVENT: {
1369 struct video_event *ev = arg;
1370 DEFINE_WAIT(wait);
1371
1372 IVTV_DEBUG_IOCTL("VIDEO_GET_EVENT\n");
1373 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1374 return -EINVAL;
1375 memset(ev, 0, sizeof(*ev));
1376 set_bit(IVTV_F_I_EV_VSYNC_ENABLED, &itv->i_flags);
1377
1378 while (1) {
1379 if (test_and_clear_bit(IVTV_F_I_EV_DEC_STOPPED, &itv->i_flags))
1380 ev->type = VIDEO_EVENT_DECODER_STOPPED;
1381 else if (test_and_clear_bit(IVTV_F_I_EV_VSYNC, &itv->i_flags)) {
1382 ev->type = VIDEO_EVENT_VSYNC;
1383 ev->u.vsync_field = test_bit(IVTV_F_I_EV_VSYNC_FIELD, &itv->i_flags) ?
1384 VIDEO_VSYNC_FIELD_ODD : VIDEO_VSYNC_FIELD_EVEN;
1385 if (itv->output_mode == OUT_UDMA_YUV &&
1386 (itv->yuv_info.lace_mode & IVTV_YUV_MODE_MASK) ==
1387 IVTV_YUV_MODE_PROGRESSIVE) {
1388 ev->u.vsync_field = VIDEO_VSYNC_FIELD_PROGRESSIVE;
1389 }
1390 }
1391 if (ev->type)
1392 return 0;
1393 if (nonblocking)
1394 return -EAGAIN;
1395 /* wait for event */
1396 prepare_to_wait(&itv->event_waitq, &wait, TASK_INTERRUPTIBLE);
1397 if ((itv->i_flags & (IVTV_F_I_EV_DEC_STOPPED|IVTV_F_I_EV_VSYNC)) == 0)
1398 schedule();
1399 finish_wait(&itv->event_waitq, &wait);
1400 if (signal_pending(current)) {
1401 /* return if a signal was received */
1402 IVTV_DEBUG_INFO("User stopped wait for event\n");
1403 return -EINTR;
1404 }
1405 }
1406 break;
1407 }
1408
1409 default:
1410 return -EINVAL;
1411 }
1412 return 0;
1413}
1414
1415static int ivtv_v4l2_do_ioctl(struct inode *inode, struct file *filp,
1416 unsigned int cmd, void *arg)
1417{
1418 struct ivtv_open_id *id = (struct ivtv_open_id *)filp->private_data;
1419 struct ivtv *itv = id->itv;
1420 int ret;
1421
1422 /* check priority */
1423 switch (cmd) {
1424 case VIDIOC_S_CTRL:
1425 case VIDIOC_S_STD:
1426 case VIDIOC_S_INPUT:
1427 case VIDIOC_S_OUTPUT:
1428 case VIDIOC_S_TUNER:
1429 case VIDIOC_S_FREQUENCY:
1430 case VIDIOC_S_FMT:
1431 case VIDIOC_S_CROP:
1432 case VIDIOC_S_AUDIO:
1433 case VIDIOC_S_AUDOUT:
1434 case VIDIOC_S_EXT_CTRLS:
1435 case VIDIOC_S_FBUF:
1436 ret = v4l2_prio_check(&itv->prio, &id->prio);
1437 if (ret)
1438 return ret;
1439 }
1440
1441 switch (cmd) {
1442 case VIDIOC_DBG_G_REGISTER:
1443 case VIDIOC_DBG_S_REGISTER:
1444 case VIDIOC_G_CHIP_IDENT:
1445 case VIDIOC_INT_S_AUDIO_ROUTING:
1446 case VIDIOC_INT_RESET:
1447 if (ivtv_debug & IVTV_DBGFLG_IOCTL) {
1448 printk(KERN_INFO "ivtv%d ioctl: ", itv->num);
1449 v4l_printk_ioctl(cmd);
1450 }
1451 return ivtv_debug_ioctls(filp, cmd, arg);
1452
1453 case VIDIOC_G_PRIORITY:
1454 case VIDIOC_S_PRIORITY:
1455 case VIDIOC_QUERYCAP:
1456 case VIDIOC_ENUMINPUT:
1457 case VIDIOC_G_INPUT:
1458 case VIDIOC_S_INPUT:
1459 case VIDIOC_ENUMOUTPUT:
1460 case VIDIOC_G_OUTPUT:
1461 case VIDIOC_S_OUTPUT:
1462 case VIDIOC_G_FMT:
1463 case VIDIOC_S_FMT:
1464 case VIDIOC_TRY_FMT:
1465 case VIDIOC_ENUM_FMT:
1466 case VIDIOC_G_CROP:
1467 case VIDIOC_S_CROP:
1468 case VIDIOC_G_FREQUENCY:
1469 case VIDIOC_S_FREQUENCY:
1470 case VIDIOC_ENUMSTD:
1471 case VIDIOC_G_STD:
1472 case VIDIOC_S_STD:
1473 case VIDIOC_S_TUNER:
1474 case VIDIOC_G_TUNER:
1475 case VIDIOC_ENUMAUDIO:
1476 case VIDIOC_S_AUDIO:
1477 case VIDIOC_G_AUDIO:
1478 case VIDIOC_ENUMAUDOUT:
1479 case VIDIOC_S_AUDOUT:
1480 case VIDIOC_G_AUDOUT:
1481 case VIDIOC_G_SLICED_VBI_CAP:
1482 case VIDIOC_LOG_STATUS:
1483 case VIDIOC_G_ENC_INDEX:
1484 case VIDIOC_ENCODER_CMD:
1485 case VIDIOC_TRY_ENCODER_CMD:
1486 case VIDIOC_G_FBUF:
1487 case VIDIOC_S_FBUF:
1488 if (ivtv_debug & IVTV_DBGFLG_IOCTL) {
1489 printk(KERN_INFO "ivtv%d ioctl: ", itv->num);
1490 v4l_printk_ioctl(cmd);
1491 }
1492 return ivtv_v4l2_ioctls(itv, filp, cmd, arg);
1493
1494 case VIDIOC_QUERYMENU:
1495 case VIDIOC_QUERYCTRL:
1496 case VIDIOC_S_CTRL:
1497 case VIDIOC_G_CTRL:
1498 case VIDIOC_S_EXT_CTRLS:
1499 case VIDIOC_G_EXT_CTRLS:
1500 case VIDIOC_TRY_EXT_CTRLS:
1501 if (ivtv_debug & IVTV_DBGFLG_IOCTL) {
1502 printk(KERN_INFO "ivtv%d ioctl: ", itv->num);
1503 v4l_printk_ioctl(cmd);
1504 }
1505 return ivtv_control_ioctls(itv, cmd, arg);
1506
1507 case IVTV_IOC_DMA_FRAME:
1508 case VIDEO_GET_PTS:
1509 case VIDEO_GET_FRAME_COUNT:
1510 case VIDEO_GET_EVENT:
1511 case VIDEO_PLAY:
1512 case VIDEO_STOP:
1513 case VIDEO_FREEZE:
1514 case VIDEO_CONTINUE:
1515 case VIDEO_COMMAND:
1516 case VIDEO_TRY_COMMAND:
1517 return ivtv_decoder_ioctls(filp, cmd, arg);
1518
1519 case 0x00005401: /* Handle isatty() calls */
1520 return -EINVAL;
1521 default:
1522 return v4l_compat_translate_ioctl(inode, filp, cmd, arg,
1523 ivtv_v4l2_do_ioctl);
1524 }
1525 return 0;
1526}
1527
1528int ivtv_v4l2_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
1529 unsigned long arg)
1530{
1531 struct ivtv_open_id *id = (struct ivtv_open_id *)filp->private_data;
1532 struct ivtv *itv = id->itv;
1533
1534 /* Filter dvb ioctls that cannot be handled by video_usercopy */
1535 switch (cmd) {
1536 case VIDEO_SELECT_SOURCE:
1537 IVTV_DEBUG_IOCTL("VIDEO_SELECT_SOURCE\n");
1538 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1539 return -EINVAL;
1540 return ivtv_passthrough_mode(itv, arg == VIDEO_SOURCE_DEMUX);
1541
1542 case AUDIO_SET_MUTE:
1543 IVTV_DEBUG_IOCTL("AUDIO_SET_MUTE\n");
1544 itv->speed_mute_audio = arg;
1545 return 0;
1546
1547 case AUDIO_CHANNEL_SELECT:
1548 IVTV_DEBUG_IOCTL("AUDIO_CHANNEL_SELECT\n");
1549 if (arg > AUDIO_STEREO_SWAPPED)
1550 return -EINVAL;
1551 itv->audio_stereo_mode = arg;
1552 ivtv_vapi(itv, CX2341X_DEC_SET_AUDIO_MODE, 2, itv->audio_bilingual_mode, itv->audio_stereo_mode);
1553 return 0;
1554
1555 case AUDIO_BILINGUAL_CHANNEL_SELECT:
1556 IVTV_DEBUG_IOCTL("AUDIO_BILINGUAL_CHANNEL_SELECT\n");
1557 if (arg > AUDIO_STEREO_SWAPPED)
1558 return -EINVAL;
1559 itv->audio_bilingual_mode = arg;
1560 ivtv_vapi(itv, CX2341X_DEC_SET_AUDIO_MODE, 2, itv->audio_bilingual_mode, itv->audio_stereo_mode);
1561 return 0;
1562
1563 default:
1564 break;
1565 }
1566 return video_usercopy(inode, filp, cmd, arg, ivtv_v4l2_do_ioctl);
1567}
diff --git a/drivers/media/video/ivtv/ivtv-ioctl.h b/drivers/media/video/ivtv/ivtv-ioctl.h
new file mode 100644
index 000000000000..cbccf7a9f65c
--- /dev/null
+++ b/drivers/media/video/ivtv/ivtv-ioctl.h
@@ -0,0 +1,28 @@
1/*
2 ioctl system call
3 Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
4 Copyright (C) 2005-2007 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21u16 service2vbi(int type);
22void expand_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal);
23u16 get_service_set(struct v4l2_sliced_vbi_format *fmt);
24int ivtv_v4l2_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
25 unsigned long arg);
26int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void *arg);
27void ivtv_set_osd_alpha(struct ivtv *itv);
28int ivtv_set_speed(struct ivtv *itv, int speed);
diff --git a/drivers/media/video/ivtv/ivtv-irq.c b/drivers/media/video/ivtv/ivtv-irq.c
new file mode 100644
index 000000000000..c3a047b381b3
--- /dev/null
+++ b/drivers/media/video/ivtv/ivtv-irq.c
@@ -0,0 +1,838 @@
1/* interrupt handling
2 Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
3 Copyright (C) 2004 Chris Kennedy <c@groovy.org>
4 Copyright (C) 2005-2007 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#include "ivtv-driver.h"
22#include "ivtv-firmware.h"
23#include "ivtv-fileops.h"
24#include "ivtv-queue.h"
25#include "ivtv-udma.h"
26#include "ivtv-irq.h"
27#include "ivtv-ioctl.h"
28#include "ivtv-mailbox.h"
29#include "ivtv-vbi.h"
30#include "ivtv-yuv.h"
31
32#define DMA_MAGIC_COOKIE 0x000001fe
33
34#define SLICED_VBI_PIO 1
35
36static void ivtv_dma_dec_start(struct ivtv_stream *s);
37
38static const int ivtv_stream_map[] = {
39 IVTV_ENC_STREAM_TYPE_MPG,
40 IVTV_ENC_STREAM_TYPE_YUV,
41 IVTV_ENC_STREAM_TYPE_PCM,
42 IVTV_ENC_STREAM_TYPE_VBI,
43};
44
45static inline int ivtv_use_pio(struct ivtv_stream *s)
46{
47 struct ivtv *itv = s->itv;
48
49 return s->dma == PCI_DMA_NONE ||
50 (SLICED_VBI_PIO && s->type == IVTV_ENC_STREAM_TYPE_VBI && itv->vbi.sliced_in->service_set);
51}
52
53void ivtv_irq_work_handler(struct work_struct *work)
54{
55 struct ivtv *itv = container_of(work, struct ivtv, irq_work_queue);
56
57 DEFINE_WAIT(wait);
58
59 if (test_and_clear_bit(IVTV_F_I_WORK_HANDLER_VBI, &itv->i_flags))
60 vbi_work_handler(itv);
61
62 if (test_and_clear_bit(IVTV_F_I_WORK_HANDLER_YUV, &itv->i_flags))
63 ivtv_yuv_work_handler(itv);
64}
65
66/* Determine the required DMA size, setup enough buffers in the predma queue and
67 actually copy the data from the card to the buffers in case a PIO transfer is
68 required for this stream.
69 */
70static int stream_enc_dma_append(struct ivtv_stream *s, u32 data[CX2341X_MBOX_MAX_DATA])
71{
72 struct ivtv *itv = s->itv;
73 struct ivtv_buffer *buf;
74 struct list_head *p;
75 u32 bytes_needed = 0;
76 u32 offset, size;
77 u32 UVoffset = 0, UVsize = 0;
78 int skip_bufs = s->q_predma.buffers;
79 int idx = s->SG_length;
80 int rc;
81
82 /* sanity checks */
83 if (s->v4l2dev == NULL) {
84 IVTV_DEBUG_WARN("Stream %s not started\n", s->name);
85 return -1;
86 }
87 if (!test_bit(IVTV_F_S_CLAIMED, &s->s_flags)) {
88 IVTV_DEBUG_WARN("Stream %s not open\n", s->name);
89 return -1;
90 }
91
92 /* determine offset, size and PTS for the various streams */
93 switch (s->type) {
94 case IVTV_ENC_STREAM_TYPE_MPG:
95 offset = data[1];
96 size = data[2];
97 s->dma_pts = 0;
98 break;
99
100 case IVTV_ENC_STREAM_TYPE_YUV:
101 offset = data[1];
102 size = data[2];
103 UVoffset = data[3];
104 UVsize = data[4];
105 s->dma_pts = ((u64) data[5] << 32) | data[6];
106 break;
107
108 case IVTV_ENC_STREAM_TYPE_PCM:
109 offset = data[1] + 12;
110 size = data[2] - 12;
111 s->dma_pts = read_dec(offset - 8) |
112 ((u64)(read_dec(offset - 12)) << 32);
113 if (itv->has_cx23415)
114 offset += IVTV_DECODER_OFFSET;
115 break;
116
117 case IVTV_ENC_STREAM_TYPE_VBI:
118 size = itv->vbi.enc_size * itv->vbi.fpi;
119 offset = read_enc(itv->vbi.enc_start - 4) + 12;
120 if (offset == 12) {
121 IVTV_DEBUG_INFO("VBI offset == 0\n");
122 return -1;
123 }
124 s->dma_pts = read_enc(offset - 4) | ((u64)read_enc(offset - 8) << 32);
125 break;
126
127 case IVTV_DEC_STREAM_TYPE_VBI:
128 size = read_dec(itv->vbi.dec_start + 4) + 8;
129 offset = read_dec(itv->vbi.dec_start) + itv->vbi.dec_start;
130 s->dma_pts = 0;
131 offset += IVTV_DECODER_OFFSET;
132 break;
133 default:
134 /* shouldn't happen */
135 return -1;
136 }
137
138 /* if this is the start of the DMA then fill in the magic cookie */
139 if (s->SG_length == 0) {
140 if (itv->has_cx23415 && (s->type == IVTV_ENC_STREAM_TYPE_PCM ||
141 s->type == IVTV_DEC_STREAM_TYPE_VBI)) {
142 s->dma_backup = read_dec(offset - IVTV_DECODER_OFFSET);
143 write_dec_sync(cpu_to_le32(DMA_MAGIC_COOKIE), offset - IVTV_DECODER_OFFSET);
144 }
145 else {
146 s->dma_backup = read_enc(offset);
147 write_enc_sync(cpu_to_le32(DMA_MAGIC_COOKIE), offset);
148 }
149 s->dma_offset = offset;
150 }
151
152 bytes_needed = size;
153 if (s->type == IVTV_ENC_STREAM_TYPE_YUV) {
154 /* The size for the Y samples needs to be rounded upwards to a
155 multiple of the buf_size. The UV samples then start in the
156 next buffer. */
157 bytes_needed = s->buf_size * ((bytes_needed + s->buf_size - 1) / s->buf_size);
158 bytes_needed += UVsize;
159 }
160
161 IVTV_DEBUG_DMA("%s %s: 0x%08x bytes at 0x%08x\n",
162 ivtv_use_pio(s) ? "PIO" : "DMA", s->name, bytes_needed, offset);
163
164 rc = ivtv_queue_move(s, &s->q_free, &s->q_full, &s->q_predma, bytes_needed);
165 if (rc < 0) { /* Insufficient buffers */
166 IVTV_DEBUG_WARN("Cannot obtain %d bytes for %s data transfer\n",
167 bytes_needed, s->name);
168 return -1;
169 }
170 if (rc && !s->buffers_stolen && (s->s_flags & IVTV_F_S_APPL_IO)) {
171 IVTV_WARN("All %s stream buffers are full. Dropping data.\n", s->name);
172 IVTV_WARN("Cause: the application is not reading fast enough.\n");
173 }
174 s->buffers_stolen = rc;
175
176 /* got the buffers, now fill in SGarray (DMA) or copy the data from the card
177 to the buffers (PIO). */
178 buf = list_entry(s->q_predma.list.next, struct ivtv_buffer, list);
179 memset(buf->buf, 0, 128);
180 list_for_each(p, &s->q_predma.list) {
181 struct ivtv_buffer *buf = list_entry(p, struct ivtv_buffer, list);
182
183 if (skip_bufs-- > 0)
184 continue;
185 if (!ivtv_use_pio(s)) {
186 s->SGarray[idx].dst = cpu_to_le32(buf->dma_handle);
187 s->SGarray[idx].src = cpu_to_le32(offset);
188 s->SGarray[idx].size = cpu_to_le32(s->buf_size);
189 }
190 buf->bytesused = (size < s->buf_size) ? size : s->buf_size;
191
192 /* If PIO, then copy the data from the card to the buffer */
193 if (s->type == IVTV_DEC_STREAM_TYPE_VBI) {
194 memcpy_fromio(buf->buf, itv->dec_mem + offset - IVTV_DECODER_OFFSET, buf->bytesused);
195 }
196 else if (ivtv_use_pio(s)) {
197 memcpy_fromio(buf->buf, itv->enc_mem + offset, buf->bytesused);
198 }
199
200 s->q_predma.bytesused += buf->bytesused;
201 size -= buf->bytesused;
202 offset += s->buf_size;
203
204 /* Sync SG buffers */
205 ivtv_buf_sync_for_device(s, buf);
206
207 if (size == 0) { /* YUV */
208 /* process the UV section */
209 offset = UVoffset;
210 size = UVsize;
211 }
212 idx++;
213 }
214 s->SG_length = idx;
215 return 0;
216}
217
218static void dma_post(struct ivtv_stream *s)
219{
220 struct ivtv *itv = s->itv;
221 struct ivtv_buffer *buf = NULL;
222 struct list_head *p;
223 u32 offset;
224 u32 *u32buf;
225 int x = 0;
226
227 if (ivtv_use_pio(s)) {
228 if (s->q_predma.bytesused)
229 ivtv_queue_move(s, &s->q_predma, NULL, &s->q_dma, s->q_predma.bytesused);
230 s->SG_length = 0;
231 }
232 IVTV_DEBUG_DMA("%s %s completed (%x)\n", ivtv_use_pio(s) ? "PIO" : "DMA",
233 s->name, s->dma_offset);
234 list_for_each(p, &s->q_dma.list) {
235 buf = list_entry(p, struct ivtv_buffer, list);
236 u32buf = (u32 *)buf->buf;
237
238 /* Sync Buffer */
239 ivtv_buf_sync_for_cpu(s, buf);
240
241 if (x == 0) {
242 offset = s->dma_last_offset;
243 if (u32buf[offset / 4] != DMA_MAGIC_COOKIE)
244 {
245 for (offset = 0; offset < 64; offset++) {
246 if (u32buf[offset] == DMA_MAGIC_COOKIE) {
247 break;
248 }
249 }
250 offset *= 4;
251 if (offset == 256) {
252 IVTV_DEBUG_WARN("%s: Couldn't find start of buffer within the first 256 bytes\n", s->name);
253 offset = s->dma_last_offset;
254 }
255 if (s->dma_last_offset != offset)
256 IVTV_DEBUG_WARN("%s: offset %d -> %d\n", s->name, s->dma_last_offset, offset);
257 s->dma_last_offset = offset;
258 }
259 if (itv->has_cx23415 && (s->type == IVTV_ENC_STREAM_TYPE_PCM ||
260 s->type == IVTV_DEC_STREAM_TYPE_VBI)) {
261 write_dec_sync(0, s->dma_offset - IVTV_DECODER_OFFSET);
262 }
263 else {
264 write_enc_sync(0, s->dma_offset);
265 }
266 if (offset) {
267 buf->bytesused -= offset;
268 memcpy(buf->buf, buf->buf + offset, buf->bytesused + offset);
269 }
270 *u32buf = cpu_to_le32(s->dma_backup);
271 }
272 x++;
273 /* flag byteswap ABCD -> DCBA for MPG & VBI data outside irq */
274 if (s->type == IVTV_ENC_STREAM_TYPE_MPG ||
275 s->type == IVTV_ENC_STREAM_TYPE_VBI)
276 set_bit(IVTV_F_B_NEED_BUF_SWAP, &buf->b_flags);
277 }
278 if (buf)
279 buf->bytesused += s->dma_last_offset;
280 if (buf && s->type == IVTV_DEC_STREAM_TYPE_VBI) {
281 /* Parse and Groom VBI Data */
282 s->q_dma.bytesused -= buf->bytesused;
283 ivtv_process_vbi_data(itv, buf, 0, s->type);
284 s->q_dma.bytesused += buf->bytesused;
285 if (s->id == -1) {
286 ivtv_queue_move(s, &s->q_dma, NULL, &s->q_free, 0);
287 return;
288 }
289 }
290 ivtv_queue_move(s, &s->q_dma, NULL, &s->q_full, s->q_dma.bytesused);
291 if (s->id != -1)
292 wake_up(&s->waitq);
293}
294
295void ivtv_dma_stream_dec_prepare(struct ivtv_stream *s, u32 offset, int lock)
296{
297 struct ivtv *itv = s->itv;
298 struct ivtv_buffer *buf;
299 struct list_head *p;
300 u32 y_size = itv->params.height * itv->params.width;
301 u32 uv_offset = offset + IVTV_YUV_BUFFER_UV_OFFSET;
302 int y_done = 0;
303 int bytes_written = 0;
304 unsigned long flags = 0;
305 int idx = 0;
306
307 IVTV_DEBUG_DMA("DEC PREPARE DMA %s: %08x %08x\n", s->name, s->q_predma.bytesused, offset);
308 buf = list_entry(s->q_predma.list.next, struct ivtv_buffer, list);
309 list_for_each(p, &s->q_predma.list) {
310 struct ivtv_buffer *buf = list_entry(p, struct ivtv_buffer, list);
311
312 /* YUV UV Offset from Y Buffer */
313 if (s->type == IVTV_DEC_STREAM_TYPE_YUV && !y_done && bytes_written >= y_size) {
314 offset = uv_offset;
315 y_done = 1;
316 }
317 s->SGarray[idx].src = cpu_to_le32(buf->dma_handle);
318 s->SGarray[idx].dst = cpu_to_le32(offset);
319 s->SGarray[idx].size = cpu_to_le32(buf->bytesused);
320
321 offset += buf->bytesused;
322 bytes_written += buf->bytesused;
323
324 /* Sync SG buffers */
325 ivtv_buf_sync_for_device(s, buf);
326 idx++;
327 }
328 s->SG_length = idx;
329
330 /* Mark last buffer size for Interrupt flag */
331 s->SGarray[s->SG_length - 1].size |= cpu_to_le32(0x80000000);
332
333 /* Sync Hardware SG List of buffers */
334 ivtv_stream_sync_for_device(s);
335 if (lock)
336 spin_lock_irqsave(&itv->dma_reg_lock, flags);
337 if (!test_bit(IVTV_F_I_DMA, &itv->i_flags)) {
338 ivtv_dma_dec_start(s);
339 }
340 else {
341 set_bit(IVTV_F_S_DMA_PENDING, &s->s_flags);
342 }
343 if (lock)
344 spin_unlock_irqrestore(&itv->dma_reg_lock, flags);
345}
346
347/* start the encoder DMA */
348static void ivtv_dma_enc_start(struct ivtv_stream *s)
349{
350 struct ivtv *itv = s->itv;
351 struct ivtv_stream *s_vbi = &itv->streams[IVTV_ENC_STREAM_TYPE_VBI];
352 int i;
353
354 if (s->q_predma.bytesused)
355 ivtv_queue_move(s, &s->q_predma, NULL, &s->q_dma, s->q_predma.bytesused);
356 IVTV_DEBUG_DMA("start DMA for %s\n", s->name);
357 s->SGarray[s->SG_length - 1].size = cpu_to_le32(le32_to_cpu(s->SGarray[s->SG_length - 1].size) + 256);
358
359 /* If this is an MPEG stream, and VBI data is also pending, then append the
360 VBI DMA to the MPEG DMA and transfer both sets of data at once.
361
362 VBI DMA is a second class citizen compared to MPEG and mixing them together
363 will confuse the firmware (the end of a VBI DMA is seen as the end of a
364 MPEG DMA, thus effectively dropping an MPEG frame). So instead we make
365 sure we only use the MPEG DMA to transfer the VBI DMA if both are in
366 use. This way no conflicts occur. */
367 clear_bit(IVTV_F_S_DMA_HAS_VBI, &s->s_flags);
368 if (s->type == IVTV_ENC_STREAM_TYPE_MPG && s_vbi->SG_length &&
369 s->SG_length + s_vbi->SG_length <= s->buffers) {
370 ivtv_queue_move(s_vbi, &s_vbi->q_predma, NULL, &s_vbi->q_dma, s_vbi->q_predma.bytesused);
371 s_vbi->SGarray[s_vbi->SG_length - 1].size = cpu_to_le32(le32_to_cpu(s_vbi->SGarray[s->SG_length - 1].size) + 256);
372 for (i = 0; i < s_vbi->SG_length; i++) {
373 s->SGarray[s->SG_length++] = s_vbi->SGarray[i];
374 }
375 itv->vbi.dma_offset = s_vbi->dma_offset;
376 s_vbi->SG_length = 0;
377 set_bit(IVTV_F_S_DMA_HAS_VBI, &s->s_flags);
378 IVTV_DEBUG_DMA("include DMA for %s\n", s->name);
379 }
380
381 /* Mark last buffer size for Interrupt flag */
382 s->SGarray[s->SG_length - 1].size |= cpu_to_le32(0x80000000);
383
384 /* Sync Hardware SG List of buffers */
385 ivtv_stream_sync_for_device(s);
386 write_reg(s->SG_handle, IVTV_REG_ENCDMAADDR);
387 write_reg_sync(read_reg(IVTV_REG_DMAXFER) | 0x02, IVTV_REG_DMAXFER);
388 set_bit(IVTV_F_I_DMA, &itv->i_flags);
389 itv->cur_dma_stream = s->type;
390 itv->dma_timer.expires = jiffies + HZ / 10;
391 add_timer(&itv->dma_timer);
392}
393
394static void ivtv_dma_dec_start(struct ivtv_stream *s)
395{
396 struct ivtv *itv = s->itv;
397
398 if (s->q_predma.bytesused)
399 ivtv_queue_move(s, &s->q_predma, NULL, &s->q_dma, s->q_predma.bytesused);
400 IVTV_DEBUG_DMA("start DMA for %s\n", s->name);
401 /* put SG Handle into register 0x0c */
402 write_reg(s->SG_handle, IVTV_REG_DECDMAADDR);
403 write_reg_sync(read_reg(IVTV_REG_DMAXFER) | 0x01, IVTV_REG_DMAXFER);
404 set_bit(IVTV_F_I_DMA, &itv->i_flags);
405 itv->cur_dma_stream = s->type;
406 itv->dma_timer.expires = jiffies + HZ / 10;
407 add_timer(&itv->dma_timer);
408}
409
410static void ivtv_irq_dma_read(struct ivtv *itv)
411{
412 struct ivtv_stream *s = NULL;
413 struct ivtv_buffer *buf;
414 int hw_stream_type;
415
416 IVTV_DEBUG_IRQ("DEC DMA READ\n");
417 del_timer(&itv->dma_timer);
418 if (read_reg(IVTV_REG_DMASTATUS) & 0x14) {
419 IVTV_DEBUG_WARN("DEC DMA ERROR %x\n", read_reg(IVTV_REG_DMASTATUS));
420 write_reg(read_reg(IVTV_REG_DMASTATUS) & 3, IVTV_REG_DMASTATUS);
421 }
422 if (!test_bit(IVTV_F_I_UDMA, &itv->i_flags)) {
423 if (test_bit(IVTV_F_I_DEC_YUV, &itv->i_flags)) {
424 s = &itv->streams[IVTV_DEC_STREAM_TYPE_YUV];
425 hw_stream_type = 2;
426 }
427 else {
428 s = &itv->streams[IVTV_DEC_STREAM_TYPE_MPG];
429 hw_stream_type = 0;
430 }
431 IVTV_DEBUG_DMA("DEC DATA READ %s: %d\n", s->name, s->q_dma.bytesused);
432
433 ivtv_stream_sync_for_cpu(s);
434
435 /* For some reason must kick the firmware, like PIO mode,
436 I think this tells the firmware we are done and the size
437 of the xfer so it can calculate what we need next.
438 I think we can do this part ourselves but would have to
439 fully calculate xfer info ourselves and not use interrupts
440 */
441 ivtv_vapi(itv, CX2341X_DEC_SCHED_DMA_FROM_HOST, 3, 0, s->q_dma.bytesused,
442 hw_stream_type);
443
444 /* Free last DMA call */
445 while ((buf = ivtv_dequeue(s, &s->q_dma)) != NULL) {
446 ivtv_buf_sync_for_cpu(s, buf);
447 ivtv_enqueue(s, buf, &s->q_free);
448 }
449 wake_up(&s->waitq);
450 }
451 clear_bit(IVTV_F_I_UDMA, &itv->i_flags);
452 clear_bit(IVTV_F_I_DMA, &itv->i_flags);
453 itv->cur_dma_stream = -1;
454 wake_up(&itv->dma_waitq);
455}
456
457static void ivtv_irq_enc_dma_complete(struct ivtv *itv)
458{
459 u32 data[CX2341X_MBOX_MAX_DATA];
460 struct ivtv_stream *s;
461
462 del_timer(&itv->dma_timer);
463 ivtv_api_get_data(&itv->enc_mbox, IVTV_MBOX_DMA_END, data);
464 IVTV_DEBUG_IRQ("ENC DMA COMPLETE %x %d\n", data[0], data[1]);
465 if (test_and_clear_bit(IVTV_F_I_ENC_VBI, &itv->i_flags))
466 data[1] = 3;
467 else if (data[1] > 2)
468 return;
469 s = &itv->streams[ivtv_stream_map[data[1]]];
470 if (data[0] & 0x18) {
471 IVTV_DEBUG_WARN("ENC DMA ERROR %x\n", data[0]);
472 write_reg(read_reg(IVTV_REG_DMASTATUS) & 3, IVTV_REG_DMASTATUS);
473 ivtv_vapi(itv, CX2341X_ENC_SCHED_DMA_TO_HOST, 3, 0, 0, data[1]);
474 }
475 s->SG_length = 0;
476 clear_bit(IVTV_F_I_DMA, &itv->i_flags);
477 itv->cur_dma_stream = -1;
478 dma_post(s);
479 ivtv_stream_sync_for_cpu(s);
480 if (test_and_clear_bit(IVTV_F_S_DMA_HAS_VBI, &s->s_flags)) {
481 u32 tmp;
482
483 s = &itv->streams[IVTV_ENC_STREAM_TYPE_VBI];
484 tmp = s->dma_offset;
485 s->dma_offset = itv->vbi.dma_offset;
486 dma_post(s);
487 s->dma_offset = tmp;
488 }
489 wake_up(&itv->dma_waitq);
490}
491
492static void ivtv_irq_dma_err(struct ivtv *itv)
493{
494 u32 data[CX2341X_MBOX_MAX_DATA];
495
496 del_timer(&itv->dma_timer);
497 ivtv_api_get_data(&itv->enc_mbox, IVTV_MBOX_DMA_END, data);
498 IVTV_DEBUG_WARN("DMA ERROR %08x %08x %08x %d\n", data[0], data[1],
499 read_reg(IVTV_REG_DMASTATUS), itv->cur_dma_stream);
500 if (!test_bit(IVTV_F_I_UDMA, &itv->i_flags) &&
501 itv->cur_dma_stream >= 0 && itv->cur_dma_stream < IVTV_MAX_STREAMS) {
502 struct ivtv_stream *s = &itv->streams[itv->cur_dma_stream];
503
504 /* retry */
505 write_reg(read_reg(IVTV_REG_DMASTATUS) & 3, IVTV_REG_DMASTATUS);
506 if (s->type >= IVTV_DEC_STREAM_TYPE_MPG)
507 ivtv_dma_dec_start(s);
508 else
509 ivtv_dma_enc_start(s);
510 return;
511 }
512 clear_bit(IVTV_F_I_UDMA, &itv->i_flags);
513 clear_bit(IVTV_F_I_DMA, &itv->i_flags);
514 itv->cur_dma_stream = -1;
515 wake_up(&itv->dma_waitq);
516}
517
518static void ivtv_irq_enc_start_cap(struct ivtv *itv)
519{
520 u32 data[CX2341X_MBOX_MAX_DATA];
521 struct ivtv_stream *s;
522
523 /* Get DMA destination and size arguments from card */
524 ivtv_api_get_data(&itv->enc_mbox, IVTV_MBOX_DMA, data);
525 IVTV_DEBUG_IRQ("ENC START CAP %d: %08x %08x\n", data[0], data[1], data[2]);
526
527 if (data[0] > 2 || data[1] == 0 || data[2] == 0) {
528 IVTV_DEBUG_WARN("Unknown input: %08x %08x %08x\n",
529 data[0], data[1], data[2]);
530 return;
531 }
532 clear_bit(IVTV_F_I_ENC_VBI, &itv->i_flags);
533 s = &itv->streams[ivtv_stream_map[data[0]]];
534 if (!stream_enc_dma_append(s, data)) {
535 if (ivtv_use_pio(s)) {
536 dma_post(s);
537 ivtv_vapi(itv, CX2341X_ENC_SCHED_DMA_TO_HOST, 3, 0, 0, data[0]);
538 }
539 else {
540 set_bit(IVTV_F_S_DMA_PENDING, &s->s_flags);
541 }
542 }
543}
544
545static void ivtv_irq_enc_vbi_cap(struct ivtv *itv)
546{
547 struct ivtv_stream *s_mpg = &itv->streams[IVTV_ENC_STREAM_TYPE_MPG];
548 u32 data[CX2341X_MBOX_MAX_DATA];
549 struct ivtv_stream *s;
550
551 IVTV_DEBUG_IRQ("ENC START VBI CAP\n");
552 s = &itv->streams[IVTV_ENC_STREAM_TYPE_VBI];
553
554 if (ivtv_use_pio(s)) {
555 if (stream_enc_dma_append(s, data))
556 return;
557 if (s->q_predma.bytesused)
558 ivtv_queue_move(s, &s->q_predma, NULL, &s->q_dma, s->q_predma.bytesused);
559 s->SG_length = 0;
560 dma_post(s);
561 return;
562 }
563 /* If more than two VBI buffers are pending, then
564 clear the old ones and start with this new one.
565 This can happen during transition stages when MPEG capturing is
566 started, but the first interrupts haven't arrived yet. During
567 that period VBI requests can accumulate without being able to
568 DMA the data. Since at most four VBI DMA buffers are available,
569 we just drop the old requests when there are already three
570 requests queued. */
571 if (s->SG_length > 2) {
572 struct list_head *p;
573 list_for_each(p, &s->q_predma.list) {
574 struct ivtv_buffer *buf = list_entry(p, struct ivtv_buffer, list);
575 ivtv_buf_sync_for_cpu(s, buf);
576 }
577 ivtv_queue_move(s, &s->q_predma, NULL, &s->q_free, 0);
578 s->SG_length = 0;
579 }
580 /* if we can append the data, and the MPEG stream isn't capturing,
581 then start a DMA request for just the VBI data. */
582 if (!stream_enc_dma_append(s, data) &&
583 !test_bit(IVTV_F_S_STREAMING, &s_mpg->s_flags)) {
584 set_bit(IVTV_F_I_ENC_VBI, &itv->i_flags);
585 set_bit(IVTV_F_S_DMA_PENDING, &s->s_flags);
586 }
587}
588
589static void ivtv_irq_dev_vbi_reinsert(struct ivtv *itv)
590{
591 u32 data[CX2341X_MBOX_MAX_DATA];
592 struct ivtv_stream *s = &itv->streams[IVTV_DEC_STREAM_TYPE_VBI];
593
594 IVTV_DEBUG_IRQ("DEC VBI REINSERT\n");
595 if (test_bit(IVTV_F_S_CLAIMED, &s->s_flags) &&
596 !stream_enc_dma_append(s, data)) {
597 dma_post(s);
598 }
599}
600
601static void ivtv_irq_dec_data_req(struct ivtv *itv)
602{
603 u32 data[CX2341X_MBOX_MAX_DATA];
604 struct ivtv_stream *s;
605
606 /* YUV or MPG */
607 ivtv_api_get_data(&itv->dec_mbox, IVTV_MBOX_DMA, data);
608
609 if (test_bit(IVTV_F_I_DEC_YUV, &itv->i_flags)) {
610 itv->dma_data_req_size = itv->params.width * itv->params.height * 3 / 2;
611 itv->dma_data_req_offset = data[1] ? data[1] : yuv_offset[0];
612 s = &itv->streams[IVTV_DEC_STREAM_TYPE_YUV];
613 }
614 else {
615 itv->dma_data_req_size = data[2] >= 0x10000 ? 0x10000 : data[2];
616 itv->dma_data_req_offset = data[1];
617 s = &itv->streams[IVTV_DEC_STREAM_TYPE_MPG];
618 }
619 IVTV_DEBUG_IRQ("DEC DATA REQ %s: %d %08x %u\n", s->name, s->q_full.bytesused,
620 itv->dma_data_req_offset, itv->dma_data_req_size);
621 if (itv->dma_data_req_size == 0 || s->q_full.bytesused < itv->dma_data_req_size) {
622 set_bit(IVTV_F_S_NEEDS_DATA, &s->s_flags);
623 }
624 else {
625 clear_bit(IVTV_F_S_NEEDS_DATA, &s->s_flags);
626 ivtv_queue_move(s, &s->q_full, NULL, &s->q_predma, itv->dma_data_req_size);
627 ivtv_dma_stream_dec_prepare(s, itv->dma_data_req_offset + IVTV_DECODER_OFFSET, 0);
628 }
629}
630
631static void ivtv_irq_vsync(struct ivtv *itv)
632{
633 /* The vsync interrupt is unusual in that it won't clear until
634 * the end of the first line for the current field, at which
635 * point it clears itself. This can result in repeated vsync
636 * interrupts, or a missed vsync. Read some of the registers
637 * to determine the line being displayed and ensure we handle
638 * one vsync per frame.
639 */
640 unsigned int frame = read_reg(0x28c0) & 1;
641 int last_dma_frame = atomic_read(&itv->yuv_info.next_dma_frame);
642
643 if (0) IVTV_DEBUG_IRQ("DEC VSYNC\n");
644
645 if (((frame ^ itv->yuv_info.lace_sync_field) == 0 && ((itv->lastVsyncFrame & 1) ^ itv->yuv_info.lace_sync_field)) ||
646 (frame != (itv->lastVsyncFrame & 1) && !itv->yuv_info.frame_interlaced)) {
647 int next_dma_frame = last_dma_frame;
648
649 if (next_dma_frame >= 0 && next_dma_frame != atomic_read(&itv->yuv_info.next_fill_frame)) {
650 write_reg(yuv_offset[next_dma_frame] >> 4, 0x82c);
651 write_reg((yuv_offset[next_dma_frame] + IVTV_YUV_BUFFER_UV_OFFSET) >> 4, 0x830);
652 write_reg(yuv_offset[next_dma_frame] >> 4, 0x834);
653 write_reg((yuv_offset[next_dma_frame] + IVTV_YUV_BUFFER_UV_OFFSET) >> 4, 0x838);
654 next_dma_frame = (next_dma_frame + 1) & 0x3;
655 atomic_set(&itv->yuv_info.next_dma_frame, next_dma_frame);
656 }
657 }
658 if (frame != (itv->lastVsyncFrame & 1)) {
659 struct ivtv_stream *s = ivtv_get_output_stream(itv);
660 int work = 0;
661
662 itv->lastVsyncFrame += 1;
663 if (frame == 0) {
664 clear_bit(IVTV_F_I_VALID_DEC_TIMINGS, &itv->i_flags);
665 clear_bit(IVTV_F_I_EV_VSYNC_FIELD, &itv->i_flags);
666 }
667 else {
668 set_bit(IVTV_F_I_EV_VSYNC_FIELD, &itv->i_flags);
669 }
670 if (test_bit(IVTV_F_I_EV_VSYNC_ENABLED, &itv->i_flags)) {
671 set_bit(IVTV_F_I_EV_VSYNC, &itv->i_flags);
672 wake_up(&itv->event_waitq);
673 }
674 wake_up(&itv->vsync_waitq);
675 if (s)
676 wake_up(&s->waitq);
677
678 /* Send VBI to saa7127 */
679 if (frame) {
680 set_bit(IVTV_F_I_WORK_HANDLER_VBI, &itv->i_flags);
681 work = 1;
682 }
683
684 /* Check if we need to update the yuv registers */
685 if ((itv->yuv_info.yuv_forced_update || itv->yuv_info.new_frame_info[last_dma_frame].update) && last_dma_frame != -1) {
686 if (!itv->yuv_info.new_frame_info[last_dma_frame].update)
687 last_dma_frame = (last_dma_frame - 1) & 3;
688
689 if (itv->yuv_info.new_frame_info[last_dma_frame].src_w) {
690 itv->yuv_info.update_frame = last_dma_frame;
691 itv->yuv_info.new_frame_info[last_dma_frame].update = 0;
692 itv->yuv_info.yuv_forced_update = 0;
693 set_bit(IVTV_F_I_WORK_HANDLER_YUV, &itv->i_flags);
694 work = 1;
695 }
696 }
697 if (work)
698 queue_work(itv->irq_work_queues, &itv->irq_work_queue);
699 }
700}
701
702#define IVTV_IRQ_DMA (IVTV_IRQ_DMA_READ | IVTV_IRQ_ENC_DMA_COMPLETE | IVTV_IRQ_DMA_ERR | IVTV_IRQ_ENC_START_CAP | IVTV_IRQ_ENC_VBI_CAP | IVTV_IRQ_DEC_DATA_REQ)
703
704irqreturn_t ivtv_irq_handler(int irq, void *dev_id)
705{
706 struct ivtv *itv = (struct ivtv *)dev_id;
707 u32 combo;
708 u32 stat;
709 int i;
710 u8 vsync_force = 0;
711
712 spin_lock(&itv->dma_reg_lock);
713 /* get contents of irq status register */
714 stat = read_reg(IVTV_REG_IRQSTATUS);
715
716 combo = ~itv->irqmask & stat;
717
718 /* Clear out IRQ */
719 if (combo) write_reg(combo, IVTV_REG_IRQSTATUS);
720
721 if (0 == combo) {
722 /* The vsync interrupt is unusual and clears itself. If we
723 * took too long, we may have missed it. Do some checks
724 */
725 if (~itv->irqmask & IVTV_IRQ_DEC_VSYNC) {
726 /* vsync is enabled, see if we're in a new field */
727 if ((itv->lastVsyncFrame & 1) != (read_reg(0x28c0) & 1)) {
728 /* New field, looks like we missed it */
729 IVTV_DEBUG_YUV("VSync interrupt missed %d\n",read_reg(0x28c0)>>16);
730 vsync_force = 1;
731 }
732 }
733
734 if (!vsync_force) {
735 /* No Vsync expected, wasn't for us */
736 spin_unlock(&itv->dma_reg_lock);
737 return IRQ_NONE;
738 }
739 }
740
741 /* Exclude interrupts noted below from the output, otherwise the log is flooded with
742 these messages */
743 if (combo & ~0xff6d0400)
744 IVTV_DEBUG_IRQ("======= valid IRQ bits: 0x%08x ======\n", combo);
745
746 if (combo & IVTV_IRQ_DEC_DMA_COMPLETE) {
747 IVTV_DEBUG_IRQ("DEC DMA COMPLETE\n");
748 }
749
750 if (combo & IVTV_IRQ_DMA_READ) {
751 ivtv_irq_dma_read(itv);
752 }
753
754 if (combo & IVTV_IRQ_ENC_DMA_COMPLETE) {
755 ivtv_irq_enc_dma_complete(itv);
756 }
757
758 if (combo & IVTV_IRQ_DMA_ERR) {
759 ivtv_irq_dma_err(itv);
760 }
761
762 if (combo & IVTV_IRQ_ENC_START_CAP) {
763 ivtv_irq_enc_start_cap(itv);
764 }
765
766 if (combo & IVTV_IRQ_ENC_VBI_CAP) {
767 ivtv_irq_enc_vbi_cap(itv);
768 }
769
770 if (combo & IVTV_IRQ_DEC_VBI_RE_INSERT) {
771 ivtv_irq_dev_vbi_reinsert(itv);
772 }
773
774 if (combo & IVTV_IRQ_ENC_EOS) {
775 IVTV_DEBUG_IRQ("ENC EOS\n");
776 set_bit(IVTV_F_I_EOS, &itv->i_flags);
777 wake_up(&itv->cap_w);
778 }
779
780 if (combo & IVTV_IRQ_DEC_DATA_REQ) {
781 ivtv_irq_dec_data_req(itv);
782 }
783
784 /* Decoder Vertical Sync - We can't rely on 'combo', so check if vsync enabled */
785 if (~itv->irqmask & IVTV_IRQ_DEC_VSYNC) {
786 ivtv_irq_vsync(itv);
787 }
788
789 if (combo & IVTV_IRQ_ENC_VIM_RST) {
790 IVTV_DEBUG_IRQ("VIM RST\n");
791 /*ivtv_vapi(itv, CX2341X_ENC_REFRESH_INPUT, 0); */
792 }
793
794 if (combo & IVTV_IRQ_DEC_AUD_MODE_CHG) {
795 IVTV_DEBUG_INFO("Stereo mode changed\n");
796 }
797
798 if ((combo & IVTV_IRQ_DMA) && !test_bit(IVTV_F_I_DMA, &itv->i_flags)) {
799 for (i = 0; i < IVTV_MAX_STREAMS; i++) {
800 int idx = (i + itv->irq_rr_idx++) % IVTV_MAX_STREAMS;
801 struct ivtv_stream *s = &itv->streams[idx];
802
803 if (!test_and_clear_bit(IVTV_F_S_DMA_PENDING, &s->s_flags))
804 continue;
805 if (s->type >= IVTV_DEC_STREAM_TYPE_MPG)
806 ivtv_dma_dec_start(s);
807 else
808 ivtv_dma_enc_start(s);
809 break;
810 }
811 if (i == IVTV_MAX_STREAMS && test_and_clear_bit(IVTV_F_I_UDMA_PENDING, &itv->i_flags)) {
812 ivtv_udma_start(itv);
813 }
814 }
815
816 spin_unlock(&itv->dma_reg_lock);
817
818 /* If we've just handled a 'forced' vsync, it's safest to say it
819 * wasn't ours. Another device may have triggered it at just
820 * the right time.
821 */
822 return vsync_force ? IRQ_NONE : IRQ_HANDLED;
823}
824
825void ivtv_unfinished_dma(unsigned long arg)
826{
827 struct ivtv *itv = (struct ivtv *)arg;
828
829 if (!test_bit(IVTV_F_I_DMA, &itv->i_flags))
830 return;
831 IVTV_ERR("DMA TIMEOUT %08x %d\n", read_reg(IVTV_REG_DMASTATUS), itv->cur_dma_stream);
832
833 write_reg(read_reg(IVTV_REG_DMASTATUS) & 3, IVTV_REG_DMASTATUS);
834 clear_bit(IVTV_F_I_UDMA, &itv->i_flags);
835 clear_bit(IVTV_F_I_DMA, &itv->i_flags);
836 itv->cur_dma_stream = -1;
837 wake_up(&itv->dma_waitq);
838}
diff --git a/drivers/media/video/ivtv/ivtv-irq.h b/drivers/media/video/ivtv/ivtv-irq.h
new file mode 100644
index 000000000000..a43348a30309
--- /dev/null
+++ b/drivers/media/video/ivtv/ivtv-irq.h
@@ -0,0 +1,26 @@
1/*
2 interrupt handling
3 Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
4 Copyright (C) 2004 Chris Kennedy <c@groovy.org>
5 Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl>
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21
22irqreturn_t ivtv_irq_handler(int irq, void *dev_id);
23
24void ivtv_irq_work_handler(struct work_struct *work);
25void ivtv_dma_stream_dec_prepare(struct ivtv_stream *s, u32 offset, int lock);
26void ivtv_unfinished_dma(unsigned long arg);
diff --git a/drivers/media/video/ivtv/ivtv-mailbox.c b/drivers/media/video/ivtv/ivtv-mailbox.c
new file mode 100644
index 000000000000..6ae42a3b03cc
--- /dev/null
+++ b/drivers/media/video/ivtv/ivtv-mailbox.c
@@ -0,0 +1,360 @@
1/*
2 mailbox functions
3 Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
4 Copyright (C) 2004 Chris Kennedy <c@groovy.org>
5 Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl>
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21
22#include <stdarg.h>
23
24#include "ivtv-driver.h"
25#include "ivtv-mailbox.h"
26
27/* Firmware mailbox flags*/
28#define IVTV_MBOX_FIRMWARE_DONE 0x00000004
29#define IVTV_MBOX_DRIVER_DONE 0x00000002
30#define IVTV_MBOX_DRIVER_BUSY 0x00000001
31#define IVTV_MBOX_FREE 0x00000000
32
33/* Firmware mailbox standard timeout */
34#define IVTV_API_STD_TIMEOUT 0x02000000
35
36#define API_CACHE (1 << 0) /* Allow the command to be stored in the cache */
37#define API_RESULT (1 << 1) /* Allow 1 second for this cmd to end */
38#define API_FAST_RESULT (3 << 1) /* Allow 0.1 second for this cmd to end */
39#define API_DMA (1 << 3) /* DMA mailbox, has special handling */
40#define API_NO_WAIT_MB (1 << 4) /* Command may not wait for a free mailbox */
41#define API_NO_WAIT_RES (1 << 5) /* Command may not wait for the result */
42
43struct ivtv_api_info {
44 int flags; /* Flags, see above */
45 const char *name; /* The name of the command */
46};
47
48#define API_ENTRY(x, f) [x] = { (f), #x }
49
50static const struct ivtv_api_info api_info[256] = {
51 /* MPEG encoder API */
52 API_ENTRY(CX2341X_ENC_PING_FW, API_FAST_RESULT),
53 API_ENTRY(CX2341X_ENC_START_CAPTURE, API_RESULT),
54 API_ENTRY(CX2341X_ENC_STOP_CAPTURE, API_RESULT),
55 API_ENTRY(CX2341X_ENC_SET_AUDIO_ID, API_CACHE),
56 API_ENTRY(CX2341X_ENC_SET_VIDEO_ID, API_CACHE),
57 API_ENTRY(CX2341X_ENC_SET_PCR_ID, API_CACHE),
58 API_ENTRY(CX2341X_ENC_SET_FRAME_RATE, API_CACHE),
59 API_ENTRY(CX2341X_ENC_SET_FRAME_SIZE, API_CACHE),
60 API_ENTRY(CX2341X_ENC_SET_BIT_RATE, API_CACHE),
61 API_ENTRY(CX2341X_ENC_SET_GOP_PROPERTIES, API_CACHE),
62 API_ENTRY(CX2341X_ENC_SET_ASPECT_RATIO, API_CACHE),
63 API_ENTRY(CX2341X_ENC_SET_DNR_FILTER_MODE, API_CACHE),
64 API_ENTRY(CX2341X_ENC_SET_DNR_FILTER_PROPS, API_CACHE),
65 API_ENTRY(CX2341X_ENC_SET_CORING_LEVELS, API_CACHE),
66 API_ENTRY(CX2341X_ENC_SET_SPATIAL_FILTER_TYPE, API_CACHE),
67 API_ENTRY(CX2341X_ENC_SET_VBI_LINE, API_RESULT),
68 API_ENTRY(CX2341X_ENC_SET_STREAM_TYPE, API_CACHE),
69 API_ENTRY(CX2341X_ENC_SET_OUTPUT_PORT, API_CACHE),
70 API_ENTRY(CX2341X_ENC_SET_AUDIO_PROPERTIES, API_CACHE),
71 API_ENTRY(CX2341X_ENC_HALT_FW, API_FAST_RESULT),
72 API_ENTRY(CX2341X_ENC_GET_VERSION, API_FAST_RESULT),
73 API_ENTRY(CX2341X_ENC_SET_GOP_CLOSURE, API_CACHE),
74 API_ENTRY(CX2341X_ENC_GET_SEQ_END, API_RESULT),
75 API_ENTRY(CX2341X_ENC_SET_PGM_INDEX_INFO, API_FAST_RESULT),
76 API_ENTRY(CX2341X_ENC_SET_VBI_CONFIG, API_RESULT),
77 API_ENTRY(CX2341X_ENC_SET_DMA_BLOCK_SIZE, API_CACHE),
78 API_ENTRY(CX2341X_ENC_GET_PREV_DMA_INFO_MB_10, API_FAST_RESULT),
79 API_ENTRY(CX2341X_ENC_GET_PREV_DMA_INFO_MB_9, API_FAST_RESULT),
80 API_ENTRY(CX2341X_ENC_SCHED_DMA_TO_HOST, API_DMA),
81 API_ENTRY(CX2341X_ENC_INITIALIZE_INPUT, API_RESULT),
82 API_ENTRY(CX2341X_ENC_SET_FRAME_DROP_RATE, API_CACHE),
83 API_ENTRY(CX2341X_ENC_PAUSE_ENCODER, API_RESULT),
84 API_ENTRY(CX2341X_ENC_REFRESH_INPUT, API_NO_WAIT_MB),
85 API_ENTRY(CX2341X_ENC_SET_COPYRIGHT, API_CACHE),
86 API_ENTRY(CX2341X_ENC_SET_EVENT_NOTIFICATION, API_RESULT),
87 API_ENTRY(CX2341X_ENC_SET_NUM_VSYNC_LINES, API_CACHE),
88 API_ENTRY(CX2341X_ENC_SET_PLACEHOLDER, API_CACHE),
89 API_ENTRY(CX2341X_ENC_MUTE_VIDEO, API_RESULT),
90 API_ENTRY(CX2341X_ENC_MUTE_AUDIO, API_RESULT),
91 API_ENTRY(CX2341X_ENC_SET_VERT_CROP_LINE, API_FAST_RESULT),
92 API_ENTRY(CX2341X_ENC_MISC, API_FAST_RESULT),
93 /* Obsolete PULLDOWN API command */
94 API_ENTRY(0xb1, API_CACHE),
95
96 /* MPEG decoder API */
97 API_ENTRY(CX2341X_DEC_PING_FW, API_FAST_RESULT),
98 API_ENTRY(CX2341X_DEC_START_PLAYBACK, API_RESULT),
99 API_ENTRY(CX2341X_DEC_STOP_PLAYBACK, API_RESULT),
100 API_ENTRY(CX2341X_DEC_SET_PLAYBACK_SPEED, API_RESULT),
101 API_ENTRY(CX2341X_DEC_STEP_VIDEO, API_RESULT),
102 API_ENTRY(CX2341X_DEC_SET_DMA_BLOCK_SIZE, API_CACHE),
103 API_ENTRY(CX2341X_DEC_GET_XFER_INFO, API_FAST_RESULT),
104 API_ENTRY(CX2341X_DEC_GET_DMA_STATUS, API_FAST_RESULT),
105 API_ENTRY(CX2341X_DEC_SCHED_DMA_FROM_HOST, API_DMA),
106 API_ENTRY(CX2341X_DEC_PAUSE_PLAYBACK, API_RESULT),
107 API_ENTRY(CX2341X_DEC_HALT_FW, API_FAST_RESULT),
108 API_ENTRY(CX2341X_DEC_SET_STANDARD, API_CACHE),
109 API_ENTRY(CX2341X_DEC_GET_VERSION, API_FAST_RESULT),
110 API_ENTRY(CX2341X_DEC_SET_STREAM_INPUT, API_CACHE),
111 API_ENTRY(CX2341X_DEC_GET_TIMING_INFO, API_RESULT /*| API_NO_WAIT_RES*/),
112 API_ENTRY(CX2341X_DEC_SET_AUDIO_MODE, API_CACHE),
113 API_ENTRY(CX2341X_DEC_SET_EVENT_NOTIFICATION, API_RESULT),
114 API_ENTRY(CX2341X_DEC_SET_DISPLAY_BUFFERS, API_CACHE),
115 API_ENTRY(CX2341X_DEC_EXTRACT_VBI, API_RESULT),
116 API_ENTRY(CX2341X_DEC_SET_DECODER_SOURCE, API_FAST_RESULT),
117 API_ENTRY(CX2341X_DEC_SET_PREBUFFERING, API_CACHE),
118
119 /* OSD API */
120 API_ENTRY(CX2341X_OSD_GET_FRAMEBUFFER, API_FAST_RESULT),
121 API_ENTRY(CX2341X_OSD_GET_PIXEL_FORMAT, API_FAST_RESULT),
122 API_ENTRY(CX2341X_OSD_SET_PIXEL_FORMAT, API_CACHE),
123 API_ENTRY(CX2341X_OSD_GET_STATE, API_FAST_RESULT),
124 API_ENTRY(CX2341X_OSD_SET_STATE, API_CACHE),
125 API_ENTRY(CX2341X_OSD_GET_OSD_COORDS, API_FAST_RESULT),
126 API_ENTRY(CX2341X_OSD_SET_OSD_COORDS, API_CACHE),
127 API_ENTRY(CX2341X_OSD_GET_SCREEN_COORDS, API_FAST_RESULT),
128 API_ENTRY(CX2341X_OSD_SET_SCREEN_COORDS, API_CACHE),
129 API_ENTRY(CX2341X_OSD_GET_GLOBAL_ALPHA, API_FAST_RESULT),
130 API_ENTRY(CX2341X_OSD_SET_GLOBAL_ALPHA, API_CACHE),
131 API_ENTRY(CX2341X_OSD_SET_BLEND_COORDS, API_CACHE),
132 API_ENTRY(CX2341X_OSD_GET_FLICKER_STATE, API_FAST_RESULT),
133 API_ENTRY(CX2341X_OSD_SET_FLICKER_STATE, API_CACHE),
134 API_ENTRY(CX2341X_OSD_BLT_COPY, API_RESULT),
135 API_ENTRY(CX2341X_OSD_BLT_FILL, API_RESULT),
136 API_ENTRY(CX2341X_OSD_BLT_TEXT, API_RESULT),
137 API_ENTRY(CX2341X_OSD_SET_FRAMEBUFFER_WINDOW, API_CACHE),
138 API_ENTRY(CX2341X_OSD_SET_CHROMA_KEY, API_CACHE),
139 API_ENTRY(CX2341X_OSD_GET_ALPHA_CONTENT_INDEX, API_FAST_RESULT),
140 API_ENTRY(CX2341X_OSD_SET_ALPHA_CONTENT_INDEX, API_CACHE)
141};
142
143static int try_mailbox(struct ivtv *itv, struct ivtv_mailbox_data *mbdata, int mb)
144{
145 u32 flags = readl(&mbdata->mbox[mb].flags);
146 int is_free = flags == IVTV_MBOX_FREE || (flags & IVTV_MBOX_FIRMWARE_DONE);
147
148 /* if the mailbox is free, then try to claim it */
149 if (is_free && !test_and_set_bit(mb, &mbdata->busy)) {
150 write_sync(IVTV_MBOX_DRIVER_BUSY, &mbdata->mbox[mb].flags);
151 return 1;
152 }
153 return 0;
154}
155
156/* Try to find a free mailbox. Note mailbox 0 is reserved for DMA and so is not
157 attempted here. */
158static int get_mailbox(struct ivtv *itv, struct ivtv_mailbox_data *mbdata, int flags)
159{
160 unsigned long then = jiffies;
161 int i, mb;
162 int max_mbox = mbdata->max_mbox;
163 int retries = 100;
164
165 /* All slow commands use the same mailbox, serializing them and also
166 leaving the other mailbox free for simple fast commands. */
167 if ((flags & API_FAST_RESULT) == API_RESULT)
168 max_mbox = 1;
169
170 /* find free non-DMA mailbox */
171 for (i = 0; i < retries; i++) {
172 for (mb = 1; mb <= max_mbox; mb++)
173 if (try_mailbox(itv, mbdata, mb))
174 return mb;
175
176 /* Sleep before a retry, if not atomic */
177 if (!(flags & API_NO_WAIT_MB)) {
178 if (jiffies - then > retries * HZ / 100)
179 break;
180 ivtv_sleep_timeout(HZ / 100, 0);
181 }
182 }
183 return -ENODEV;
184}
185
186static void write_mailbox(volatile struct ivtv_mailbox __iomem *mbox, int cmd, int args, u32 data[])
187{
188 int i;
189
190 write_sync(cmd, &mbox->cmd);
191 write_sync(IVTV_API_STD_TIMEOUT, &mbox->timeout);
192
193 for (i = 0; i < CX2341X_MBOX_MAX_DATA; i++)
194 write_sync(data[i], &mbox->data[i]);
195
196 write_sync(IVTV_MBOX_DRIVER_DONE | IVTV_MBOX_DRIVER_BUSY, &mbox->flags);
197}
198
199static void clear_all_mailboxes(struct ivtv *itv, struct ivtv_mailbox_data *mbdata)
200{
201 int i;
202
203 for (i = 0; i <= mbdata->max_mbox; i++) {
204 IVTV_DEBUG_WARN("Clearing mailbox %d: cmd 0x%08x flags 0x%08x\n",
205 i, readl(&mbdata->mbox[i].cmd), readl(&mbdata->mbox[i].flags));
206 write_sync(0, &mbdata->mbox[i].flags);
207 clear_bit(i, &mbdata->busy);
208 }
209}
210
211static int ivtv_api_call(struct ivtv *itv, int cmd, int args, u32 data[])
212{
213 struct ivtv_mailbox_data *mbdata = (cmd >= 128) ? &itv->enc_mbox : &itv->dec_mbox;
214 volatile struct ivtv_mailbox __iomem *mbox;
215 int api_timeout = HZ;
216 int flags, mb, i;
217 unsigned long then;
218
219 /* sanity checks */
220 if (NULL == mbdata) {
221 IVTV_ERR("No mailbox allocated\n");
222 return -ENODEV;
223 }
224 if (args < 0 || args > CX2341X_MBOX_MAX_DATA ||
225 cmd < 0 || cmd > 255 || api_info[cmd].name == NULL) {
226 IVTV_ERR("Invalid API call: cmd = 0x%02x, args = %d\n", cmd, args);
227 return -EINVAL;
228 }
229
230 IVTV_DEBUG_API("API Call: %s\n", api_info[cmd].name);
231
232 /* clear possibly uninitialized part of data array */
233 for (i = args; i < CX2341X_MBOX_MAX_DATA; i++)
234 data[i] = 0;
235
236 /* If this command was issued within the last 30 minutes and with identical
237 data, then just return 0 as there is no need to issue this command again.
238 Just an optimization to prevent unnecessary use of mailboxes. */
239 if (itv->api_cache[cmd].last_jiffies &&
240 jiffies - itv->api_cache[cmd].last_jiffies < HZ * 1800 &&
241 !memcmp(data, itv->api_cache[cmd].data, sizeof(itv->api_cache[cmd].data))) {
242 itv->api_cache[cmd].last_jiffies = jiffies;
243 return 0;
244 }
245
246 flags = api_info[cmd].flags;
247
248 if (flags & API_DMA) {
249 for (i = 0; i < 100; i++) {
250 mb = i % (mbdata->max_mbox + 1);
251 if (try_mailbox(itv, mbdata, mb)) {
252 write_mailbox(&mbdata->mbox[mb], cmd, args, data);
253 clear_bit(mb, &mbdata->busy);
254 return 0;
255 }
256 IVTV_DEBUG_WARN("%s: mailbox %d not free %08x\n",
257 api_info[cmd].name, mb, readl(&mbdata->mbox[mb].flags));
258 }
259 IVTV_WARN("Could not find free DMA mailbox for %s\n", api_info[cmd].name);
260 clear_all_mailboxes(itv, mbdata);
261 return -EBUSY;
262 }
263
264 if ((flags & API_FAST_RESULT) == API_FAST_RESULT)
265 api_timeout = HZ / 10;
266
267 mb = get_mailbox(itv, mbdata, flags);
268 if (mb < 0) {
269 IVTV_DEBUG_WARN("No free mailbox found (%s)\n", api_info[cmd].name);
270 clear_all_mailboxes(itv, mbdata);
271 return -EBUSY;
272 }
273 mbox = &mbdata->mbox[mb];
274 write_mailbox(mbox, cmd, args, data);
275 if (flags & API_CACHE) {
276 memcpy(itv->api_cache[cmd].data, data, sizeof(itv->api_cache[cmd].data));
277 itv->api_cache[cmd].last_jiffies = jiffies;
278 }
279 if ((flags & API_RESULT) == 0) {
280 clear_bit(mb, &mbdata->busy);
281 return 0;
282 }
283
284 /* Get results */
285 then = jiffies;
286
287 while (!(readl(&mbox->flags) & IVTV_MBOX_FIRMWARE_DONE)) {
288 if (jiffies - then > api_timeout) {
289 IVTV_DEBUG_WARN("Could not get result (%s)\n", api_info[cmd].name);
290 /* reset the mailbox, but it is likely too late already */
291 write_sync(0, &mbox->flags);
292 clear_bit(mb, &mbdata->busy);
293 return -EIO;
294 }
295 if (flags & API_NO_WAIT_RES)
296 mdelay(1);
297 else
298 ivtv_sleep_timeout(HZ / 100, 0);
299 }
300 if (jiffies - then > HZ / 10)
301 IVTV_DEBUG_WARN("%s took %lu jiffies (%d per HZ)\n",
302 api_info[cmd].name, jiffies - then, HZ);
303
304 for (i = 0; i < CX2341X_MBOX_MAX_DATA; i++)
305 data[i] = readl(&mbox->data[i]);
306 write_sync(0, &mbox->flags);
307 clear_bit(mb, &mbdata->busy);
308 return 0;
309}
310
311int ivtv_api(struct ivtv *itv, int cmd, int args, u32 data[])
312{
313 int res = ivtv_api_call(itv, cmd, args, data);
314
315 /* Allow a single retry, probably already too late though.
316 If there is no free mailbox then that is usually an indication
317 of a more serious problem. */
318 return (res == -EBUSY) ? ivtv_api_call(itv, cmd, args, data) : res;
319}
320
321int ivtv_api_func(void *priv, int cmd, int in, int out, u32 data[CX2341X_MBOX_MAX_DATA])
322{
323 return ivtv_api(priv, cmd, in, data);
324}
325
326int ivtv_vapi_result(struct ivtv *itv, u32 data[CX2341X_MBOX_MAX_DATA], int cmd, int args, ...)
327{
328 va_list ap;
329 int i;
330
331 va_start(ap, args);
332 for (i = 0; i < args; i++) {
333 data[i] = va_arg(ap, u32);
334 }
335 va_end(ap);
336 return ivtv_api(itv, cmd, args, data);
337}
338
339int ivtv_vapi(struct ivtv *itv, int cmd, int args, ...)
340{
341 u32 data[CX2341X_MBOX_MAX_DATA];
342 va_list ap;
343 int i;
344
345 va_start(ap, args);
346 for (i = 0; i < args; i++) {
347 data[i] = va_arg(ap, u32);
348 }
349 va_end(ap);
350 return ivtv_api(itv, cmd, args, data);
351}
352
353/* This one is for stuff that can't sleep.. irq handlers, etc.. */
354void ivtv_api_get_data(struct ivtv_mailbox_data *mbdata, int mb, u32 data[])
355{
356 int i;
357
358 for (i = 0; i < CX2341X_MBOX_MAX_DATA; i++)
359 data[i] = readl(&mbdata->mbox[mb].data[i]);
360}
diff --git a/drivers/media/video/ivtv/ivtv-mailbox.h b/drivers/media/video/ivtv/ivtv-mailbox.h
new file mode 100644
index 000000000000..79b8aec14370
--- /dev/null
+++ b/drivers/media/video/ivtv/ivtv-mailbox.h
@@ -0,0 +1,25 @@
1/*
2 mailbox functions
3 Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
4 Copyright (C) 2005-2007 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21void ivtv_api_get_data(struct ivtv_mailbox_data *mbox, int mb, u32 data[]);
22int ivtv_api(struct ivtv *itv, int cmd, int args, u32 data[]);
23int ivtv_vapi_result(struct ivtv *itv, u32 data[CX2341X_MBOX_MAX_DATA], int cmd, int args, ...);
24int ivtv_vapi(struct ivtv *itv, int cmd, int args, ...);
25int ivtv_api_func(void *priv, int cmd, int in, int out, u32 data[CX2341X_MBOX_MAX_DATA]);
diff --git a/drivers/media/video/ivtv/ivtv-queue.c b/drivers/media/video/ivtv/ivtv-queue.c
new file mode 100644
index 000000000000..ccfcef1ad91a
--- /dev/null
+++ b/drivers/media/video/ivtv/ivtv-queue.c
@@ -0,0 +1,262 @@
1/*
2 buffer queues.
3 Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
4 Copyright (C) 2004 Chris Kennedy <c@groovy.org>
5 Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl>
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21
22#include "ivtv-driver.h"
23#include "ivtv-streams.h"
24#include "ivtv-queue.h"
25#include "ivtv-mailbox.h"
26
27int ivtv_buf_copy_from_user(struct ivtv_stream *s, struct ivtv_buffer *buf, const char __user *src, int copybytes)
28{
29 if (s->buf_size - buf->bytesused < copybytes)
30 copybytes = s->buf_size - buf->bytesused;
31 if (copy_from_user(buf->buf + buf->bytesused, src, copybytes)) {
32 return -EFAULT;
33 }
34 buf->bytesused += copybytes;
35 return copybytes;
36}
37
38void ivtv_buf_swap(struct ivtv_buffer *buf)
39{
40 int i;
41
42 for (i = 0; i < buf->bytesused; i += 4)
43 swab32s((u32 *)(buf->buf + i));
44}
45
46void ivtv_queue_init(struct ivtv_queue *q)
47{
48 INIT_LIST_HEAD(&q->list);
49 q->buffers = 0;
50 q->length = 0;
51 q->bytesused = 0;
52}
53
54void ivtv_enqueue(struct ivtv_stream *s, struct ivtv_buffer *buf, struct ivtv_queue *q)
55{
56 unsigned long flags = 0;
57
58 /* clear the buffer if it is going to be enqueued to the free queue */
59 if (q == &s->q_free) {
60 buf->bytesused = 0;
61 buf->readpos = 0;
62 buf->b_flags = 0;
63 }
64 spin_lock_irqsave(&s->qlock, flags);
65 list_add_tail(&buf->list, &q->list);
66 q->buffers++;
67 q->length += s->buf_size;
68 q->bytesused += buf->bytesused - buf->readpos;
69 spin_unlock_irqrestore(&s->qlock, flags);
70}
71
72struct ivtv_buffer *ivtv_dequeue(struct ivtv_stream *s, struct ivtv_queue *q)
73{
74 struct ivtv_buffer *buf = NULL;
75 unsigned long flags = 0;
76
77 spin_lock_irqsave(&s->qlock, flags);
78 if (!list_empty(&q->list)) {
79 buf = list_entry(q->list.next, struct ivtv_buffer, list);
80 list_del_init(q->list.next);
81 q->buffers--;
82 q->length -= s->buf_size;
83 q->bytesused -= buf->bytesused - buf->readpos;
84 }
85 spin_unlock_irqrestore(&s->qlock, flags);
86 return buf;
87}
88
89static void ivtv_queue_move_buf(struct ivtv_stream *s, struct ivtv_queue *from,
90 struct ivtv_queue *to, int clear, int full)
91{
92 struct ivtv_buffer *buf = list_entry(from->list.next, struct ivtv_buffer, list);
93
94 list_move_tail(from->list.next, &to->list);
95 from->buffers--;
96 from->length -= s->buf_size;
97 from->bytesused -= buf->bytesused - buf->readpos;
98 /* special handling for q_free */
99 if (clear)
100 buf->bytesused = buf->readpos = buf->b_flags = 0;
101 else if (full) {
102 /* special handling for stolen buffers, assume
103 all bytes are used. */
104 buf->bytesused = s->buf_size;
105 buf->readpos = buf->b_flags = 0;
106 }
107 to->buffers++;
108 to->length += s->buf_size;
109 to->bytesused += buf->bytesused - buf->readpos;
110}
111
112/* Move 'needed_bytes' worth of buffers from queue 'from' into queue 'to'.
113 If 'needed_bytes' == 0, then move all buffers from 'from' into 'to'.
114 If 'steal' != NULL, then buffers may also taken from that queue if
115 needed.
116
117 The buffer is automatically cleared if it goes to the free queue. It is
118 also cleared if buffers need to be taken from the 'steal' queue and
119 the 'from' queue is the free queue.
120
121 When 'from' is q_free, then needed_bytes is compared to the total
122 available buffer length, otherwise needed_bytes is compared to the
123 bytesused value. For the 'steal' queue the total available buffer
124 length is always used.
125
126 -ENOMEM is returned if the buffers could not be obtained, 0 if all
127 buffers where obtained from the 'from' list and if non-zero then
128 the number of stolen buffers is returned. */
129int ivtv_queue_move(struct ivtv_stream *s, struct ivtv_queue *from, struct ivtv_queue *steal,
130 struct ivtv_queue *to, int needed_bytes)
131{
132 unsigned long flags;
133 int rc = 0;
134 int from_free = from == &s->q_free;
135 int to_free = to == &s->q_free;
136 int bytes_available;
137
138 spin_lock_irqsave(&s->qlock, flags);
139 if (needed_bytes == 0) {
140 from_free = 1;
141 needed_bytes = from->length;
142 }
143
144 bytes_available = from_free ? from->length : from->bytesused;
145 bytes_available += steal ? steal->length : 0;
146
147 if (bytes_available < needed_bytes) {
148 spin_unlock_irqrestore(&s->qlock, flags);
149 return -ENOMEM;
150 }
151 if (from_free) {
152 u32 old_length = to->length;
153
154 while (to->length - old_length < needed_bytes) {
155 if (list_empty(&from->list))
156 from = steal;
157 if (from == steal)
158 rc++; /* keep track of 'stolen' buffers */
159 ivtv_queue_move_buf(s, from, to, 1, 0);
160 }
161 }
162 else {
163 u32 old_bytesused = to->bytesused;
164
165 while (to->bytesused - old_bytesused < needed_bytes) {
166 if (list_empty(&from->list))
167 from = steal;
168 if (from == steal)
169 rc++; /* keep track of 'stolen' buffers */
170 ivtv_queue_move_buf(s, from, to, to_free, rc);
171 }
172 }
173 spin_unlock_irqrestore(&s->qlock, flags);
174 return rc;
175}
176
177void ivtv_flush_queues(struct ivtv_stream *s)
178{
179 ivtv_queue_move(s, &s->q_io, NULL, &s->q_free, 0);
180 ivtv_queue_move(s, &s->q_full, NULL, &s->q_free, 0);
181 ivtv_queue_move(s, &s->q_dma, NULL, &s->q_free, 0);
182 ivtv_queue_move(s, &s->q_predma, NULL, &s->q_free, 0);
183}
184
185int ivtv_stream_alloc(struct ivtv_stream *s)
186{
187 struct ivtv *itv = s->itv;
188 int SGsize = sizeof(struct ivtv_SG_element) * s->buffers;
189 int i;
190
191 if (s->buffers == 0)
192 return 0;
193
194 IVTV_DEBUG_INFO("Allocate %s%s stream: %d x %d buffers (%dkB total)\n",
195 s->dma != PCI_DMA_NONE ? "DMA " : "",
196 s->name, s->buffers, s->buf_size, s->buffers * s->buf_size / 1024);
197
198 /* Allocate DMA SG Arrays */
199 if (s->dma != PCI_DMA_NONE) {
200 s->SGarray = (struct ivtv_SG_element *)kzalloc(SGsize, GFP_KERNEL);
201 if (s->SGarray == NULL) {
202 IVTV_ERR("Could not allocate SGarray for %s stream\n", s->name);
203 return -ENOMEM;
204 }
205 s->SG_length = 0;
206 s->SG_handle = pci_map_single(itv->dev, s->SGarray, SGsize, s->dma);
207 ivtv_stream_sync_for_cpu(s);
208 }
209
210 /* allocate stream buffers. Initially all buffers are in q_free. */
211 for (i = 0; i < s->buffers; i++) {
212 struct ivtv_buffer *buf = kzalloc(sizeof(struct ivtv_buffer), GFP_KERNEL);
213
214 if (buf == NULL)
215 break;
216 buf->buf = kmalloc(s->buf_size + 256, GFP_KERNEL);
217 if (buf->buf == NULL) {
218 kfree(buf);
219 break;
220 }
221 INIT_LIST_HEAD(&buf->list);
222 if (s->dma != PCI_DMA_NONE) {
223 buf->dma_handle = pci_map_single(s->itv->dev,
224 buf->buf, s->buf_size + 256, s->dma);
225 ivtv_buf_sync_for_cpu(s, buf);
226 }
227 ivtv_enqueue(s, buf, &s->q_free);
228 }
229 if (i == s->buffers)
230 return 0;
231 IVTV_ERR("Couldn't allocate buffers for %s stream\n", s->name);
232 ivtv_stream_free(s);
233 return -ENOMEM;
234}
235
236void ivtv_stream_free(struct ivtv_stream *s)
237{
238 struct ivtv_buffer *buf;
239
240 /* move all buffers to q_free */
241 ivtv_flush_queues(s);
242
243 /* empty q_free */
244 while ((buf = ivtv_dequeue(s, &s->q_free))) {
245 if (s->dma != PCI_DMA_NONE)
246 pci_unmap_single(s->itv->dev, buf->dma_handle,
247 s->buf_size + 256, s->dma);
248 kfree(buf->buf);
249 kfree(buf);
250 }
251
252 /* Free SG Array/Lists */
253 if (s->SGarray != NULL) {
254 if (s->SG_handle != IVTV_DMA_UNMAPPED) {
255 pci_unmap_single(s->itv->dev, s->SG_handle,
256 sizeof(struct ivtv_SG_element) * s->buffers, PCI_DMA_TODEVICE);
257 s->SG_handle = IVTV_DMA_UNMAPPED;
258 }
259 s->SGarray = NULL;
260 s->SG_length = 0;
261 }
262}
diff --git a/drivers/media/video/ivtv/ivtv-queue.h b/drivers/media/video/ivtv/ivtv-queue.h
new file mode 100644
index 000000000000..903edd4b4381
--- /dev/null
+++ b/drivers/media/video/ivtv/ivtv-queue.h
@@ -0,0 +1,64 @@
1/*
2 buffer queues.
3 Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
4 Copyright (C) 2004 Chris Kennedy <c@groovy.org>
5 Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl>
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21
22#define IVTV_DMA_UNMAPPED ((u32) -1)
23
24/* ivtv_buffer utility functions */
25static inline void ivtv_buf_sync_for_cpu(struct ivtv_stream *s, struct ivtv_buffer *buf)
26{
27 if (s->dma != PCI_DMA_NONE)
28 pci_dma_sync_single_for_cpu(s->itv->dev, buf->dma_handle,
29 s->buf_size + 256, s->dma);
30}
31
32static inline void ivtv_buf_sync_for_device(struct ivtv_stream *s, struct ivtv_buffer *buf)
33{
34 if (s->dma != PCI_DMA_NONE)
35 pci_dma_sync_single_for_device(s->itv->dev, buf->dma_handle,
36 s->buf_size + 256, s->dma);
37}
38
39int ivtv_buf_copy_from_user(struct ivtv_stream *s, struct ivtv_buffer *buf, const char __user *src, int copybytes);
40void ivtv_buf_swap(struct ivtv_buffer *buf);
41
42/* ivtv_queue utility functions */
43void ivtv_queue_init(struct ivtv_queue *q);
44void ivtv_enqueue(struct ivtv_stream *s, struct ivtv_buffer *buf, struct ivtv_queue *q);
45struct ivtv_buffer *ivtv_dequeue(struct ivtv_stream *s, struct ivtv_queue *q);
46int ivtv_queue_move(struct ivtv_stream *s, struct ivtv_queue *from, struct ivtv_queue *steal,
47 struct ivtv_queue *to, int needed_bytes);
48void ivtv_flush_queues(struct ivtv_stream *s);
49
50/* ivtv_stream utility functions */
51int ivtv_stream_alloc(struct ivtv_stream *s);
52void ivtv_stream_free(struct ivtv_stream *s);
53
54static inline void ivtv_stream_sync_for_cpu(struct ivtv_stream *s)
55{
56 pci_dma_sync_single_for_cpu(s->itv->dev, s->SG_handle,
57 sizeof(struct ivtv_SG_element) * s->buffers, PCI_DMA_TODEVICE);
58}
59
60static inline void ivtv_stream_sync_for_device(struct ivtv_stream *s)
61{
62 pci_dma_sync_single_for_device(s->itv->dev, s->SG_handle,
63 sizeof(struct ivtv_SG_element) * s->buffers, PCI_DMA_TODEVICE);
64}
diff --git a/drivers/media/video/ivtv/ivtv-streams.c b/drivers/media/video/ivtv/ivtv-streams.c
new file mode 100644
index 000000000000..01a41a844a30
--- /dev/null
+++ b/drivers/media/video/ivtv/ivtv-streams.c
@@ -0,0 +1,977 @@
1/*
2 init/start/stop/exit stream functions
3 Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
4 Copyright (C) 2004 Chris Kennedy <c@groovy.org>
5 Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl>
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21
22/* License: GPL
23 * Author: Kevin Thayer <nufan_wfk at yahoo dot com>
24 *
25 * This file will hold API related functions, both internal (firmware api)
26 * and external (v4l2, etc)
27 *
28 * -----
29 * MPG600/MPG160 support by T.Adachi <tadachi@tadachi-net.com>
30 * and Takeru KOMORIYA<komoriya@paken.org>
31 *
32 * AVerMedia M179 GPIO info by Chris Pinkham <cpinkham@bc2va.org>
33 * using information provided by Jiun-Kuei Jung @ AVerMedia.
34 */
35
36#include "ivtv-driver.h"
37#include "ivtv-fileops.h"
38#include "ivtv-i2c.h"
39#include "ivtv-queue.h"
40#include "ivtv-mailbox.h"
41#include "ivtv-audio.h"
42#include "ivtv-video.h"
43#include "ivtv-vbi.h"
44#include "ivtv-ioctl.h"
45#include "ivtv-irq.h"
46#include "ivtv-streams.h"
47#include "ivtv-cards.h"
48
49static struct file_operations ivtv_v4l2_enc_fops = {
50 .owner = THIS_MODULE,
51 .read = ivtv_v4l2_read,
52 .write = ivtv_v4l2_write,
53 .open = ivtv_v4l2_open,
54 .ioctl = ivtv_v4l2_ioctl,
55 .release = ivtv_v4l2_close,
56 .poll = ivtv_v4l2_enc_poll,
57};
58
59static struct file_operations ivtv_v4l2_dec_fops = {
60 .owner = THIS_MODULE,
61 .read = ivtv_v4l2_read,
62 .write = ivtv_v4l2_write,
63 .open = ivtv_v4l2_open,
64 .ioctl = ivtv_v4l2_ioctl,
65 .release = ivtv_v4l2_close,
66 .poll = ivtv_v4l2_dec_poll,
67};
68
69static struct {
70 const char *name;
71 int vfl_type;
72 int minor_offset;
73 int dma, pio;
74 enum v4l2_buf_type buf_type;
75 struct file_operations *fops;
76} ivtv_stream_info[] = {
77 { /* IVTV_ENC_STREAM_TYPE_MPG */
78 "encoder MPEG",
79 VFL_TYPE_GRABBER, 0,
80 PCI_DMA_FROMDEVICE, 0, V4L2_BUF_TYPE_VIDEO_CAPTURE,
81 &ivtv_v4l2_enc_fops
82 },
83 { /* IVTV_ENC_STREAM_TYPE_YUV */
84 "encoder YUV",
85 VFL_TYPE_GRABBER, IVTV_V4L2_ENC_YUV_OFFSET,
86 PCI_DMA_FROMDEVICE, 0, V4L2_BUF_TYPE_VIDEO_CAPTURE,
87 &ivtv_v4l2_enc_fops
88 },
89 { /* IVTV_ENC_STREAM_TYPE_VBI */
90 "encoder VBI",
91 VFL_TYPE_VBI, 0,
92 PCI_DMA_FROMDEVICE, 0, V4L2_BUF_TYPE_VBI_CAPTURE,
93 &ivtv_v4l2_enc_fops
94 },
95 { /* IVTV_ENC_STREAM_TYPE_PCM */
96 "encoder PCM audio",
97 VFL_TYPE_GRABBER, IVTV_V4L2_ENC_PCM_OFFSET,
98 PCI_DMA_FROMDEVICE, 0, V4L2_BUF_TYPE_PRIVATE,
99 &ivtv_v4l2_enc_fops
100 },
101 { /* IVTV_ENC_STREAM_TYPE_RAD */
102 "encoder radio",
103 VFL_TYPE_RADIO, 0,
104 PCI_DMA_NONE, 1, V4L2_BUF_TYPE_PRIVATE,
105 &ivtv_v4l2_enc_fops
106 },
107 { /* IVTV_DEC_STREAM_TYPE_MPG */
108 "decoder MPEG",
109 VFL_TYPE_GRABBER, IVTV_V4L2_DEC_MPG_OFFSET,
110 PCI_DMA_TODEVICE, 0, V4L2_BUF_TYPE_VIDEO_OUTPUT,
111 &ivtv_v4l2_dec_fops
112 },
113 { /* IVTV_DEC_STREAM_TYPE_VBI */
114 "decoder VBI",
115 VFL_TYPE_VBI, IVTV_V4L2_DEC_VBI_OFFSET,
116 PCI_DMA_NONE, 1, V4L2_BUF_TYPE_VBI_CAPTURE,
117 &ivtv_v4l2_enc_fops
118 },
119 { /* IVTV_DEC_STREAM_TYPE_VOUT */
120 "decoder VOUT",
121 VFL_TYPE_VBI, IVTV_V4L2_DEC_VOUT_OFFSET,
122 PCI_DMA_NONE, 1, V4L2_BUF_TYPE_VBI_OUTPUT,
123 &ivtv_v4l2_dec_fops
124 },
125 { /* IVTV_DEC_STREAM_TYPE_YUV */
126 "decoder YUV",
127 VFL_TYPE_GRABBER, IVTV_V4L2_DEC_YUV_OFFSET,
128 PCI_DMA_TODEVICE, 0, V4L2_BUF_TYPE_VIDEO_OUTPUT,
129 &ivtv_v4l2_dec_fops
130 }
131};
132
133static void ivtv_stream_init(struct ivtv *itv, int type)
134{
135 struct ivtv_stream *s = &itv->streams[type];
136 struct video_device *dev = s->v4l2dev;
137
138 /* we need to keep v4l2dev, so restore it afterwards */
139 memset(s, 0, sizeof(*s));
140 s->v4l2dev = dev;
141
142 /* initialize ivtv_stream fields */
143 s->itv = itv;
144 s->type = type;
145 s->name = ivtv_stream_info[type].name;
146
147 if (ivtv_stream_info[type].pio)
148 s->dma = PCI_DMA_NONE;
149 else
150 s->dma = ivtv_stream_info[type].dma;
151 s->buf_size = itv->stream_buf_size[type];
152 if (s->buf_size)
153 s->buffers = itv->options.megabytes[type] * 1024 * 1024 / s->buf_size;
154 spin_lock_init(&s->qlock);
155 init_waitqueue_head(&s->waitq);
156 s->id = -1;
157 s->SG_handle = IVTV_DMA_UNMAPPED;
158 ivtv_queue_init(&s->q_free);
159 ivtv_queue_init(&s->q_full);
160 ivtv_queue_init(&s->q_dma);
161 ivtv_queue_init(&s->q_predma);
162 ivtv_queue_init(&s->q_io);
163}
164
165static int ivtv_reg_dev(struct ivtv *itv, int type)
166{
167 struct ivtv_stream *s = &itv->streams[type];
168 int vfl_type = ivtv_stream_info[type].vfl_type;
169 int minor_offset = ivtv_stream_info[type].minor_offset;
170 int minor;
171
172 /* These four fields are always initialized. If v4l2dev == NULL, then
173 this stream is not in use. In that case no other fields but these
174 four can be used. */
175 s->v4l2dev = NULL;
176 s->itv = itv;
177 s->type = type;
178 s->name = ivtv_stream_info[type].name;
179
180 /* Check whether the radio is supported */
181 if (type == IVTV_ENC_STREAM_TYPE_RAD && !(itv->v4l2_cap & V4L2_CAP_RADIO))
182 return 0;
183 if (type >= IVTV_DEC_STREAM_TYPE_MPG && !(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
184 return 0;
185
186 if (minor_offset >= 0)
187 /* card number + user defined offset + device offset */
188 minor = itv->num + ivtv_first_minor + minor_offset;
189 else
190 minor = -1;
191
192 /* User explicitly selected 0 buffers for these streams, so don't
193 create them. */
194 if (minor >= 0 && ivtv_stream_info[type].dma != PCI_DMA_NONE &&
195 itv->options.megabytes[type] == 0) {
196 IVTV_INFO("Disabled %s device\n", ivtv_stream_info[type].name);
197 return 0;
198 }
199
200 ivtv_stream_init(itv, type);
201
202 /* allocate and initialize the v4l2 video device structure */
203 s->v4l2dev = video_device_alloc();
204 if (s->v4l2dev == NULL) {
205 IVTV_ERR("Couldn't allocate v4l2 video_device for %s\n", s->name);
206 return -ENOMEM;
207 }
208
209 s->v4l2dev->type = VID_TYPE_CAPTURE | VID_TYPE_TUNER | VID_TYPE_TELETEXT |
210 VID_TYPE_CLIPPING | VID_TYPE_SCALES | VID_TYPE_MPEG_ENCODER;
211 if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) {
212 s->v4l2dev->type |= VID_TYPE_MPEG_DECODER;
213 }
214 snprintf(s->v4l2dev->name, sizeof(s->v4l2dev->name), "ivtv%d %s",
215 itv->num, s->name);
216
217 s->v4l2dev->minor = minor;
218 s->v4l2dev->dev = &itv->dev->dev;
219 s->v4l2dev->fops = ivtv_stream_info[type].fops;
220 s->v4l2dev->release = video_device_release;
221
222 if (minor >= 0) {
223 /* Register device. First try the desired minor, then any free one. */
224 if (video_register_device(s->v4l2dev, vfl_type, minor) &&
225 video_register_device(s->v4l2dev, vfl_type, -1)) {
226 IVTV_ERR("Couldn't register v4l2 device for %s minor %d\n",
227 s->name, minor);
228 video_device_release(s->v4l2dev);
229 s->v4l2dev = NULL;
230 return -ENOMEM;
231 }
232 }
233 else {
234 /* Don't register a 'hidden' stream (OSD) */
235 IVTV_INFO("Created framebuffer stream for %s\n", s->name);
236 return 0;
237 }
238
239 switch (vfl_type) {
240 case VFL_TYPE_GRABBER:
241 IVTV_INFO("Registered device video%d for %s (%d MB)\n",
242 s->v4l2dev->minor, s->name, itv->options.megabytes[type]);
243 break;
244 case VFL_TYPE_RADIO:
245 IVTV_INFO("Registered device radio%d for %s\n",
246 s->v4l2dev->minor - MINOR_VFL_TYPE_RADIO_MIN, s->name);
247 break;
248 case VFL_TYPE_VBI:
249 if (itv->options.megabytes[type])
250 IVTV_INFO("Registered device vbi%d for %s (%d MB)\n",
251 s->v4l2dev->minor - MINOR_VFL_TYPE_VBI_MIN,
252 s->name, itv->options.megabytes[type]);
253 else
254 IVTV_INFO("Registered device vbi%d for %s\n",
255 s->v4l2dev->minor - MINOR_VFL_TYPE_VBI_MIN, s->name);
256 break;
257 }
258 return 0;
259}
260
261/* Initialize v4l2 variables and register v4l2 devices */
262int ivtv_streams_setup(struct ivtv *itv)
263{
264 int type;
265
266 /* Setup V4L2 Devices */
267 for (type = 0; type < IVTV_MAX_STREAMS; type++) {
268 /* Register Device */
269 if (ivtv_reg_dev(itv, type))
270 break;
271
272 if (itv->streams[type].v4l2dev == NULL)
273 continue;
274
275 /* Allocate Stream */
276 if (ivtv_stream_alloc(&itv->streams[type]))
277 break;
278 }
279 if (type == IVTV_MAX_STREAMS) {
280 return 0;
281 }
282
283 /* One or more streams could not be initialized. Clean 'em all up. */
284 ivtv_streams_cleanup(itv);
285 return -ENOMEM;
286}
287
288/* Unregister v4l2 devices */
289void ivtv_streams_cleanup(struct ivtv *itv)
290{
291 int type;
292
293 /* Teardown all streams */
294 for (type = 0; type < IVTV_MAX_STREAMS; type++) {
295 struct video_device *vdev = itv->streams[type].v4l2dev;
296
297 itv->streams[type].v4l2dev = NULL;
298 if (vdev == NULL)
299 continue;
300
301 ivtv_stream_free(&itv->streams[type]);
302 /* Free Device */
303 if (vdev->minor == -1) /* 'Hidden' never registered stream (OSD) */
304 video_device_release(vdev);
305 else /* All others, just unregister. */
306 video_unregister_device(vdev);
307 }
308}
309
310static void ivtv_vbi_setup(struct ivtv *itv)
311{
312 int raw = itv->vbi.sliced_in->service_set == 0;
313 u32 data[CX2341X_MBOX_MAX_DATA];
314 int lines;
315 int i;
316
317 /* If Embed then streamtype must be Program */
318 /* TODO: should we really do this? */
319 if (0 && !raw && itv->vbi.insert_mpeg) {
320 itv->params.stream_type = 0;
321
322 /* assign stream type */
323 ivtv_vapi(itv, CX2341X_ENC_SET_STREAM_TYPE, 1, itv->params.stream_type);
324 }
325
326 /* Reset VBI */
327 ivtv_vapi(itv, CX2341X_ENC_SET_VBI_LINE, 5, 0xffff , 0, 0, 0, 0);
328
329 if (itv->is_60hz) {
330 itv->vbi.count = 12;
331 itv->vbi.start[0] = 10;
332 itv->vbi.start[1] = 273;
333 } else { /* PAL/SECAM */
334 itv->vbi.count = 18;
335 itv->vbi.start[0] = 6;
336 itv->vbi.start[1] = 318;
337 }
338
339 /* setup VBI registers */
340 itv->video_dec_func(itv, VIDIOC_S_FMT, &itv->vbi.in);
341
342 /* determine number of lines and total number of VBI bytes.
343 A raw line takes 1443 bytes: 2 * 720 + 4 byte frame header - 1
344 The '- 1' byte is probably an unused U or V byte. Or something...
345 A sliced line takes 51 bytes: 4 byte frame header, 4 byte internal
346 header, 42 data bytes + checksum (to be confirmed) */
347 if (raw) {
348 lines = itv->vbi.count * 2;
349 } else {
350 lines = itv->is_60hz ? 24 : 38;
351 if (itv->is_60hz && (itv->hw_flags & IVTV_HW_CX25840))
352 lines += 2;
353 }
354
355 itv->vbi.enc_size = lines * (raw ? itv->vbi.raw_size : itv->vbi.sliced_size);
356
357 /* Note: sliced vs raw flag doesn't seem to have any effect
358 TODO: check mode (0x02) value with older ivtv versions. */
359 data[0] = raw | 0x02 | (0xbd << 8);
360
361 /* Every X number of frames a VBI interrupt arrives (frames as in 25 or 30 fps) */
362 data[1] = 1;
363 /* The VBI frames are stored in a ringbuffer with this size (with a VBI frame as unit) */
364 data[2] = raw ? 4 : 8;
365 /* The start/stop codes determine which VBI lines end up in the raw VBI data area.
366 The codes are from table 24 in the saa7115 datasheet. Each raw/sliced/video line
367 is framed with codes FF0000XX where XX is the SAV/EAV (Start/End of Active Video)
368 code. These values for raw VBI are obtained from a driver disassembly. The sliced
369 start/stop codes was deduced from this, but they do not appear in the driver.
370 Other code pairs that I found are: 0x250E6249/0x13545454 and 0x25256262/0x38137F54.
371 However, I have no idea what these values are for. */
372 if (itv->hw_flags & IVTV_HW_CX25840) {
373 /* Setup VBI for the cx25840 digitizer */
374 if (raw) {
375 data[3] = 0x20602060;
376 data[4] = 0x30703070;
377 } else {
378 data[3] = 0xB0F0B0F0;
379 data[4] = 0xA0E0A0E0;
380 }
381 /* Lines per frame */
382 data[5] = lines;
383 /* bytes per line */
384 data[6] = (raw ? itv->vbi.raw_size : itv->vbi.sliced_size);
385 } else {
386 /* Setup VBI for the saa7115 digitizer */
387 if (raw) {
388 data[3] = 0x25256262;
389 data[4] = 0x387F7F7F;
390 } else {
391 data[3] = 0xABABECEC;
392 data[4] = 0xB6F1F1F1;
393 }
394 /* Lines per frame */
395 data[5] = lines;
396 /* bytes per line */
397 data[6] = itv->vbi.enc_size / lines;
398 }
399
400 IVTV_DEBUG_INFO(
401 "Setup VBI API header 0x%08x pkts %d buffs %d ln %d sz %d\n",
402 data[0], data[1], data[2], data[5], data[6]);
403
404 ivtv_api(itv, CX2341X_ENC_SET_VBI_CONFIG, 7, data);
405
406 /* returns the VBI encoder memory area. */
407 itv->vbi.enc_start = data[2];
408 itv->vbi.fpi = data[0];
409 if (!itv->vbi.fpi)
410 itv->vbi.fpi = 1;
411
412 IVTV_DEBUG_INFO("Setup VBI start 0x%08x frames %d fpi %d lines 0x%08x\n",
413 itv->vbi.enc_start, data[1], itv->vbi.fpi, itv->digitizer);
414
415 /* select VBI lines.
416 Note that the sliced argument seems to have no effect. */
417 for (i = 2; i <= 24; i++) {
418 int valid;
419
420 if (itv->is_60hz) {
421 valid = i >= 10 && i < 22;
422 } else {
423 valid = i >= 6 && i < 24;
424 }
425 ivtv_vapi(itv, CX2341X_ENC_SET_VBI_LINE, 5, i - 1,
426 valid, 0 , 0, 0);
427 ivtv_vapi(itv, CX2341X_ENC_SET_VBI_LINE, 5, (i - 1) | 0x80000000,
428 valid, 0, 0, 0);
429 }
430
431 /* Remaining VBI questions:
432 - Is it possible to select particular VBI lines only for inclusion in the MPEG
433 stream? Currently you can only get the first X lines.
434 - Is mixed raw and sliced VBI possible?
435 - What's the meaning of the raw/sliced flag?
436 - What's the meaning of params 2, 3 & 4 of the Select VBI command? */
437}
438
439int ivtv_start_v4l2_encode_stream(struct ivtv_stream *s)
440{
441 u32 data[CX2341X_MBOX_MAX_DATA];
442 struct ivtv *itv = s->itv;
443 int captype = 0, subtype = 0;
444 int enable_passthrough = 0;
445
446 if (s->v4l2dev == NULL)
447 return -EINVAL;
448
449 IVTV_DEBUG_INFO("Start encoder stream %s\n", s->name);
450
451 switch (s->type) {
452 case IVTV_ENC_STREAM_TYPE_MPG:
453 captype = 0;
454 subtype = 3;
455
456 /* Stop Passthrough */
457 if (itv->output_mode == OUT_PASSTHROUGH) {
458 ivtv_passthrough_mode(itv, 0);
459 enable_passthrough = 1;
460 }
461 itv->mpg_data_received = itv->vbi_data_inserted = 0;
462 itv->dualwatch_jiffies = jiffies;
463 itv->dualwatch_stereo_mode = itv->params.audio_properties & 0x0300;
464 itv->search_pack_header = 0;
465 break;
466
467 case IVTV_ENC_STREAM_TYPE_YUV:
468 if (itv->output_mode == OUT_PASSTHROUGH) {
469 captype = 2;
470 subtype = 11; /* video+audio+decoder */
471 break;
472 }
473 captype = 1;
474 subtype = 1;
475 break;
476 case IVTV_ENC_STREAM_TYPE_PCM:
477 captype = 1;
478 subtype = 2;
479 break;
480 case IVTV_ENC_STREAM_TYPE_VBI:
481 captype = 1;
482 subtype = 4;
483
484 itv->vbi.frame = 0;
485 itv->vbi.inserted_frame = 0;
486 memset(itv->vbi.sliced_mpeg_size,
487 0, sizeof(itv->vbi.sliced_mpeg_size));
488 break;
489 default:
490 return -EINVAL;
491 }
492 s->subtype = subtype;
493 s->buffers_stolen = 0;
494
495 /* mute/unmute video */
496 ivtv_vapi(itv, CX2341X_ENC_MUTE_VIDEO, 1, test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags) ? 1 : 0);
497
498 /* Clear Streamoff flags in case left from last capture */
499 clear_bit(IVTV_F_S_STREAMOFF, &s->s_flags);
500
501 if (atomic_read(&itv->capturing) == 0) {
502 /* Always use frame based mode. Experiments have demonstrated that byte
503 stream based mode results in dropped frames and corruption. Not often,
504 but occasionally. Many thanks go to Leonard Orb who spent a lot of
505 effort and time trying to trace the cause of the drop outs. */
506 /* 1 frame per DMA */
507 /*ivtv_vapi(itv, CX2341X_ENC_SET_DMA_BLOCK_SIZE, 2, 128, 0); */
508 ivtv_vapi(itv, CX2341X_ENC_SET_DMA_BLOCK_SIZE, 2, 1, 1);
509
510 /* Stuff from Windows, we don't know what it is */
511 ivtv_vapi(itv, CX2341X_ENC_SET_VERT_CROP_LINE, 1, 0);
512 /* According to the docs, this should be correct. However, this is
513 untested. I don't dare enable this without having tested it.
514 Only very few old cards actually have this hardware combination.
515 ivtv_vapi(itv, CX2341X_ENC_SET_VERT_CROP_LINE, 1,
516 ((itv->hw_flags & IVTV_HW_SAA7114) && itv->is_60hz) ? 10001 : 0);
517 */
518 ivtv_vapi(itv, CX2341X_ENC_MISC, 2, 3, !itv->has_cx23415);
519 ivtv_vapi(itv, CX2341X_ENC_MISC, 2, 8, 0);
520 ivtv_vapi(itv, CX2341X_ENC_MISC, 2, 4, 1);
521 ivtv_vapi(itv, CX2341X_ENC_MISC, 1, 12);
522
523 /* assign placeholder */
524 ivtv_vapi(itv, CX2341X_ENC_SET_PLACEHOLDER, 12,
525 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
526
527 ivtv_vapi(itv, CX2341X_ENC_SET_NUM_VSYNC_LINES, 2, itv->digitizer, itv->digitizer);
528
529 /* Setup VBI */
530 if (itv->v4l2_cap & V4L2_CAP_VBI_CAPTURE) {
531 ivtv_vbi_setup(itv);
532 }
533
534 /* assign program index info. Mask 7: select I/P/B, Num_req: 400 max */
535 ivtv_vapi_result(itv, data, CX2341X_ENC_SET_PGM_INDEX_INFO, 2, 7, 400);
536 itv->pgm_info_offset = data[0];
537 itv->pgm_info_num = data[1];
538 itv->pgm_info_write_idx = 0;
539 itv->pgm_info_read_idx = 0;
540
541 IVTV_DEBUG_INFO("PGM Index at 0x%08x with %d elements\n",
542 itv->pgm_info_offset, itv->pgm_info_num);
543
544 /* Setup API for Stream */
545 cx2341x_update(itv, ivtv_api_func, NULL, &itv->params);
546 }
547
548 /* Vsync Setup */
549 if (itv->has_cx23415 && !test_and_set_bit(IVTV_F_I_DIG_RST, &itv->i_flags)) {
550 /* event notification (on) */
551 ivtv_vapi(itv, CX2341X_ENC_SET_EVENT_NOTIFICATION, 4, 0, 1, IVTV_IRQ_ENC_VIM_RST, -1);
552 ivtv_clear_irq_mask(itv, IVTV_IRQ_ENC_VIM_RST);
553 }
554
555 if (atomic_read(&itv->capturing) == 0) {
556 /* Clear all Pending Interrupts */
557 ivtv_set_irq_mask(itv, IVTV_IRQ_MASK_CAPTURE);
558
559 clear_bit(IVTV_F_I_EOS, &itv->i_flags);
560
561 /* Initialize Digitizer for Capture */
562 ivtv_vapi(itv, CX2341X_ENC_INITIALIZE_INPUT, 0);
563
564 ivtv_sleep_timeout(HZ / 10, 0);
565 }
566
567 /* begin_capture */
568 if (ivtv_vapi(itv, CX2341X_ENC_START_CAPTURE, 2, captype, subtype))
569 {
570 IVTV_DEBUG_WARN( "Error starting capture!\n");
571 return -EINVAL;
572 }
573
574 /* Start Passthrough */
575 if (enable_passthrough) {
576 ivtv_passthrough_mode(itv, 1);
577 }
578
579 if (s->type == IVTV_ENC_STREAM_TYPE_VBI)
580 ivtv_clear_irq_mask(itv, IVTV_IRQ_ENC_VBI_CAP);
581 else
582 ivtv_clear_irq_mask(itv, IVTV_IRQ_MASK_CAPTURE);
583
584 /* you're live! sit back and await interrupts :) */
585 atomic_inc(&itv->capturing);
586 return 0;
587}
588
589static int ivtv_setup_v4l2_decode_stream(struct ivtv_stream *s)
590{
591 u32 data[CX2341X_MBOX_MAX_DATA];
592 struct ivtv *itv = s->itv;
593 int datatype;
594
595 if (s->v4l2dev == NULL)
596 return -EINVAL;
597
598 IVTV_DEBUG_INFO("Setting some initial decoder settings\n");
599
600 /* disable VBI signals, if the MPEG stream contains VBI data,
601 then that data will be processed automatically for you. */
602 ivtv_disable_vbi(itv);
603
604 /* set audio mode to left/stereo for dual/stereo mode. */
605 ivtv_vapi(itv, CX2341X_DEC_SET_AUDIO_MODE, 2, itv->audio_bilingual_mode, itv->audio_stereo_mode);
606
607 /* set number of internal decoder buffers */
608 ivtv_vapi(itv, CX2341X_DEC_SET_DISPLAY_BUFFERS, 1, 0);
609
610 /* prebuffering */
611 ivtv_vapi(itv, CX2341X_DEC_SET_PREBUFFERING, 1, 1);
612
613 /* extract from user packets */
614 ivtv_vapi_result(itv, data, CX2341X_DEC_EXTRACT_VBI, 1, 1);
615 itv->vbi.dec_start = data[0];
616
617 IVTV_DEBUG_INFO("Decoder VBI RE-Insert start 0x%08x size 0x%08x\n",
618 itv->vbi.dec_start, data[1]);
619
620 /* set decoder source settings */
621 /* Data type: 0 = mpeg from host,
622 1 = yuv from encoder,
623 2 = yuv_from_host */
624 switch (s->type) {
625 case IVTV_DEC_STREAM_TYPE_YUV:
626 datatype = itv->output_mode == OUT_PASSTHROUGH ? 1 : 2;
627 IVTV_DEBUG_INFO("Setup DEC YUV Stream data[0] = %d\n", datatype);
628 break;
629 case IVTV_DEC_STREAM_TYPE_MPG:
630 default:
631 datatype = 0;
632 break;
633 }
634 if (ivtv_vapi(itv, CX2341X_DEC_SET_DECODER_SOURCE, 4, datatype,
635 itv->params.width, itv->params.height, itv->params.audio_properties)) {
636 IVTV_DEBUG_WARN("COULDN'T INITIALIZE DECODER SOURCE\n");
637 }
638 return 0;
639}
640
641int ivtv_start_v4l2_decode_stream(struct ivtv_stream *s, int gop_offset)
642{
643 struct ivtv *itv = s->itv;
644
645 if (s->v4l2dev == NULL)
646 return -EINVAL;
647
648 if (test_and_set_bit(IVTV_F_S_STREAMING, &s->s_flags))
649 return 0; /* already started */
650
651 IVTV_DEBUG_INFO("Starting decode stream %s (gop_offset %d)\n", s->name, gop_offset);
652
653 /* Clear Streamoff */
654 if (s->type == IVTV_DEC_STREAM_TYPE_YUV) {
655 /* Initialize Decoder */
656 /* Reprogram Decoder YUV Buffers for YUV */
657 write_reg(yuv_offset[0] >> 4, 0x82c);
658 write_reg((yuv_offset[0] + IVTV_YUV_BUFFER_UV_OFFSET) >> 4, 0x830);
659 write_reg(yuv_offset[0] >> 4, 0x834);
660 write_reg((yuv_offset[0] + IVTV_YUV_BUFFER_UV_OFFSET) >> 4, 0x838);
661
662 write_reg_sync(0x00000000 | (0x0c << 16) | (0x0b << 8), 0x2d24);
663
664 write_reg_sync(0x00108080, 0x2898);
665 /* Enable YUV decoder output */
666 write_reg_sync(0x01, IVTV_REG_VDM);
667 }
668
669 ivtv_setup_v4l2_decode_stream(s);
670
671 /* set dma size to 65536 bytes */
672 ivtv_vapi(itv, CX2341X_DEC_SET_DMA_BLOCK_SIZE, 1, 65536);
673
674 clear_bit(IVTV_F_S_STREAMOFF, &s->s_flags);
675
676 /* Zero out decoder counters */
677 writel(0, &itv->dec_mbox.mbox[IVTV_MBOX_FIELD_DISPLAYED].data[0]);
678 writel(0, &itv->dec_mbox.mbox[IVTV_MBOX_FIELD_DISPLAYED].data[1]);
679 writel(0, &itv->dec_mbox.mbox[IVTV_MBOX_FIELD_DISPLAYED].data[2]);
680 writel(0, &itv->dec_mbox.mbox[IVTV_MBOX_FIELD_DISPLAYED].data[3]);
681 writel(0, &itv->dec_mbox.mbox[IVTV_MBOX_DMA].data[0]);
682 writel(0, &itv->dec_mbox.mbox[IVTV_MBOX_DMA].data[1]);
683 writel(0, &itv->dec_mbox.mbox[IVTV_MBOX_DMA].data[2]);
684 writel(0, &itv->dec_mbox.mbox[IVTV_MBOX_DMA].data[3]);
685
686 /* turn on notification of dual/stereo mode change */
687 ivtv_vapi(itv, CX2341X_DEC_SET_EVENT_NOTIFICATION, 4, 0, 1, IVTV_IRQ_DEC_AUD_MODE_CHG, -1);
688
689 /* start playback */
690 ivtv_vapi(itv, CX2341X_DEC_START_PLAYBACK, 2, gop_offset, 0);
691
692 /* Clear the following Interrupt mask bits for decoding */
693 ivtv_clear_irq_mask(itv, IVTV_IRQ_MASK_DECODE);
694 IVTV_DEBUG_IRQ("IRQ Mask is now: 0x%08x\n", itv->irqmask);
695
696 /* you're live! sit back and await interrupts :) */
697 atomic_inc(&itv->decoding);
698 return 0;
699}
700
701void ivtv_stop_all_captures(struct ivtv *itv)
702{
703 int i;
704
705 for (i = IVTV_MAX_STREAMS - 1; i >= 0; i--) {
706 struct ivtv_stream *s = &itv->streams[i];
707
708 if (s->v4l2dev == NULL)
709 continue;
710 if (test_bit(IVTV_F_S_STREAMING, &s->s_flags)) {
711 ivtv_stop_v4l2_encode_stream(s, 0);
712 }
713 }
714}
715
716int ivtv_stop_v4l2_encode_stream(struct ivtv_stream *s, int gop_end)
717{
718 struct ivtv *itv = s->itv;
719 DECLARE_WAITQUEUE(wait, current);
720 int cap_type;
721 unsigned long then;
722 int stopmode;
723 u32 data[CX2341X_MBOX_MAX_DATA];
724
725 if (s->v4l2dev == NULL)
726 return -EINVAL;
727
728 /* This function assumes that you are allowed to stop the capture
729 and that we are actually capturing */
730
731 IVTV_DEBUG_INFO("Stop Capture\n");
732
733 if (s->type == IVTV_DEC_STREAM_TYPE_VOUT)
734 return 0;
735 if (atomic_read(&itv->capturing) == 0)
736 return 0;
737
738 switch (s->type) {
739 case IVTV_ENC_STREAM_TYPE_YUV:
740 cap_type = 1;
741 break;
742 case IVTV_ENC_STREAM_TYPE_PCM:
743 cap_type = 1;
744 break;
745 case IVTV_ENC_STREAM_TYPE_VBI:
746 cap_type = 1;
747 break;
748 case IVTV_ENC_STREAM_TYPE_MPG:
749 default:
750 cap_type = 0;
751 break;
752 }
753
754 /* Stop Capture Mode */
755 if (s->type == IVTV_ENC_STREAM_TYPE_MPG && gop_end) {
756 stopmode = 0;
757 } else {
758 stopmode = 1;
759 }
760
761 /* end_capture */
762 /* when: 0 = end of GOP 1 = NOW!, type: 0 = mpeg, subtype: 3 = video+audio */
763 ivtv_vapi(itv, CX2341X_ENC_STOP_CAPTURE, 3, stopmode, cap_type, s->subtype);
764
765 /* only run these if we're shutting down the last cap */
766 if (atomic_read(&itv->capturing) - 1 == 0) {
767 /* event notification (off) */
768 if (test_and_clear_bit(IVTV_F_I_DIG_RST, &itv->i_flags)) {
769 /* type: 0 = refresh */
770 /* on/off: 0 = off, intr: 0x10000000, mbox_id: -1: none */
771 ivtv_vapi(itv, CX2341X_ENC_SET_EVENT_NOTIFICATION, 4, 0, 0, IVTV_IRQ_ENC_VIM_RST, -1);
772 ivtv_set_irq_mask(itv, IVTV_IRQ_ENC_VIM_RST);
773 }
774 }
775
776 then = jiffies;
777
778 if (!test_bit(IVTV_F_S_PASSTHROUGH, &s->s_flags)) {
779 if (s->type == IVTV_ENC_STREAM_TYPE_MPG && gop_end) {
780 /* only run these if we're shutting down the last cap */
781 unsigned long duration;
782
783 then = jiffies;
784 add_wait_queue(&itv->cap_w, &wait);
785
786 set_current_state(TASK_INTERRUPTIBLE);
787
788 /* wait 2s for EOS interrupt */
789 while (!test_bit(IVTV_F_I_EOS, &itv->i_flags) && jiffies < then + 2 * HZ) {
790 schedule_timeout(HZ / 100);
791 }
792
793 /* To convert jiffies to ms, we must multiply by 1000
794 * and divide by HZ. To avoid runtime division, we
795 * convert this to multiplication by 1000/HZ.
796 * Since integer division truncates, we get the best
797 * accuracy if we do a rounding calculation of the constant.
798 * Think of the case where HZ is 1024.
799 */
800 duration = ((1000 + HZ / 2) / HZ) * (jiffies - then);
801
802 if (!test_bit(IVTV_F_I_EOS, &itv->i_flags)) {
803 IVTV_DEBUG_WARN("%s: EOS interrupt not received! stopping anyway.\n", s->name);
804 IVTV_DEBUG_WARN("%s: waited %lu ms.\n", s->name, duration);
805 } else {
806 IVTV_DEBUG_INFO("%s: EOS took %lu ms to occur.\n", s->name, duration);
807 }
808 set_current_state(TASK_RUNNING);
809 remove_wait_queue(&itv->cap_w, &wait);
810 }
811
812 then = jiffies;
813 /* Make sure DMA is complete */
814 add_wait_queue(&s->waitq, &wait);
815 set_current_state(TASK_INTERRUPTIBLE);
816 do {
817 /* check if DMA is pending */
818 if ((s->type == IVTV_ENC_STREAM_TYPE_MPG) && /* MPG Only */
819 (read_reg(IVTV_REG_DMASTATUS) & 0x02)) {
820 /* Check for last DMA */
821 ivtv_vapi_result(itv, data, CX2341X_ENC_GET_SEQ_END, 2, 0, 0);
822
823 if (data[0] == 1) {
824 IVTV_DEBUG_DMA("%s: Last DMA of size 0x%08x\n", s->name, data[1]);
825 break;
826 }
827 } else if (read_reg(IVTV_REG_DMASTATUS) & 0x02) {
828 break;
829 }
830
831 ivtv_sleep_timeout(HZ / 100, 1);
832 } while (then + HZ * 2 > jiffies);
833
834 set_current_state(TASK_RUNNING);
835 remove_wait_queue(&s->waitq, &wait);
836 }
837
838 atomic_dec(&itv->capturing);
839
840 /* Clear capture and no-read bits */
841 clear_bit(IVTV_F_S_STREAMING, &s->s_flags);
842
843 if (s->type == IVTV_ENC_STREAM_TYPE_VBI)
844 ivtv_set_irq_mask(itv, IVTV_IRQ_ENC_VBI_CAP);
845
846 if (atomic_read(&itv->capturing) > 0) {
847 return 0;
848 }
849
850 /* Set the following Interrupt mask bits for capture */
851 ivtv_set_irq_mask(itv, IVTV_IRQ_MASK_CAPTURE);
852
853 wake_up(&s->waitq);
854
855 return 0;
856}
857
858int ivtv_stop_v4l2_decode_stream(struct ivtv_stream *s, int flags, u64 pts)
859{
860 struct ivtv *itv = s->itv;
861
862 if (s->v4l2dev == NULL)
863 return -EINVAL;
864
865 if (s->type != IVTV_DEC_STREAM_TYPE_YUV && s->type != IVTV_DEC_STREAM_TYPE_MPG)
866 return -EINVAL;
867
868 if (!test_bit(IVTV_F_S_STREAMING, &s->s_flags))
869 return 0;
870
871 IVTV_DEBUG_INFO("Stop Decode at %llu, flags: %x\n", pts, flags);
872
873 /* Stop Decoder */
874 if (!(flags & VIDEO_CMD_STOP_IMMEDIATELY) || pts) {
875 u32 tmp = 0;
876
877 /* Wait until the decoder is no longer running */
878 if (pts) {
879 ivtv_vapi(itv, CX2341X_DEC_STOP_PLAYBACK, 3,
880 0, (u32)(pts & 0xffffffff), (u32)(pts >> 32));
881 }
882 while (1) {
883 u32 data[CX2341X_MBOX_MAX_DATA];
884 ivtv_vapi_result(itv, data, CX2341X_DEC_GET_XFER_INFO, 0);
885 if (s->q_full.buffers + s->q_dma.buffers == 0) {
886 if (tmp == data[3])
887 break;
888 tmp = data[3];
889 }
890 if (ivtv_sleep_timeout(HZ/10, 1))
891 break;
892 }
893 }
894 ivtv_vapi(itv, CX2341X_DEC_STOP_PLAYBACK, 3, flags & VIDEO_CMD_STOP_TO_BLACK, 0, 0);
895
896 /* turn off notification of dual/stereo mode change */
897 ivtv_vapi(itv, CX2341X_DEC_SET_EVENT_NOTIFICATION, 4, 0, 0, IVTV_IRQ_DEC_AUD_MODE_CHG, -1);
898
899 ivtv_set_irq_mask(itv, IVTV_IRQ_MASK_DECODE);
900
901 clear_bit(IVTV_F_S_NEEDS_DATA, &s->s_flags);
902 clear_bit(IVTV_F_S_STREAMING, &s->s_flags);
903 ivtv_flush_queues(s);
904
905 if (!test_bit(IVTV_F_S_PASSTHROUGH, &s->s_flags)) {
906 /* disable VBI on TV-out */
907 ivtv_disable_vbi(itv);
908 }
909
910 /* decrement decoding */
911 atomic_dec(&itv->decoding);
912
913 set_bit(IVTV_F_I_EV_DEC_STOPPED, &itv->i_flags);
914 wake_up(&itv->event_waitq);
915
916 /* wake up wait queues */
917 wake_up(&s->waitq);
918
919 return 0;
920}
921
922int ivtv_passthrough_mode(struct ivtv *itv, int enable)
923{
924 struct ivtv_stream *yuv_stream = &itv->streams[IVTV_ENC_STREAM_TYPE_YUV];
925 struct ivtv_stream *dec_stream = &itv->streams[IVTV_DEC_STREAM_TYPE_YUV];
926
927 if (yuv_stream->v4l2dev == NULL || dec_stream->v4l2dev == NULL)
928 return -EINVAL;
929
930 IVTV_DEBUG_INFO("ivtv ioctl: Select passthrough mode\n");
931
932 /* Prevent others from starting/stopping streams while we
933 initiate/terminate passthrough mode */
934 if (enable) {
935 if (itv->output_mode == OUT_PASSTHROUGH) {
936 return 0;
937 }
938 if (ivtv_set_output_mode(itv, OUT_PASSTHROUGH) != OUT_PASSTHROUGH)
939 return -EBUSY;
940
941 /* Fully initialize stream, and then unflag init */
942 set_bit(IVTV_F_S_PASSTHROUGH, &dec_stream->s_flags);
943 set_bit(IVTV_F_S_STREAMING, &dec_stream->s_flags);
944
945 /* Setup YUV Decoder */
946 ivtv_setup_v4l2_decode_stream(dec_stream);
947
948 /* Start Decoder */
949 ivtv_vapi(itv, CX2341X_DEC_START_PLAYBACK, 2, 0, 1);
950 atomic_inc(&itv->decoding);
951
952 /* Setup capture if not already done */
953 if (atomic_read(&itv->capturing) == 0) {
954 cx2341x_update(itv, ivtv_api_func, NULL, &itv->params);
955 }
956
957 /* Start Passthrough Mode */
958 ivtv_vapi(itv, CX2341X_ENC_START_CAPTURE, 2, 2, 11);
959 atomic_inc(&itv->capturing);
960 return 0;
961 }
962
963 if (itv->output_mode != OUT_PASSTHROUGH)
964 return 0;
965
966 /* Stop Passthrough Mode */
967 ivtv_vapi(itv, CX2341X_ENC_STOP_CAPTURE, 3, 1, 2, 11);
968 ivtv_vapi(itv, CX2341X_DEC_STOP_PLAYBACK, 3, 1, 0, 0);
969
970 atomic_dec(&itv->capturing);
971 atomic_dec(&itv->decoding);
972 clear_bit(IVTV_F_S_PASSTHROUGH, &dec_stream->s_flags);
973 clear_bit(IVTV_F_S_STREAMING, &dec_stream->s_flags);
974 itv->output_mode = OUT_NONE;
975
976 return 0;
977}
diff --git a/drivers/media/video/ivtv/ivtv-streams.h b/drivers/media/video/ivtv/ivtv-streams.h
new file mode 100644
index 000000000000..8597b75384a7
--- /dev/null
+++ b/drivers/media/video/ivtv/ivtv-streams.h
@@ -0,0 +1,31 @@
1/*
2 init/start/stop/exit stream functions
3 Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
4 Copyright (C) 2005-2007 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21int ivtv_streams_setup(struct ivtv *itv);
22void ivtv_streams_cleanup(struct ivtv *itv);
23
24/* Capture related */
25int ivtv_start_v4l2_encode_stream(struct ivtv_stream *s);
26int ivtv_stop_v4l2_encode_stream(struct ivtv_stream *s, int gop_end);
27int ivtv_start_v4l2_decode_stream(struct ivtv_stream *s, int gop_offset);
28int ivtv_stop_v4l2_decode_stream(struct ivtv_stream *s, int flags, u64 pts);
29
30void ivtv_stop_all_captures(struct ivtv *itv);
31int ivtv_passthrough_mode(struct ivtv *itv, int enable);
diff --git a/drivers/media/video/ivtv/ivtv-udma.c b/drivers/media/video/ivtv/ivtv-udma.c
new file mode 100644
index 000000000000..bd642e1aafc3
--- /dev/null
+++ b/drivers/media/video/ivtv/ivtv-udma.c
@@ -0,0 +1,200 @@
1/*
2 User DMA
3
4 Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
5 Copyright (C) 2004 Chris Kennedy <c@groovy.org>
6 Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl>
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22
23#include "ivtv-driver.h"
24#include "ivtv-streams.h"
25#include "ivtv-udma.h"
26
27void ivtv_udma_get_page_info(struct ivtv_dma_page_info *dma_page, unsigned long first, unsigned long size)
28{
29 dma_page->uaddr = first & PAGE_MASK;
30 dma_page->offset = first & ~PAGE_MASK;
31 dma_page->tail = 1 + ((first+size-1) & ~PAGE_MASK);
32 dma_page->first = (first & PAGE_MASK) >> PAGE_SHIFT;
33 dma_page->last = ((first+size-1) & PAGE_MASK) >> PAGE_SHIFT;
34 dma_page->page_count = dma_page->last - dma_page->first + 1;
35 if (dma_page->page_count == 1) dma_page->tail -= dma_page->offset;
36}
37
38int ivtv_udma_fill_sg_list (struct ivtv_user_dma *dma, struct ivtv_dma_page_info *dma_page, int map_offset)
39{
40 int i, offset;
41
42 offset = dma_page->offset;
43
44 /* Fill SG Array with new values */
45 for (i = 0; i < dma_page->page_count; i++) {
46 if (i == dma_page->page_count - 1) {
47 dma->SGlist[map_offset].length = dma_page->tail;
48 }
49 else {
50 dma->SGlist[map_offset].length = PAGE_SIZE - offset;
51 }
52 dma->SGlist[map_offset].offset = offset;
53 dma->SGlist[map_offset].page = dma->map[map_offset];
54 offset = 0;
55 map_offset++;
56 }
57 return map_offset;
58}
59
60void ivtv_udma_fill_sg_array (struct ivtv_user_dma *dma, u32 buffer_offset, u32 buffer_offset_2, u32 split) {
61 int i;
62 struct scatterlist *sg;
63
64 for (i = 0, sg = dma->SGlist; i < dma->SG_length; i++, sg++) {
65 dma->SGarray[i].size = cpu_to_le32(sg_dma_len(sg));
66 dma->SGarray[i].src = cpu_to_le32(sg_dma_address(sg));
67 dma->SGarray[i].dst = cpu_to_le32(buffer_offset);
68 buffer_offset += sg_dma_len(sg);
69
70 split -= sg_dma_len(sg);
71 if (split == 0)
72 buffer_offset = buffer_offset_2;
73 }
74}
75
76/* User DMA Buffers */
77void ivtv_udma_alloc(struct ivtv *itv)
78{
79 if (itv->udma.SG_handle == 0) {
80 /* Map DMA Page Array Buffer */
81 itv->udma.SG_handle = pci_map_single(itv->dev, itv->udma.SGarray,
82 sizeof(itv->udma.SGarray), PCI_DMA_TODEVICE);
83 ivtv_udma_sync_for_cpu(itv);
84 }
85}
86
87int ivtv_udma_setup(struct ivtv *itv, unsigned long ivtv_dest_addr,
88 void __user *userbuf, int size_in_bytes)
89{
90 struct ivtv_dma_page_info user_dma;
91 struct ivtv_user_dma *dma = &itv->udma;
92 int err;
93
94 IVTV_DEBUG_DMA("ivtv_udma_setup, dst: 0x%08x\n", (unsigned int)ivtv_dest_addr);
95
96 /* Still in USE */
97 if (dma->SG_length || dma->page_count) {
98 IVTV_DEBUG_WARN("ivtv_udma_setup: SG_length %d page_count %d still full?\n",
99 dma->SG_length, dma->page_count);
100 return -EBUSY;
101 }
102
103 ivtv_udma_get_page_info(&user_dma, (unsigned long)userbuf, size_in_bytes);
104
105 if (user_dma.page_count <= 0) {
106 IVTV_DEBUG_WARN("ivtv_udma_setup: Error %d page_count from %d bytes %d offset\n",
107 user_dma.page_count, size_in_bytes, user_dma.offset);
108 return -EINVAL;
109 }
110
111 /* Get user pages for DMA Xfer */
112 down_read(&current->mm->mmap_sem);
113 err = get_user_pages(current, current->mm,
114 user_dma.uaddr, user_dma.page_count, 0, 1, dma->map, NULL);
115 up_read(&current->mm->mmap_sem);
116
117 if (user_dma.page_count != err) {
118 IVTV_DEBUG_WARN("failed to map user pages, returned %d instead of %d\n",
119 err, user_dma.page_count);
120 return -EINVAL;
121 }
122
123 dma->page_count = user_dma.page_count;
124
125 /* Fill SG List with new values */
126 ivtv_udma_fill_sg_list(dma, &user_dma, 0);
127
128 /* Map SG List */
129 dma->SG_length = pci_map_sg(itv->dev, dma->SGlist, dma->page_count, PCI_DMA_TODEVICE);
130
131 /* Fill SG Array with new values */
132 ivtv_udma_fill_sg_array (dma, ivtv_dest_addr, 0, -1);
133
134 /* Tag SG Array with Interrupt Bit */
135 dma->SGarray[dma->SG_length - 1].size |= cpu_to_le32(0x80000000);
136
137 ivtv_udma_sync_for_device(itv);
138 return dma->page_count;
139}
140
141void ivtv_udma_unmap(struct ivtv *itv)
142{
143 struct ivtv_user_dma *dma = &itv->udma;
144 int i;
145
146 IVTV_DEBUG_INFO("ivtv_unmap_user_dma\n");
147
148 /* Nothing to free */
149 if (dma->page_count == 0)
150 return;
151
152 /* Unmap Scatterlist */
153 if (dma->SG_length) {
154 pci_unmap_sg(itv->dev, dma->SGlist, dma->page_count, PCI_DMA_TODEVICE);
155 dma->SG_length = 0;
156 }
157 /* sync DMA */
158 ivtv_udma_sync_for_cpu(itv);
159
160 /* Release User Pages */
161 for (i = 0; i < dma->page_count; i++) {
162 put_page(dma->map[i]);
163 }
164 dma->page_count = 0;
165}
166
167void ivtv_udma_free(struct ivtv *itv)
168{
169 /* Unmap SG Array */
170 if (itv->udma.SG_handle) {
171 pci_unmap_single(itv->dev, itv->udma.SG_handle,
172 sizeof(itv->udma.SGarray), PCI_DMA_TODEVICE);
173 }
174
175 /* Unmap Scatterlist */
176 if (itv->udma.SG_length) {
177 pci_unmap_sg(itv->dev, itv->udma.SGlist, itv->udma.page_count, PCI_DMA_TODEVICE);
178 }
179}
180
181void ivtv_udma_start(struct ivtv *itv)
182{
183 IVTV_DEBUG_DMA("start UDMA\n");
184 write_reg(itv->udma.SG_handle, IVTV_REG_DECDMAADDR);
185 write_reg_sync(read_reg(IVTV_REG_DMAXFER) | 0x01, IVTV_REG_DMAXFER);
186 set_bit(IVTV_F_I_DMA, &itv->i_flags);
187 set_bit(IVTV_F_I_UDMA, &itv->i_flags);
188}
189
190void ivtv_udma_prepare(struct ivtv *itv)
191{
192 unsigned long flags;
193
194 spin_lock_irqsave(&itv->dma_reg_lock, flags);
195 if (!test_bit(IVTV_F_I_DMA, &itv->i_flags))
196 ivtv_udma_start(itv);
197 else
198 set_bit(IVTV_F_I_UDMA_PENDING, &itv->i_flags);
199 spin_unlock_irqrestore(&itv->dma_reg_lock, flags);
200}
diff --git a/drivers/media/video/ivtv/ivtv-udma.h b/drivers/media/video/ivtv/ivtv-udma.h
new file mode 100644
index 000000000000..e131bccedec0
--- /dev/null
+++ b/drivers/media/video/ivtv/ivtv-udma.h
@@ -0,0 +1,43 @@
1/*
2 Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
3 Copyright (C) 2004 Chris Kennedy <c@groovy.org>
4 Copyright (C) 2006-2007 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21/* User DMA functions */
22void ivtv_udma_get_page_info(struct ivtv_dma_page_info *dma_page, unsigned long first, unsigned long size);
23int ivtv_udma_fill_sg_list(struct ivtv_user_dma *dma, struct ivtv_dma_page_info *dma_page, int map_offset);
24void ivtv_udma_fill_sg_array(struct ivtv_user_dma *dma, u32 buffer_offset, u32 buffer_offset_2, u32 split);
25int ivtv_udma_setup(struct ivtv *itv, unsigned long ivtv_dest_addr,
26 void __user *userbuf, int size_in_bytes);
27void ivtv_udma_unmap(struct ivtv *itv);
28void ivtv_udma_free(struct ivtv *itv);
29void ivtv_udma_alloc(struct ivtv *itv);
30void ivtv_udma_prepare(struct ivtv *itv);
31void ivtv_udma_start(struct ivtv *itv);
32
33static inline void ivtv_udma_sync_for_device(struct ivtv *itv)
34{
35 pci_dma_sync_single_for_device((struct pci_dev *)itv->dev, itv->udma.SG_handle,
36 sizeof(itv->udma.SGarray), PCI_DMA_TODEVICE);
37}
38
39static inline void ivtv_udma_sync_for_cpu(struct ivtv *itv)
40{
41 pci_dma_sync_single_for_cpu((struct pci_dev *)itv->dev, itv->udma.SG_handle,
42 sizeof(itv->udma.SGarray), PCI_DMA_TODEVICE);
43}
diff --git a/drivers/media/video/ivtv/ivtv-vbi.c b/drivers/media/video/ivtv/ivtv-vbi.c
new file mode 100644
index 000000000000..5efa5a867818
--- /dev/null
+++ b/drivers/media/video/ivtv/ivtv-vbi.c
@@ -0,0 +1,538 @@
1/*
2 Vertical Blank Interval support functions
3 Copyright (C) 2004-2007 Hans Verkuil <hverkuil@xs4all.nl>
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19
20#include "ivtv-driver.h"
21#include "ivtv-video.h"
22#include "ivtv-vbi.h"
23#include "ivtv-ioctl.h"
24#include "ivtv-queue.h"
25
26static int odd_parity(u8 c)
27{
28 c ^= (c >> 4);
29 c ^= (c >> 2);
30 c ^= (c >> 1);
31
32 return c & 1;
33}
34
35static void passthrough_vbi_data(struct ivtv *itv, int cnt)
36{
37 int wss = 0;
38 u8 cc[4] = { 0x80, 0x80, 0x80, 0x80 };
39 u8 vps[13];
40 int found_cc = 0;
41 int found_wss = 0;
42 int found_vps = 0;
43 int cc_pos = itv->vbi.cc_pos;
44 int i;
45
46 for (i = 0; i < cnt; i++) {
47 struct v4l2_sliced_vbi_data *d = itv->vbi.sliced_dec_data + i;
48
49 if (d->id == V4L2_SLICED_CAPTION_525 && d->line == 21) {
50 found_cc = 1;
51 if (d->field) {
52 cc[2] = d->data[0];
53 cc[3] = d->data[1];
54 } else {
55 cc[0] = d->data[0];
56 cc[1] = d->data[1];
57 }
58 }
59 else if (d->id == V4L2_SLICED_VPS && d->line == 16 && d->field == 0) {
60 memcpy(vps, d->data, sizeof(vps));
61 found_vps = 1;
62 }
63 else if (d->id == V4L2_SLICED_WSS_625 && d->line == 23 && d->field == 0) {
64 wss = d->data[0] | d->data[1] << 8;
65 found_wss = 1;
66 }
67 }
68
69 if (itv->vbi.wss_found != found_wss || itv->vbi.wss != wss) {
70 itv->vbi.wss = wss;
71 itv->vbi.wss_found = found_wss;
72 set_bit(IVTV_F_I_UPDATE_WSS, &itv->i_flags);
73 }
74
75 if (found_vps || itv->vbi.vps_found) {
76 itv->vbi.vps[0] = vps[2];
77 itv->vbi.vps[1] = vps[8];
78 itv->vbi.vps[2] = vps[9];
79 itv->vbi.vps[3] = vps[10];
80 itv->vbi.vps[4] = vps[11];
81 itv->vbi.vps_found = found_vps;
82 set_bit(IVTV_F_I_UPDATE_VPS, &itv->i_flags);
83 }
84
85 if (found_cc && cc_pos < sizeof(itv->vbi.cc_data_even)) {
86 itv->vbi.cc_data_odd[cc_pos] = cc[0];
87 itv->vbi.cc_data_odd[cc_pos + 1] = cc[1];
88 itv->vbi.cc_data_even[cc_pos] = cc[2];
89 itv->vbi.cc_data_even[cc_pos + 1] = cc[3];
90 itv->vbi.cc_pos = cc_pos + 2;
91 set_bit(IVTV_F_I_UPDATE_CC, &itv->i_flags);
92 }
93}
94
95static void copy_vbi_data(struct ivtv *itv, int lines, u32 pts_stamp)
96{
97 int line = 0;
98 int i;
99 u32 linemask[2] = { 0, 0 };
100 unsigned short size;
101 static const u8 mpeg_hdr_data[] = {
102 0x00, 0x00, 0x01, 0xba, 0x44, 0x00, 0x0c, 0x66,
103 0x24, 0x01, 0x01, 0xd1, 0xd3, 0xfa, 0xff, 0xff,
104 0x00, 0x00, 0x01, 0xbd, 0x00, 0x1a, 0x84, 0x80,
105 0x07, 0x21, 0x00, 0x5d, 0x63, 0xa7, 0xff, 0xff
106 };
107 const int sd = sizeof(mpeg_hdr_data); /* start of vbi data */
108 int idx = itv->vbi.frame % IVTV_VBI_FRAMES;
109 u8 *dst = &itv->vbi.sliced_mpeg_data[idx][0];
110
111 for (i = 0; i < lines; i++) {
112 int f, l;
113
114 if (itv->vbi.sliced_data[i].id == 0)
115 continue;
116
117 l = itv->vbi.sliced_data[i].line - 6;
118 f = itv->vbi.sliced_data[i].field;
119 if (f)
120 l += 18;
121 if (l < 32)
122 linemask[0] |= (1 << l);
123 else
124 linemask[1] |= (1 << (l - 32));
125 dst[sd + 12 + line * 43] = service2vbi(itv->vbi.sliced_data[i].id);
126 memcpy(dst + sd + 12 + line * 43 + 1, itv->vbi.sliced_data[i].data, 42);
127 line++;
128 }
129 memcpy(dst, mpeg_hdr_data, sizeof(mpeg_hdr_data));
130 if (line == 36) {
131 /* All lines are used, so there is no space for the linemask
132 (the max size of the VBI data is 36 * 43 + 4 bytes).
133 So in this case we use the magic number 'ITV0'. */
134 memcpy(dst + sd, "ITV0", 4);
135 memcpy(dst + sd + 4, dst + sd + 12, line * 43);
136 size = 4 + ((43 * line + 3) & ~3);
137 } else {
138 memcpy(dst + sd, "itv0", 4);
139 memcpy(dst + sd + 4, &linemask[0], 8);
140 size = 12 + ((43 * line + 3) & ~3);
141 }
142 dst[4+16] = (size + 10) >> 8;
143 dst[5+16] = (size + 10) & 0xff;
144 dst[9+16] = 0x21 | ((pts_stamp >> 29) & 0x6);
145 dst[10+16] = (pts_stamp >> 22) & 0xff;
146 dst[11+16] = 1 | ((pts_stamp >> 14) & 0xff);
147 dst[12+16] = (pts_stamp >> 7) & 0xff;
148 dst[13+16] = 1 | ((pts_stamp & 0x7f) << 1);
149 itv->vbi.sliced_mpeg_size[idx] = sd + size;
150}
151
152static int ivtv_convert_ivtv_vbi(struct ivtv *itv, u8 *p)
153{
154 u32 linemask[2];
155 int i, l, id2;
156 int line = 0;
157
158 if (!memcmp(p, "itv0", 4)) {
159 memcpy(linemask, p + 4, 8);
160 p += 12;
161 } else if (!memcmp(p, "ITV0", 4)) {
162 linemask[0] = 0xffffffff;
163 linemask[1] = 0xf;
164 p += 4;
165 } else {
166 /* unknown VBI data stream */
167 return 0;
168 }
169 for (i = 0; i < 36; i++) {
170 int err = 0;
171
172 if (i < 32 && !(linemask[0] & (1 << i)))
173 continue;
174 if (i >= 32 && !(linemask[1] & (1 << (i - 32))))
175 continue;
176 id2 = *p & 0xf;
177 switch (id2) {
178 case IVTV_SLICED_TYPE_TELETEXT_B:
179 id2 = V4L2_SLICED_TELETEXT_B;
180 break;
181 case IVTV_SLICED_TYPE_CAPTION_525:
182 id2 = V4L2_SLICED_CAPTION_525;
183 err = !odd_parity(p[1]) || !odd_parity(p[2]);
184 break;
185 case IVTV_SLICED_TYPE_VPS:
186 id2 = V4L2_SLICED_VPS;
187 break;
188 case IVTV_SLICED_TYPE_WSS_625:
189 id2 = V4L2_SLICED_WSS_625;
190 break;
191 default:
192 id2 = 0;
193 break;
194 }
195 if (err == 0) {
196 l = (i < 18) ? i + 6 : i - 18 + 6;
197 itv->vbi.sliced_dec_data[line].line = l;
198 itv->vbi.sliced_dec_data[line].field = i >= 18;
199 itv->vbi.sliced_dec_data[line].id = id2;
200 memcpy(itv->vbi.sliced_dec_data[line].data, p + 1, 42);
201 line++;
202 }
203 p += 43;
204 }
205 while (line < 36) {
206 itv->vbi.sliced_dec_data[line].id = 0;
207 itv->vbi.sliced_dec_data[line].line = 0;
208 itv->vbi.sliced_dec_data[line].field = 0;
209 line++;
210 }
211 return line * sizeof(itv->vbi.sliced_dec_data[0]);
212}
213
214ssize_t ivtv_write_vbi(struct ivtv *itv, const char __user *ubuf, size_t count)
215{
216 /* Should be a __user pointer, but sparse doesn't parse this bit correctly. */
217 const struct v4l2_sliced_vbi_data *p = (const struct v4l2_sliced_vbi_data *)ubuf;
218 u8 cc[4] = { 0x80, 0x80, 0x80, 0x80 };
219 int found_cc = 0;
220 int cc_pos = itv->vbi.cc_pos;
221
222 if (itv->vbi.service_set_out == 0)
223 return -EPERM;
224
225 while (count >= sizeof(struct v4l2_sliced_vbi_data)) {
226 switch (p->id) {
227 case V4L2_SLICED_CAPTION_525:
228 if (p->id == V4L2_SLICED_CAPTION_525 &&
229 p->line == 21 &&
230 (itv->vbi.service_set_out &
231 V4L2_SLICED_CAPTION_525) == 0) {
232 break;
233 }
234 found_cc = 1;
235 if (p->field) {
236 cc[2] = p->data[0];
237 cc[3] = p->data[1];
238 } else {
239 cc[0] = p->data[0];
240 cc[1] = p->data[1];
241 }
242 break;
243
244 case V4L2_SLICED_VPS:
245 if (p->line == 16 && p->field == 0 &&
246 (itv->vbi.service_set_out & V4L2_SLICED_VPS)) {
247 itv->vbi.vps[0] = p->data[2];
248 itv->vbi.vps[1] = p->data[8];
249 itv->vbi.vps[2] = p->data[9];
250 itv->vbi.vps[3] = p->data[10];
251 itv->vbi.vps[4] = p->data[11];
252 itv->vbi.vps_found = 1;
253 set_bit(IVTV_F_I_UPDATE_VPS, &itv->i_flags);
254 }
255 break;
256
257 case V4L2_SLICED_WSS_625:
258 if (p->line == 23 && p->field == 0 &&
259 (itv->vbi.service_set_out & V4L2_SLICED_WSS_625)) {
260 /* No lock needed for WSS */
261 itv->vbi.wss = p->data[0] | (p->data[1] << 8);
262 itv->vbi.wss_found = 1;
263 set_bit(IVTV_F_I_UPDATE_WSS, &itv->i_flags);
264 }
265 break;
266
267 default:
268 break;
269 }
270 count -= sizeof(*p);
271 p++;
272 }
273
274 if (found_cc && cc_pos < sizeof(itv->vbi.cc_data_even)) {
275 itv->vbi.cc_data_odd[cc_pos] = cc[0];
276 itv->vbi.cc_data_odd[cc_pos + 1] = cc[1];
277 itv->vbi.cc_data_even[cc_pos] = cc[2];
278 itv->vbi.cc_data_even[cc_pos + 1] = cc[3];
279 itv->vbi.cc_pos = cc_pos + 2;
280 set_bit(IVTV_F_I_UPDATE_CC, &itv->i_flags);
281 }
282
283 return (const char __user *)p - ubuf;
284}
285
286/* Compress raw VBI format, removes leading SAV codes and surplus space after the
287 field.
288 Returns new compressed size. */
289static u32 compress_raw_buf(struct ivtv *itv, u8 *buf, u32 size)
290{
291 u32 line_size = itv->vbi.raw_decoder_line_size;
292 u32 lines = itv->vbi.count;
293 u8 sav1 = itv->vbi.raw_decoder_sav_odd_field;
294 u8 sav2 = itv->vbi.raw_decoder_sav_even_field;
295 u8 *q = buf;
296 u8 *p;
297 int i;
298
299 for (i = 0; i < lines; i++) {
300 p = buf + i * line_size;
301
302 /* Look for SAV code */
303 if (p[0] != 0xff || p[1] || p[2] || (p[3] != sav1 && p[3] != sav2)) {
304 break;
305 }
306 memcpy(q, p + 4, line_size - 4);
307 q += line_size - 4;
308 }
309 return lines * (line_size - 4);
310}
311
312
313/* Compressed VBI format, all found sliced blocks put next to one another
314 Returns new compressed size */
315static u32 compress_sliced_buf(struct ivtv *itv, u32 line, u8 *buf, u32 size, u8 sav)
316{
317 u32 line_size = itv->vbi.sliced_decoder_line_size;
318 struct v4l2_decode_vbi_line vbi;
319 int i;
320
321 /* find the first valid line */
322 for (i = 0; i < size; i++, buf++) {
323 if (buf[0] == 0xff && !buf[1] && !buf[2] && buf[3] == sav)
324 break;
325 }
326
327 size -= i;
328 if (size < line_size) {
329 return line;
330 }
331 for (i = 0; i < size / line_size; i++) {
332 u8 *p = buf + i * line_size;
333
334 /* Look for SAV code */
335 if (p[0] != 0xff || p[1] || p[2] || p[3] != sav) {
336 continue;
337 }
338 vbi.p = p + 4;
339 itv->video_dec_func(itv, VIDIOC_INT_DECODE_VBI_LINE, &vbi);
340 if (vbi.type) {
341 itv->vbi.sliced_data[line].id = vbi.type;
342 itv->vbi.sliced_data[line].field = vbi.is_second_field;
343 itv->vbi.sliced_data[line].line = vbi.line;
344 memcpy(itv->vbi.sliced_data[line].data, vbi.p, 42);
345 line++;
346 }
347 }
348 return line;
349}
350
351void ivtv_process_vbi_data(struct ivtv *itv, struct ivtv_buffer *buf,
352 u64 pts_stamp, int streamtype)
353{
354 u8 *p = (u8 *) buf->buf;
355 u32 size = buf->bytesused;
356 int y;
357
358 /* Raw VBI data */
359 if (streamtype == IVTV_ENC_STREAM_TYPE_VBI && itv->vbi.sliced_in->service_set == 0) {
360 u8 type;
361
362 ivtv_buf_swap(buf);
363
364 type = p[3];
365
366 size = buf->bytesused = compress_raw_buf(itv, p, size);
367
368 /* second field of the frame? */
369 if (type == itv->vbi.raw_decoder_sav_even_field) {
370 /* Dirty hack needed for backwards
371 compatibility of old VBI software. */
372 p += size - 4;
373 memcpy(p, &itv->vbi.frame, 4);
374 itv->vbi.frame++;
375 }
376 return;
377 }
378
379 /* Sliced VBI data with data insertion */
380 if (streamtype == IVTV_ENC_STREAM_TYPE_VBI) {
381 int lines;
382
383 ivtv_buf_swap(buf);
384
385 /* first field */
386 lines = compress_sliced_buf(itv, 0, p, size / 2,
387 itv->vbi.sliced_decoder_sav_odd_field);
388 /* second field */
389 /* experimentation shows that the second half does not always begin
390 at the exact address. So start a bit earlier (hence 32). */
391 lines = compress_sliced_buf(itv, lines, p + size / 2 - 32, size / 2 + 32,
392 itv->vbi.sliced_decoder_sav_even_field);
393 /* always return at least one empty line */
394 if (lines == 0) {
395 itv->vbi.sliced_data[0].id = 0;
396 itv->vbi.sliced_data[0].line = 0;
397 itv->vbi.sliced_data[0].field = 0;
398 lines = 1;
399 }
400 buf->bytesused = size = lines * sizeof(itv->vbi.sliced_data[0]);
401 memcpy(p, &itv->vbi.sliced_data[0], size);
402
403 if (itv->vbi.insert_mpeg) {
404 copy_vbi_data(itv, lines, pts_stamp);
405 }
406 itv->vbi.frame++;
407 return;
408 }
409
410 /* Sliced VBI re-inserted from an MPEG stream */
411 if (streamtype == IVTV_DEC_STREAM_TYPE_VBI) {
412 /* If the size is not 4-byte aligned, then the starting address
413 for the swapping is also shifted. After swapping the data the
414 real start address of the VBI data is exactly 4 bytes after the
415 original start. It's a bit fiddly but it works like a charm.
416 Non-4-byte alignment happens when an lseek is done on the input
417 mpeg file to a non-4-byte aligned position. So on arrival here
418 the VBI data is also non-4-byte aligned. */
419 int offset = size & 3;
420 int cnt;
421
422 if (offset) {
423 p += 4 - offset;
424 }
425 /* Swap Buffer */
426 for (y = 0; y < size; y += 4) {
427 swab32s((u32 *)(p + y));
428 }
429
430 cnt = ivtv_convert_ivtv_vbi(itv, p + offset);
431 memcpy(buf->buf, itv->vbi.sliced_dec_data, cnt);
432 buf->bytesused = cnt;
433
434 passthrough_vbi_data(itv, cnt / sizeof(itv->vbi.sliced_dec_data[0]));
435 return;
436 }
437}
438
439void ivtv_disable_vbi(struct ivtv *itv)
440{
441 clear_bit(IVTV_F_I_UPDATE_WSS, &itv->i_flags);
442 clear_bit(IVTV_F_I_UPDATE_VPS, &itv->i_flags);
443 clear_bit(IVTV_F_I_UPDATE_CC, &itv->i_flags);
444 ivtv_set_wss(itv, 0, 0);
445 ivtv_set_cc(itv, 0, 0, 0, 0, 0);
446 ivtv_set_vps(itv, 0, 0, 0, 0, 0, 0);
447 itv->vbi.vps_found = itv->vbi.wss_found = 0;
448 itv->vbi.wss = 0;
449 itv->vbi.cc_pos = 0;
450}
451
452
453void vbi_work_handler(struct ivtv *itv)
454{
455 struct v4l2_sliced_vbi_data data;
456
457 /* Lock */
458 if (itv->output_mode == OUT_PASSTHROUGH) {
459 /* Note: currently only the saa7115 is used in a PVR350,
460 so these commands are for now saa7115 specific. */
461 if (itv->is_50hz) {
462 data.id = V4L2_SLICED_WSS_625;
463 data.field = 0;
464
465 if (itv->video_dec_func(itv, VIDIOC_INT_G_VBI_DATA, &data) == 0) {
466 ivtv_set_wss(itv, 1, data.data[0] & 0xf);
467 itv->vbi.wss_no_update = 0;
468 } else if (itv->vbi.wss_no_update == 4) {
469 ivtv_set_wss(itv, 1, 0x8); /* 4x3 full format */
470 } else {
471 itv->vbi.wss_no_update++;
472 }
473 }
474 else {
475 u8 c1 = 0, c2 = 0, c3 = 0, c4 = 0;
476 int mode = 0;
477
478 data.id = V4L2_SLICED_CAPTION_525;
479 data.field = 0;
480 if (itv->video_dec_func(itv, VIDIOC_INT_G_VBI_DATA, &data) == 0) {
481 mode |= 1;
482 c1 = data.data[0];
483 c2 = data.data[1];
484 }
485 data.field = 1;
486 if (itv->video_dec_func(itv, VIDIOC_INT_G_VBI_DATA, &data) == 0) {
487 mode |= 2;
488 c3 = data.data[0];
489 c4 = data.data[1];
490 }
491 if (mode) {
492 itv->vbi.cc_no_update = 0;
493 ivtv_set_cc(itv, mode, c1, c2, c3, c4);
494 } else if (itv->vbi.cc_no_update == 4) {
495 ivtv_set_cc(itv, 0, 0, 0, 0, 0);
496 } else {
497 itv->vbi.cc_no_update++;
498 }
499 }
500 return;
501 }
502
503 if (test_and_clear_bit(IVTV_F_I_UPDATE_WSS, &itv->i_flags)) {
504 /* Lock */
505 ivtv_set_wss(itv, itv->vbi.wss_found, itv->vbi.wss & 0xf);
506 }
507
508 if (test_and_clear_bit(IVTV_F_I_UPDATE_CC, &itv->i_flags)) {
509 if (itv->vbi.cc_pos == 0) {
510 ivtv_set_cc(itv, 3, 0x80, 0x80, 0x80, 0x80);
511 }
512 while (itv->vbi.cc_pos) {
513 u8 cc_odd0 = itv->vbi.cc_data_odd[0];
514 u8 cc_odd1 = itv->vbi.cc_data_odd[1];
515 u8 cc_even0 = itv->vbi.cc_data_even[0];
516 u8 cc_even1 = itv->vbi.cc_data_even[1];
517
518 memcpy(itv->vbi.cc_data_odd, itv->vbi.cc_data_odd + 2, sizeof(itv->vbi.cc_data_odd) - 2);
519 memcpy(itv->vbi.cc_data_even, itv->vbi.cc_data_even + 2, sizeof(itv->vbi.cc_data_even) - 2);
520 itv->vbi.cc_pos -= 2;
521 if (itv->vbi.cc_pos && cc_odd0 == 0x80 && cc_odd1 == 0x80)
522 continue;
523
524 /* Send to Saa7127 */
525 ivtv_set_cc(itv, 3, cc_odd0, cc_odd1, cc_even0, cc_even1);
526 if (itv->vbi.cc_pos == 0)
527 set_bit(IVTV_F_I_UPDATE_CC, &itv->i_flags);
528 break;
529 }
530 }
531
532 if (test_and_clear_bit(IVTV_F_I_UPDATE_VPS, &itv->i_flags)) {
533 /* Lock */
534 ivtv_set_vps(itv, itv->vbi.vps_found,
535 itv->vbi.vps[0], itv->vbi.vps[1],
536 itv->vbi.vps[2], itv->vbi.vps[3], itv->vbi.vps[4]);
537 }
538}
diff --git a/drivers/media/video/ivtv/ivtv-vbi.h b/drivers/media/video/ivtv/ivtv-vbi.h
new file mode 100644
index 000000000000..cdaea697b3ec
--- /dev/null
+++ b/drivers/media/video/ivtv/ivtv-vbi.h
@@ -0,0 +1,26 @@
1/*
2 Vertical Blank Interval support functions
3 Copyright (C) 2004-2007 Hans Verkuil <hverkuil@xs4all.nl>
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19
20ssize_t ivtv_write_vbi(struct ivtv *itv, const char __user *ubuf, size_t count);
21void ivtv_process_vbi_data(struct ivtv *itv, struct ivtv_buffer *buf,
22 u64 pts_stamp, int streamtype);
23int ivtv_used_line(struct ivtv *itv, int line, int field);
24void ivtv_disable_vbi(struct ivtv *itv);
25void ivtv_set_vbi(unsigned long arg);
26void vbi_work_handler(struct ivtv *itv);
diff --git a/drivers/media/video/ivtv/ivtv-version.h b/drivers/media/video/ivtv/ivtv-version.h
new file mode 100644
index 000000000000..85530a3cd369
--- /dev/null
+++ b/drivers/media/video/ivtv/ivtv-version.h
@@ -0,0 +1,26 @@
1/*
2 ivtv driver version information
3 Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl>
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19
20#define IVTV_DRIVER_NAME "ivtv"
21#define IVTV_DRIVER_VERSION_MAJOR 1
22#define IVTV_DRIVER_VERSION_MINOR 0
23#define IVTV_DRIVER_VERSION_PATCHLEVEL 0
24
25#define IVTV_VERSION __stringify(IVTV_DRIVER_VERSION_MAJOR) "." __stringify(IVTV_DRIVER_VERSION_MINOR) "." __stringify(IVTV_DRIVER_VERSION_PATCHLEVEL)
26#define IVTV_DRIVER_VERSION KERNEL_VERSION(IVTV_DRIVER_VERSION_MAJOR,IVTV_DRIVER_VERSION_MINOR,IVTV_DRIVER_VERSION_PATCHLEVEL)
diff --git a/drivers/media/video/ivtv/ivtv-video.c b/drivers/media/video/ivtv/ivtv-video.c
new file mode 100644
index 000000000000..5858b197d510
--- /dev/null
+++ b/drivers/media/video/ivtv/ivtv-video.c
@@ -0,0 +1,142 @@
1/*
2 saa7127 interface functions
3 Copyright (C) 2004-2007 Hans Verkuil <hverkuil@xs4all.nl>
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19
20#include "ivtv-driver.h"
21#include "ivtv-video.h"
22#include "ivtv-i2c.h"
23#include "ivtv-gpio.h"
24#include "ivtv-cards.h"
25#include <media/upd64031a.h>
26#include <media/upd64083.h>
27
28void ivtv_set_vps(struct ivtv *itv, int enabled, u8 vps1, u8 vps2, u8 vps3,
29 u8 vps4, u8 vps5)
30{
31 struct v4l2_sliced_vbi_data data;
32
33 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
34 return;
35 data.id = V4L2_SLICED_VPS;
36 data.field = 0;
37 data.line = enabled ? 16 : 0;
38 data.data[4] = vps1;
39 data.data[10] = vps2;
40 data.data[11] = vps3;
41 data.data[12] = vps4;
42 data.data[13] = vps5;
43 ivtv_saa7127(itv, VIDIOC_INT_S_VBI_DATA, &data);
44}
45
46void ivtv_set_cc(struct ivtv *itv, int mode, u8 cc1, u8 cc2, u8 cc3, u8 cc4)
47{
48 struct v4l2_sliced_vbi_data data;
49
50 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
51 return;
52 data.id = V4L2_SLICED_CAPTION_525;
53 data.field = 0;
54 data.line = (mode & 1) ? 21 : 0;
55 data.data[0] = cc1;
56 data.data[1] = cc2;
57 ivtv_saa7127(itv, VIDIOC_INT_S_VBI_DATA, &data);
58 data.field = 1;
59 data.line = (mode & 2) ? 21 : 0;
60 data.data[0] = cc3;
61 data.data[1] = cc4;
62 ivtv_saa7127(itv, VIDIOC_INT_S_VBI_DATA, &data);
63}
64
65void ivtv_set_wss(struct ivtv *itv, int enabled, int mode)
66{
67 struct v4l2_sliced_vbi_data data;
68
69 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
70 return;
71 /* When using a 50 Hz system, always turn on the
72 wide screen signal with 4x3 ratio as the default.
73 Turning this signal on and off can confuse certain
74 TVs. As far as I can tell there is no reason not to
75 transmit this signal. */
76 if ((itv->std & V4L2_STD_625_50) && !enabled) {
77 enabled = 1;
78 mode = 0x08; /* 4x3 full format */
79 }
80 data.id = V4L2_SLICED_WSS_625;
81 data.field = 0;
82 data.line = enabled ? 23 : 0;
83 data.data[0] = mode & 0xff;
84 data.data[1] = (mode >> 8) & 0xff;
85 ivtv_saa7127(itv, VIDIOC_INT_S_VBI_DATA, &data);
86}
87
88void ivtv_video_set_io(struct ivtv *itv)
89{
90 struct v4l2_routing route;
91 int inp = itv->active_input;
92 u32 type;
93
94 route.input = itv->card->video_inputs[inp].video_input;
95 route.output = 0;
96 itv->video_dec_func(itv, VIDIOC_INT_S_VIDEO_ROUTING, &route);
97
98 type = itv->card->video_inputs[inp].video_type;
99
100 if (type == IVTV_CARD_INPUT_VID_TUNER) {
101 route.input = 0; /* Tuner */
102 } else if (type < IVTV_CARD_INPUT_COMPOSITE1) {
103 route.input = 2; /* S-Video */
104 } else {
105 route.input = 1; /* Composite */
106 }
107
108 if (itv->card->hw_video & IVTV_HW_GPIO)
109 ivtv_gpio(itv, VIDIOC_INT_S_VIDEO_ROUTING, &route);
110
111 if (itv->card->hw_video & IVTV_HW_UPD64031A) {
112 if (type == IVTV_CARD_INPUT_VID_TUNER ||
113 type >= IVTV_CARD_INPUT_COMPOSITE1) {
114 /* Composite: GR on, connect to 3DYCS */
115 route.input = UPD64031A_GR_ON | UPD64031A_3DYCS_COMPOSITE;
116 } else {
117 /* S-Video: GR bypassed, turn it off */
118 route.input = UPD64031A_GR_OFF | UPD64031A_3DYCS_DISABLE;
119 }
120 route.input |= itv->card->gr_config;
121
122 ivtv_upd64031a(itv, VIDIOC_INT_S_VIDEO_ROUTING, &route);
123 }
124
125 if (itv->card->hw_video & IVTV_HW_UPD6408X) {
126 route.input = UPD64083_YCS_MODE;
127 if (type > IVTV_CARD_INPUT_VID_TUNER &&
128 type < IVTV_CARD_INPUT_COMPOSITE1) {
129 /* S-Video uses YCNR mode and internal Y-ADC, the upd64031a
130 is not used. */
131 route.input |= UPD64083_YCNR_MODE;
132 }
133 else if (itv->card->hw_video & IVTV_HW_UPD64031A) {
134 /* Use upd64031a output for tuner and composite(CX23416GYC only) inputs */
135 if ((type == IVTV_CARD_INPUT_VID_TUNER)||
136 (itv->card->type == IVTV_CARD_CX23416GYC)) {
137 route.input |= UPD64083_EXT_Y_ADC;
138 }
139 }
140 ivtv_upd64083(itv, VIDIOC_INT_S_VIDEO_ROUTING, &route);
141 }
142}
diff --git a/drivers/media/video/ivtv/ivtv-video.h b/drivers/media/video/ivtv/ivtv-video.h
new file mode 100644
index 000000000000..c8ade5d3c413
--- /dev/null
+++ b/drivers/media/video/ivtv/ivtv-video.h
@@ -0,0 +1,24 @@
1/*
2 saa7127 interface functions
3 Copyright (C) 2004-2007 Hans Verkuil <hverkuil@xs4all.nl>
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19
20void ivtv_set_wss(struct ivtv *itv, int enabled, int mode);
21void ivtv_set_cc(struct ivtv *itv, int mode, u8 cc1, u8 cc2, u8 cc3, u8 cc4);
22void ivtv_set_vps(struct ivtv *itv, int enabled, u8 vps1, u8 vps2, u8 vps3,
23 u8 vps4, u8 vps5);
24void ivtv_video_set_io(struct ivtv *itv);
diff --git a/drivers/media/video/ivtv/ivtv-yuv.c b/drivers/media/video/ivtv/ivtv-yuv.c
new file mode 100644
index 000000000000..bcea09542e5a
--- /dev/null
+++ b/drivers/media/video/ivtv/ivtv-yuv.c
@@ -0,0 +1,1129 @@
1/*
2 yuv support
3
4 Copyright (C) 2007 Ian Armstrong <ian@iarmst.demon.co.uk>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#include "ivtv-driver.h"
22#include "ivtv-queue.h"
23#include "ivtv-udma.h"
24#include "ivtv-irq.h"
25#include "ivtv-yuv.h"
26
27static int ivtv_yuv_prep_user_dma(struct ivtv *itv, struct ivtv_user_dma *dma,
28 struct ivtv_dma_frame *args)
29{
30 struct ivtv_dma_page_info y_dma;
31 struct ivtv_dma_page_info uv_dma;
32
33 int i;
34 int y_pages, uv_pages;
35
36 unsigned long y_buffer_offset, uv_buffer_offset;
37 int y_decode_height, uv_decode_height, y_size;
38 int frame = atomic_read(&itv->yuv_info.next_fill_frame);
39
40 y_buffer_offset = IVTV_DEC_MEM_START + yuv_offset[frame];
41 uv_buffer_offset = y_buffer_offset + IVTV_YUV_BUFFER_UV_OFFSET;
42
43 y_decode_height = uv_decode_height = args->src.height + args->src.top;
44
45 if (y_decode_height < 512-16)
46 y_buffer_offset += 720 * 16;
47
48 if (y_decode_height & 15)
49 y_decode_height = (y_decode_height + 16) & ~15;
50
51 if (uv_decode_height & 31)
52 uv_decode_height = (uv_decode_height + 32) & ~31;
53
54 y_size = 720 * y_decode_height;
55
56 /* Still in USE */
57 if (dma->SG_length || dma->page_count) {
58 IVTV_DEBUG_WARN("prep_user_dma: SG_length %d page_count %d still full?\n",
59 dma->SG_length, dma->page_count);
60 return -EBUSY;
61 }
62
63 ivtv_udma_get_page_info (&y_dma, (unsigned long)args->y_source, 720 * y_decode_height);
64 ivtv_udma_get_page_info (&uv_dma, (unsigned long)args->uv_source, 360 * uv_decode_height);
65
66 /* Get user pages for DMA Xfer */
67 down_read(&current->mm->mmap_sem);
68 y_pages = get_user_pages(current, current->mm, y_dma.uaddr, y_dma.page_count, 0, 1, &dma->map[0], NULL);
69 uv_pages = get_user_pages(current, current->mm, uv_dma.uaddr, uv_dma.page_count, 0, 1, &dma->map[y_pages], NULL);
70 up_read(&current->mm->mmap_sem);
71
72 dma->page_count = y_dma.page_count + uv_dma.page_count;
73
74 if (y_pages + uv_pages != dma->page_count) {
75 IVTV_DEBUG_WARN("failed to map user pages, returned %d instead of %d\n",
76 y_pages + uv_pages, dma->page_count);
77
78 for (i = 0; i < dma->page_count; i++) {
79 put_page(dma->map[i]);
80 }
81 dma->page_count = 0;
82 return -EINVAL;
83 }
84
85 /* Fill & map SG List */
86 ivtv_udma_fill_sg_list (dma, &uv_dma, ivtv_udma_fill_sg_list (dma, &y_dma, 0));
87 dma->SG_length = pci_map_sg(itv->dev, dma->SGlist, dma->page_count, PCI_DMA_TODEVICE);
88
89 /* Fill SG Array with new values */
90 ivtv_udma_fill_sg_array (dma, y_buffer_offset, uv_buffer_offset, y_size);
91
92 /* If we've offset the y plane, ensure top area is blanked */
93 if (args->src.height + args->src.top < 512-16) {
94 if (itv->yuv_info.blanking_dmaptr) {
95 dma->SGarray[dma->SG_length].size = cpu_to_le32(720*16);
96 dma->SGarray[dma->SG_length].src = cpu_to_le32(itv->yuv_info.blanking_dmaptr);
97 dma->SGarray[dma->SG_length].dst = cpu_to_le32(IVTV_DEC_MEM_START + yuv_offset[frame]);
98 dma->SG_length++;
99 }
100 }
101
102 /* Tag SG Array with Interrupt Bit */
103 dma->SGarray[dma->SG_length - 1].size |= cpu_to_le32(0x80000000);
104
105 ivtv_udma_sync_for_device(itv);
106 return 0;
107}
108
109/* We rely on a table held in the firmware - Quick check. */
110int ivtv_yuv_filter_check(struct ivtv *itv)
111{
112 int i, offset_y, offset_uv;
113
114 for (i=0, offset_y = 16, offset_uv = 4; i<16; i++, offset_y += 24, offset_uv += 12) {
115 if ((read_dec(IVTV_YUV_HORIZONTAL_FILTER_OFFSET + offset_y) != i << 16) ||
116 (read_dec(IVTV_YUV_VERTICAL_FILTER_OFFSET + offset_uv) != i << 16)) {
117 IVTV_WARN ("YUV filter table not found in firmware.\n");
118 return -1;
119 }
120 }
121 return 0;
122}
123
124static void ivtv_yuv_filter(struct ivtv *itv, int h_filter, int v_filter_1, int v_filter_2)
125{
126 int filter_index, filter_line;
127
128 /* If any filter is -1, then don't update it */
129 if (h_filter > -1) {
130 if (h_filter > 4) h_filter = 4;
131 filter_index = h_filter * 384;
132 filter_line = 0;
133 while (filter_line < 16) {
134 write_reg(read_dec(IVTV_YUV_HORIZONTAL_FILTER_OFFSET + filter_index), 0x02804);
135 write_reg(read_dec(IVTV_YUV_HORIZONTAL_FILTER_OFFSET + filter_index), 0x0281c);
136 filter_index += 4;
137 write_reg(read_dec(IVTV_YUV_HORIZONTAL_FILTER_OFFSET + filter_index), 0x02808);
138 write_reg(read_dec(IVTV_YUV_HORIZONTAL_FILTER_OFFSET + filter_index), 0x02820);
139 filter_index += 4;
140 write_reg(read_dec(IVTV_YUV_HORIZONTAL_FILTER_OFFSET + filter_index), 0x0280c);
141 write_reg(read_dec(IVTV_YUV_HORIZONTAL_FILTER_OFFSET + filter_index), 0x02824);
142 filter_index += 4;
143 write_reg(read_dec(IVTV_YUV_HORIZONTAL_FILTER_OFFSET + filter_index), 0x02810);
144 write_reg(read_dec(IVTV_YUV_HORIZONTAL_FILTER_OFFSET + filter_index), 0x02828);
145 filter_index += 4;
146 write_reg(read_dec(IVTV_YUV_HORIZONTAL_FILTER_OFFSET + filter_index), 0x02814);
147 write_reg(read_dec(IVTV_YUV_HORIZONTAL_FILTER_OFFSET + filter_index), 0x0282c);
148 filter_index += 8;
149 write_reg(0, 0x02818);
150 write_reg(0, 0x02830);
151 filter_line ++;
152 }
153 IVTV_DEBUG_YUV("h_filter -> %d\n",h_filter);
154 }
155
156 if (v_filter_1 > -1) {
157 if (v_filter_1 > 4) v_filter_1 = 4;
158 filter_index = v_filter_1 * 192;
159 filter_line = 0;
160 while (filter_line < 16) {
161 write_reg(read_dec(IVTV_YUV_VERTICAL_FILTER_OFFSET + filter_index), 0x02900);
162 filter_index += 4;
163 write_reg(read_dec(IVTV_YUV_VERTICAL_FILTER_OFFSET + filter_index), 0x02904);
164 filter_index += 8;
165 write_reg(0, 0x02908);
166 filter_line ++;
167 }
168 IVTV_DEBUG_YUV("v_filter_1 -> %d\n",v_filter_1);
169 }
170
171 if (v_filter_2 > -1) {
172 if (v_filter_2 > 4) v_filter_2 = 4;
173 filter_index = v_filter_2 * 192;
174 filter_line = 0;
175 while (filter_line < 16) {
176 write_reg(read_dec(IVTV_YUV_VERTICAL_FILTER_OFFSET + filter_index), 0x0290c);
177 filter_index += 4;
178 write_reg(read_dec(IVTV_YUV_VERTICAL_FILTER_OFFSET + filter_index), 0x02910);
179 filter_index += 8;
180 write_reg(0, 0x02914);
181 filter_line ++;
182 }
183 IVTV_DEBUG_YUV("v_filter_2 -> %d\n",v_filter_2);
184 }
185}
186
187static void ivtv_yuv_handle_horizontal(struct ivtv *itv, struct yuv_frame_info *window)
188{
189 u32 reg_2834, reg_2838, reg_283c;
190 u32 reg_2844, reg_2854, reg_285c;
191 u32 reg_2864, reg_2874, reg_2890;
192 u32 reg_2870, reg_2870_base, reg_2870_offset;
193 int x_cutoff;
194 int h_filter;
195 u32 master_width;
196
197 IVTV_DEBUG_WARN( "Need to adjust to width %d src_w %d dst_w %d src_x %d dst_x %d\n",
198 window->tru_w, window->src_w, window->dst_w,window->src_x, window->dst_x);
199
200 /* How wide is the src image */
201 x_cutoff = window->src_w + window->src_x;
202
203 /* Set the display width */
204 reg_2834 = window->dst_w;
205 reg_2838 = reg_2834;
206
207 /* Set the display position */
208 reg_2890 = window->dst_x;
209
210 /* Index into the image horizontally */
211 reg_2870 = 0;
212
213 /* 2870 is normally fudged to align video coords with osd coords.
214 If running full screen, it causes an unwanted left shift
215 Remove the fudge if we almost fill the screen.
216 Gradually adjust the offset to avoid the video 'snapping'
217 left/right if it gets dragged through this region.
218 Only do this if osd is full width. */
219 if (window->vis_w == 720) {
220 if ((window->tru_x - window->pan_x > -1) && (window->tru_x - window->pan_x <= 40) && (window->dst_w >= 680)){
221 reg_2870 = 10 - (window->tru_x - window->pan_x) / 4;
222 }
223 else if ((window->tru_x - window->pan_x < 0) && (window->tru_x - window->pan_x >= -20) && (window->dst_w >= 660)) {
224 reg_2870 = (10 + (window->tru_x - window->pan_x) / 2);
225 }
226
227 if (window->dst_w >= window->src_w)
228 reg_2870 = reg_2870 << 16 | reg_2870;
229 else
230 reg_2870 = ((reg_2870 & ~1) << 15) | (reg_2870 & ~1);
231 }
232
233 if (window->dst_w < window->src_w)
234 reg_2870 = 0x000d000e - reg_2870;
235 else
236 reg_2870 = 0x0012000e - reg_2870;
237
238 /* We're also using 2870 to shift the image left (src_x & negative dst_x) */
239 reg_2870_offset = (window->src_x*((window->dst_w << 21)/window->src_w))>>19;
240
241 if (window->dst_w >= window->src_w) {
242 x_cutoff &= ~1;
243 master_width = (window->src_w * 0x00200000) / (window->dst_w);
244 if (master_width * window->dst_w != window->src_w * 0x00200000) master_width ++;
245 reg_2834 = (reg_2834 << 16) | x_cutoff;
246 reg_2838 = (reg_2838 << 16) | x_cutoff;
247 reg_283c = master_width >> 2;
248 reg_2844 = master_width >> 2;
249 reg_2854 = master_width;
250 reg_285c = master_width >> 1;
251 reg_2864 = master_width >> 1;
252
253 /* We also need to factor in the scaling
254 (src_w - dst_w) / (src_w / 4) */
255 if (window->dst_w > window->src_w)
256 reg_2870_base = ((window->dst_w - window->src_w)<<16) / (window->src_w <<14);
257 else
258 reg_2870_base = 0;
259
260 reg_2870 += (((reg_2870_offset << 14) & 0xFFFF0000) | reg_2870_offset >> 2) + (reg_2870_base << 17 | reg_2870_base);
261 reg_2874 = 0;
262 }
263 else if (window->dst_w < window->src_w / 2) {
264 master_width = (window->src_w * 0x00080000) / window->dst_w;
265 if (master_width * window->dst_w != window->src_w * 0x00080000) master_width ++;
266 reg_2834 = (reg_2834 << 16) | x_cutoff;
267 reg_2838 = (reg_2838 << 16) | x_cutoff;
268 reg_283c = master_width >> 2;
269 reg_2844 = master_width >> 1;
270 reg_2854 = master_width;
271 reg_285c = master_width >> 1;
272 reg_2864 = master_width >> 1;
273 reg_2870 += (((reg_2870_offset << 15) & 0xFFFF0000) | reg_2870_offset);
274 reg_2870 += (5 - (((window->src_w + window->src_w / 2) - 1) / window->dst_w)) << 16;
275 reg_2874 = 0x00000012;
276 }
277 else {
278 master_width = (window->src_w * 0x00100000) / window->dst_w;
279 if (master_width * window->dst_w != window->src_w * 0x00100000) master_width ++;
280 reg_2834 = (reg_2834 << 16) | x_cutoff;
281 reg_2838 = (reg_2838 << 16) | x_cutoff;
282 reg_283c = master_width >> 2;
283 reg_2844 = master_width >> 1;
284 reg_2854 = master_width;
285 reg_285c = master_width >> 1;
286 reg_2864 = master_width >> 1;
287 reg_2870 += (((reg_2870_offset << 14) & 0xFFFF0000) | reg_2870_offset >> 1);
288 reg_2870 += (5 - (((window->src_w * 3) - 1) / window->dst_w)) << 16;
289 reg_2874 = 0x00000001;
290 }
291
292 /* Select the horizontal filter */
293 if (window->src_w == window->dst_w) {
294 /* An exact size match uses filter 0 */
295 h_filter = 0;
296 }
297 else {
298 /* Figure out which filter to use */
299 h_filter = ((window->src_w << 16) / window->dst_w) >> 15;
300 h_filter = (h_filter >> 1) + (h_filter & 1);
301 /* Only an exact size match can use filter 0 */
302 if (h_filter == 0) h_filter = 1;
303 }
304
305 write_reg(reg_2834, 0x02834);
306 write_reg(reg_2838, 0x02838);
307 IVTV_DEBUG_YUV("Update reg 0x2834 %08x->%08x 0x2838 %08x->%08x\n",itv->yuv_info.reg_2834, reg_2834, itv->yuv_info.reg_2838, reg_2838);
308
309 write_reg(reg_283c, 0x0283c);
310 write_reg(reg_2844, 0x02844);
311
312 IVTV_DEBUG_YUV("Update reg 0x283c %08x->%08x 0x2844 %08x->%08x\n",itv->yuv_info.reg_283c, reg_283c, itv->yuv_info.reg_2844, reg_2844);
313
314 write_reg(0x00080514, 0x02840);
315 write_reg(0x00100514, 0x02848);
316 IVTV_DEBUG_YUV("Update reg 0x2840 %08x->%08x 0x2848 %08x->%08x\n",itv->yuv_info.reg_2840, 0x00080514, itv->yuv_info.reg_2848, 0x00100514);
317
318 write_reg(reg_2854, 0x02854);
319 IVTV_DEBUG_YUV("Update reg 0x2854 %08x->%08x \n",itv->yuv_info.reg_2854, reg_2854);
320
321 write_reg(reg_285c, 0x0285c);
322 write_reg(reg_2864, 0x02864);
323 IVTV_DEBUG_YUV("Update reg 0x285c %08x->%08x 0x2864 %08x->%08x\n",itv->yuv_info.reg_285c, reg_285c, itv->yuv_info.reg_2864, reg_2864);
324
325 write_reg(reg_2874, 0x02874);
326 IVTV_DEBUG_YUV("Update reg 0x2874 %08x->%08x\n",itv->yuv_info.reg_2874, reg_2874);
327
328 write_reg(reg_2870, 0x02870);
329 IVTV_DEBUG_YUV("Update reg 0x2870 %08x->%08x\n",itv->yuv_info.reg_2870, reg_2870);
330
331 write_reg( reg_2890,0x02890);
332 IVTV_DEBUG_YUV("Update reg 0x2890 %08x->%08x\n",itv->yuv_info.reg_2890, reg_2890);
333
334 /* Only update the filter if we really need to */
335 if (h_filter != itv->yuv_info.h_filter) {
336 ivtv_yuv_filter (itv,h_filter,-1,-1);
337 itv->yuv_info.h_filter = h_filter;
338 }
339}
340
341static void ivtv_yuv_handle_vertical(struct ivtv *itv, struct yuv_frame_info *window)
342{
343 u32 master_height;
344 u32 reg_2918, reg_291c, reg_2920, reg_2928;
345 u32 reg_2930, reg_2934, reg_293c;
346 u32 reg_2940, reg_2944, reg_294c;
347 u32 reg_2950, reg_2954, reg_2958, reg_295c;
348 u32 reg_2960, reg_2964, reg_2968, reg_296c;
349 u32 reg_289c;
350 u32 src_y_major_y, src_y_minor_y;
351 u32 src_y_major_uv, src_y_minor_uv;
352 u32 reg_2964_base, reg_2968_base;
353 int v_filter_1, v_filter_2;
354
355 IVTV_DEBUG_WARN("Need to adjust to height %d src_h %d dst_h %d src_y %d dst_y %d\n",
356 window->tru_h, window->src_h, window->dst_h,window->src_y, window->dst_y);
357
358 /* What scaling mode is being used... */
359 if (window->interlaced_y) {
360 IVTV_DEBUG_YUV("Scaling mode Y: Interlaced\n");
361 }
362 else {
363 IVTV_DEBUG_YUV("Scaling mode Y: Progressive\n");
364 }
365
366 if (window->interlaced_uv) {
367 IVTV_DEBUG_YUV("Scaling mode UV: Interlaced\n");
368 }
369 else {
370 IVTV_DEBUG_YUV("Scaling mode UV: Progressive\n");
371 }
372
373 /* What is the source video being treated as... */
374 if (itv->yuv_info.frame_interlaced) {
375 IVTV_DEBUG_WARN("Source video: Interlaced\n");
376 }
377 else {
378 IVTV_DEBUG_WARN("Source video: Non-interlaced\n");
379 }
380
381 /* We offset into the image using two different index methods, so split
382 the y source coord into two parts. */
383 if (window->src_y < 8) {
384 src_y_minor_uv = window->src_y;
385 src_y_major_uv = 0;
386 }
387 else {
388 src_y_minor_uv = 8;
389 src_y_major_uv = window->src_y - 8;
390 }
391
392 src_y_minor_y = src_y_minor_uv;
393 src_y_major_y = src_y_major_uv;
394
395 if (window->offset_y) src_y_minor_y += 16;
396
397 if (window->interlaced_y)
398 reg_2918 = (window->dst_h << 16) | (window->src_h + src_y_minor_y);
399 else
400 reg_2918 = (window->dst_h << 16) | ((window->src_h + src_y_minor_y) << 1);
401
402 if (window->interlaced_uv)
403 reg_291c = (window->dst_h << 16) | ((window->src_h + src_y_minor_uv) >> 1);
404 else
405 reg_291c = (window->dst_h << 16) | (window->src_h + src_y_minor_uv);
406
407 reg_2964_base = (src_y_minor_y * ((window->dst_h << 16)/window->src_h)) >> 14;
408 reg_2968_base = (src_y_minor_uv * ((window->dst_h << 16)/window->src_h)) >> 14;
409
410 if (window->dst_h / 2 >= window->src_h && !window->interlaced_y) {
411 master_height = (window->src_h * 0x00400000) / window->dst_h;
412 if ((window->src_h * 0x00400000) - (master_height * window->dst_h) >= window->dst_h / 2) master_height ++;
413 reg_2920 = master_height >> 2;
414 reg_2928 = master_height >> 3;
415 reg_2930 = master_height;
416 reg_2940 = master_height >> 1;
417 reg_2964_base >>= 3;
418 reg_2968_base >>= 3;
419 reg_296c = 0x00000000;
420 }
421 else if (window->dst_h >= window->src_h) {
422 master_height = (window->src_h * 0x00400000) / window->dst_h;
423 master_height = (master_height >> 1) + (master_height & 1);
424 reg_2920 = master_height >> 2;
425 reg_2928 = master_height >> 2;
426 reg_2930 = master_height;
427 reg_2940 = master_height >> 1;
428 reg_296c = 0x00000000;
429 if (window->interlaced_y) {
430 reg_2964_base >>= 3;
431 }
432 else {
433 reg_296c ++;
434 reg_2964_base >>= 2;
435 }
436 if (window->interlaced_uv) reg_2928 >>= 1;
437 reg_2968_base >>= 3;
438 }
439 else if (window->dst_h >= window->src_h / 2) {
440 master_height = (window->src_h * 0x00200000) / window->dst_h;
441 master_height = (master_height >> 1) + (master_height & 1);
442 reg_2920 = master_height >> 2;
443 reg_2928 = master_height >> 2;
444 reg_2930 = master_height;
445 reg_2940 = master_height;
446 reg_296c = 0x00000101;
447 if (window->interlaced_y) {
448 reg_2964_base >>= 2;
449 }
450 else {
451 reg_296c ++;
452 reg_2964_base >>= 1;
453 }
454 if (window->interlaced_uv) reg_2928 >>= 1;
455 reg_2968_base >>= 2;
456 }
457 else {
458 master_height = (window->src_h * 0x00100000) / window->dst_h;
459 master_height = (master_height >> 1) + (master_height & 1);
460 reg_2920 = master_height >> 2;
461 reg_2928 = master_height >> 2;
462 reg_2930 = master_height;
463 reg_2940 = master_height;
464 reg_2964_base >>= 1;
465 reg_2968_base >>= 2;
466 reg_296c = 0x00000102;
467 }
468
469 /* FIXME These registers change depending on scaled / unscaled output
470 We really need to work out what they should be */
471 if (window->src_h == window->dst_h){
472 reg_2934 = 0x00020000;
473 reg_293c = 0x00100000;
474 reg_2944 = 0x00040000;
475 reg_294c = 0x000b0000;
476 }
477 else {
478 reg_2934 = 0x00000FF0;
479 reg_293c = 0x00000FF0;
480 reg_2944 = 0x00000FF0;
481 reg_294c = 0x00000FF0;
482 }
483
484 /* The first line to be displayed */
485 reg_2950 = 0x00010000 + src_y_major_y;
486 if (window->interlaced_y) reg_2950 += 0x00010000;
487 reg_2954 = reg_2950 + 1;
488
489 reg_2958 = 0x00010000 + (src_y_major_y >> 1);
490 if (window->interlaced_uv) reg_2958 += 0x00010000;
491 reg_295c = reg_2958 + 1;
492
493 if (itv->yuv_info.decode_height == 480)
494 reg_289c = 0x011e0017;
495 else
496 reg_289c = 0x01500017;
497
498 if (window->dst_y < 0)
499 reg_289c = (reg_289c - ((window->dst_y & ~1)<<15))-(window->dst_y >>1);
500 else
501 reg_289c = (reg_289c + ((window->dst_y & ~1)<<15))+(window->dst_y >>1);
502
503 /* How much of the source to decode.
504 Take into account the source offset */
505 reg_2960 = ((src_y_minor_y + window->src_h + src_y_major_y) - 1 ) |
506 ((((src_y_minor_uv + window->src_h + src_y_major_uv) - 1) & ~1) << 15);
507
508 /* Calculate correct value for register 2964 */
509 if (window->src_h == window->dst_h)
510 reg_2964 = 1;
511 else {
512 reg_2964 = 2 + ((window->dst_h << 1) / window->src_h);
513 reg_2964 = (reg_2964 >> 1) + (reg_2964 & 1);
514 }
515 reg_2968 = (reg_2964 << 16) + reg_2964 + (reg_2964 >> 1);
516 reg_2964 = (reg_2964 << 16) + reg_2964 + (reg_2964 * 46 / 94);
517
518 /* Okay, we've wasted time working out the correct value,
519 but if we use it, it fouls the the window alignment.
520 Fudge it to what we want... */
521 reg_2964 = 0x00010001 + ((reg_2964 & 0x0000FFFF) - (reg_2964 >> 16));
522 reg_2968 = 0x00010001 + ((reg_2968 & 0x0000FFFF) - (reg_2968 >> 16));
523
524 /* Deviate further from what it should be. I find the flicker headache
525 inducing so try to reduce it slightly. Leave 2968 as-is otherwise
526 colours foul. */
527 if ((reg_2964 != 0x00010001) && (window->dst_h / 2 <= window->src_h))
528 reg_2964 = (reg_2964 & 0xFFFF0000) + ((reg_2964 & 0x0000FFFF)/2);
529
530 if (!window->interlaced_y) reg_2964 -= 0x00010001;
531 if (!window->interlaced_uv) reg_2968 -= 0x00010001;
532
533 reg_2964 += ((reg_2964_base << 16) | reg_2964_base);
534 reg_2968 += ((reg_2968_base << 16) | reg_2968_base);
535
536 /* Select the vertical filter */
537 if (window->src_h == window->dst_h) {
538 /* An exact size match uses filter 0/1 */
539 v_filter_1 = 0;
540 v_filter_2 = 1;
541 }
542 else {
543 /* Figure out which filter to use */
544 v_filter_1 = ((window->src_h << 16) / window->dst_h) >> 15;
545 v_filter_1 = (v_filter_1 >> 1) + (v_filter_1 & 1);
546 /* Only an exact size match can use filter 0 */
547 if (v_filter_1 == 0) v_filter_1 = 1;
548 v_filter_2 = v_filter_1;
549 }
550
551 write_reg(reg_2934, 0x02934);
552 write_reg(reg_293c, 0x0293c);
553 IVTV_DEBUG_YUV("Update reg 0x2934 %08x->%08x 0x293c %08x->%08x\n",itv->yuv_info.reg_2934, reg_2934, itv->yuv_info.reg_293c, reg_293c);
554 write_reg(reg_2944, 0x02944);
555 write_reg(reg_294c, 0x0294c);
556 IVTV_DEBUG_YUV("Update reg 0x2944 %08x->%08x 0x294c %08x->%08x\n",itv->yuv_info.reg_2944, reg_2944, itv->yuv_info.reg_294c, reg_294c);
557
558 /* Ensure 2970 is 0 (does it ever change ?) */
559/* write_reg(0,0x02970); */
560/* IVTV_DEBUG_YUV("Update reg 0x2970 %08x->%08x\n",itv->yuv_info.reg_2970, 0); */
561
562 write_reg(reg_2930, 0x02938);
563 write_reg(reg_2930, 0x02930);
564 IVTV_DEBUG_YUV("Update reg 0x2930 %08x->%08x 0x2938 %08x->%08x\n",itv->yuv_info.reg_2930, reg_2930, itv->yuv_info.reg_2938, reg_2930);
565
566 write_reg(reg_2928, 0x02928);
567 write_reg(reg_2928+0x514, 0x0292C);
568 IVTV_DEBUG_YUV("Update reg 0x2928 %08x->%08x 0x292c %08x->%08x\n",itv->yuv_info.reg_2928, reg_2928, itv->yuv_info.reg_292c, reg_2928+0x514);
569
570 write_reg(reg_2920, 0x02920);
571 write_reg(reg_2920+0x514, 0x02924);
572 IVTV_DEBUG_YUV("Update reg 0x2920 %08x->%08x 0x2924 %08x->%08x\n",itv->yuv_info.reg_2920, reg_2920, itv->yuv_info.reg_2924, 0x514+reg_2920);
573
574 write_reg (reg_2918,0x02918);
575 write_reg (reg_291c,0x0291C);
576 IVTV_DEBUG_YUV("Update reg 0x2918 %08x->%08x 0x291C %08x->%08x\n",itv->yuv_info.reg_2918,reg_2918,itv->yuv_info.reg_291c,reg_291c);
577
578 write_reg(reg_296c, 0x0296c);
579 IVTV_DEBUG_YUV("Update reg 0x296c %08x->%08x\n",itv->yuv_info.reg_296c, reg_296c);
580
581 write_reg(reg_2940, 0x02948);
582 write_reg(reg_2940, 0x02940);
583 IVTV_DEBUG_YUV("Update reg 0x2940 %08x->%08x 0x2948 %08x->%08x\n",itv->yuv_info.reg_2940, reg_2940, itv->yuv_info.reg_2948, reg_2940);
584
585 write_reg(reg_2950, 0x02950);
586 write_reg(reg_2954, 0x02954);
587 IVTV_DEBUG_YUV("Update reg 0x2950 %08x->%08x 0x2954 %08x->%08x\n",itv->yuv_info.reg_2950, reg_2950, itv->yuv_info.reg_2954, reg_2954);
588
589 write_reg(reg_2958, 0x02958);
590 write_reg(reg_295c, 0x0295C);
591 IVTV_DEBUG_YUV("Update reg 0x2958 %08x->%08x 0x295C %08x->%08x\n",itv->yuv_info.reg_2958, reg_2958, itv->yuv_info.reg_295c, reg_295c);
592
593 write_reg(reg_2960, 0x02960);
594 IVTV_DEBUG_YUV("Update reg 0x2960 %08x->%08x \n",itv->yuv_info.reg_2960, reg_2960);
595
596 write_reg(reg_2964, 0x02964);
597 write_reg(reg_2968, 0x02968);
598 IVTV_DEBUG_YUV("Update reg 0x2964 %08x->%08x 0x2968 %08x->%08x\n",itv->yuv_info.reg_2964, reg_2964, itv->yuv_info.reg_2968, reg_2968);
599
600 write_reg( reg_289c,0x0289c);
601 IVTV_DEBUG_YUV("Update reg 0x289c %08x->%08x\n",itv->yuv_info.reg_289c, reg_289c);
602
603 /* Only update filter 1 if we really need to */
604 if (v_filter_1 != itv->yuv_info.v_filter_1) {
605 ivtv_yuv_filter (itv,-1,v_filter_1,-1);
606 itv->yuv_info.v_filter_1 = v_filter_1;
607 }
608
609 /* Only update filter 2 if we really need to */
610 if (v_filter_2 != itv->yuv_info.v_filter_2) {
611 ivtv_yuv_filter (itv,-1,-1,v_filter_2);
612 itv->yuv_info.v_filter_2 = v_filter_2;
613 }
614
615 itv->yuv_info.frame_interlaced_last = itv->yuv_info.frame_interlaced;
616}
617
618/* Modify the supplied coordinate information to fit the visible osd area */
619static u32 ivtv_yuv_window_setup (struct ivtv *itv, struct yuv_frame_info *window)
620{
621 int osd_crop, lace_threshold;
622 u32 osd_scale;
623 u32 yuv_update = 0;
624
625 lace_threshold = itv->yuv_info.lace_threshold;
626 if (lace_threshold < 0)
627 lace_threshold = itv->yuv_info.decode_height - 1;
628
629 /* Work out the lace settings */
630 switch (itv->yuv_info.lace_mode) {
631 case IVTV_YUV_MODE_PROGRESSIVE: /* Progressive mode */
632 itv->yuv_info.frame_interlaced = 0;
633 if (window->tru_h < 512 || (window->tru_h > 576 && window->tru_h < 1021))
634 window->interlaced_y = 0;
635 else
636 window->interlaced_y = 1;
637
638 if (window->tru_h < 1021 && (window->dst_h >= window->src_h /2))
639 window->interlaced_uv = 0;
640 else
641 window->interlaced_uv = 1;
642 break;
643
644 case IVTV_YUV_MODE_AUTO:
645 if (window->tru_h <= lace_threshold || window->tru_h > 576 || window->tru_w > 720){
646 itv->yuv_info.frame_interlaced = 0;
647 if ((window->tru_h < 512) ||
648 (window->tru_h > 576 && window->tru_h < 1021) ||
649 (window->tru_w > 720 && window->tru_h < 1021))
650 window->interlaced_y = 0;
651 else
652 window->interlaced_y = 1;
653
654 if (window->tru_h < 1021 && (window->dst_h >= window->src_h /2))
655 window->interlaced_uv = 0;
656 else
657 window->interlaced_uv = 1;
658 }
659 else {
660 itv->yuv_info.frame_interlaced = 1;
661 window->interlaced_y = 1;
662 window->interlaced_uv = 1;
663 }
664 break;
665
666 case IVTV_YUV_MODE_INTERLACED: /* Interlace mode */
667 default:
668 itv->yuv_info.frame_interlaced = 1;
669 window->interlaced_y = 1;
670 window->interlaced_uv = 1;
671 break;
672 }
673
674 /* Sorry, but no negative coords for src */
675 if (window->src_x < 0) window->src_x = 0;
676 if (window->src_y < 0) window->src_y = 0;
677
678 /* Can only reduce width down to 1/4 original size */
679 if ((osd_crop = window->src_w - ( 4 * window->dst_w )) > 0) {
680 window->src_x += osd_crop / 2;
681 window->src_w = (window->src_w - osd_crop) & ~3;
682 window->dst_w = window->src_w / 4;
683 window->dst_w += window->dst_w & 1;
684 }
685
686 /* Can only reduce height down to 1/4 original size */
687 if (window->src_h / window->dst_h >= 2) {
688 /* Overflow may be because we're running progressive, so force mode switch */
689 window->interlaced_y = 1;
690 /* Make sure we're still within limits for interlace */
691 if ((osd_crop = window->src_h - ( 4 * window->dst_h )) > 0) {
692 /* If we reach here we'll have to force the height. */
693 window->src_y += osd_crop / 2;
694 window->src_h = (window->src_h - osd_crop) & ~3;
695 window->dst_h = window->src_h / 4;
696 window->dst_h += window->dst_h & 1;
697 }
698 }
699
700 /* If there's nothing to safe to display, we may as well stop now */
701 if ((int)window->dst_w <= 2 || (int)window->dst_h <= 2 || (int)window->src_w <= 2 || (int)window->src_h <= 2) {
702 return 0;
703 }
704
705 /* Ensure video remains inside OSD area */
706 osd_scale = (window->src_h << 16) / window->dst_h;
707
708 if ((osd_crop = window->pan_y - window->dst_y) > 0) {
709 /* Falls off the upper edge - crop */
710 window->src_y += (osd_scale * osd_crop) >> 16;
711 window->src_h -= (osd_scale * osd_crop) >> 16;
712 window->dst_h -= osd_crop;
713 window->dst_y = 0;
714 }
715 else {
716 window->dst_y -= window->pan_y;
717 }
718
719 if ((osd_crop = window->dst_h + window->dst_y - window->vis_h) > 0) {
720 /* Falls off the lower edge - crop */
721 window->dst_h -= osd_crop;
722 window->src_h -= (osd_scale * osd_crop) >> 16;
723 }
724
725 osd_scale = (window->src_w << 16) / window->dst_w;
726
727 if ((osd_crop = window->pan_x - window->dst_x) > 0) {
728 /* Fall off the left edge - crop */
729 window->src_x += (osd_scale * osd_crop) >> 16;
730 window->src_w -= (osd_scale * osd_crop) >> 16;
731 window->dst_w -= osd_crop;
732 window->dst_x = 0;
733 }
734 else {
735 window->dst_x -= window->pan_x;
736 }
737
738 if ((osd_crop = window->dst_w + window->dst_x - window->vis_w) > 0) {
739 /* Falls off the right edge - crop */
740 window->dst_w -= osd_crop;
741 window->src_w -= (osd_scale * osd_crop) >> 16;
742 }
743
744 /* The OSD can be moved. Track to it */
745 window->dst_x += itv->yuv_info.osd_x_offset;
746 window->dst_y += itv->yuv_info.osd_y_offset;
747
748 /* Width & height for both src & dst must be even.
749 Same for coordinates. */
750 window->dst_w &= ~1;
751 window->dst_x &= ~1;
752
753 window->src_w += window->src_x & 1;
754 window->src_x &= ~1;
755
756 window->src_w &= ~1;
757 window->dst_w &= ~1;
758
759 window->dst_h &= ~1;
760 window->dst_y &= ~1;
761
762 window->src_h += window->src_y & 1;
763 window->src_y &= ~1;
764
765 window->src_h &= ~1;
766 window->dst_h &= ~1;
767
768 /* Due to rounding, we may have reduced the output size to <1/4 of the source
769 Check again, but this time just resize. Don't change source coordinates */
770 if (window->dst_w < window->src_w / 4) {
771 window->src_w &= ~3;
772 window->dst_w = window->src_w / 4;
773 window->dst_w += window->dst_w & 1;
774 }
775 if (window->dst_h < window->src_h / 4) {
776 window->src_h &= ~3;
777 window->dst_h = window->src_h / 4;
778 window->dst_h += window->dst_h & 1;
779 }
780
781 /* Check again. If there's nothing to safe to display, stop now */
782 if ((int)window->dst_w <= 2 || (int)window->dst_h <= 2 || (int)window->src_w <= 2 || (int)window->src_h <= 2) {
783 return 0;
784 }
785
786 /* Both x offset & width are linked, so they have to be done together */
787 if ((itv->yuv_info.old_frame_info.dst_w != window->dst_w) ||
788 (itv->yuv_info.old_frame_info.src_w != window->src_w) ||
789 (itv->yuv_info.old_frame_info.dst_x != window->dst_x) ||
790 (itv->yuv_info.old_frame_info.src_x != window->src_x) ||
791 (itv->yuv_info.old_frame_info.pan_x != window->pan_x) ||
792 (itv->yuv_info.old_frame_info.vis_w != window->vis_w)) {
793 yuv_update |= IVTV_YUV_UPDATE_HORIZONTAL;
794 }
795
796 if ((itv->yuv_info.old_frame_info.src_h != window->src_h) ||
797 (itv->yuv_info.old_frame_info.dst_h != window->dst_h) ||
798 (itv->yuv_info.old_frame_info.dst_y != window->dst_y) ||
799 (itv->yuv_info.old_frame_info.src_y != window->src_y) ||
800 (itv->yuv_info.old_frame_info.pan_y != window->pan_y) ||
801 (itv->yuv_info.old_frame_info.vis_h != window->vis_h) ||
802 (itv->yuv_info.old_frame_info.interlaced_y != window->interlaced_y) ||
803 (itv->yuv_info.old_frame_info.interlaced_uv != window->interlaced_uv)) {
804 yuv_update |= IVTV_YUV_UPDATE_VERTICAL;
805 }
806
807 return yuv_update;
808}
809
810/* Update the scaling register to the requested value */
811void ivtv_yuv_work_handler (struct ivtv *itv)
812{
813 struct yuv_frame_info window;
814 u32 yuv_update;
815
816 int frame = itv->yuv_info.update_frame;
817
818/* IVTV_DEBUG_YUV("Update yuv registers for frame %d\n",frame); */
819 memcpy(&window, &itv->yuv_info.new_frame_info[frame], sizeof (window));
820
821 /* Update the osd pan info */
822 window.pan_x = itv->yuv_info.osd_x_pan;
823 window.pan_y = itv->yuv_info.osd_y_pan;
824 window.vis_w = itv->yuv_info.osd_vis_w;
825 window.vis_h = itv->yuv_info.osd_vis_h;
826
827 /* Calculate the display window coordinates. Exit if nothing left */
828 if (!(yuv_update = ivtv_yuv_window_setup (itv, &window)))
829 return;
830
831 /* Update horizontal settings */
832 if (yuv_update & IVTV_YUV_UPDATE_HORIZONTAL)
833 ivtv_yuv_handle_horizontal(itv, &window);
834
835 if (yuv_update & IVTV_YUV_UPDATE_VERTICAL)
836 ivtv_yuv_handle_vertical(itv, &window);
837
838 memcpy(&itv->yuv_info.old_frame_info, &window, sizeof (itv->yuv_info.old_frame_info));
839}
840
841static void ivtv_yuv_init (struct ivtv *itv)
842{
843 IVTV_DEBUG_YUV("ivtv_yuv_init\n");
844
845 /* Take a snapshot of the current register settings */
846 itv->yuv_info.reg_2834 = read_reg(0x02834);
847 itv->yuv_info.reg_2838 = read_reg(0x02838);
848 itv->yuv_info.reg_283c = read_reg(0x0283c);
849 itv->yuv_info.reg_2840 = read_reg(0x02840);
850 itv->yuv_info.reg_2844 = read_reg(0x02844);
851 itv->yuv_info.reg_2848 = read_reg(0x02848);
852 itv->yuv_info.reg_2854 = read_reg(0x02854);
853 itv->yuv_info.reg_285c = read_reg(0x0285c);
854 itv->yuv_info.reg_2864 = read_reg(0x02864);
855 itv->yuv_info.reg_2870 = read_reg(0x02870);
856 itv->yuv_info.reg_2874 = read_reg(0x02874);
857 itv->yuv_info.reg_2898 = read_reg(0x02898);
858 itv->yuv_info.reg_2890 = read_reg(0x02890);
859
860 itv->yuv_info.reg_289c = read_reg(0x0289c);
861 itv->yuv_info.reg_2918 = read_reg(0x02918);
862 itv->yuv_info.reg_291c = read_reg(0x0291c);
863 itv->yuv_info.reg_2920 = read_reg(0x02920);
864 itv->yuv_info.reg_2924 = read_reg(0x02924);
865 itv->yuv_info.reg_2928 = read_reg(0x02928);
866 itv->yuv_info.reg_292c = read_reg(0x0292c);
867 itv->yuv_info.reg_2930 = read_reg(0x02930);
868 itv->yuv_info.reg_2934 = read_reg(0x02934);
869 itv->yuv_info.reg_2938 = read_reg(0x02938);
870 itv->yuv_info.reg_293c = read_reg(0x0293c);
871 itv->yuv_info.reg_2940 = read_reg(0x02940);
872 itv->yuv_info.reg_2944 = read_reg(0x02944);
873 itv->yuv_info.reg_2948 = read_reg(0x02948);
874 itv->yuv_info.reg_294c = read_reg(0x0294c);
875 itv->yuv_info.reg_2950 = read_reg(0x02950);
876 itv->yuv_info.reg_2954 = read_reg(0x02954);
877 itv->yuv_info.reg_2958 = read_reg(0x02958);
878 itv->yuv_info.reg_295c = read_reg(0x0295c);
879 itv->yuv_info.reg_2960 = read_reg(0x02960);
880 itv->yuv_info.reg_2964 = read_reg(0x02964);
881 itv->yuv_info.reg_2968 = read_reg(0x02968);
882 itv->yuv_info.reg_296c = read_reg(0x0296c);
883 itv->yuv_info.reg_2970 = read_reg(0x02970);
884
885 itv->yuv_info.v_filter_1 = -1;
886 itv->yuv_info.v_filter_2 = -1;
887 itv->yuv_info.h_filter = -1;
888
889 /* Set some valid size info */
890 itv->yuv_info.osd_x_offset = read_reg(0x02a04) & 0x00000FFF;
891 itv->yuv_info.osd_y_offset = (read_reg(0x02a04) >> 16) & 0x00000FFF;
892
893 /* Bit 2 of reg 2878 indicates current decoder output format
894 0 : NTSC 1 : PAL */
895 if (read_reg(0x2878) & 4)
896 itv->yuv_info.decode_height = 576;
897 else
898 itv->yuv_info.decode_height = 480;
899
900 /* If no visible size set, assume full size */
901 if (!itv->yuv_info.osd_vis_w) itv->yuv_info.osd_vis_w = 720 - itv->yuv_info.osd_x_offset;
902 if (!itv->yuv_info.osd_vis_h) itv->yuv_info.osd_vis_h = itv->yuv_info.decode_height - itv->yuv_info.osd_y_offset;
903
904 /* We need a buffer for blanking when Y plane is offset - non-fatal if we can't get one */
905 itv->yuv_info.blanking_ptr = kzalloc(720*16,GFP_KERNEL);
906 if (itv->yuv_info.blanking_ptr) {
907 itv->yuv_info.blanking_dmaptr = pci_map_single(itv->dev, itv->yuv_info.blanking_ptr, 720*16, PCI_DMA_TODEVICE);
908 }
909 else {
910 itv->yuv_info.blanking_dmaptr = 0;
911 IVTV_DEBUG_WARN ("Failed to allocate yuv blanking buffer\n");
912 }
913
914 IVTV_DEBUG_WARN("Enable video output\n");
915 write_reg_sync(0x00108080, 0x2898);
916
917 /* Enable YUV decoder output */
918 write_reg_sync(0x01, IVTV_REG_VDM);
919
920 set_bit(IVTV_F_I_DECODING_YUV, &itv->i_flags);
921 atomic_set(&itv->yuv_info.next_dma_frame,0);
922}
923
924int ivtv_yuv_prep_frame(struct ivtv *itv, struct ivtv_dma_frame *args)
925{
926 DEFINE_WAIT(wait);
927 int rc = 0;
928 int got_sig = 0;
929 int frame, next_fill_frame, last_fill_frame;
930
931 IVTV_DEBUG_INFO("yuv_prep_frame\n");
932
933 if (atomic_read(&itv->yuv_info.next_dma_frame) == -1) ivtv_yuv_init(itv);
934
935 frame = atomic_read(&itv->yuv_info.next_fill_frame);
936 next_fill_frame = (frame + 1) & 0x3;
937 last_fill_frame = (atomic_read(&itv->yuv_info.next_dma_frame)+1) & 0x3;
938
939 if (next_fill_frame != last_fill_frame && last_fill_frame != frame) {
940 /* Buffers are full - Overwrite the last frame */
941 next_fill_frame = frame;
942 frame = (frame - 1) & 3;
943 }
944
945 /* Take a snapshot of the yuv coordinate information */
946 itv->yuv_info.new_frame_info[frame].src_x = args->src.left;
947 itv->yuv_info.new_frame_info[frame].src_y = args->src.top;
948 itv->yuv_info.new_frame_info[frame].src_w = args->src.width;
949 itv->yuv_info.new_frame_info[frame].src_h = args->src.height;
950 itv->yuv_info.new_frame_info[frame].dst_x = args->dst.left;
951 itv->yuv_info.new_frame_info[frame].dst_y = args->dst.top;
952 itv->yuv_info.new_frame_info[frame].dst_w = args->dst.width;
953 itv->yuv_info.new_frame_info[frame].dst_h = args->dst.height;
954 itv->yuv_info.new_frame_info[frame].tru_x = args->dst.left;
955 itv->yuv_info.new_frame_info[frame].tru_w = args->src_width;
956 itv->yuv_info.new_frame_info[frame].tru_h = args->src_height;
957
958 /* Are we going to offset the Y plane */
959 if (args->src.height + args->src.top < 512-16)
960 itv->yuv_info.new_frame_info[frame].offset_y = 1;
961 else
962 itv->yuv_info.new_frame_info[frame].offset_y = 0;
963
964 /* Snapshot the osd pan info */
965 itv->yuv_info.new_frame_info[frame].pan_x = itv->yuv_info.osd_x_pan;
966 itv->yuv_info.new_frame_info[frame].pan_y = itv->yuv_info.osd_y_pan;
967 itv->yuv_info.new_frame_info[frame].vis_w = itv->yuv_info.osd_vis_w;
968 itv->yuv_info.new_frame_info[frame].vis_h = itv->yuv_info.osd_vis_h;
969
970 itv->yuv_info.new_frame_info[frame].update = 0;
971 itv->yuv_info.new_frame_info[frame].interlaced_y = 0;
972 itv->yuv_info.new_frame_info[frame].interlaced_uv = 0;
973
974 if (memcmp (&itv->yuv_info.old_frame_info_args, &itv->yuv_info.new_frame_info[frame],
975 sizeof (itv->yuv_info.new_frame_info[frame]))) {
976 memcpy(&itv->yuv_info.old_frame_info_args, &itv->yuv_info.new_frame_info[frame], sizeof (itv->yuv_info.old_frame_info_args));
977 itv->yuv_info.new_frame_info[frame].update = 1;
978/* IVTV_DEBUG_YUV ("Requesting register update for frame %d\n",frame); */
979 }
980
981 /* DMA the frame */
982 mutex_lock(&itv->udma.lock);
983
984 if ((rc = ivtv_yuv_prep_user_dma(itv, &itv->udma, args)) != 0) {
985 mutex_unlock(&itv->udma.lock);
986 return rc;
987 }
988
989 ivtv_udma_prepare(itv);
990 prepare_to_wait(&itv->dma_waitq, &wait, TASK_INTERRUPTIBLE);
991 /* if no UDMA is pending and no UDMA is in progress, then the DMA
992 is finished */
993 while (itv->i_flags & (IVTV_F_I_UDMA_PENDING | IVTV_F_I_UDMA)) {
994 /* don't interrupt if the DMA is in progress but break off
995 a still pending DMA. */
996 got_sig = signal_pending(current);
997 if (got_sig && test_and_clear_bit(IVTV_F_I_UDMA_PENDING, &itv->i_flags))
998 break;
999 got_sig = 0;
1000 schedule();
1001 }
1002 finish_wait(&itv->dma_waitq, &wait);
1003
1004 /* Unmap Last DMA Xfer */
1005 ivtv_udma_unmap(itv);
1006
1007 if (got_sig) {
1008 IVTV_DEBUG_INFO("User stopped YUV UDMA\n");
1009 mutex_unlock(&itv->udma.lock);
1010 return -EINTR;
1011 }
1012
1013 atomic_set(&itv->yuv_info.next_fill_frame, next_fill_frame);
1014
1015 mutex_unlock(&itv->udma.lock);
1016 return rc;
1017}
1018
1019void ivtv_yuv_close(struct ivtv *itv)
1020{
1021 int h_filter, v_filter_1, v_filter_2;
1022
1023 IVTV_DEBUG_YUV("ivtv_yuv_close\n");
1024 ivtv_waitq(&itv->vsync_waitq);
1025
1026 atomic_set(&itv->yuv_info.next_dma_frame, -1);
1027 atomic_set(&itv->yuv_info.next_fill_frame, 0);
1028
1029 /* Reset registers we have changed so mpeg playback works */
1030
1031 /* If we fully restore this register, the display may remain active.
1032 Restore, but set one bit to blank the video. Firmware will always
1033 clear this bit when needed, so not a problem. */
1034 write_reg(itv->yuv_info.reg_2898 | 0x01000000, 0x2898);
1035
1036 write_reg(itv->yuv_info.reg_2834, 0x02834);
1037 write_reg(itv->yuv_info.reg_2838, 0x02838);
1038 write_reg(itv->yuv_info.reg_283c, 0x0283c);
1039 write_reg(itv->yuv_info.reg_2840, 0x02840);
1040 write_reg(itv->yuv_info.reg_2844, 0x02844);
1041 write_reg(itv->yuv_info.reg_2848, 0x02848);
1042 write_reg(itv->yuv_info.reg_2854, 0x02854);
1043 write_reg(itv->yuv_info.reg_285c, 0x0285c);
1044 write_reg(itv->yuv_info.reg_2864, 0x02864);
1045 write_reg(itv->yuv_info.reg_2870, 0x02870);
1046 write_reg(itv->yuv_info.reg_2874, 0x02874);
1047 write_reg(itv->yuv_info.reg_2890, 0x02890);
1048 write_reg(itv->yuv_info.reg_289c, 0x0289c);
1049
1050 write_reg(itv->yuv_info.reg_2918, 0x02918);
1051 write_reg(itv->yuv_info.reg_291c, 0x0291c);
1052 write_reg(itv->yuv_info.reg_2920, 0x02920);
1053 write_reg(itv->yuv_info.reg_2924, 0x02924);
1054 write_reg(itv->yuv_info.reg_2928, 0x02928);
1055 write_reg(itv->yuv_info.reg_292c, 0x0292c);
1056 write_reg(itv->yuv_info.reg_2930, 0x02930);
1057 write_reg(itv->yuv_info.reg_2934, 0x02934);
1058 write_reg(itv->yuv_info.reg_2938, 0x02938);
1059 write_reg(itv->yuv_info.reg_293c, 0x0293c);
1060 write_reg(itv->yuv_info.reg_2940, 0x02940);
1061 write_reg(itv->yuv_info.reg_2944, 0x02944);
1062 write_reg(itv->yuv_info.reg_2948, 0x02948);
1063 write_reg(itv->yuv_info.reg_294c, 0x0294c);
1064 write_reg(itv->yuv_info.reg_2950, 0x02950);
1065 write_reg(itv->yuv_info.reg_2954, 0x02954);
1066 write_reg(itv->yuv_info.reg_2958, 0x02958);
1067 write_reg(itv->yuv_info.reg_295c, 0x0295c);
1068 write_reg(itv->yuv_info.reg_2960, 0x02960);
1069 write_reg(itv->yuv_info.reg_2964, 0x02964);
1070 write_reg(itv->yuv_info.reg_2968, 0x02968);
1071 write_reg(itv->yuv_info.reg_296c, 0x0296c);
1072 write_reg(itv->yuv_info.reg_2970, 0x02970);
1073
1074 /* Prepare to restore filters */
1075
1076 /* First the horizontal filter */
1077 if ((itv->yuv_info.reg_2834 & 0x0000FFFF) == (itv->yuv_info.reg_2834 >> 16)) {
1078 /* An exact size match uses filter 0 */
1079 h_filter = 0;
1080 }
1081 else {
1082 /* Figure out which filter to use */
1083 h_filter = ((itv->yuv_info.reg_2834 << 16) / (itv->yuv_info.reg_2834 >> 16)) >> 15;
1084 h_filter = (h_filter >> 1) + (h_filter & 1);
1085 /* Only an exact size match can use filter 0. */
1086 if (h_filter < 1) h_filter = 1;
1087 }
1088
1089 /* Now the vertical filter */
1090 if ((itv->yuv_info.reg_2918 & 0x0000FFFF) == (itv->yuv_info.reg_2918 >> 16)) {
1091 /* An exact size match uses filter 0/1 */
1092 v_filter_1 = 0;
1093 v_filter_2 = 1;
1094 }
1095 else {
1096 /* Figure out which filter to use */
1097 v_filter_1 = ((itv->yuv_info.reg_2918 << 16) / (itv->yuv_info.reg_2918 >> 16)) >> 15;
1098 v_filter_1 = (v_filter_1 >> 1) + (v_filter_1 & 1);
1099 /* Only an exact size match can use filter 0 */
1100 if (v_filter_1 == 0) v_filter_1 = 1;
1101 v_filter_2 = v_filter_1;
1102 }
1103
1104 /* Now restore the filters */
1105 ivtv_yuv_filter (itv,h_filter,v_filter_1,v_filter_2);
1106
1107 /* and clear a few registers */
1108 write_reg(0, 0x02814);
1109 write_reg(0, 0x0282c);
1110 write_reg(0, 0x02904);
1111 write_reg(0, 0x02910);
1112
1113 /* Release the blanking buffer */
1114 if (itv->yuv_info.blanking_ptr) {
1115 kfree (itv->yuv_info.blanking_ptr);
1116 itv->yuv_info.blanking_ptr = NULL;
1117 pci_unmap_single(itv->dev, itv->yuv_info.blanking_dmaptr, 720*16, PCI_DMA_TODEVICE);
1118 }
1119
1120 /* Invalidate the old dimension information */
1121 itv->yuv_info.old_frame_info.src_w = 0;
1122 itv->yuv_info.old_frame_info.src_h = 0;
1123 itv->yuv_info.old_frame_info_args.src_w = 0;
1124 itv->yuv_info.old_frame_info_args.src_h = 0;
1125
1126 /* All done. */
1127 clear_bit(IVTV_F_I_DECODING_YUV, &itv->i_flags);
1128}
1129
diff --git a/drivers/media/video/ivtv/ivtv-yuv.h b/drivers/media/video/ivtv/ivtv-yuv.h
new file mode 100644
index 000000000000..88972d3f77c4
--- /dev/null
+++ b/drivers/media/video/ivtv/ivtv-yuv.h
@@ -0,0 +1,24 @@
1/*
2 yuv support
3
4 Copyright (C) 2007 Ian Armstrong <ian@iarmst.demon.co.uk>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21int ivtv_yuv_filter_check(struct ivtv *itv);
22int ivtv_yuv_prep_frame(struct ivtv *itv, struct ivtv_dma_frame *args);
23void ivtv_yuv_close(struct ivtv *itv);
24void ivtv_yuv_work_handler (struct ivtv *itv);
diff --git a/drivers/media/video/msp3400-driver.c b/drivers/media/video/msp3400-driver.c
index ba1af3c8525e..3bb7d6634862 100644
--- a/drivers/media/video/msp3400-driver.c
+++ b/drivers/media/video/msp3400-driver.c
@@ -773,6 +773,9 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
773 break; 773 break;
774 } 774 }
775 775
776 case VIDIOC_G_CHIP_IDENT:
777 return v4l2_chip_ident_i2c_client(client, arg, state->ident, (state->rev1 << 16) | state->rev2);
778
776 default: 779 default:
777 /* unknown */ 780 /* unknown */
778 return -EINVAL; 781 return -EINVAL;
@@ -872,6 +875,8 @@ static int msp_attach(struct i2c_adapter *adapter, int address, int kind)
872 snprintf(client->name, sizeof(client->name), "MSP%d4%02d%c-%c%d", 875 snprintf(client->name, sizeof(client->name), "MSP%d4%02d%c-%c%d",
873 msp_family, msp_product, 876 msp_family, msp_product,
874 msp_revision, msp_hard, msp_rom); 877 msp_revision, msp_hard, msp_rom);
878 /* Rev B=2, C=3, D=4, G=7 */
879 state->ident = msp_family * 10000 + 4000 + msp_product * 10 + msp_revision - '@';
875 880
876 /* Has NICAM support: all mspx41x and mspx45x products have NICAM */ 881 /* Has NICAM support: all mspx41x and mspx45x products have NICAM */
877 state->has_nicam = msp_prod_hi == 1 || msp_prod_hi == 5; 882 state->has_nicam = msp_prod_hi == 1 || msp_prod_hi == 5;
diff --git a/drivers/media/video/msp3400-driver.h b/drivers/media/video/msp3400-driver.h
index 7531efa1615e..ab69a290e5dc 100644
--- a/drivers/media/video/msp3400-driver.h
+++ b/drivers/media/video/msp3400-driver.h
@@ -50,6 +50,7 @@ extern int msp_stereo_thresh;
50 50
51struct msp_state { 51struct msp_state {
52 int rev1, rev2; 52 int rev1, rev2;
53 int ident;
53 u8 has_nicam; 54 u8 has_nicam;
54 u8 has_radio; 55 u8 has_radio;
55 u8 has_headphones; 56 u8 has_headphones;
diff --git a/drivers/media/video/ov7670.c b/drivers/media/video/ov7670.c
index 5ed0adc4ca26..03bc369a9e49 100644
--- a/drivers/media/video/ov7670.c
+++ b/drivers/media/video/ov7670.c
@@ -5,6 +5,8 @@
5 * by Jonathan Corbet with substantial inspiration from Mark 5 * by Jonathan Corbet with substantial inspiration from Mark
6 * McClelland's ovcamchip code. 6 * McClelland's ovcamchip code.
7 * 7 *
8 * Copyright 2006-7 Jonathan Corbet <corbet@lwn.net>
9 *
8 * This file may be distributed under the terms of the GNU General 10 * This file may be distributed under the terms of the GNU General
9 * Public License, version 2. 11 * Public License, version 2.
10 */ 12 */
@@ -15,6 +17,7 @@
15#include <linux/delay.h> 17#include <linux/delay.h>
16#include <linux/videodev.h> 18#include <linux/videodev.h>
17#include <media/v4l2-common.h> 19#include <media/v4l2-common.h>
20#include <media/v4l2-chip-ident.h>
18#include <linux/i2c.h> 21#include <linux/i2c.h>
19 22
20 23
@@ -162,6 +165,10 @@ MODULE_LICENSE("GPL");
162 165
163#define REG_GFIX 0x69 /* Fix gain control */ 166#define REG_GFIX 0x69 /* Fix gain control */
164 167
168#define REG_REG76 0x76 /* OV's name */
169#define R76_BLKPCOR 0x80 /* Black pixel correction enable */
170#define R76_WHTPCOR 0x40 /* White pixel correction enable */
171
165#define REG_RGB444 0x8c /* RGB 444 control */ 172#define REG_RGB444 0x8c /* RGB 444 control */
166#define R444_ENABLE 0x02 /* Turn on RGB444, overrides 5x5 */ 173#define R444_ENABLE 0x02 /* Turn on RGB444, overrides 5x5 */
167#define R444_RGBX 0x01 /* Empty nibble at end */ 174#define R444_RGBX 0x01 /* Empty nibble at end */
@@ -255,7 +262,7 @@ static struct regval_list ov7670_default_regs[] = {
255 262
256 /* Almost all of these are magic "reserved" values. */ 263 /* Almost all of these are magic "reserved" values. */
257 { REG_COM5, 0x61 }, { REG_COM6, 0x4b }, 264 { REG_COM5, 0x61 }, { REG_COM6, 0x4b },
258 { 0x16, 0x02 }, { REG_MVFP, 0x07|MVFP_MIRROR }, 265 { 0x16, 0x02 }, { REG_MVFP, 0x07 },
259 { 0x21, 0x02 }, { 0x22, 0x91 }, 266 { 0x21, 0x02 }, { 0x22, 0x91 },
260 { 0x29, 0x07 }, { 0x33, 0x0b }, 267 { 0x29, 0x07 }, { 0x33, 0x0b },
261 { 0x35, 0x0b }, { 0x37, 0x1d }, 268 { 0x35, 0x0b }, { 0x37, 0x1d },
@@ -380,6 +387,13 @@ static struct regval_list ov7670_fmt_rgb444[] = {
380 { 0xff, 0xff }, 387 { 0xff, 0xff },
381}; 388};
382 389
390static struct regval_list ov7670_fmt_raw[] = {
391 { REG_COM7, COM7_BAYER },
392 { REG_COM13, 0x08 }, /* No gamma, magic rsvd bit */
393 { REG_COM16, 0x3d }, /* Edge enhancement, denoise */
394 { REG_REG76, 0xe1 }, /* Pix correction, magic rsvd */
395 { 0xff, 0xff },
396};
383 397
384 398
385 399
@@ -483,32 +497,39 @@ static struct ov7670_format_struct {
483 __u32 pixelformat; 497 __u32 pixelformat;
484 struct regval_list *regs; 498 struct regval_list *regs;
485 int cmatrix[CMATRIX_LEN]; 499 int cmatrix[CMATRIX_LEN];
500 int bpp; /* Bytes per pixel */
486} ov7670_formats[] = { 501} ov7670_formats[] = {
487 { 502 {
488 .desc = "YUYV 4:2:2", 503 .desc = "YUYV 4:2:2",
489 .pixelformat = V4L2_PIX_FMT_YUYV, 504 .pixelformat = V4L2_PIX_FMT_YUYV,
490 .regs = ov7670_fmt_yuv422, 505 .regs = ov7670_fmt_yuv422,
491 .cmatrix = { 128, -128, 0, -34, -94, 128 }, 506 .cmatrix = { 128, -128, 0, -34, -94, 128 },
507 .bpp = 2,
492 }, 508 },
493 { 509 {
494 .desc = "RGB 444", 510 .desc = "RGB 444",
495 .pixelformat = V4L2_PIX_FMT_RGB444, 511 .pixelformat = V4L2_PIX_FMT_RGB444,
496 .regs = ov7670_fmt_rgb444, 512 .regs = ov7670_fmt_rgb444,
497 .cmatrix = { 179, -179, 0, -61, -176, 228 }, 513 .cmatrix = { 179, -179, 0, -61, -176, 228 },
514 .bpp = 2,
498 }, 515 },
499 { 516 {
500 .desc = "RGB 565", 517 .desc = "RGB 565",
501 .pixelformat = V4L2_PIX_FMT_RGB565, 518 .pixelformat = V4L2_PIX_FMT_RGB565,
502 .regs = ov7670_fmt_rgb565, 519 .regs = ov7670_fmt_rgb565,
503 .cmatrix = { 179, -179, 0, -61, -176, 228 }, 520 .cmatrix = { 179, -179, 0, -61, -176, 228 },
521 .bpp = 2,
522 },
523 {
524 .desc = "Raw RGB Bayer",
525 .pixelformat = V4L2_PIX_FMT_SBGGR8,
526 .regs = ov7670_fmt_raw,
527 .cmatrix = { 0, 0, 0, 0, 0, 0 },
528 .bpp = 1
504 }, 529 },
505}; 530};
506#define N_OV7670_FMTS (sizeof(ov7670_formats)/sizeof(ov7670_formats[0])) 531#define N_OV7670_FMTS ARRAY_SIZE(ov7670_formats)
507 532
508/*
509 * All formats we support are 2 bytes/pixel.
510 */
511#define BYTES_PER_PIXEL 2
512 533
513/* 534/*
514 * Then there is the issue of window sizes. Try to capture the info here. 535 * Then there is the issue of window sizes. Try to capture the info here.
@@ -685,7 +706,7 @@ static int ov7670_try_fmt(struct i2c_client *c, struct v4l2_format *fmt,
685 */ 706 */
686 pix->width = wsize->width; 707 pix->width = wsize->width;
687 pix->height = wsize->height; 708 pix->height = wsize->height;
688 pix->bytesperline = pix->width*BYTES_PER_PIXEL; 709 pix->bytesperline = pix->width*ov7670_formats[index].bpp;
689 pix->sizeimage = pix->height*pix->bytesperline; 710 pix->sizeimage = pix->height*pix->bytesperline;
690 return 0; 711 return 0;
691} 712}
@@ -1270,9 +1291,8 @@ static int ov7670_command(struct i2c_client *client, unsigned int cmd,
1270 void *arg) 1291 void *arg)
1271{ 1292{
1272 switch (cmd) { 1293 switch (cmd) {
1273 case VIDIOC_INT_G_CHIP_IDENT: 1294 case VIDIOC_G_CHIP_IDENT:
1274 * (enum v4l2_chip_ident *) arg = V4L2_IDENT_OV7670; 1295 return v4l2_chip_ident_i2c_client(client, arg, V4L2_IDENT_OV7670, 0);
1275 return 0;
1276 1296
1277 case VIDIOC_INT_RESET: 1297 case VIDIOC_INT_RESET:
1278 ov7670_reset(client); 1298 ov7670_reset(client);
diff --git a/drivers/media/video/planb.c b/drivers/media/video/planb.c
index 86d2884e16c6..fe184f93c016 100644
--- a/drivers/media/video/planb.c
+++ b/drivers/media/video/planb.c
@@ -2207,7 +2207,7 @@ static int find_planb(void)
2207 "membase 0x%x (base reg. 0x%x)\n", 2207 "membase 0x%x (base reg. 0x%x)\n",
2208 bus, PCI_SLOT(dev_fn), PCI_FUNC(dev_fn), old_base, confreg); 2208 bus, PCI_SLOT(dev_fn), PCI_FUNC(dev_fn), old_base, confreg);
2209 2209
2210 pdev = pci_find_slot (bus, dev_fn); 2210 pdev = pci_get_bus_and_slot(bus, dev_fn);
2211 if (!pdev) { 2211 if (!pdev) {
2212 printk(KERN_ERR "planb: cannot find slot\n"); 2212 printk(KERN_ERR "planb: cannot find slot\n");
2213 goto err_out; 2213 goto err_out;
@@ -2237,6 +2237,7 @@ static int find_planb(void)
2237 pb->planb_base = planb_regs; 2237 pb->planb_base = planb_regs;
2238 pb->planb_base_phys = (struct planb_registers *)new_base; 2238 pb->planb_base_phys = (struct planb_registers *)new_base;
2239 pb->irq = irq; 2239 pb->irq = irq;
2240 pb->dev = pdev;
2240 2241
2241 return planb_num; 2242 return planb_num;
2242 2243
@@ -2244,6 +2245,7 @@ err_out_disable:
2244 pci_disable_device(pdev); 2245 pci_disable_device(pdev);
2245err_out: 2246err_out:
2246 /* FIXME handle error */ /* comment moved from pci_find_slot, above */ 2247 /* FIXME handle error */ /* comment moved from pci_find_slot, above */
2248 pci_dev_put(pdev);
2247 return 0; 2249 return 0;
2248} 2250}
2249 2251
@@ -2271,6 +2273,8 @@ static void release_planb(void)
2271 printk(KERN_INFO "PlanB: unregistering with v4l\n"); 2273 printk(KERN_INFO "PlanB: unregistering with v4l\n");
2272 video_unregister_device(&pb->video_dev); 2274 video_unregister_device(&pb->video_dev);
2273 2275
2276 pci_dev_put(pb->dev);
2277
2274 /* note that iounmap() does nothing on the PPC right now */ 2278 /* note that iounmap() does nothing on the PPC right now */
2275 iounmap ((void *)pb->planb_base); 2279 iounmap ((void *)pb->planb_base);
2276 } 2280 }
diff --git a/drivers/media/video/planb.h b/drivers/media/video/planb.h
index 92823211d0c5..e21b5735c103 100644
--- a/drivers/media/video/planb.h
+++ b/drivers/media/video/planb.h
@@ -177,6 +177,7 @@ struct planb {
177 struct mutex lock; 177 struct mutex lock;
178 unsigned int irq; /* interrupt number */ 178 unsigned int irq; /* interrupt number */
179 volatile unsigned int intr_mask; 179 volatile unsigned int intr_mask;
180 struct pci_dev *dev; /* Our PCI device */
180 181
181 int overlay; /* overlay running? */ 182 int overlay; /* overlay running? */
182 struct planb_window win; 183 struct planb_window win;
diff --git a/drivers/media/video/pvrusb2/pvrusb2-encoder.c b/drivers/media/video/pvrusb2/pvrusb2-encoder.c
index 5786faf9b3b8..5669c8ca9ca3 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-encoder.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-encoder.c
@@ -324,7 +324,7 @@ static int pvr2_encoder_vcmd(struct pvr2_hdw *hdw, int cmd,
324 324
325/* This implements some extra setup for the encoder that seems to be 325/* This implements some extra setup for the encoder that seems to be
326 specific to the PVR USB2 hardware. */ 326 specific to the PVR USB2 hardware. */
327int pvr2_encoder_prep_config(struct pvr2_hdw *hdw) 327static int pvr2_encoder_prep_config(struct pvr2_hdw *hdw)
328{ 328{
329 int ret = 0; 329 int ret = 0;
330 int encMisc3Arg = 0; 330 int encMisc3Arg = 0;
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h b/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h
index 16bd74199601..ce66ab8ff2d8 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h
@@ -283,6 +283,8 @@ struct pvr2_hdw {
283 int unit_number; /* ID for driver instance */ 283 int unit_number; /* ID for driver instance */
284 unsigned long serial_number; /* ID for hardware itself */ 284 unsigned long serial_number; /* ID for hardware itself */
285 285
286 char bus_info[32]; /* Bus location info */
287
286 /* Minor numbers used by v4l logic (yes, this is a hack, as there 288 /* Minor numbers used by v4l logic (yes, this is a hack, as there
287 should be no v4l junk here). Probably a better way to do this. */ 289 should be no v4l junk here). Probably a better way to do this. */
288 int v4l_minor_number_video; 290 int v4l_minor_number_video;
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
index 9916cf32494d..acf651e01f94 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
@@ -1008,6 +1008,13 @@ unsigned long pvr2_hdw_get_sn(struct pvr2_hdw *hdw)
1008 return hdw->serial_number; 1008 return hdw->serial_number;
1009} 1009}
1010 1010
1011
1012const char *pvr2_hdw_get_bus_info(struct pvr2_hdw *hdw)
1013{
1014 return hdw->bus_info;
1015}
1016
1017
1011unsigned long pvr2_hdw_get_cur_freq(struct pvr2_hdw *hdw) 1018unsigned long pvr2_hdw_get_cur_freq(struct pvr2_hdw *hdw)
1012{ 1019{
1013 return hdw->freqSelector ? hdw->freqValTelevision : hdw->freqValRadio; 1020 return hdw->freqSelector ? hdw->freqValTelevision : hdw->freqValRadio;
@@ -2105,6 +2112,11 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf,
2105 hdw->usb_intf = intf; 2112 hdw->usb_intf = intf;
2106 hdw->usb_dev = interface_to_usbdev(intf); 2113 hdw->usb_dev = interface_to_usbdev(intf);
2107 2114
2115 scnprintf(hdw->bus_info,sizeof(hdw->bus_info),
2116 "usb %s address %d",
2117 hdw->usb_dev->dev.bus_id,
2118 hdw->usb_dev->devnum);
2119
2108 ifnum = hdw->usb_intf->cur_altsetting->desc.bInterfaceNumber; 2120 ifnum = hdw->usb_intf->cur_altsetting->desc.bInterfaceNumber;
2109 usb_set_interface(hdw->usb_dev,ifnum,0); 2121 usb_set_interface(hdw->usb_dev,ifnum,0);
2110 2122
@@ -3275,7 +3287,9 @@ int pvr2_hdw_register_access(struct pvr2_hdw *hdw,
3275 mutex_lock(&hdw->i2c_list_lock); do { 3287 mutex_lock(&hdw->i2c_list_lock); do {
3276 list_for_each(item,&hdw->i2c_clients) { 3288 list_for_each(item,&hdw->i2c_clients) {
3277 cp = list_entry(item,struct pvr2_i2c_client,list); 3289 cp = list_entry(item,struct pvr2_i2c_client,list);
3278 if (!v4l2_chip_match_i2c_client(cp->client, req.match_type, req.match_chip)) { 3290 if (!v4l2_chip_match_i2c_client(
3291 cp->client,
3292 req.match_type, req.match_chip)) {
3279 continue; 3293 continue;
3280 } 3294 }
3281 stat = pvr2_i2c_client_cmd( 3295 stat = pvr2_i2c_client_cmd(
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.h b/drivers/media/video/pvrusb2/pvrusb2-hdw.h
index 0c9cca43ff85..4dba8d006324 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-hdw.h
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.h
@@ -124,6 +124,9 @@ struct usb_device *pvr2_hdw_get_dev(struct pvr2_hdw *);
124/* Retrieve serial number of device */ 124/* Retrieve serial number of device */
125unsigned long pvr2_hdw_get_sn(struct pvr2_hdw *); 125unsigned long pvr2_hdw_get_sn(struct pvr2_hdw *);
126 126
127/* Retrieve bus location info of device */
128const char *pvr2_hdw_get_bus_info(struct pvr2_hdw *);
129
127/* Called when hardware has been unplugged */ 130/* Called when hardware has been unplugged */
128void pvr2_hdw_disconnect(struct pvr2_hdw *); 131void pvr2_hdw_disconnect(struct pvr2_hdw *);
129 132
diff --git a/drivers/media/video/pvrusb2/pvrusb2-sysfs.c b/drivers/media/video/pvrusb2/pvrusb2-sysfs.c
index 91396fd573e4..a741c556a39a 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-sysfs.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-sysfs.c
@@ -42,9 +42,11 @@ struct pvr2_sysfs {
42 struct class_device_attribute attr_v4l_minor_number; 42 struct class_device_attribute attr_v4l_minor_number;
43 struct class_device_attribute attr_v4l_radio_minor_number; 43 struct class_device_attribute attr_v4l_radio_minor_number;
44 struct class_device_attribute attr_unit_number; 44 struct class_device_attribute attr_unit_number;
45 struct class_device_attribute attr_bus_info;
45 int v4l_minor_number_created_ok; 46 int v4l_minor_number_created_ok;
46 int v4l_radio_minor_number_created_ok; 47 int v4l_radio_minor_number_created_ok;
47 int unit_number_created_ok; 48 int unit_number_created_ok;
49 int bus_info_created_ok;
48}; 50};
49 51
50#ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC 52#ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
@@ -705,6 +707,10 @@ static void class_dev_destroy(struct pvr2_sysfs *sfp)
705 pvr2_sysfs_tear_down_debugifc(sfp); 707 pvr2_sysfs_tear_down_debugifc(sfp);
706#endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */ 708#endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
707 pvr2_sysfs_tear_down_controls(sfp); 709 pvr2_sysfs_tear_down_controls(sfp);
710 if (sfp->bus_info_created_ok) {
711 class_device_remove_file(sfp->class_dev,
712 &sfp->attr_bus_info);
713 }
708 if (sfp->v4l_minor_number_created_ok) { 714 if (sfp->v4l_minor_number_created_ok) {
709 class_device_remove_file(sfp->class_dev, 715 class_device_remove_file(sfp->class_dev,
710 &sfp->attr_v4l_minor_number); 716 &sfp->attr_v4l_minor_number);
@@ -735,6 +741,16 @@ static ssize_t v4l_minor_number_show(struct class_device *class_dev,char *buf)
735} 741}
736 742
737 743
744static ssize_t bus_info_show(struct class_device *class_dev,char *buf)
745{
746 struct pvr2_sysfs *sfp;
747 sfp = (struct pvr2_sysfs *)class_dev->class_data;
748 if (!sfp) return -EINVAL;
749 return scnprintf(buf,PAGE_SIZE,"%s\n",
750 pvr2_hdw_get_bus_info(sfp->channel.hdw));
751}
752
753
738static ssize_t v4l_radio_minor_number_show(struct class_device *class_dev, 754static ssize_t v4l_radio_minor_number_show(struct class_device *class_dev,
739 char *buf) 755 char *buf)
740{ 756{
@@ -836,6 +852,20 @@ static void class_dev_create(struct pvr2_sysfs *sfp,
836 sfp->unit_number_created_ok = !0; 852 sfp->unit_number_created_ok = !0;
837 } 853 }
838 854
855 sfp->attr_bus_info.attr.owner = THIS_MODULE;
856 sfp->attr_bus_info.attr.name = "bus_info_str";
857 sfp->attr_bus_info.attr.mode = S_IRUGO;
858 sfp->attr_bus_info.show = bus_info_show;
859 sfp->attr_bus_info.store = NULL;
860 ret = class_device_create_file(sfp->class_dev,
861 &sfp->attr_bus_info);
862 if (ret < 0) {
863 printk(KERN_WARNING "%s: class_device_create_file error: %d\n",
864 __FUNCTION__, ret);
865 } else {
866 sfp->bus_info_created_ok = !0;
867 }
868
839 pvr2_sysfs_add_controls(sfp); 869 pvr2_sysfs_add_controls(sfp);
840#ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC 870#ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
841 pvr2_sysfs_add_debugifc(sfp); 871 pvr2_sysfs_add_debugifc(sfp);
diff --git a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
index 25d3830b482a..4563b3df8a0d 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
@@ -203,6 +203,8 @@ static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file,
203 struct v4l2_capability *cap = arg; 203 struct v4l2_capability *cap = arg;
204 204
205 memcpy(cap, &pvr_capability, sizeof(struct v4l2_capability)); 205 memcpy(cap, &pvr_capability, sizeof(struct v4l2_capability));
206 strlcpy(cap->bus_info,pvr2_hdw_get_bus_info(hdw),
207 sizeof(cap->bus_info));
206 208
207 ret = 0; 209 ret = 0;
208 break; 210 break;
diff --git a/drivers/media/video/pwc/pwc-ctrl.c b/drivers/media/video/pwc/pwc-ctrl.c
index 0bd115588f31..338ced7188f2 100644
--- a/drivers/media/video/pwc/pwc-ctrl.c
+++ b/drivers/media/video/pwc/pwc-ctrl.c
@@ -140,6 +140,8 @@ static const char *size2name[PSZ_MAX] =
140 An alternate value of 0 means this mode is not available at all. 140 An alternate value of 0 means this mode is not available at all.
141 */ 141 */
142 142
143#define PWC_FPS_MAX_NALA 8
144
143struct Nala_table_entry { 145struct Nala_table_entry {
144 char alternate; /* USB alternate setting */ 146 char alternate; /* USB alternate setting */
145 int compressed; /* Compressed yes/no */ 147 int compressed; /* Compressed yes/no */
@@ -147,7 +149,9 @@ struct Nala_table_entry {
147 unsigned char mode[3]; /* precomputed mode table */ 149 unsigned char mode[3]; /* precomputed mode table */
148}; 150};
149 151
150static struct Nala_table_entry Nala_table[PSZ_MAX][8] = 152static unsigned int Nala_fps_vector[PWC_FPS_MAX_NALA] = { 4, 5, 7, 10, 12, 15, 20, 24 };
153
154static struct Nala_table_entry Nala_table[PSZ_MAX][PWC_FPS_MAX_NALA] =
151{ 155{
152#include "pwc-nala.h" 156#include "pwc-nala.h"
153}; 157};
@@ -423,6 +427,59 @@ int pwc_set_video_mode(struct pwc_device *pdev, int width, int height, int frame
423 return 0; 427 return 0;
424} 428}
425 429
430static unsigned int pwc_get_fps_Nala(struct pwc_device *pdev, unsigned int index, unsigned int size)
431{
432 unsigned int i;
433
434 for (i = 0; i < PWC_FPS_MAX_NALA; i++) {
435 if (Nala_table[size][i].alternate) {
436 if (index--==0) return Nala_fps_vector[i];
437 }
438 }
439 return 0;
440}
441
442static unsigned int pwc_get_fps_Kiara(struct pwc_device *pdev, unsigned int index, unsigned int size)
443{
444 unsigned int i;
445
446 for (i = 0; i < PWC_FPS_MAX_KIARA; i++) {
447 if (Kiara_table[size][i][3].alternate) {
448 if (index--==0) return Kiara_fps_vector[i];
449 }
450 }
451 return 0;
452}
453
454static unsigned int pwc_get_fps_Timon(struct pwc_device *pdev, unsigned int index, unsigned int size)
455{
456 unsigned int i;
457
458 for (i=0; i < PWC_FPS_MAX_TIMON; i++) {
459 if (Timon_table[size][i][3].alternate) {
460 if (index--==0) return Timon_fps_vector[i];
461 }
462 }
463 return 0;
464}
465
466unsigned int pwc_get_fps(struct pwc_device *pdev, unsigned int index, unsigned int size)
467{
468 unsigned int ret;
469
470 if (DEVICE_USE_CODEC1(pdev->type)) {
471 ret = pwc_get_fps_Nala(pdev, index, size);
472
473 } else if (DEVICE_USE_CODEC3(pdev->type)) {
474 ret = pwc_get_fps_Kiara(pdev, index, size);
475
476 } else {
477 ret = pwc_get_fps_Timon(pdev, index, size);
478 }
479
480 return ret;
481}
482
426#define BLACK_Y 0 483#define BLACK_Y 0
427#define BLACK_U 128 484#define BLACK_U 128
428#define BLACK_V 128 485#define BLACK_V 128
@@ -1343,7 +1400,7 @@ int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg)
1343 ret = pwc_read_red_gain(pdev, &ARGR(wb).read_red); 1400 ret = pwc_read_red_gain(pdev, &ARGR(wb).read_red);
1344 if (ret < 0) 1401 if (ret < 0)
1345 break; 1402 break;
1346 ret =pwc_read_blue_gain(pdev, &ARGR(wb).read_blue); 1403 ret = pwc_read_blue_gain(pdev, &ARGR(wb).read_blue);
1347 if (ret < 0) 1404 if (ret < 0)
1348 break; 1405 break;
1349 } 1406 }
diff --git a/drivers/media/video/pwc/pwc-if.c b/drivers/media/video/pwc/pwc-if.c
index 27ed76986ca2..085332a503de 100644
--- a/drivers/media/video/pwc/pwc-if.c
+++ b/drivers/media/video/pwc/pwc-if.c
@@ -95,8 +95,8 @@ static const struct usb_device_id pwc_device_table [] = {
95 { USB_DEVICE(0x046D, 0x08B3) }, /* Logitech QuickCam Zoom (old model) */ 95 { USB_DEVICE(0x046D, 0x08B3) }, /* Logitech QuickCam Zoom (old model) */
96 { USB_DEVICE(0x046D, 0x08B4) }, /* Logitech QuickCam Zoom (new model) */ 96 { USB_DEVICE(0x046D, 0x08B4) }, /* Logitech QuickCam Zoom (new model) */
97 { USB_DEVICE(0x046D, 0x08B5) }, /* Logitech QuickCam Orbit/Sphere */ 97 { USB_DEVICE(0x046D, 0x08B5) }, /* Logitech QuickCam Orbit/Sphere */
98 { USB_DEVICE(0x046D, 0x08B6) }, /* Logitech (reserved) */ 98 { USB_DEVICE(0x046D, 0x08B6) }, /* Cisco VT Camera */
99 { USB_DEVICE(0x046D, 0x08B7) }, /* Logitech (reserved) */ 99 { USB_DEVICE(0x046D, 0x08B7) }, /* Logitech ViewPort AV 100 */
100 { USB_DEVICE(0x046D, 0x08B8) }, /* Logitech (reserved) */ 100 { USB_DEVICE(0x046D, 0x08B8) }, /* Logitech (reserved) */
101 { USB_DEVICE(0x055D, 0x9000) }, /* Samsung MPC-C10 */ 101 { USB_DEVICE(0x055D, 0x9000) }, /* Samsung MPC-C10 */
102 { USB_DEVICE(0x055D, 0x9001) }, /* Samsung MPC-C30 */ 102 { USB_DEVICE(0x055D, 0x9001) }, /* Samsung MPC-C30 */
@@ -1493,7 +1493,7 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
1493 case 0x0329: 1493 case 0x0329:
1494 PWC_INFO("Philips SPC 900NC USB webcam detected.\n"); 1494 PWC_INFO("Philips SPC 900NC USB webcam detected.\n");
1495 name = "Philips SPC 900NC webcam"; 1495 name = "Philips SPC 900NC webcam";
1496 type_id = 720; 1496 type_id = 740;
1497 break; 1497 break;
1498 default: 1498 default:
1499 return -ENODEV; 1499 return -ENODEV;
@@ -1547,8 +1547,16 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
1547 features |= FEATURE_MOTOR_PANTILT; 1547 features |= FEATURE_MOTOR_PANTILT;
1548 break; 1548 break;
1549 case 0x08b6: 1549 case 0x08b6:
1550 PWC_INFO("Logitech/Cisco VT Camera webcam detected.\n");
1551 name = "Cisco VT Camera";
1552 type_id = 740; /* CCD sensor */
1553 break;
1550 case 0x08b7: 1554 case 0x08b7:
1551 case 0x08b8: 1555 PWC_INFO("Logitech ViewPort AV 100 webcam detected.\n");
1556 name = "Logitech ViewPort AV 100";
1557 type_id = 740; /* CCD sensor */
1558 break;
1559 case 0x08b8: /* Where this released? */
1552 PWC_INFO("Logitech QuickCam detected (reserved ID).\n"); 1560 PWC_INFO("Logitech QuickCam detected (reserved ID).\n");
1553 name = "Logitech QuickCam (res.)"; 1561 name = "Logitech QuickCam (res.)";
1554 type_id = 730; /* Assuming CMOS */ 1562 type_id = 730; /* Assuming CMOS */
diff --git a/drivers/media/video/pwc/pwc-ioctl.h b/drivers/media/video/pwc/pwc-ioctl.h
index 784bc72521fa..cec660299768 100644
--- a/drivers/media/video/pwc/pwc-ioctl.h
+++ b/drivers/media/video/pwc/pwc-ioctl.h
@@ -2,7 +2,7 @@
2#define PWC_IOCTL_H 2#define PWC_IOCTL_H
3 3
4/* (C) 2001-2004 Nemosoft Unv. 4/* (C) 2001-2004 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.
@@ -25,7 +25,7 @@
25 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 25 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26*/ 26*/
27 27
28/* This is pwc-ioctl.h belonging to PWC 8.12.1 28/* This is pwc-ioctl.h belonging to PWC 10.0.10
29 It contains structures and defines to communicate from user space 29 It contains structures and defines to communicate from user space
30 directly to the driver. 30 directly to the driver.
31 */ 31 */
@@ -51,6 +51,9 @@
51 ... the function 51 ... the function
52 */ 52 */
53 53
54#include <linux/types.h>
55#include <linux/version.h>
56
54 57
55 /* Enumeration of image sizes */ 58 /* Enumeration of image sizes */
56#define PSZ_SQCIF 0x00 59#define PSZ_SQCIF 0x00
@@ -65,6 +68,8 @@
65/* The frame rate is encoded in the video_window.flags parameter using 68/* The frame rate is encoded in the video_window.flags parameter using
66 the upper 16 bits, since some flags are defined nowadays. The following 69 the upper 16 bits, since some flags are defined nowadays. The following
67 defines provide a mask and shift to filter out this value. 70 defines provide a mask and shift to filter out this value.
71 This value can also be passing using the private flag when using v4l2 and
72 VIDIOC_S_FMT ioctl.
68 73
69 In 'Snapshot' mode the camera freezes its automatic exposure and colour 74 In 'Snapshot' mode the camera freezes its automatic exposure and colour
70 balance controls. 75 balance controls.
@@ -73,6 +78,8 @@
73#define PWC_FPS_MASK 0x00FF0000 78#define PWC_FPS_MASK 0x00FF0000
74#define PWC_FPS_FRMASK 0x003F0000 79#define PWC_FPS_FRMASK 0x003F0000
75#define PWC_FPS_SNAPSHOT 0x00400000 80#define PWC_FPS_SNAPSHOT 0x00400000
81#define PWC_QLT_MASK 0x03000000
82#define PWC_QLT_SHIFT 24
76 83
77 84
78/* structure for transferring x & y coordinates */ 85/* structure for transferring x & y coordinates */
@@ -289,4 +296,29 @@ struct pwc_table_init_buffer {
289}; 296};
290#define VIDIOCPWCGVIDTABLE _IOR('v', 216, struct pwc_table_init_buffer) 297#define VIDIOCPWCGVIDTABLE _IOR('v', 216, struct pwc_table_init_buffer)
291 298
299/*
300 * This is private command used when communicating with v4l2.
301 * In the future all private ioctl will be remove/replace to
302 * use interface offer by v4l2.
303 */
304
305#define V4L2_CID_PRIVATE_SAVE_USER (V4L2_CID_PRIVATE_BASE + 0)
306#define V4L2_CID_PRIVATE_RESTORE_USER (V4L2_CID_PRIVATE_BASE + 1)
307#define V4L2_CID_PRIVATE_RESTORE_FACTORY (V4L2_CID_PRIVATE_BASE + 2)
308#define V4L2_CID_PRIVATE_COLOUR_MODE (V4L2_CID_PRIVATE_BASE + 3)
309#define V4L2_CID_PRIVATE_AUTOCONTOUR (V4L2_CID_PRIVATE_BASE + 4)
310#define V4L2_CID_PRIVATE_CONTOUR (V4L2_CID_PRIVATE_BASE + 5)
311#define V4L2_CID_PRIVATE_BACKLIGHT (V4L2_CID_PRIVATE_BASE + 6)
312#define V4L2_CID_PRIVATE_FLICKERLESS (V4L2_CID_PRIVATE_BASE + 7)
313#define V4L2_CID_PRIVATE_NOISE_REDUCTION (V4L2_CID_PRIVATE_BASE + 8)
314
315struct pwc_raw_frame {
316 __le16 type; /* type of the webcam */
317 __le16 vbandlength; /* Size of 4lines compressed (used by the decompressor) */
318 __u8 cmd[4]; /* the four byte of the command (in case of nala,
319 only the first 3 bytes is filled) */
320 __u8 rawframe[0]; /* frame_size = H/4*vbandlength */
321} __attribute__ ((packed));
322
323
292#endif 324#endif
diff --git a/drivers/media/video/pwc/pwc-kiara.c b/drivers/media/video/pwc/pwc-kiara.c
index fec39cc5a9f1..f4ae83c0cf2b 100644
--- a/drivers/media/video/pwc/pwc-kiara.c
+++ b/drivers/media/video/pwc/pwc-kiara.c
@@ -42,6 +42,8 @@
42#include "pwc-kiara.h" 42#include "pwc-kiara.h"
43#include "pwc-uncompress.h" 43#include "pwc-uncompress.h"
44 44
45const unsigned int Kiara_fps_vector[PWC_FPS_MAX_KIARA] = { 5, 10, 15, 20, 25, 30 };
46
45const struct Kiara_table_entry Kiara_table[PSZ_MAX][6][4] = 47const struct Kiara_table_entry Kiara_table[PSZ_MAX][6][4] =
46{ 48{
47 /* SQCIF */ 49 /* SQCIF */
diff --git a/drivers/media/video/pwc/pwc-kiara.h b/drivers/media/video/pwc/pwc-kiara.h
index 0bdb22547d86..047dad8c15f7 100644
--- a/drivers/media/video/pwc/pwc-kiara.h
+++ b/drivers/media/video/pwc/pwc-kiara.h
@@ -29,6 +29,8 @@
29 29
30#include <media/pwc-ioctl.h> 30#include <media/pwc-ioctl.h>
31 31
32#define PWC_FPS_MAX_KIARA 6
33
32struct Kiara_table_entry 34struct Kiara_table_entry
33{ 35{
34 char alternate; /* USB alternate interface */ 36 char alternate; /* USB alternate interface */
@@ -37,8 +39,9 @@ struct Kiara_table_entry
37 unsigned char mode[12]; /* precomputed mode settings for cam */ 39 unsigned char mode[12]; /* precomputed mode settings for cam */
38}; 40};
39 41
40extern const struct Kiara_table_entry Kiara_table[PSZ_MAX][6][4]; 42extern const struct Kiara_table_entry Kiara_table[PSZ_MAX][PWC_FPS_MAX_KIARA][4];
41extern const unsigned int KiaraRomTable[8][2][16][8]; 43extern const unsigned int KiaraRomTable[8][2][16][8];
44extern const unsigned int Kiara_fps_vector[PWC_FPS_MAX_KIARA];
42 45
43#endif 46#endif
44 47
diff --git a/drivers/media/video/pwc/pwc-timon.c b/drivers/media/video/pwc/pwc-timon.c
index be65bdcd195b..c56c174b161c 100644
--- a/drivers/media/video/pwc/pwc-timon.c
+++ b/drivers/media/video/pwc/pwc-timon.c
@@ -40,7 +40,9 @@
40 40
41#include "pwc-timon.h" 41#include "pwc-timon.h"
42 42
43const struct Timon_table_entry Timon_table[PSZ_MAX][6][4] = 43const unsigned int Timon_fps_vector[PWC_FPS_MAX_TIMON] = { 5, 10, 15, 20, 25, 30 };
44
45const struct Timon_table_entry Timon_table[PSZ_MAX][PWC_FPS_MAX_TIMON][4] =
44{ 46{
45 /* SQCIF */ 47 /* SQCIF */
46 { 48 {
diff --git a/drivers/media/video/pwc/pwc-timon.h b/drivers/media/video/pwc/pwc-timon.h
index eef9e2cd4320..a6e22224c95f 100644
--- a/drivers/media/video/pwc/pwc-timon.h
+++ b/drivers/media/video/pwc/pwc-timon.h
@@ -44,6 +44,8 @@
44 44
45#include <media/pwc-ioctl.h> 45#include <media/pwc-ioctl.h>
46 46
47#define PWC_FPS_MAX_TIMON 6
48
47struct Timon_table_entry 49struct Timon_table_entry
48{ 50{
49 char alternate; /* USB alternate interface */ 51 char alternate; /* USB alternate interface */
@@ -52,9 +54,9 @@ struct Timon_table_entry
52 unsigned char mode[13]; /* precomputed mode settings for cam */ 54 unsigned char mode[13]; /* precomputed mode settings for cam */
53}; 55};
54 56
55extern const struct Timon_table_entry Timon_table[PSZ_MAX][6][4]; 57extern const struct Timon_table_entry Timon_table[PSZ_MAX][PWC_FPS_MAX_TIMON][4];
56extern const unsigned int TimonRomTable [16][2][16][8]; 58extern const unsigned int TimonRomTable [16][2][16][8];
57 59extern const unsigned int Timon_fps_vector[PWC_FPS_MAX_TIMON];
58 60
59#endif 61#endif
60 62
diff --git a/drivers/media/video/pwc/pwc-v4l.c b/drivers/media/video/pwc/pwc-v4l.c
index d5e6bc850643..32fbe1ae6251 100644
--- a/drivers/media/video/pwc/pwc-v4l.c
+++ b/drivers/media/video/pwc/pwc-v4l.c
@@ -1168,7 +1168,7 @@ int pwc_video_do_ioctl(struct inode *inode, struct file *file,
1168 buf->sequence = 0; 1168 buf->sequence = 0;
1169 buf->memory = V4L2_MEMORY_MMAP; 1169 buf->memory = V4L2_MEMORY_MMAP;
1170 buf->m.offset = pdev->fill_image * pdev->len_per_image; 1170 buf->m.offset = pdev->fill_image * pdev->len_per_image;
1171 buf->length = buf->bytesused; 1171 buf->length = pdev->len_per_image;
1172 pwc_next_image(pdev); 1172 pwc_next_image(pdev);
1173 1173
1174 PWC_DEBUG_IOCTL("VIDIOC_DQBUF: buf->index=%d\n",buf->index); 1174 PWC_DEBUG_IOCTL("VIDIOC_DQBUF: buf->index=%d\n",buf->index);
@@ -1193,6 +1193,64 @@ int pwc_video_do_ioctl(struct inode *inode, struct file *file,
1193 return 0; 1193 return 0;
1194 } 1194 }
1195 1195
1196 case VIDIOC_ENUM_FRAMESIZES:
1197 {
1198 struct v4l2_frmsizeenum *fsize = arg;
1199 unsigned int i = 0, index = fsize->index;
1200
1201 if (fsize->pixel_format == V4L2_PIX_FMT_YUV420) {
1202 for (i = 0; i < PSZ_MAX; i++) {
1203 if (pdev->image_mask & (1UL << i)) {
1204 if (!index--) {
1205 fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
1206 fsize->discrete.width = pwc_image_sizes[i].x;
1207 fsize->discrete.height = pwc_image_sizes[i].y;
1208 return 0;
1209 }
1210 }
1211 }
1212 } else if (fsize->index == 0 &&
1213 ((fsize->pixel_format == V4L2_PIX_FMT_PWC1 && DEVICE_USE_CODEC1(pdev->type)) ||
1214 (fsize->pixel_format == V4L2_PIX_FMT_PWC2 && DEVICE_USE_CODEC23(pdev->type)))) {
1215
1216 fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
1217 fsize->discrete.width = pdev->abs_max.x;
1218 fsize->discrete.height = pdev->abs_max.y;
1219 return 0;
1220 }
1221 return -EINVAL;
1222 }
1223
1224 case VIDIOC_ENUM_FRAMEINTERVALS:
1225 {
1226 struct v4l2_frmivalenum *fival = arg;
1227 int size = -1;
1228 unsigned int i;
1229
1230 for (i = 0; i < PSZ_MAX; i++) {
1231 if (pwc_image_sizes[i].x == fival->width &&
1232 pwc_image_sizes[i].y == fival->height) {
1233 size = i;
1234 break;
1235 }
1236 }
1237
1238 /* TODO: Support raw format */
1239 if (size < 0 || fival->pixel_format != V4L2_PIX_FMT_YUV420) {
1240 return -EINVAL;
1241 }
1242
1243 i = pwc_get_fps(pdev, fival->index, size);
1244 if (!i)
1245 return -EINVAL;
1246
1247 fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;
1248 fival->discrete.numerator = 1;
1249 fival->discrete.denominator = i;
1250
1251 return 0;
1252 }
1253
1196 default: 1254 default:
1197 return pwc_ioctl(pdev, cmd, arg); 1255 return pwc_ioctl(pdev, cmd, arg);
1198 } /* ..switch */ 1256 } /* ..switch */
diff --git a/drivers/media/video/pwc/pwc.h b/drivers/media/video/pwc/pwc.h
index e778a2b8c280..acbb9312960a 100644
--- a/drivers/media/video/pwc/pwc.h
+++ b/drivers/media/video/pwc/pwc.h
@@ -44,7 +44,7 @@
44#define PWC_MINOR 0 44#define PWC_MINOR 0
45#define PWC_EXTRAMINOR 12 45#define PWC_EXTRAMINOR 12
46#define PWC_VERSION_CODE KERNEL_VERSION(PWC_MAJOR,PWC_MINOR,PWC_EXTRAMINOR) 46#define PWC_VERSION_CODE KERNEL_VERSION(PWC_MAJOR,PWC_MINOR,PWC_EXTRAMINOR)
47#define PWC_VERSION "10.0.12" 47#define PWC_VERSION "10.0.13"
48#define PWC_NAME "pwc" 48#define PWC_NAME "pwc"
49#define PFX PWC_NAME ": " 49#define PFX PWC_NAME ": "
50 50
@@ -85,7 +85,7 @@
85#define PWC_INFO(fmt, args...) printk(KERN_INFO PFX fmt, ##args) 85#define PWC_INFO(fmt, args...) printk(KERN_INFO PFX fmt, ##args)
86#define PWC_TRACE(fmt, args...) PWC_DEBUG(TRACE, fmt, ##args) 86#define PWC_TRACE(fmt, args...) PWC_DEBUG(TRACE, fmt, ##args)
87 87
88#else /* if ! CONFIG_PWC_DEBUG */ 88#else /* if ! CONFIG_USB_PWC_DEBUG */
89 89
90#define PWC_ERROR(fmt, args...) printk(KERN_ERR PFX fmt, ##args) 90#define PWC_ERROR(fmt, args...) printk(KERN_ERR PFX fmt, ##args)
91#define PWC_WARNING(fmt, args...) printk(KERN_WARNING PFX fmt, ##args) 91#define PWC_WARNING(fmt, args...) printk(KERN_WARNING PFX fmt, ##args)
@@ -287,6 +287,7 @@ void pwc_construct(struct pwc_device *pdev);
287/** Functions in pwc-ctrl.c */ 287/** Functions in pwc-ctrl.c */
288/* Request a certain video mode. Returns < 0 if not possible */ 288/* Request a certain video mode. Returns < 0 if not possible */
289extern int pwc_set_video_mode(struct pwc_device *pdev, int width, int height, int frames, int compression, int snapshot); 289extern int pwc_set_video_mode(struct pwc_device *pdev, int width, int height, int frames, int compression, int snapshot);
290extern unsigned int pwc_get_fps(struct pwc_device *pdev, unsigned int index, unsigned int size);
290/* Calculate the number of bytes per image (not frame) */ 291/* Calculate the number of bytes per image (not frame) */
291extern int pwc_mpt_reset(struct pwc_device *pdev, int flags); 292extern int pwc_mpt_reset(struct pwc_device *pdev, int flags);
292extern int pwc_mpt_set_angle(struct pwc_device *pdev, int pan, int tilt); 293extern int pwc_mpt_set_angle(struct pwc_device *pdev, int pan, int tilt);
diff --git a/drivers/media/video/saa7115.c b/drivers/media/video/saa7115.c
index 4d5bbd859de1..2d18f0069821 100644
--- a/drivers/media/video/saa7115.c
+++ b/drivers/media/video/saa7115.c
@@ -45,6 +45,7 @@
45#include <linux/i2c.h> 45#include <linux/i2c.h>
46#include <linux/videodev2.h> 46#include <linux/videodev2.h>
47#include <media/v4l2-common.h> 47#include <media/v4l2-common.h>
48#include <media/v4l2-chip-ident.h>
48#include <media/saa7115.h> 49#include <media/saa7115.h>
49#include <asm/div64.h> 50#include <asm/div64.h>
50 51
@@ -80,7 +81,7 @@ struct saa711x_state {
80 int sat; 81 int sat;
81 int width; 82 int width;
82 int height; 83 int height;
83 enum v4l2_chip_ident ident; 84 u32 ident;
84 u32 audclk_freq; 85 u32 audclk_freq;
85 u32 crystal_freq; 86 u32 crystal_freq;
86 u8 ucgc; 87 u8 ucgc;
@@ -1232,7 +1233,6 @@ static void saa711x_decode_vbi_line(struct i2c_client *client,
1232static int saa711x_command(struct i2c_client *client, unsigned int cmd, void *arg) 1233static int saa711x_command(struct i2c_client *client, unsigned int cmd, void *arg)
1233{ 1234{
1234 struct saa711x_state *state = i2c_get_clientdata(client); 1235 struct saa711x_state *state = i2c_get_clientdata(client);
1235 int *iarg = arg;
1236 1236
1237 /* ioctls to allow direct access to the saa7115 registers for testing */ 1237 /* ioctls to allow direct access to the saa7115 registers for testing */
1238 switch (cmd) { 1238 switch (cmd) {
@@ -1437,9 +1437,8 @@ static int saa711x_command(struct i2c_client *client, unsigned int cmd, void *ar
1437 } 1437 }
1438#endif 1438#endif
1439 1439
1440 case VIDIOC_INT_G_CHIP_IDENT: 1440 case VIDIOC_G_CHIP_IDENT:
1441 *iarg = state->ident; 1441 return v4l2_chip_ident_i2c_client(client, arg, state->ident, 0);
1442 break;
1443 1442
1444 default: 1443 default:
1445 return -EINVAL; 1444 return -EINVAL;
@@ -1487,6 +1486,7 @@ static int saa711x_attach(struct i2c_adapter *adapter, int address, int kind)
1487 if (memcmp(name, "1f711", 5)) { 1486 if (memcmp(name, "1f711", 5)) {
1488 v4l_dbg(1, debug, client, "chip found @ 0x%x (ID %s) does not match a known saa711x chip.\n", 1487 v4l_dbg(1, debug, client, "chip found @ 0x%x (ID %s) does not match a known saa711x chip.\n",
1489 address << 1, name); 1488 address << 1, name);
1489 kfree(client);
1490 return 0; 1490 return 0;
1491 } 1491 }
1492 1492
diff --git a/drivers/media/video/saa7127.c b/drivers/media/video/saa7127.c
index 654863db1591..9f986930490f 100644
--- a/drivers/media/video/saa7127.c
+++ b/drivers/media/video/saa7127.c
@@ -54,6 +54,7 @@
54#include <linux/i2c.h> 54#include <linux/i2c.h>
55#include <linux/videodev2.h> 55#include <linux/videodev2.h>
56#include <media/v4l2-common.h> 56#include <media/v4l2-common.h>
57#include <media/v4l2-chip-ident.h>
57#include <media/saa7127.h> 58#include <media/saa7127.h>
58 59
59static int debug = 0; 60static int debug = 0;
@@ -234,7 +235,7 @@ static struct i2c_reg_value saa7127_init_config_50hz[] = {
234 235
235struct saa7127_state { 236struct saa7127_state {
236 v4l2_std_id std; 237 v4l2_std_id std;
237 enum v4l2_chip_ident ident; 238 u32 ident;
238 enum saa7127_input_type input_type; 239 enum saa7127_input_type input_type;
239 enum saa7127_output_type output_type; 240 enum saa7127_output_type output_type;
240 int video_enable; 241 int video_enable;
@@ -550,12 +551,12 @@ static int saa7127_command(struct i2c_client *client,
550 struct v4l2_routing *route = arg; 551 struct v4l2_routing *route = arg;
551 552
552 switch (cmd) { 553 switch (cmd) {
553 case VIDIOC_S_STD: 554 case VIDIOC_INT_S_STD_OUTPUT:
554 if (state->std == *(v4l2_std_id *)arg) 555 if (state->std == *(v4l2_std_id *)arg)
555 break; 556 break;
556 return saa7127_set_std(client, *(v4l2_std_id *)arg); 557 return saa7127_set_std(client, *(v4l2_std_id *)arg);
557 558
558 case VIDIOC_G_STD: 559 case VIDIOC_INT_G_STD_OUTPUT:
559 *(v4l2_std_id *)arg = state->std; 560 *(v4l2_std_id *)arg = state->std;
560 break; 561 break;
561 562
@@ -650,9 +651,8 @@ static int saa7127_command(struct i2c_client *client,
650 break; 651 break;
651 } 652 }
652 653
653 case VIDIOC_INT_G_CHIP_IDENT: 654 case VIDIOC_G_CHIP_IDENT:
654 *(enum v4l2_chip_ident *)arg = state->ident; 655 return v4l2_chip_ident_i2c_client(client, arg, state->ident, 0);
655 break;
656 656
657 default: 657 default:
658 return -EINVAL; 658 return -EINVAL;
diff --git a/drivers/media/video/saa7134/Kconfig b/drivers/media/video/saa7134/Kconfig
index 59da79ce2efd..309dca368f4a 100644
--- a/drivers/media/video/saa7134/Kconfig
+++ b/drivers/media/video/saa7134/Kconfig
@@ -46,6 +46,7 @@ config VIDEO_SAA7134_DVB
46 select DVB_NXT200X if !DVB_FE_CUSTOMISE 46 select DVB_NXT200X if !DVB_FE_CUSTOMISE
47 select DVB_TDA10086 if !DVB_FE_CUSTOMISE 47 select DVB_TDA10086 if !DVB_FE_CUSTOMISE
48 select DVB_TDA826X if !DVB_FE_CUSTOMISE 48 select DVB_TDA826X if !DVB_FE_CUSTOMISE
49 select DVB_TDA827X if !DVB_FE_CUSTOMISE
49 select DVB_ISL6421 if !DVB_FE_CUSTOMISE 50 select DVB_ISL6421 if !DVB_FE_CUSTOMISE
50 ---help--- 51 ---help---
51 This adds support for DVB cards based on the 52 This adds support for DVB cards based on the
diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c
index 89f32107f46b..4ea479baee74 100644
--- a/drivers/media/video/saa7134/saa7134-cards.c
+++ b/drivers/media/video/saa7134/saa7134-cards.c
@@ -1543,12 +1543,12 @@ struct saa7134_board saa7134_boards[] = {
1543 },{ 1543 },{
1544 .name = name_comp1, 1544 .name = name_comp1,
1545 .vmux = 0, 1545 .vmux = 0,
1546 .amux = LINE2, 1546 .amux = LINE1,
1547 .gpio = 0x02, 1547 .gpio = 0x02,
1548 },{ 1548 },{
1549 .name = name_svideo, 1549 .name = name_svideo,
1550 .vmux = 6, 1550 .vmux = 6,
1551 .amux = LINE2, 1551 .amux = LINE1,
1552 .gpio = 0x02, 1552 .gpio = 0x02,
1553 }}, 1553 }},
1554 .radio = { 1554 .radio = {
@@ -1778,17 +1778,19 @@ struct saa7134_board saa7134_boards[] = {
1778 [SAA7134_BOARD_FLYDVBTDUO] = { 1778 [SAA7134_BOARD_FLYDVBTDUO] = {
1779 /* LifeView FlyDVB-T DUO */ 1779 /* LifeView FlyDVB-T DUO */
1780 /* "Nico Sabbi <nsabbi@tiscali.it> Hartmut Hackmann hartmut.hackmann@t-online.de*/ 1780 /* "Nico Sabbi <nsabbi@tiscali.it> Hartmut Hackmann hartmut.hackmann@t-online.de*/
1781 .name = "LifeView FlyDVB-T DUO", 1781 .name = "LifeView FlyDVB-T DUO / MSI TV@nywhere Duo",
1782 .audio_clock = 0x00200000, 1782 .audio_clock = 0x00200000,
1783 .tuner_type = TUNER_PHILIPS_TDA8290, 1783 .tuner_type = TUNER_PHILIPS_TDA8290,
1784 .radio_type = UNSET, 1784 .radio_type = UNSET,
1785 .tuner_addr = ADDR_UNSET, 1785 .tuner_addr = ADDR_UNSET,
1786 .radio_addr = ADDR_UNSET, 1786 .radio_addr = ADDR_UNSET,
1787 .gpiomask = 0x00200000,
1787 .mpeg = SAA7134_MPEG_DVB, 1788 .mpeg = SAA7134_MPEG_DVB,
1788 .inputs = {{ 1789 .inputs = {{
1789 .name = name_tv, 1790 .name = name_tv,
1790 .vmux = 1, 1791 .vmux = 1,
1791 .amux = TV, 1792 .amux = TV,
1793 .gpio = 0x200000, /* GPIO21=High for TV input */
1792 .tv = 1, 1794 .tv = 1,
1793 },{ 1795 },{
1794 .name = name_comp1, /* Composite signal on S-Video input */ 1796 .name = name_comp1, /* Composite signal on S-Video input */
@@ -1803,6 +1805,11 @@ struct saa7134_board saa7134_boards[] = {
1803 .vmux = 8, 1805 .vmux = 8,
1804 .amux = LINE2, 1806 .amux = LINE2,
1805 }}, 1807 }},
1808 .radio = {
1809 .name = name_radio,
1810 .amux = TV,
1811 .gpio = 0x000000, /* GPIO21=Low for FM radio antenna */
1812 },
1806 }, 1813 },
1807 [SAA7134_BOARD_PHILIPS_TOUGH] = { 1814 [SAA7134_BOARD_PHILIPS_TOUGH] = {
1808 .name = "Philips TOUGH DVB-T reference design", 1815 .name = "Philips TOUGH DVB-T reference design",
@@ -2546,8 +2553,9 @@ struct saa7134_board saa7134_boards[] = {
2546 .radio_type = UNSET, 2553 .radio_type = UNSET,
2547 .tuner_addr = ADDR_UNSET, 2554 .tuner_addr = ADDR_UNSET,
2548 .radio_addr = ADDR_UNSET, 2555 .radio_addr = ADDR_UNSET,
2556 .tuner_config = 0,
2549 .mpeg = SAA7134_MPEG_DVB, 2557 .mpeg = SAA7134_MPEG_DVB,
2550 .gpiomask = 1 << 21, 2558 .gpiomask = 0x0200000,
2551 .inputs = {{ 2559 .inputs = {{
2552 .name = name_tv, 2560 .name = name_tv,
2553 .vmux = 1, 2561 .vmux = 1,
@@ -2624,7 +2632,7 @@ struct saa7134_board saa7134_boards[] = {
2624 }}, 2632 }},
2625 .radio = { 2633 .radio = {
2626 .name = name_radio, 2634 .name = name_radio,
2627 .amux = LINE1, 2635 .amux = TV,
2628 .gpio = 0x0200000, 2636 .gpio = 0x0200000,
2629 }, 2637 },
2630 }, 2638 },
@@ -3043,6 +3051,7 @@ struct saa7134_board saa7134_boards[] = {
3043 .radio_type = UNSET, 3051 .radio_type = UNSET,
3044 .tuner_addr = ADDR_UNSET, 3052 .tuner_addr = ADDR_UNSET,
3045 .radio_addr = ADDR_UNSET, 3053 .radio_addr = ADDR_UNSET,
3054 .tuner_config = 1,
3046 .mpeg = SAA7134_MPEG_DVB, 3055 .mpeg = SAA7134_MPEG_DVB,
3047 .gpiomask = 0x000200000, 3056 .gpiomask = 0x000200000,
3048 .inputs = {{ 3057 .inputs = {{
@@ -3289,6 +3298,115 @@ struct saa7134_board saa7134_boards[] = {
3289 .amux = LINE1, 3298 .amux = LINE1,
3290 }}, 3299 }},
3291 }, 3300 },
3301 [SAA7134_BOARD_PHILIPS_TIGER_S] = {
3302 .name = "Philips Tiger - S Reference design",
3303 .audio_clock = 0x00187de7,
3304 .tuner_type = TUNER_PHILIPS_TDA8290,
3305 .radio_type = UNSET,
3306 .tuner_addr = ADDR_UNSET,
3307 .radio_addr = ADDR_UNSET,
3308 .tuner_config = 2,
3309 .mpeg = SAA7134_MPEG_DVB,
3310 .gpiomask = 0x0200000,
3311 .inputs = {{
3312 .name = name_tv,
3313 .vmux = 1,
3314 .amux = TV,
3315 .tv = 1,
3316 },{
3317 .name = name_comp1,
3318 .vmux = 3,
3319 .amux = LINE1,
3320 },{
3321 .name = name_svideo,
3322 .vmux = 8,
3323 .amux = LINE1,
3324 }},
3325 .radio = {
3326 .name = name_radio,
3327 .amux = TV,
3328 .gpio = 0x0200000,
3329 },
3330 },
3331 [SAA7134_BOARD_AVERMEDIA_M102] = {
3332 .name = "Avermedia M102",
3333 .audio_clock = 0x00187de7,
3334 .tuner_type = TUNER_PHILIPS_TDA8290,
3335 .radio_type = UNSET,
3336 .tuner_addr = ADDR_UNSET,
3337 .radio_addr = ADDR_UNSET,
3338 .gpiomask = 1<<21,
3339 .inputs = {{
3340 .name = name_tv,
3341 .vmux = 1,
3342 .amux = TV,
3343 .tv = 1,
3344 },{
3345 .name = name_comp1,
3346 .vmux = 0,
3347 .amux = LINE2,
3348 },{
3349 .name = name_svideo,
3350 .vmux = 6,
3351 .amux = LINE2,
3352 }},
3353 },
3354 [SAA7134_BOARD_ASUS_P7131_4871] = {
3355 .name = "ASUS P7131 4871",
3356 .audio_clock = 0x00187de7,
3357 .tuner_type = TUNER_PHILIPS_TDA8290,
3358 .radio_type = UNSET,
3359 .tuner_addr = ADDR_UNSET,
3360 .radio_addr = ADDR_UNSET,
3361 .tuner_config = 2,
3362 .mpeg = SAA7134_MPEG_DVB,
3363 .gpiomask = 0x0200000,
3364 .inputs = {{
3365 .name = name_tv,
3366 .vmux = 1,
3367 .amux = TV,
3368 .tv = 1,
3369 .gpio = 0x0200000,
3370 }},
3371 },
3372 [SAA7134_BOARD_ASUSTeK_P7131_HYBRID_LNA] = {
3373 .name = "ASUSTeK P7131 Hybrid",
3374 .audio_clock = 0x00187de7,
3375 .tuner_type = TUNER_PHILIPS_TDA8290,
3376 .radio_type = UNSET,
3377 .tuner_addr = ADDR_UNSET,
3378 .radio_addr = ADDR_UNSET,
3379 .tuner_config = 2,
3380 .gpiomask = 1 << 21,
3381 .mpeg = SAA7134_MPEG_DVB,
3382 .inputs = {{
3383 .name = name_tv,
3384 .vmux = 1,
3385 .amux = TV,
3386 .tv = 1,
3387 .gpio = 0x0000000,
3388 },{
3389 .name = name_comp1,
3390 .vmux = 3,
3391 .amux = LINE2,
3392 .gpio = 0x0200000,
3393 },{
3394 .name = name_comp2,
3395 .vmux = 0,
3396 .amux = LINE2,
3397 .gpio = 0x0200000,
3398 },{
3399 .name = name_svideo,
3400 .vmux = 8,
3401 .amux = LINE2,
3402 .gpio = 0x0200000,
3403 }},
3404 .radio = {
3405 .name = name_radio,
3406 .amux = TV,
3407 .gpio = 0x0200000,
3408 },
3409 },
3292}; 3410};
3293 3411
3294const unsigned int saa7134_bcount = ARRAY_SIZE(saa7134_boards); 3412const unsigned int saa7134_bcount = ARRAY_SIZE(saa7134_boards);
@@ -3914,7 +4032,7 @@ struct pci_device_id saa7134_pci_tbl[] = {
3914 .device = PCI_DEVICE_ID_PHILIPS_SAA7133, 4032 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
3915 .subvendor = 0x1043, 4033 .subvendor = 0x1043,
3916 .subdevice = 0x4876, 4034 .subdevice = 0x4876,
3917 .driver_data = SAA7134_BOARD_ASUSTeK_P7131_DUAL, 4035 .driver_data = SAA7134_BOARD_ASUSTeK_P7131_HYBRID_LNA,
3918 },{ 4036 },{
3919 .vendor = PCI_VENDOR_ID_PHILIPS, 4037 .vendor = PCI_VENDOR_ID_PHILIPS,
3920 .device = PCI_DEVICE_ID_PHILIPS_SAA7133, 4038 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
@@ -3958,6 +4076,30 @@ struct pci_device_id saa7134_pci_tbl[] = {
3958 .subdevice = 0x1175, 4076 .subdevice = 0x1175,
3959 .driver_data = SAA7134_BOARD_CINERGY_HT_PCI, 4077 .driver_data = SAA7134_BOARD_CINERGY_HT_PCI,
3960 },{ 4078 },{
4079 .vendor = PCI_VENDOR_ID_PHILIPS,
4080 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
4081 .subvendor = 0x1461, /* Avermedia Technologies Inc */
4082 .subdevice = 0xf31e,
4083 .driver_data = SAA7134_BOARD_AVERMEDIA_M102,
4084 },{
4085 .vendor = PCI_VENDOR_ID_PHILIPS,
4086 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
4087 .subvendor = 0x4E42, /* MSI */
4088 .subdevice = 0x0306, /* TV@nywhere DUO */
4089 .driver_data = SAA7134_BOARD_FLYDVBTDUO,
4090 },{
4091 .vendor = PCI_VENDOR_ID_PHILIPS,
4092 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
4093 .subvendor = 0x1043,
4094 .subdevice = 0x4871,
4095 .driver_data = SAA7134_BOARD_ASUS_P7131_4871,
4096 },{
4097 .vendor = PCI_VENDOR_ID_PHILIPS,
4098 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
4099 .subvendor = 0x1043,
4100 .subdevice = 0x4857,
4101 .driver_data = SAA7134_BOARD_ASUSTeK_P7131_DUAL,
4102 },{
3961 /* --- boards without eeprom + subsystem ID --- */ 4103 /* --- boards without eeprom + subsystem ID --- */
3962 .vendor = PCI_VENDOR_ID_PHILIPS, 4104 .vendor = PCI_VENDOR_ID_PHILIPS,
3963 .device = PCI_DEVICE_ID_PHILIPS_SAA7134, 4105 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
@@ -3971,7 +4113,6 @@ struct pci_device_id saa7134_pci_tbl[] = {
3971 .subdevice = 0, 4113 .subdevice = 0,
3972 .driver_data = SAA7134_BOARD_NOAUTO, 4114 .driver_data = SAA7134_BOARD_NOAUTO,
3973 },{ 4115 },{
3974
3975 /* --- default catch --- */ 4116 /* --- default catch --- */
3976 .vendor = PCI_VENDOR_ID_PHILIPS, 4117 .vendor = PCI_VENDOR_ID_PHILIPS,
3977 .device = PCI_DEVICE_ID_PHILIPS_SAA7130, 4118 .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
@@ -4063,6 +4204,7 @@ int saa7134_board_init1(struct saa7134_dev *dev)
4063 case SAA7134_BOARD_SEDNA_PC_TV_CARDBUS: 4204 case SAA7134_BOARD_SEDNA_PC_TV_CARDBUS:
4064 case SAA7134_BOARD_FLYDVBT_LR301: 4205 case SAA7134_BOARD_FLYDVBT_LR301:
4065 case SAA7134_BOARD_ASUSTeK_P7131_DUAL: 4206 case SAA7134_BOARD_ASUSTeK_P7131_DUAL:
4207 case SAA7134_BOARD_ASUSTeK_P7131_HYBRID_LNA:
4066 case SAA7134_BOARD_FLYDVBTDUO: 4208 case SAA7134_BOARD_FLYDVBTDUO:
4067 case SAA7134_BOARD_PROTEUS_2309: 4209 case SAA7134_BOARD_PROTEUS_2309:
4068 case SAA7134_BOARD_AVERMEDIA_A16AR: 4210 case SAA7134_BOARD_AVERMEDIA_A16AR:
@@ -4103,8 +4245,8 @@ int saa7134_board_init1(struct saa7134_dev *dev)
4103 break; 4245 break;
4104 case SAA7134_BOARD_ADS_DUO_CARDBUS_PTV331: 4246 case SAA7134_BOARD_ADS_DUO_CARDBUS_PTV331:
4105 case SAA7134_BOARD_FLYDVBT_HYBRID_CARDBUS: 4247 case SAA7134_BOARD_FLYDVBT_HYBRID_CARDBUS:
4106 saa_writeb(SAA7134_GPIO_GPMODE3, 0x08); 4248 saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x08000000, 0x08000000);
4107 saa_writeb(SAA7134_GPIO_GPSTATUS3, 0x00); 4249 saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x08000000, 0x00000000);
4108 break; 4250 break;
4109 case SAA7134_BOARD_AVERMEDIA_CARDBUS: 4251 case SAA7134_BOARD_AVERMEDIA_CARDBUS:
4110 /* power-up tuner chip */ 4252 /* power-up tuner chip */
@@ -4137,6 +4279,11 @@ int saa7134_board_init1(struct saa7134_dev *dev)
4137 "%s: Dual decoder functionality is disabled for now, use the other chip.\n", 4279 "%s: Dual decoder functionality is disabled for now, use the other chip.\n",
4138 dev->name,card(dev).name,dev->name,dev->name); 4280 dev->name,card(dev).name,dev->name,dev->name);
4139 break; 4281 break;
4282 case SAA7134_BOARD_AVERMEDIA_M102:
4283 /* enable tuner */
4284 saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x8c040007, 0x8c040007);
4285 saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x0c0007cd, 0x0c0007cd);
4286 break;
4140 } 4287 }
4141 return 0; 4288 return 0;
4142} 4289}
@@ -4146,6 +4293,9 @@ int saa7134_board_init2(struct saa7134_dev *dev)
4146{ 4293{
4147 unsigned char buf; 4294 unsigned char buf;
4148 int board; 4295 int board;
4296 struct tuner_setup tun_setup;
4297 tun_setup.config = 0;
4298 tun_setup.tuner_callback = saa7134_tuner_callback;
4149 4299
4150 switch (dev->board) { 4300 switch (dev->board) {
4151 case SAA7134_BOARD_BMK_MPEX_NOTUNER: 4301 case SAA7134_BOARD_BMK_MPEX_NOTUNER:
@@ -4162,8 +4312,6 @@ int saa7134_board_init2(struct saa7134_dev *dev)
4162 dev->tuner_type = saa7134_boards[dev->board].tuner_type; 4312 dev->tuner_type = saa7134_boards[dev->board].tuner_type;
4163 4313
4164 if (TUNER_ABSENT != dev->tuner_type) { 4314 if (TUNER_ABSENT != dev->tuner_type) {
4165 struct tuner_setup tun_setup;
4166
4167 tun_setup.mode_mask = T_RADIO | T_ANALOG_TV | T_DIGITAL_TV; 4315 tun_setup.mode_mask = T_RADIO | T_ANALOG_TV | T_DIGITAL_TV;
4168 tun_setup.type = dev->tuner_type; 4316 tun_setup.type = dev->tuner_type;
4169 tun_setup.addr = ADDR_UNSET; 4317 tun_setup.addr = ADDR_UNSET;
@@ -4173,7 +4321,6 @@ int saa7134_board_init2(struct saa7134_dev *dev)
4173 break; 4321 break;
4174 case SAA7134_BOARD_MD7134: 4322 case SAA7134_BOARD_MD7134:
4175 { 4323 {
4176 struct tuner_setup tun_setup;
4177 u8 subaddr; 4324 u8 subaddr;
4178 u8 data[3]; 4325 u8 data[3];
4179 int ret, tuner_t; 4326 int ret, tuner_t;
@@ -4245,7 +4392,6 @@ int saa7134_board_init2(struct saa7134_dev *dev)
4245 * the channel decoder. We have to make it transparent to find it 4392 * the channel decoder. We have to make it transparent to find it
4246 */ 4393 */
4247 { 4394 {
4248 struct tuner_setup tun_setup;
4249 u8 data[] = { 0x07, 0x02}; 4395 u8 data[] = { 0x07, 0x02};
4250 struct i2c_msg msg = {.addr=0x08, .flags=0, .buf=data, .len = sizeof(data)}; 4396 struct i2c_msg msg = {.addr=0x08, .flags=0, .buf=data, .len = sizeof(data)};
4251 i2c_transfer(&dev->i2c_adap, &msg, 1); 4397 i2c_transfer(&dev->i2c_adap, &msg, 1);
@@ -4258,16 +4404,38 @@ int saa7134_board_init2(struct saa7134_dev *dev)
4258 } 4404 }
4259 break; 4405 break;
4260 case SAA7134_BOARD_PHILIPS_TIGER: 4406 case SAA7134_BOARD_PHILIPS_TIGER:
4407 case SAA7134_BOARD_PHILIPS_TIGER_S:
4408 {
4409 u8 data[] = { 0x3c, 0x33, 0x60};
4410 struct i2c_msg msg = {.addr=0x08, .flags=0, .buf=data, .len = sizeof(data)};
4411 if(dev->autodetected && (dev->eedata[0x49] == 0x50)) {
4412 dev->board = SAA7134_BOARD_PHILIPS_TIGER_S;
4413 printk(KERN_INFO "%s: Reconfigured board as %s\n",
4414 dev->name, saa7134_boards[dev->board].name);
4415 }
4416 if(dev->board == SAA7134_BOARD_PHILIPS_TIGER_S) {
4417 tun_setup.mode_mask = T_ANALOG_TV | T_DIGITAL_TV;
4418 tun_setup.type = TUNER_PHILIPS_TDA8290;
4419 tun_setup.addr = 0x4b;
4420 tun_setup.config = 2;
4421
4422 saa7134_i2c_call_clients (dev, TUNER_SET_TYPE_ADDR,&tun_setup);
4423 data[2] = 0x68;
4424 }
4425 i2c_transfer(&dev->i2c_adap, &msg, 1);
4426 }
4427 break;
4261 case SAA7134_BOARD_PINNACLE_PCTV_310i: 4428 case SAA7134_BOARD_PINNACLE_PCTV_310i:
4262 case SAA7134_BOARD_TEVION_DVBT_220RF: 4429 case SAA7134_BOARD_TEVION_DVBT_220RF:
4263 case SAA7134_BOARD_ASUSTeK_P7131_DUAL: 4430 case SAA7134_BOARD_ASUSTeK_P7131_DUAL:
4431 case SAA7134_BOARD_ASUSTeK_P7131_HYBRID_LNA:
4264 case SAA7134_BOARD_MEDION_MD8800_QUADRO: 4432 case SAA7134_BOARD_MEDION_MD8800_QUADRO:
4265 case SAA7134_BOARD_HAUPPAUGE_HVR1110: 4433 case SAA7134_BOARD_HAUPPAUGE_HVR1110:
4266 /* this is a hybrid board, initialize to analog mode 4434 /* this is a hybrid board, initialize to analog mode
4267 * and configure firmware eeprom address 4435 * and configure firmware eeprom address
4268 */ 4436 */
4269 { 4437 {
4270 u8 data[] = { 0x3c, 0x33, 0x68}; 4438 u8 data[] = { 0x3c, 0x33, 0x60};
4271 struct i2c_msg msg = {.addr=0x08, .flags=0, .buf=data, .len = sizeof(data)}; 4439 struct i2c_msg msg = {.addr=0x08, .flags=0, .buf=data, .len = sizeof(data)};
4272 i2c_transfer(&dev->i2c_adap, &msg, 1); 4440 i2c_transfer(&dev->i2c_adap, &msg, 1);
4273 } 4441 }
@@ -4281,18 +4449,18 @@ int saa7134_board_init2(struct saa7134_dev *dev)
4281 break; 4449 break;
4282 case SAA7134_BOARD_ADS_DUO_CARDBUS_PTV331: 4450 case SAA7134_BOARD_ADS_DUO_CARDBUS_PTV331:
4283 case SAA7134_BOARD_FLYDVBT_HYBRID_CARDBUS: 4451 case SAA7134_BOARD_FLYDVBT_HYBRID_CARDBUS:
4284 /* make the tda10046 find its eeprom */ 4452 /* initialize analog mode */
4285 { 4453 {
4286 u8 data[] = { 0x3c, 0x33, 0x62}; 4454 u8 data[] = { 0x3c, 0x33, 0x6a};
4287 struct i2c_msg msg = {.addr=0x08, .flags=0, .buf=data, .len = sizeof(data)}; 4455 struct i2c_msg msg = {.addr=0x08, .flags=0, .buf=data, .len = sizeof(data)};
4288 i2c_transfer(&dev->i2c_adap, &msg, 1); 4456 i2c_transfer(&dev->i2c_adap, &msg, 1);
4289 } 4457 }
4290 break; 4458 break;
4291 case SAA7134_BOARD_CINERGY_HT_PCMCIA: 4459 case SAA7134_BOARD_CINERGY_HT_PCMCIA:
4292 case SAA7134_BOARD_CINERGY_HT_PCI: 4460 case SAA7134_BOARD_CINERGY_HT_PCI:
4293 /* make the tda10046 find its eeprom */ 4461 /* initialize analog mode */
4294 { 4462 {
4295 u8 data[] = { 0x3c, 0x33, 0x60}; 4463 u8 data[] = { 0x3c, 0x33, 0x68};
4296 struct i2c_msg msg = {.addr=0x08, .flags=0, .buf=data, .len = sizeof(data)}; 4464 struct i2c_msg msg = {.addr=0x08, .flags=0, .buf=data, .len = sizeof(data)};
4297 i2c_transfer(&dev->i2c_adap, &msg, 1); 4465 i2c_transfer(&dev->i2c_adap, &msg, 1);
4298 } 4466 }
diff --git a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c
index ed038fff3b4f..25f84701a8e8 100644
--- a/drivers/media/video/saa7134/saa7134-core.c
+++ b/drivers/media/video/saa7134/saa7134-core.c
@@ -117,6 +117,64 @@ void saa7134_track_gpio(struct saa7134_dev *dev, char *msg)
117 dev->name, mode, (~mode) & status, mode & status, msg); 117 dev->name, mode, (~mode) & status, mode & status, msg);
118} 118}
119 119
120void saa7134_set_gpio(struct saa7134_dev *dev, int bit_no, int value)
121{
122 u32 index, bitval;
123
124 index = 1 << bit_no;
125 switch (value) {
126 case 0: /* static value */
127 case 1: dprintk("setting GPIO%d to static %d\n", bit_no, value);
128 /* turn sync mode off if necessary */
129 if (index & 0x00c00000)
130 saa_andorb(SAA7134_VIDEO_PORT_CTRL6, 0x0f, 0x00);
131 if (value)
132 bitval = index;
133 else
134 bitval = 0;
135 saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, index, index);
136 saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, index, bitval);
137 break;
138 case 3: /* tristate */
139 dprintk("setting GPIO%d to tristate\n", bit_no);
140 saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, index, 0);
141 break;
142 }
143}
144
145int saa7134_tuner_callback(void *ptr, int command, int arg)
146{
147 u8 sync_control;
148 struct saa7134_dev *dev = ptr;
149
150 switch (dev->tuner_type) {
151 case TUNER_PHILIPS_TDA8290:
152 switch (command) {
153 case 0: /* switch LNA gain through GPIO 22*/
154 saa7134_set_gpio(dev, 22, arg) ;
155 break;
156 case 1: /* vsync output at GPIO22. 50 / 60Hz */
157 dprintk("setting GPIO22 to vsync %d\n", arg);
158 saa_andorb(SAA7134_VIDEO_PORT_CTRL3, 0x80, 0x80);
159 saa_andorb(SAA7134_VIDEO_PORT_CTRL6, 0x0f, 0x03);
160 if (arg == 1)
161 sync_control = 11;
162 else
163 sync_control = 17;
164 saa_writeb(SAA7134_VGATE_START, sync_control);
165 saa_writeb(SAA7134_VGATE_STOP, sync_control + 1);
166 saa_andorb(SAA7134_MISC_VGATE_MSB, 0x03, 0x00);
167 break;
168 default:
169 return -EINVAL;
170 }
171 break;
172 default:
173 return -ENODEV;
174 }
175 return 0;
176}
177
120/* ------------------------------------------------------------------ */ 178/* ------------------------------------------------------------------ */
121 179
122 180
@@ -124,55 +182,28 @@ void saa7134_track_gpio(struct saa7134_dev *dev, char *msg)
124/* delayed request_module */ 182/* delayed request_module */
125 183
126#if defined(CONFIG_MODULES) && defined(MODULE) 184#if defined(CONFIG_MODULES) && defined(MODULE)
127static int need_empress;
128static int need_dvb;
129static int need_alsa;
130static int need_oss;
131 185
132static int pending_call(struct notifier_block *self, unsigned long state,
133 void *module)
134{
135 if (module != THIS_MODULE || state != MODULE_STATE_LIVE)
136 return NOTIFY_DONE;
137 186
138 if (need_empress) 187static void request_module_async(struct work_struct *work){
188 struct saa7134_dev* dev = container_of(work, struct saa7134_dev, request_module_wk);
189 if (card_is_empress(dev))
139 request_module("saa7134-empress"); 190 request_module("saa7134-empress");
140 if (need_dvb) 191 if (card_is_dvb(dev))
141 request_module("saa7134-dvb"); 192 request_module("saa7134-dvb");
142 if (need_alsa) 193 if (alsa)
143 request_module("saa7134-alsa"); 194 request_module("saa7134-alsa");
144 if (need_oss) 195 if (oss)
145 request_module("saa7134-oss"); 196 request_module("saa7134-oss");
146 return NOTIFY_DONE;
147} 197}
148 198
149static int pending_registered; 199static void request_submodules(struct saa7134_dev *dev)
150static struct notifier_block pending_notifier = {
151 .notifier_call = pending_call,
152};
153
154static void request_module_depend(char *name, int *flag)
155{ 200{
156 int err; 201 INIT_WORK(&dev->request_module_wk, request_module_async);
157 switch (THIS_MODULE->state) { 202 schedule_work(&dev->request_module_wk);
158 case MODULE_STATE_COMING:
159 if (!pending_registered) {
160 err = register_module_notifier(&pending_notifier);
161 pending_registered = 1;
162 }
163 *flag = 1;
164 break;
165 case MODULE_STATE_LIVE:
166 request_module(name);
167 break;
168 default:
169 /* nothing */;
170 break;
171 }
172} 203}
173 204
174#else 205#else
175#define request_module_depend(name,flag) 206#define request_submodules(dev)
176#endif /* CONFIG_MODULES */ 207#endif /* CONFIG_MODULES */
177 208
178/* ------------------------------------------------------------------ */ 209/* ------------------------------------------------------------------ */
@@ -703,7 +734,6 @@ static int saa7134_hwfini(struct saa7134_dev *dev)
703 saa7134_ts_fini(dev); 734 saa7134_ts_fini(dev);
704 saa7134_input_fini(dev); 735 saa7134_input_fini(dev);
705 saa7134_vbi_fini(dev); 736 saa7134_vbi_fini(dev);
706 saa7134_video_fini(dev);
707 saa7134_tvaudio_fini(dev); 737 saa7134_tvaudio_fini(dev);
708 return 0; 738 return 0;
709} 739}
@@ -944,18 +974,9 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
944 request_module("tuner"); 974 request_module("tuner");
945 if (card_is_empress(dev)) { 975 if (card_is_empress(dev)) {
946 request_module("saa6752hs"); 976 request_module("saa6752hs");
947 request_module_depend("saa7134-empress",&need_empress);
948 } 977 }
949 978
950 if (card_is_dvb(dev)) 979 request_submodules(dev);
951 request_module_depend("saa7134-dvb",&need_dvb);
952
953
954 if (alsa)
955 request_module_depend("saa7134-alsa",&need_alsa);
956
957 if (oss)
958 request_module_depend("saa7134-oss",&need_oss);
959 980
960 v4l2_prio_init(&dev->prio); 981 v4l2_prio_init(&dev->prio);
961 982
@@ -1013,6 +1034,9 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
1013 saa7134_dmasound_init(dev); 1034 saa7134_dmasound_init(dev);
1014 } 1035 }
1015 1036
1037 if (TUNER_ABSENT != dev->tuner_type)
1038 saa7134_i2c_call_clients(dev, TUNER_SET_STANDBY, NULL);
1039
1016 return 0; 1040 return 0;
1017 1041
1018 fail4: 1042 fail4:
@@ -1152,10 +1176,6 @@ static int saa7134_init(void)
1152 1176
1153static void saa7134_fini(void) 1177static void saa7134_fini(void)
1154{ 1178{
1155#if defined(CONFIG_MODULES) && defined(MODULE)
1156 if (pending_registered)
1157 unregister_module_notifier(&pending_notifier);
1158#endif /* CONFIG_MODULES */
1159 pci_unregister_driver(&saa7134_pci_driver); 1179 pci_unregister_driver(&saa7134_pci_driver);
1160} 1180}
1161 1181
@@ -1164,6 +1184,7 @@ module_exit(saa7134_fini);
1164 1184
1165/* ----------------------------------------------------------- */ 1185/* ----------------------------------------------------------- */
1166 1186
1187EXPORT_SYMBOL(saa7134_set_gpio);
1167EXPORT_SYMBOL(saa7134_i2c_call_clients); 1188EXPORT_SYMBOL(saa7134_i2c_call_clients);
1168EXPORT_SYMBOL(saa7134_devlist); 1189EXPORT_SYMBOL(saa7134_devlist);
1169EXPORT_SYMBOL(saa7134_boards); 1190EXPORT_SYMBOL(saa7134_boards);
diff --git a/drivers/media/video/saa7134/saa7134-dvb.c b/drivers/media/video/saa7134/saa7134-dvb.c
index e3059fd33951..65aec881bbde 100644
--- a/drivers/media/video/saa7134/saa7134-dvb.c
+++ b/drivers/media/video/saa7134/saa7134-dvb.c
@@ -41,7 +41,9 @@
41 41
42#include "tda10086.h" 42#include "tda10086.h"
43#include "tda826x.h" 43#include "tda826x.h"
44#include "tda827x.h"
44#include "isl6421.h" 45#include "isl6421.h"
46
45MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]"); 47MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
46MODULE_LICENSE("GPL"); 48MODULE_LICENSE("GPL");
47 49
@@ -54,7 +56,21 @@ static int use_frontend = 0;
54module_param(use_frontend, int, 0644); 56module_param(use_frontend, int, 0644);
55MODULE_PARM_DESC(use_frontend,"for cards with multiple frontends (0: terrestrial, 1: satellite)"); 57MODULE_PARM_DESC(use_frontend,"for cards with multiple frontends (0: terrestrial, 1: satellite)");
56 58
57/* ------------------------------------------------------------------ */ 59static int debug = 0;
60module_param(debug, int, 0644);
61MODULE_PARM_DESC(debug, "Turn on/off module debugging (default:off).");
62
63#define dprintk(fmt, arg...) do { if (debug) \
64 printk(KERN_DEBUG "%s/dvb: " fmt, dev->name , ## arg); } while(0)
65
66/* Print a warning */
67#define wprintk(fmt, arg...) \
68 printk(KERN_WARNING "%s/dvb: " fmt, dev->name, ## arg)
69
70/* ------------------------------------------------------------------
71 * mt352 based DVB-T cards
72 */
73
58static int pinnacle_antenna_pwr(struct saa7134_dev *dev, int on) 74static int pinnacle_antenna_pwr(struct saa7134_dev *dev, int on)
59{ 75{
60 u32 ok; 76 u32 ok;
@@ -75,8 +91,7 @@ static int pinnacle_antenna_pwr(struct saa7134_dev *dev, int on)
75 saa_setl(SAA7134_GPIO_GPSTATUS0 >> 2, (1 << 28)); 91 saa_setl(SAA7134_GPIO_GPSTATUS0 >> 2, (1 << 28));
76 udelay(10); 92 udelay(10);
77 ok = saa_readl(SAA7134_GPIO_GPSTATUS0) & (1 << 27); 93 ok = saa_readl(SAA7134_GPIO_GPSTATUS0) & (1 << 27);
78 printk("%s: %s %s\n", dev->name, __FUNCTION__, 94 dprintk("%s %s\n", __FUNCTION__, ok ? "on" : "off");
79 ok ? "on" : "off");
80 95
81 if (!ok) 96 if (!ok)
82 saa_clearl(SAA7134_GPIO_GPSTATUS0 >> 2, (1 << 26)); 97 saa_clearl(SAA7134_GPIO_GPSTATUS0 >> 2, (1 << 26));
@@ -96,7 +111,7 @@ static int mt352_pinnacle_init(struct dvb_frontend* fe)
96 static u8 irq_cfg [] = { INTERRUPT_EN_0, 0x00, 0x00, 0x00, 0x00 }; 111 static u8 irq_cfg [] = { INTERRUPT_EN_0, 0x00, 0x00, 0x00, 0x00 };
97 struct saa7134_dev *dev= fe->dvb->priv; 112 struct saa7134_dev *dev= fe->dvb->priv;
98 113
99 printk("%s: %s called\n",dev->name,__FUNCTION__); 114 dprintk("%s called\n", __FUNCTION__);
100 115
101 mt352_write(fe, clock_config, sizeof(clock_config)); 116 mt352_write(fe, clock_config, sizeof(clock_config));
102 udelay(200); 117 udelay(200);
@@ -185,10 +200,26 @@ static struct mt352_config avermedia_777 = {
185 .demod_init = mt352_aver777_init, 200 .demod_init = mt352_aver777_init,
186}; 201};
187 202
188/* ------------------------------------------------------------------ */ 203/* ==================================================================
189static int philips_tda6651_pll_set(u8 addr, struct dvb_frontend *fe, struct dvb_frontend_parameters *params) 204 * tda1004x based DVB-T cards, helper functions
205 */
206
207static int philips_tda1004x_request_firmware(struct dvb_frontend *fe,
208 const struct firmware **fw, char *name)
209{
210 struct saa7134_dev *dev = fe->dvb->priv;
211 return request_firmware(fw, name, &dev->pci->dev);
212}
213
214/* ------------------------------------------------------------------
215 * these tuners are tu1216, td1316(a)
216 */
217
218static int philips_tda6651_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
190{ 219{
191 struct saa7134_dev *dev = fe->dvb->priv; 220 struct saa7134_dev *dev = fe->dvb->priv;
221 struct tda1004x_state *state = fe->demodulator_priv;
222 u8 addr = state->config->tuner_address;
192 u8 tuner_buf[4]; 223 u8 tuner_buf[4];
193 struct i2c_msg tuner_msg = {.addr = addr,.flags = 0,.buf = tuner_buf,.len = 224 struct i2c_msg tuner_msg = {.addr = addr,.flags = 0,.buf = tuner_buf,.len =
194 sizeof(tuner_buf) }; 225 sizeof(tuner_buf) };
@@ -263,15 +294,20 @@ static int philips_tda6651_pll_set(u8 addr, struct dvb_frontend *fe, struct dvb_
263 294
264 if (fe->ops.i2c_gate_ctrl) 295 if (fe->ops.i2c_gate_ctrl)
265 fe->ops.i2c_gate_ctrl(fe, 1); 296 fe->ops.i2c_gate_ctrl(fe, 1);
266 if (i2c_transfer(&dev->i2c_adap, &tuner_msg, 1) != 1) 297 if (i2c_transfer(&dev->i2c_adap, &tuner_msg, 1) != 1) {
298 wprintk("could not write to tuner at addr: 0x%02x\n",
299 addr << 1);
267 return -EIO; 300 return -EIO;
301 }
268 msleep(1); 302 msleep(1);
269 return 0; 303 return 0;
270} 304}
271 305
272static int philips_tda6651_pll_init(u8 addr, struct dvb_frontend *fe) 306static int philips_tu1216_init(struct dvb_frontend *fe)
273{ 307{
274 struct saa7134_dev *dev = fe->dvb->priv; 308 struct saa7134_dev *dev = fe->dvb->priv;
309 struct tda1004x_state *state = fe->demodulator_priv;
310 u8 addr = state->config->tuner_address;
275 static u8 tu1216_init[] = { 0x0b, 0xf5, 0x85, 0xab }; 311 static u8 tu1216_init[] = { 0x0b, 0xf5, 0x85, 0xab };
276 struct i2c_msg tuner_msg = {.addr = addr,.flags = 0,.buf = tu1216_init,.len = sizeof(tu1216_init) }; 312 struct i2c_msg tuner_msg = {.addr = addr,.flags = 0,.buf = tu1216_init,.len = sizeof(tu1216_init) };
277 313
@@ -287,46 +323,17 @@ static int philips_tda6651_pll_init(u8 addr, struct dvb_frontend *fe)
287 323
288/* ------------------------------------------------------------------ */ 324/* ------------------------------------------------------------------ */
289 325
290static int philips_tu1216_tuner_60_init(struct dvb_frontend *fe)
291{
292 return philips_tda6651_pll_init(0x60, fe);
293}
294
295static int philips_tu1216_tuner_60_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
296{
297 return philips_tda6651_pll_set(0x60, fe, params);
298}
299
300static int philips_tda1004x_request_firmware(struct dvb_frontend *fe,
301 const struct firmware **fw, char *name)
302{
303 struct saa7134_dev *dev = fe->dvb->priv;
304 return request_firmware(fw, name, &dev->pci->dev);
305}
306
307static struct tda1004x_config philips_tu1216_60_config = { 326static struct tda1004x_config philips_tu1216_60_config = {
308
309 .demod_address = 0x8, 327 .demod_address = 0x8,
310 .invert = 1, 328 .invert = 1,
311 .invert_oclk = 0, 329 .invert_oclk = 0,
312 .xtal_freq = TDA10046_XTAL_4M, 330 .xtal_freq = TDA10046_XTAL_4M,
313 .agc_config = TDA10046_AGC_DEFAULT, 331 .agc_config = TDA10046_AGC_DEFAULT,
314 .if_freq = TDA10046_FREQ_3617, 332 .if_freq = TDA10046_FREQ_3617,
315 .request_firmware = philips_tda1004x_request_firmware, 333 .tuner_address = 0x60,
334 .request_firmware = philips_tda1004x_request_firmware
316}; 335};
317 336
318/* ------------------------------------------------------------------ */
319
320static int philips_tu1216_tuner_61_init(struct dvb_frontend *fe)
321{
322 return philips_tda6651_pll_init(0x61, fe);
323}
324
325static int philips_tu1216_tuner_61_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
326{
327 return philips_tda6651_pll_set(0x61, fe, params);
328}
329
330static struct tda1004x_config philips_tu1216_61_config = { 337static struct tda1004x_config philips_tu1216_61_config = {
331 338
332 .demod_address = 0x8, 339 .demod_address = 0x8,
@@ -335,7 +342,8 @@ static struct tda1004x_config philips_tu1216_61_config = {
335 .xtal_freq = TDA10046_XTAL_4M, 342 .xtal_freq = TDA10046_XTAL_4M,
336 .agc_config = TDA10046_AGC_DEFAULT, 343 .agc_config = TDA10046_AGC_DEFAULT,
337 .if_freq = TDA10046_FREQ_3617, 344 .if_freq = TDA10046_FREQ_3617,
338 .request_firmware = philips_tda1004x_request_firmware, 345 .tuner_address = 0x61,
346 .request_firmware = philips_tda1004x_request_firmware
339}; 347};
340 348
341/* ------------------------------------------------------------------ */ 349/* ------------------------------------------------------------------ */
@@ -343,24 +351,42 @@ static struct tda1004x_config philips_tu1216_61_config = {
343static int philips_td1316_tuner_init(struct dvb_frontend *fe) 351static int philips_td1316_tuner_init(struct dvb_frontend *fe)
344{ 352{
345 struct saa7134_dev *dev = fe->dvb->priv; 353 struct saa7134_dev *dev = fe->dvb->priv;
354 struct tda1004x_state *state = fe->demodulator_priv;
355 u8 addr = state->config->tuner_address;
346 static u8 msg[] = { 0x0b, 0xf5, 0x86, 0xab }; 356 static u8 msg[] = { 0x0b, 0xf5, 0x86, 0xab };
347 struct i2c_msg init_msg = {.addr = 0x61,.flags = 0,.buf = msg,.len = sizeof(msg) }; 357 struct i2c_msg init_msg = {.addr = addr,.flags = 0,.buf = msg,.len = sizeof(msg) };
348 358
349 /* setup PLL configuration */ 359 /* setup PLL configuration */
350 if (fe->ops.i2c_gate_ctrl) 360 if (fe->ops.i2c_gate_ctrl)
351 fe->ops.i2c_gate_ctrl(fe, 1); 361 fe->ops.i2c_gate_ctrl(fe, 1);
352 if (i2c_transfer(&dev->i2c_adap, &init_msg, 1) != 1) 362 if (i2c_transfer(&dev->i2c_adap, &init_msg, 1) != 1)
353 return -EIO; 363 return -EIO;
354 if (fe->ops.i2c_gate_ctrl)
355 fe->ops.i2c_gate_ctrl(fe, 0);
356 return 0; 364 return 0;
357} 365}
358 366
359static int philips_td1316_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) 367static int philips_td1316_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
360{ 368{
361 return philips_tda6651_pll_set(0x61, fe, params); 369 return philips_tda6651_pll_set(fe, params);
362} 370}
363 371
372static int philips_td1316_tuner_sleep(struct dvb_frontend *fe)
373{
374 struct saa7134_dev *dev = fe->dvb->priv;
375 struct tda1004x_state *state = fe->demodulator_priv;
376 u8 addr = state->config->tuner_address;
377 static u8 msg[] = { 0x0b, 0xdc, 0x86, 0xa4 };
378 struct i2c_msg analog_msg = {.addr = addr,.flags = 0,.buf = msg,.len = sizeof(msg) };
379
380 /* switch the tuner to analog mode */
381 if (fe->ops.i2c_gate_ctrl)
382 fe->ops.i2c_gate_ctrl(fe, 1);
383 if (i2c_transfer(&dev->i2c_adap, &analog_msg, 1) != 1)
384 return -EIO;
385 return 0;
386}
387
388/* ------------------------------------------------------------------ */
389
364static int philips_europa_tuner_init(struct dvb_frontend *fe) 390static int philips_europa_tuner_init(struct dvb_frontend *fe)
365{ 391{
366 struct saa7134_dev *dev = fe->dvb->priv; 392 struct saa7134_dev *dev = fe->dvb->priv;
@@ -380,18 +406,14 @@ static int philips_europa_tuner_init(struct dvb_frontend *fe)
380static int philips_europa_tuner_sleep(struct dvb_frontend *fe) 406static int philips_europa_tuner_sleep(struct dvb_frontend *fe)
381{ 407{
382 struct saa7134_dev *dev = fe->dvb->priv; 408 struct saa7134_dev *dev = fe->dvb->priv;
383 /* this message actually turns the tuner back to analog mode */
384 static u8 msg[] = { 0x0b, 0xdc, 0x86, 0xa4 };
385 struct i2c_msg analog_msg = {.addr = 0x61,.flags = 0,.buf = msg,.len = sizeof(msg) };
386 409
387 i2c_transfer(&dev->i2c_adap, &analog_msg, 1); 410 static u8 msg[] = { 0x00, 0x14 };
388 msleep(1); 411 struct i2c_msg analog_msg = {.addr = 0x43,.flags = 0,.buf = msg,.len = sizeof(msg) };
412
413 if (philips_td1316_tuner_sleep(fe))
414 return -EIO;
389 415
390 /* switch the board to analog mode */ 416 /* switch the board to analog mode */
391 analog_msg.addr = 0x43;
392 analog_msg.len = 0x02;
393 msg[0] = 0x00;
394 msg[1] = 0x14;
395 if (fe->ops.i2c_gate_ctrl) 417 if (fe->ops.i2c_gate_ctrl)
396 fe->ops.i2c_gate_ctrl(fe, 1); 418 fe->ops.i2c_gate_ctrl(fe, 1);
397 i2c_transfer(&dev->i2c_adap, &analog_msg, 1); 419 i2c_transfer(&dev->i2c_adap, &analog_msg, 1);
@@ -416,7 +438,8 @@ static struct tda1004x_config philips_europa_config = {
416 .xtal_freq = TDA10046_XTAL_4M, 438 .xtal_freq = TDA10046_XTAL_4M,
417 .agc_config = TDA10046_AGC_IFO_AUTO_POS, 439 .agc_config = TDA10046_AGC_IFO_AUTO_POS,
418 .if_freq = TDA10046_FREQ_052, 440 .if_freq = TDA10046_FREQ_052,
419 .request_firmware = NULL, 441 .tuner_address = 0x61,
442 .request_firmware = philips_tda1004x_request_firmware
420}; 443};
421 444
422/* ------------------------------------------------------------------ */ 445/* ------------------------------------------------------------------ */
@@ -424,9 +447,11 @@ static struct tda1004x_config philips_europa_config = {
424static int philips_fmd1216_tuner_init(struct dvb_frontend *fe) 447static int philips_fmd1216_tuner_init(struct dvb_frontend *fe)
425{ 448{
426 struct saa7134_dev *dev = fe->dvb->priv; 449 struct saa7134_dev *dev = fe->dvb->priv;
450 struct tda1004x_state *state = fe->demodulator_priv;
451 u8 addr = state->config->tuner_address;
427 /* this message is to set up ATC and ALC */ 452 /* this message is to set up ATC and ALC */
428 static u8 fmd1216_init[] = { 0x0b, 0xdc, 0x9c, 0xa0 }; 453 static u8 fmd1216_init[] = { 0x0b, 0xdc, 0x9c, 0xa0 };
429 struct i2c_msg tuner_msg = {.addr = 0x61,.flags = 0,.buf = fmd1216_init,.len = sizeof(fmd1216_init) }; 454 struct i2c_msg tuner_msg = {.addr = addr,.flags = 0,.buf = fmd1216_init,.len = sizeof(fmd1216_init) };
430 455
431 if (fe->ops.i2c_gate_ctrl) 456 if (fe->ops.i2c_gate_ctrl)
432 fe->ops.i2c_gate_ctrl(fe, 1); 457 fe->ops.i2c_gate_ctrl(fe, 1);
@@ -440,9 +465,11 @@ static int philips_fmd1216_tuner_init(struct dvb_frontend *fe)
440static int philips_fmd1216_tuner_sleep(struct dvb_frontend *fe) 465static int philips_fmd1216_tuner_sleep(struct dvb_frontend *fe)
441{ 466{
442 struct saa7134_dev *dev = fe->dvb->priv; 467 struct saa7134_dev *dev = fe->dvb->priv;
468 struct tda1004x_state *state = fe->demodulator_priv;
469 u8 addr = state->config->tuner_address;
443 /* this message actually turns the tuner back to analog mode */ 470 /* this message actually turns the tuner back to analog mode */
444 static u8 fmd1216_init[] = { 0x0b, 0xdc, 0x9c, 0x60 }; 471 u8 fmd1216_init[] = { 0x0b, 0xdc, 0x9c, 0x60 };
445 struct i2c_msg tuner_msg = {.addr = 0x61,.flags = 0,.buf = fmd1216_init,.len = sizeof(fmd1216_init) }; 472 struct i2c_msg tuner_msg = {.addr = addr,.flags = 0,.buf = fmd1216_init,.len = sizeof(fmd1216_init) };
446 473
447 if (fe->ops.i2c_gate_ctrl) 474 if (fe->ops.i2c_gate_ctrl)
448 fe->ops.i2c_gate_ctrl(fe, 1); 475 fe->ops.i2c_gate_ctrl(fe, 1);
@@ -460,8 +487,10 @@ static int philips_fmd1216_tuner_sleep(struct dvb_frontend *fe)
460static int philips_fmd1216_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) 487static int philips_fmd1216_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
461{ 488{
462 struct saa7134_dev *dev = fe->dvb->priv; 489 struct saa7134_dev *dev = fe->dvb->priv;
490 struct tda1004x_state *state = fe->demodulator_priv;
491 u8 addr = state->config->tuner_address;
463 u8 tuner_buf[4]; 492 u8 tuner_buf[4];
464 struct i2c_msg tuner_msg = {.addr = 0x61,.flags = 0,.buf = tuner_buf,.len = 493 struct i2c_msg tuner_msg = {.addr = addr,.flags = 0,.buf = tuner_buf,.len =
465 sizeof(tuner_buf) }; 494 sizeof(tuner_buf) };
466 int tuner_frequency = 0; 495 int tuner_frequency = 0;
467 int divider = 0; 496 int divider = 0;
@@ -536,8 +565,11 @@ static int philips_fmd1216_tuner_set_params(struct dvb_frontend *fe, struct dvb_
536 565
537 if (fe->ops.i2c_gate_ctrl) 566 if (fe->ops.i2c_gate_ctrl)
538 fe->ops.i2c_gate_ctrl(fe, 1); 567 fe->ops.i2c_gate_ctrl(fe, 1);
539 if (i2c_transfer(&dev->i2c_adap, &tuner_msg, 1) != 1) 568 if (i2c_transfer(&dev->i2c_adap, &tuner_msg, 1) != 1) {
569 wprintk("could not write to tuner at addr: 0x%02x\n",
570 addr << 1);
540 return -EIO; 571 return -EIO;
572 }
541 return 0; 573 return 0;
542} 574}
543 575
@@ -548,582 +580,365 @@ static struct tda1004x_config medion_cardbus = {
548 .xtal_freq = TDA10046_XTAL_16M, 580 .xtal_freq = TDA10046_XTAL_16M,
549 .agc_config = TDA10046_AGC_IFO_AUTO_NEG, 581 .agc_config = TDA10046_AGC_IFO_AUTO_NEG,
550 .if_freq = TDA10046_FREQ_3613, 582 .if_freq = TDA10046_FREQ_3613,
551 .request_firmware = NULL, 583 .tuner_address = 0x61,
584 .request_firmware = philips_tda1004x_request_firmware
552}; 585};
553 586
554/* ------------------------------------------------------------------ */ 587/* ------------------------------------------------------------------
555 588 * tda 1004x based cards with philips silicon tuner
556struct tda827x_data { 589 */
557 u32 lomax;
558 u8 spd;
559 u8 bs;
560 u8 bp;
561 u8 cp;
562 u8 gc3;
563 u8 div1p5;
564};
565
566static struct tda827x_data tda827x_dvbt[] = {
567 { .lomax = 62000000, .spd = 3, .bs = 2, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 1},
568 { .lomax = 66000000, .spd = 3, .bs = 3, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 1},
569 { .lomax = 76000000, .spd = 3, .bs = 1, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 0},
570 { .lomax = 84000000, .spd = 3, .bs = 2, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 0},
571 { .lomax = 93000000, .spd = 3, .bs = 2, .bp = 0, .cp = 0, .gc3 = 1, .div1p5 = 0},
572 { .lomax = 98000000, .spd = 3, .bs = 3, .bp = 0, .cp = 0, .gc3 = 1, .div1p5 = 0},
573 { .lomax = 109000000, .spd = 3, .bs = 3, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 0},
574 { .lomax = 123000000, .spd = 2, .bs = 2, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 1},
575 { .lomax = 133000000, .spd = 2, .bs = 3, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 1},
576 { .lomax = 151000000, .spd = 2, .bs = 1, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 0},
577 { .lomax = 154000000, .spd = 2, .bs = 2, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 0},
578 { .lomax = 181000000, .spd = 2, .bs = 2, .bp = 1, .cp = 0, .gc3 = 0, .div1p5 = 0},
579 { .lomax = 185000000, .spd = 2, .bs = 2, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0},
580 { .lomax = 217000000, .spd = 2, .bs = 3, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0},
581 { .lomax = 244000000, .spd = 1, .bs = 2, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 1},
582 { .lomax = 265000000, .spd = 1, .bs = 3, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 1},
583 { .lomax = 302000000, .spd = 1, .bs = 1, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0},
584 { .lomax = 324000000, .spd = 1, .bs = 2, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0},
585 { .lomax = 370000000, .spd = 1, .bs = 2, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 0},
586 { .lomax = 454000000, .spd = 1, .bs = 3, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 0},
587 { .lomax = 493000000, .spd = 0, .bs = 2, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 1},
588 { .lomax = 530000000, .spd = 0, .bs = 3, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 1},
589 { .lomax = 554000000, .spd = 0, .bs = 1, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 0},
590 { .lomax = 604000000, .spd = 0, .bs = 1, .bp = 4, .cp = 0, .gc3 = 0, .div1p5 = 0},
591 { .lomax = 696000000, .spd = 0, .bs = 2, .bp = 4, .cp = 0, .gc3 = 0, .div1p5 = 0},
592 { .lomax = 740000000, .spd = 0, .bs = 2, .bp = 4, .cp = 1, .gc3 = 0, .div1p5 = 0},
593 { .lomax = 820000000, .spd = 0, .bs = 3, .bp = 4, .cp = 0, .gc3 = 0, .div1p5 = 0},
594 { .lomax = 865000000, .spd = 0, .bs = 3, .bp = 4, .cp = 1, .gc3 = 0, .div1p5 = 0},
595 { .lomax = 0, .spd = 0, .bs = 0, .bp = 0, .cp = 0, .gc3 = 0, .div1p5 = 0}
596};
597
598static int philips_tda827x_tuner_init(struct dvb_frontend *fe)
599{
600 return 0;
601}
602 590
603static int philips_tda827x_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) 591static void philips_tda827x_lna_gain(struct dvb_frontend *fe, int high)
604{ 592{
605 struct saa7134_dev *dev = fe->dvb->priv; 593 struct saa7134_dev *dev = fe->dvb->priv;
606 u8 tuner_buf[14]; 594 struct tda1004x_state *state = fe->demodulator_priv;
607 595 u8 addr = state->config->i2c_gate;
608 struct i2c_msg tuner_msg = {.addr = 0x60,.flags = 0,.buf = tuner_buf, 596 u8 config = state->config->tuner_config;
609 .len = sizeof(tuner_buf) }; 597 u8 GP00_CF[] = {0x20, 0x01};
610 int i, tuner_freq, if_freq; 598 u8 GP00_LEV[] = {0x22, 0x00};
611 u32 N; 599
612 switch (params->u.ofdm.bandwidth) { 600 struct i2c_msg msg = {.addr = addr,.flags = 0,.buf = GP00_CF, .len = 2};
613 case BANDWIDTH_6_MHZ: 601 if (config) {
614 if_freq = 4000000; 602 if (high) {
615 break; 603 dprintk("setting LNA to high gain\n");
616 case BANDWIDTH_7_MHZ: 604 } else {
617 if_freq = 4500000; 605 dprintk("setting LNA to low gain\n");
618 break; 606 }
619 default: /* 8 MHz or Auto */
620 if_freq = 5000000;
621 break;
622 }
623 tuner_freq = params->frequency + if_freq;
624
625 i = 0;
626 while (tda827x_dvbt[i].lomax < tuner_freq) {
627 if(tda827x_dvbt[i + 1].lomax == 0)
628 break;
629 i++;
630 } 607 }
631 608 switch (config) {
632 N = ((tuner_freq + 125000) / 250000) << (tda827x_dvbt[i].spd + 2); 609 case 0: /* no LNA */
633 tuner_buf[0] = 0;
634 tuner_buf[1] = (N>>8) | 0x40;
635 tuner_buf[2] = N & 0xff;
636 tuner_buf[3] = 0;
637 tuner_buf[4] = 0x52;
638 tuner_buf[5] = (tda827x_dvbt[i].spd << 6) + (tda827x_dvbt[i].div1p5 << 5) +
639 (tda827x_dvbt[i].bs << 3) + tda827x_dvbt[i].bp;
640 tuner_buf[6] = (tda827x_dvbt[i].gc3 << 4) + 0x8f;
641 tuner_buf[7] = 0xbf;
642 tuner_buf[8] = 0x2a;
643 tuner_buf[9] = 0x05;
644 tuner_buf[10] = 0xff;
645 tuner_buf[11] = 0x00;
646 tuner_buf[12] = 0x00;
647 tuner_buf[13] = 0x40;
648
649 tuner_msg.len = 14;
650 if (fe->ops.i2c_gate_ctrl)
651 fe->ops.i2c_gate_ctrl(fe, 1);
652 if (i2c_transfer(&dev->i2c_adap, &tuner_msg, 1) != 1)
653 return -EIO;
654
655 msleep(500);
656 /* correct CP value */
657 tuner_buf[0] = 0x30;
658 tuner_buf[1] = 0x50 + tda827x_dvbt[i].cp;
659 tuner_msg.len = 2;
660 if (fe->ops.i2c_gate_ctrl)
661 fe->ops.i2c_gate_ctrl(fe, 1);
662 i2c_transfer(&dev->i2c_adap, &tuner_msg, 1);
663
664 return 0;
665}
666
667static int philips_tda827x_tuner_sleep(struct dvb_frontend *fe)
668{
669 struct saa7134_dev *dev = fe->dvb->priv;
670 static u8 tda827x_sleep[] = { 0x30, 0xd0};
671 struct i2c_msg tuner_msg = {.addr = 0x60,.flags = 0,.buf = tda827x_sleep,
672 .len = sizeof(tda827x_sleep) };
673 if (fe->ops.i2c_gate_ctrl)
674 fe->ops.i2c_gate_ctrl(fe, 1);
675 i2c_transfer(&dev->i2c_adap, &tuner_msg, 1);
676 return 0;
677}
678
679static struct tda1004x_config tda827x_lifeview_config = {
680 .demod_address = 0x08,
681 .invert = 1,
682 .invert_oclk = 0,
683 .xtal_freq = TDA10046_XTAL_16M,
684 .agc_config = TDA10046_AGC_TDA827X_GP11,
685 .if_freq = TDA10046_FREQ_045,
686 .request_firmware = NULL,
687};
688
689/* ------------------------------------------------------------------ */
690
691struct tda827xa_data {
692 u32 lomax;
693 u8 svco;
694 u8 spd;
695 u8 scr;
696 u8 sbs;
697 u8 gc3;
698};
699
700static struct tda827xa_data tda827xa_dvbt[] = {
701 { .lomax = 56875000, .svco = 3, .spd = 4, .scr = 0, .sbs = 0, .gc3 = 1},
702 { .lomax = 67250000, .svco = 0, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 1},
703 { .lomax = 81250000, .svco = 1, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 1},
704 { .lomax = 97500000, .svco = 2, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 1},
705 { .lomax = 113750000, .svco = 3, .spd = 3, .scr = 0, .sbs = 1, .gc3 = 1},
706 { .lomax = 134500000, .svco = 0, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1},
707 { .lomax = 154000000, .svco = 1, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1},
708 { .lomax = 162500000, .svco = 1, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1},
709 { .lomax = 183000000, .svco = 2, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1},
710 { .lomax = 195000000, .svco = 2, .spd = 2, .scr = 0, .sbs = 2, .gc3 = 1},
711 { .lomax = 227500000, .svco = 3, .spd = 2, .scr = 0, .sbs = 2, .gc3 = 1},
712 { .lomax = 269000000, .svco = 0, .spd = 1, .scr = 0, .sbs = 2, .gc3 = 1},
713 { .lomax = 290000000, .svco = 1, .spd = 1, .scr = 0, .sbs = 2, .gc3 = 1},
714 { .lomax = 325000000, .svco = 1, .spd = 1, .scr = 0, .sbs = 3, .gc3 = 1},
715 { .lomax = 390000000, .svco = 2, .spd = 1, .scr = 0, .sbs = 3, .gc3 = 1},
716 { .lomax = 455000000, .svco = 3, .spd = 1, .scr = 0, .sbs = 3, .gc3 = 1},
717 { .lomax = 520000000, .svco = 0, .spd = 0, .scr = 0, .sbs = 3, .gc3 = 1},
718 { .lomax = 538000000, .svco = 0, .spd = 0, .scr = 1, .sbs = 3, .gc3 = 1},
719 { .lomax = 550000000, .svco = 1, .spd = 0, .scr = 0, .sbs = 3, .gc3 = 1},
720 { .lomax = 620000000, .svco = 1, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0},
721 { .lomax = 650000000, .svco = 1, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0},
722 { .lomax = 700000000, .svco = 2, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0},
723 { .lomax = 780000000, .svco = 2, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0},
724 { .lomax = 820000000, .svco = 3, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0},
725 { .lomax = 870000000, .svco = 3, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0},
726 { .lomax = 911000000, .svco = 3, .spd = 0, .scr = 2, .sbs = 4, .gc3 = 0},
727 { .lomax = 0, .svco = 0, .spd = 0, .scr = 0, .sbs = 0, .gc3 = 0}};
728
729
730static int philips_tda827xa_pll_set(u8 addr, struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
731{
732 struct saa7134_dev *dev = fe->dvb->priv;
733 u8 tuner_buf[14];
734 unsigned char reg2[2];
735
736 struct i2c_msg msg = {.addr = addr,.flags = 0,.buf = tuner_buf};
737 int i, tuner_freq, if_freq;
738 u32 N;
739
740 switch (params->u.ofdm.bandwidth) {
741 case BANDWIDTH_6_MHZ:
742 if_freq = 4000000;
743 break; 610 break;
744 case BANDWIDTH_7_MHZ: 611 case 1: /* switch is GPIO 0 of tda8290 */
745 if_freq = 4500000; 612 case 2:
613 /* turn Vsync off */
614 saa7134_set_gpio(dev, 22, 0);
615 GP00_LEV[1] = high ? 0 : 1;
616 if (i2c_transfer(&dev->i2c_adap, &msg, 1) != 1) {
617 wprintk("could not access tda8290 at addr: 0x%02x\n",
618 addr << 1);
619 return;
620 }
621 msg.buf = GP00_LEV;
622 if (config == 2)
623 GP00_LEV[1] = high ? 1 : 0;
624 i2c_transfer(&dev->i2c_adap, &msg, 1);
746 break; 625 break;
747 default: /* 8 MHz or Auto */ 626 case 3: /* switch with GPIO of saa713x */
748 if_freq = 5000000; 627 saa7134_set_gpio(dev, 22, high);
749 break; 628 break;
750 } 629 }
751 tuner_freq = params->frequency + if_freq;
752
753 i = 0;
754 while (tda827xa_dvbt[i].lomax < tuner_freq) {
755 if(tda827xa_dvbt[i + 1].lomax == 0)
756 break;
757 i++;
758 }
759
760 N = ((tuner_freq + 31250) / 62500) << tda827xa_dvbt[i].spd;
761 tuner_buf[0] = 0; // subaddress
762 tuner_buf[1] = N >> 8;
763 tuner_buf[2] = N & 0xff;
764 tuner_buf[3] = 0;
765 tuner_buf[4] = 0x16;
766 tuner_buf[5] = (tda827xa_dvbt[i].spd << 5) + (tda827xa_dvbt[i].svco << 3) +
767 tda827xa_dvbt[i].sbs;
768 tuner_buf[6] = 0x4b + (tda827xa_dvbt[i].gc3 << 4);
769 tuner_buf[7] = 0x0c;
770 tuner_buf[8] = 0x06;
771 tuner_buf[9] = 0x24;
772 tuner_buf[10] = 0xff;
773 tuner_buf[11] = 0x60;
774 tuner_buf[12] = 0x00;
775 tuner_buf[13] = 0x39; // lpsel
776 msg.len = 14;
777 if (fe->ops.i2c_gate_ctrl)
778 fe->ops.i2c_gate_ctrl(fe, 1);
779 if (i2c_transfer(&dev->i2c_adap, &msg, 1) != 1)
780 return -EIO;
781
782 msg.buf= reg2;
783 msg.len = 2;
784 reg2[0] = 0x60;
785 reg2[1] = 0x3c;
786 if (fe->ops.i2c_gate_ctrl)
787 fe->ops.i2c_gate_ctrl(fe, 1);
788 i2c_transfer(&dev->i2c_adap, &msg, 1);
789
790 reg2[0] = 0xa0;
791 reg2[1] = 0x40;
792 if (fe->ops.i2c_gate_ctrl)
793 fe->ops.i2c_gate_ctrl(fe, 1);
794 i2c_transfer(&dev->i2c_adap, &msg, 1);
795
796 msleep(2);
797 /* correct CP value */
798 reg2[0] = 0x30;
799 reg2[1] = 0x10 + tda827xa_dvbt[i].scr;
800 msg.len = 2;
801 if (fe->ops.i2c_gate_ctrl)
802 fe->ops.i2c_gate_ctrl(fe, 1);
803 i2c_transfer(&dev->i2c_adap, &msg, 1);
804
805 msleep(550);
806 reg2[0] = 0x50;
807 reg2[1] = 0x4f + (tda827xa_dvbt[i].gc3 << 4);
808 if (fe->ops.i2c_gate_ctrl)
809 fe->ops.i2c_gate_ctrl(fe, 1);
810 i2c_transfer(&dev->i2c_adap, &msg, 1);
811
812 return 0;
813
814} 630}
815 631
816static int philips_tda827xa_tuner_sleep(u8 addr, struct dvb_frontend *fe) 632static int tda8290_i2c_gate_ctrl( struct dvb_frontend* fe, int enable)
817{ 633{
818 struct saa7134_dev *dev = fe->dvb->priv; 634 struct tda1004x_state *state = fe->demodulator_priv;
819 static u8 tda827xa_sleep[] = { 0x30, 0x90};
820 struct i2c_msg tuner_msg = {.addr = addr,.flags = 0,.buf = tda827xa_sleep,
821 .len = sizeof(tda827xa_sleep) };
822 if (fe->ops.i2c_gate_ctrl)
823 fe->ops.i2c_gate_ctrl(fe, 1);
824 i2c_transfer(&dev->i2c_adap, &tuner_msg, 1);
825 if (fe->ops.i2c_gate_ctrl)
826 fe->ops.i2c_gate_ctrl(fe, 0);
827 return 0;
828}
829 635
830/* ------------------------------------------------------------------ */ 636 u8 addr = state->config->i2c_gate;
831
832static int tda8290_i2c_gate_ctrl(struct dvb_frontend* fe, int enable)
833{
834 struct saa7134_dev *dev = fe->dvb->priv;
835 static u8 tda8290_close[] = { 0x21, 0xc0}; 637 static u8 tda8290_close[] = { 0x21, 0xc0};
836 static u8 tda8290_open[] = { 0x21, 0x80}; 638 static u8 tda8290_open[] = { 0x21, 0x80};
837 struct i2c_msg tda8290_msg = {.addr = 0x4b,.flags = 0, .len = 2}; 639 struct i2c_msg tda8290_msg = {.addr = addr,.flags = 0, .len = 2};
838 if (enable) { 640 if (enable) {
839 tda8290_msg.buf = tda8290_close; 641 tda8290_msg.buf = tda8290_close;
840 } else { 642 } else {
841 tda8290_msg.buf = tda8290_open; 643 tda8290_msg.buf = tda8290_open;
842 } 644 }
843 if (i2c_transfer(&dev->i2c_adap, &tda8290_msg, 1) != 1) 645 if (i2c_transfer(state->i2c, &tda8290_msg, 1) != 1) {
646 struct saa7134_dev *dev = fe->dvb->priv;
647 wprintk("could not access tda8290 I2C gate\n");
844 return -EIO; 648 return -EIO;
649 }
845 msleep(20); 650 msleep(20);
846 return 0; 651 return 0;
847} 652}
848 653
849/* ------------------------------------------------------------------ */ 654/* ------------------------------------------------------------------ */
850 655
851static int philips_tiger_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) 656static int philips_tda827x_tuner_init(struct dvb_frontend *fe)
852{ 657{
853 int ret; 658 struct saa7134_dev *dev = fe->dvb->priv;
659 struct tda1004x_state *state = fe->demodulator_priv;
854 660
855 ret = philips_tda827xa_pll_set(0x61, fe, params); 661 switch (state->config->antenna_switch) {
856 if (ret != 0) 662 case 0: break;
857 return ret; 663 case 1: dprintk("setting GPIO21 to 0 (TV antenna?)\n");
664 saa7134_set_gpio(dev, 21, 0);
665 break;
666 case 2: dprintk("setting GPIO21 to 1 (Radio antenna?)\n");
667 saa7134_set_gpio(dev, 21, 1);
668 break;
669 }
858 return 0; 670 return 0;
859} 671}
860 672
861static int philips_tiger_tuner_init(struct dvb_frontend *fe) 673static int philips_tda827x_tuner_sleep(struct dvb_frontend *fe)
862{ 674{
863 struct saa7134_dev *dev = fe->dvb->priv; 675 struct saa7134_dev *dev = fe->dvb->priv;
864 static u8 data[] = { 0x3c, 0x33, 0x6a}; 676 struct tda1004x_state *state = fe->demodulator_priv;
865 struct i2c_msg msg = {.addr=0x08, .flags=0, .buf=data, .len = sizeof(data)};
866 677
867 if (i2c_transfer(&dev->i2c_adap, &msg, 1) != 1) 678 switch (state->config->antenna_switch) {
868 return -EIO; 679 case 0: break;
680 case 1: dprintk("setting GPIO21 to 1 (Radio antenna?)\n");
681 saa7134_set_gpio(dev, 21, 1);
682 break;
683 case 2: dprintk("setting GPIO21 to 0 (TV antenna?)\n");
684 saa7134_set_gpio(dev, 21, 0);
685 break;
686 }
869 return 0; 687 return 0;
870} 688}
871 689
872static int philips_tiger_tuner_sleep(struct dvb_frontend *fe) 690static struct tda827x_config tda827x_cfg = {
873{ 691 .lna_gain = philips_tda827x_lna_gain,
874 struct saa7134_dev *dev = fe->dvb->priv; 692 .init = philips_tda827x_tuner_init,
875 static u8 data[] = { 0x3c, 0x33, 0x68}; 693 .sleep = philips_tda827x_tuner_sleep
876 struct i2c_msg msg = {.addr=0x08, .flags=0, .buf=data, .len = sizeof(data)}; 694};
877 695
878 i2c_transfer(&dev->i2c_adap, &msg, 1); 696static void configure_tda827x_fe(struct saa7134_dev *dev, struct tda1004x_config *tda_conf)
879 philips_tda827xa_tuner_sleep( 0x61, fe); 697{
880 return 0; 698 dev->dvb.frontend = dvb_attach(tda10046_attach, tda_conf, &dev->i2c_adap);
699 if (dev->dvb.frontend) {
700 if (tda_conf->i2c_gate)
701 dev->dvb.frontend->ops.i2c_gate_ctrl = tda8290_i2c_gate_ctrl;
702 if (dvb_attach(tda827x_attach, dev->dvb.frontend, tda_conf->tuner_address,
703 &dev->i2c_adap,&tda827x_cfg) == NULL) {
704 wprintk("no tda827x tuner found at addr: %02x\n",
705 tda_conf->tuner_address);
706 }
707 }
881} 708}
882 709
883static struct tda1004x_config philips_tiger_config = { 710/* ------------------------------------------------------------------ */
711static struct tda1004x_config tda827x_lifeview_config = {
884 .demod_address = 0x08, 712 .demod_address = 0x08,
885 .invert = 1, 713 .invert = 1,
886 .invert_oclk = 0, 714 .invert_oclk = 0,
887 .xtal_freq = TDA10046_XTAL_16M, 715 .xtal_freq = TDA10046_XTAL_16M,
888 .agc_config = TDA10046_AGC_TDA827X_GP11, 716 .agc_config = TDA10046_AGC_TDA827X,
717 .gpio_config = TDA10046_GP11_I,
889 .if_freq = TDA10046_FREQ_045, 718 .if_freq = TDA10046_FREQ_045,
890 .request_firmware = NULL, 719 .tuner_address = 0x60,
720 .request_firmware = philips_tda1004x_request_firmware
891}; 721};
892/* ------------------------------------------------------------------ */
893
894static int cinergy_ht_tuner_init(struct dvb_frontend *fe)
895{
896 struct saa7134_dev *dev = fe->dvb->priv;
897 static u8 data[] = { 0x3c, 0x33, 0x62};
898 struct i2c_msg msg = {.addr=0x08, .flags=0, .buf=data, .len = sizeof(data)};
899 722
900 if (i2c_transfer(&dev->i2c_adap, &msg, 1) != 1) 723static struct tda1004x_config philips_tiger_config = {
901 return -EIO; 724 .demod_address = 0x08,
902 return 0; 725 .invert = 1,
903} 726 .invert_oclk = 0,
904 727 .xtal_freq = TDA10046_XTAL_16M,
905static int cinergy_ht_tuner_sleep(struct dvb_frontend *fe) 728 .agc_config = TDA10046_AGC_TDA827X,
906{ 729 .gpio_config = TDA10046_GP11_I,
907 struct saa7134_dev *dev = fe->dvb->priv; 730 .if_freq = TDA10046_FREQ_045,
908 static u8 data[] = { 0x3c, 0x33, 0x60}; 731 .i2c_gate = 0x4b,
909 struct i2c_msg msg = {.addr=0x08, .flags=0, .buf=data, .len = sizeof(data)}; 732 .tuner_address = 0x61,
910 733 .tuner_config = 0,
911 i2c_transfer(&dev->i2c_adap, &msg, 1); 734 .antenna_switch= 1,
912 philips_tda827xa_tuner_sleep( 0x61, fe); 735 .request_firmware = philips_tda1004x_request_firmware
913 return 0; 736};
914}
915 737
916static struct tda1004x_config cinergy_ht_config = { 738static struct tda1004x_config cinergy_ht_config = {
917 .demod_address = 0x08, 739 .demod_address = 0x08,
918 .invert = 1, 740 .invert = 1,
919 .invert_oclk = 0, 741 .invert_oclk = 0,
920 .xtal_freq = TDA10046_XTAL_16M, 742 .xtal_freq = TDA10046_XTAL_16M,
921 .agc_config = TDA10046_AGC_TDA827X_GP01, 743 .agc_config = TDA10046_AGC_TDA827X,
744 .gpio_config = TDA10046_GP01_I,
922 .if_freq = TDA10046_FREQ_045, 745 .if_freq = TDA10046_FREQ_045,
923 .request_firmware = NULL, 746 .i2c_gate = 0x4b,
747 .tuner_address = 0x61,
748 .tuner_config = 0,
749 .request_firmware = philips_tda1004x_request_firmware
924}; 750};
925 751
926/* ------------------------------------------------------------------ */ 752static struct tda1004x_config cinergy_ht_pci_config = {
753 .demod_address = 0x08,
754 .invert = 1,
755 .invert_oclk = 0,
756 .xtal_freq = TDA10046_XTAL_16M,
757 .agc_config = TDA10046_AGC_TDA827X,
758 .gpio_config = TDA10046_GP01_I,
759 .if_freq = TDA10046_FREQ_045,
760 .i2c_gate = 0x4b,
761 .tuner_address = 0x60,
762 .tuner_config = 0,
763 .request_firmware = philips_tda1004x_request_firmware
764};
927 765
928static struct tda1004x_config pinnacle_pctv_310i_config = { 766static struct tda1004x_config philips_tiger_s_config = {
929 .demod_address = 0x08, 767 .demod_address = 0x08,
930 .invert = 1, 768 .invert = 1,
931 .invert_oclk = 0, 769 .invert_oclk = 0,
932 .xtal_freq = TDA10046_XTAL_16M, 770 .xtal_freq = TDA10046_XTAL_16M,
933 .agc_config = TDA10046_AGC_TDA827X_GP11, 771 .agc_config = TDA10046_AGC_TDA827X,
772 .gpio_config = TDA10046_GP01_I,
934 .if_freq = TDA10046_FREQ_045, 773 .if_freq = TDA10046_FREQ_045,
935 .request_firmware = philips_tda1004x_request_firmware, 774 .i2c_gate = 0x4b,
775 .tuner_address = 0x61,
776 .tuner_config = 2,
777 .antenna_switch= 1,
778 .request_firmware = philips_tda1004x_request_firmware
936}; 779};
937 780
938/* ------------------------------------------------------------------ */ 781static struct tda1004x_config pinnacle_pctv_310i_config = {
782 .demod_address = 0x08,
783 .invert = 1,
784 .invert_oclk = 0,
785 .xtal_freq = TDA10046_XTAL_16M,
786 .agc_config = TDA10046_AGC_TDA827X,
787 .gpio_config = TDA10046_GP11_I,
788 .if_freq = TDA10046_FREQ_045,
789 .i2c_gate = 0x4b,
790 .tuner_address = 0x61,
791 .tuner_config = 1,
792 .request_firmware = philips_tda1004x_request_firmware
793};
939 794
940static struct tda1004x_config hauppauge_hvr_1110_config = { 795static struct tda1004x_config hauppauge_hvr_1110_config = {
941 .demod_address = 0x08, 796 .demod_address = 0x08,
942 .invert = 1, 797 .invert = 1,
943 .invert_oclk = 0, 798 .invert_oclk = 0,
944 .xtal_freq = TDA10046_XTAL_16M, 799 .xtal_freq = TDA10046_XTAL_16M,
945 .agc_config = TDA10046_AGC_TDA827X_GP11, 800 .agc_config = TDA10046_AGC_TDA827X,
801 .gpio_config = TDA10046_GP11_I,
946 .if_freq = TDA10046_FREQ_045, 802 .if_freq = TDA10046_FREQ_045,
947 .request_firmware = philips_tda1004x_request_firmware, 803 .i2c_gate = 0x4b,
804 .tuner_address = 0x61,
805 .request_firmware = philips_tda1004x_request_firmware
948}; 806};
949 807
950/* ------------------------------------------------------------------ */
951
952static struct tda1004x_config asus_p7131_dual_config = { 808static struct tda1004x_config asus_p7131_dual_config = {
953 .demod_address = 0x08, 809 .demod_address = 0x08,
954 .invert = 1, 810 .invert = 1,
955 .invert_oclk = 0, 811 .invert_oclk = 0,
956 .xtal_freq = TDA10046_XTAL_16M, 812 .xtal_freq = TDA10046_XTAL_16M,
957 .agc_config = TDA10046_AGC_TDA827X_GP11, 813 .agc_config = TDA10046_AGC_TDA827X,
814 .gpio_config = TDA10046_GP11_I,
958 .if_freq = TDA10046_FREQ_045, 815 .if_freq = TDA10046_FREQ_045,
959 .request_firmware = philips_tda1004x_request_firmware, 816 .i2c_gate = 0x4b,
817 .tuner_address = 0x61,
818 .tuner_config = 0,
819 .antenna_switch= 2,
820 .request_firmware = philips_tda1004x_request_firmware
960}; 821};
961 822
962static int asus_p7131_dual_tuner_init(struct dvb_frontend *fe)
963{
964 struct saa7134_dev *dev = fe->dvb->priv;
965 static u8 data[] = { 0x3c, 0x33, 0x6a};
966 struct i2c_msg msg = {.addr=0x08, .flags=0, .buf=data, .len = sizeof(data)};
967
968 if (i2c_transfer(&dev->i2c_adap, &msg, 1) != 1)
969 return -EIO;
970 /* make sure the DVB-T antenna input is set */
971 saa_setl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x0200000);
972 return 0;
973}
974
975static int asus_p7131_dual_tuner_sleep(struct dvb_frontend *fe)
976{
977 struct saa7134_dev *dev = fe->dvb->priv;
978 static u8 data[] = { 0x3c, 0x33, 0x68};
979 struct i2c_msg msg = {.addr=0x08, .flags=0, .buf=data, .len = sizeof(data)};
980
981 i2c_transfer(&dev->i2c_adap, &msg, 1);
982 philips_tda827xa_tuner_sleep( 0x61, fe);
983 /* reset antenna inputs for analog usage */
984 saa_clearl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x0200000);
985 return 0;
986}
987
988/* ------------------------------------------------------------------ */
989
990static int lifeview_trio_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
991{
992 int ret;
993
994 ret = philips_tda827xa_pll_set(0x60, fe, params);
995 return ret;
996}
997
998static int lifeview_trio_tuner_sleep(struct dvb_frontend *fe)
999{
1000 philips_tda827xa_tuner_sleep(0x60, fe);
1001 return 0;
1002}
1003
1004static struct tda1004x_config lifeview_trio_config = { 823static struct tda1004x_config lifeview_trio_config = {
1005 .demod_address = 0x09, 824 .demod_address = 0x09,
1006 .invert = 1, 825 .invert = 1,
1007 .invert_oclk = 0, 826 .invert_oclk = 0,
1008 .xtal_freq = TDA10046_XTAL_16M, 827 .xtal_freq = TDA10046_XTAL_16M,
1009 .agc_config = TDA10046_AGC_TDA827X_GP00, 828 .agc_config = TDA10046_AGC_TDA827X,
829 .gpio_config = TDA10046_GP00_I,
1010 .if_freq = TDA10046_FREQ_045, 830 .if_freq = TDA10046_FREQ_045,
1011 .request_firmware = NULL, 831 .tuner_address = 0x60,
832 .request_firmware = philips_tda1004x_request_firmware
1012}; 833};
1013 834
1014/* ------------------------------------------------------------------ */ 835static struct tda1004x_config tevion_dvbt220rf_config = {
1015
1016static int ads_duo_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
1017{
1018 int ret;
1019
1020 ret = philips_tda827xa_pll_set(0x61, fe, params);
1021 return ret;
1022}
1023
1024static int ads_duo_tuner_init(struct dvb_frontend *fe)
1025{
1026 struct saa7134_dev *dev = fe->dvb->priv;
1027 /* route TDA8275a AGC input to the channel decoder */
1028 saa_writeb(SAA7134_GPIO_GPSTATUS2, 0x60);
1029 return 0;
1030}
1031
1032static int ads_duo_tuner_sleep(struct dvb_frontend *fe)
1033{
1034 struct saa7134_dev *dev = fe->dvb->priv;
1035 /* route TDA8275a AGC input to the analog IF chip*/
1036 saa_writeb(SAA7134_GPIO_GPSTATUS2, 0x20);
1037 philips_tda827xa_tuner_sleep( 0x61, fe);
1038 return 0;
1039}
1040
1041static struct tda1004x_config ads_tech_duo_config = {
1042 .demod_address = 0x08, 836 .demod_address = 0x08,
1043 .invert = 1, 837 .invert = 1,
1044 .invert_oclk = 0, 838 .invert_oclk = 0,
1045 .xtal_freq = TDA10046_XTAL_16M, 839 .xtal_freq = TDA10046_XTAL_16M,
1046 .agc_config = TDA10046_AGC_TDA827X_GP00, 840 .agc_config = TDA10046_AGC_TDA827X,
841 .gpio_config = TDA10046_GP11_I,
1047 .if_freq = TDA10046_FREQ_045, 842 .if_freq = TDA10046_FREQ_045,
1048 .request_firmware = NULL, 843 .tuner_address = 0x60,
844 .request_firmware = philips_tda1004x_request_firmware
1049}; 845};
1050 846
1051/* ------------------------------------------------------------------ */ 847static struct tda1004x_config md8800_dvbt_config = {
1052 848 .demod_address = 0x08,
1053static int tevion_dvb220rf_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) 849 .invert = 1,
1054{ 850 .invert_oclk = 0,
1055 int ret; 851 .xtal_freq = TDA10046_XTAL_16M,
1056 ret = philips_tda827xa_pll_set(0x60, fe, params); 852 .agc_config = TDA10046_AGC_TDA827X,
1057 return ret; 853 .gpio_config = TDA10046_GP01_I,
1058} 854 .if_freq = TDA10046_FREQ_045,
1059 855 .i2c_gate = 0x4b,
1060static int tevion_dvb220rf_tuner_sleep(struct dvb_frontend *fe) 856 .tuner_address = 0x60,
1061{ 857 .tuner_config = 0,
1062 philips_tda827xa_tuner_sleep( 0x61, fe); 858 .request_firmware = philips_tda1004x_request_firmware
1063 return 0; 859};
1064}
1065 860
1066static struct tda1004x_config tevion_dvbt220rf_config = { 861static struct tda1004x_config asus_p7131_4871_config = {
1067 .demod_address = 0x08, 862 .demod_address = 0x08,
1068 .invert = 1, 863 .invert = 1,
1069 .invert_oclk = 0, 864 .invert_oclk = 0,
1070 .xtal_freq = TDA10046_XTAL_16M, 865 .xtal_freq = TDA10046_XTAL_16M,
1071 .agc_config = TDA10046_AGC_TDA827X_GP11, 866 .agc_config = TDA10046_AGC_TDA827X,
867 .gpio_config = TDA10046_GP01_I,
1072 .if_freq = TDA10046_FREQ_045, 868 .if_freq = TDA10046_FREQ_045,
1073 .request_firmware = NULL, 869 .i2c_gate = 0x4b,
870 .tuner_address = 0x61,
871 .tuner_config = 2,
872 .antenna_switch= 2,
873 .request_firmware = philips_tda1004x_request_firmware
1074}; 874};
1075 875
1076/* ------------------------------------------------------------------ */ 876static struct tda1004x_config asus_p7131_hybrid_lna_config = {
877 .demod_address = 0x08,
878 .invert = 1,
879 .invert_oclk = 0,
880 .xtal_freq = TDA10046_XTAL_16M,
881 .agc_config = TDA10046_AGC_TDA827X,
882 .gpio_config = TDA10046_GP11_I,
883 .if_freq = TDA10046_FREQ_045,
884 .i2c_gate = 0x4b,
885 .tuner_address = 0x61,
886 .tuner_config = 2,
887 .antenna_switch= 2,
888 .request_firmware = philips_tda1004x_request_firmware
889};
890/* ------------------------------------------------------------------
891 * special case: this card uses saa713x GPIO22 for the mode switch
892 */
1077 893
1078static int md8800_dvbt_analog_mode(struct dvb_frontend *fe) 894static int ads_duo_tuner_init(struct dvb_frontend *fe)
1079{ 895{
1080 struct saa7134_dev *dev = fe->dvb->priv; 896 struct saa7134_dev *dev = fe->dvb->priv;
1081 static u8 data[] = { 0x3c, 0x33, 0x68}; 897 philips_tda827x_tuner_init(fe);
1082 struct i2c_msg msg = {.addr=0x08, .flags=0, .buf=data, .len = sizeof(data)}; 898 /* route TDA8275a AGC input to the channel decoder */
1083 899 saa7134_set_gpio(dev, 22, 1);
1084 i2c_transfer(&dev->i2c_adap, &msg, 1);
1085 philips_tda827xa_tuner_sleep( 0x61, fe);
1086 return 0; 900 return 0;
1087} 901}
1088 902
1089static int md8800_dvbt_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) 903static int ads_duo_tuner_sleep(struct dvb_frontend *fe)
1090{ 904{
1091 int ret;
1092 struct saa7134_dev *dev = fe->dvb->priv; 905 struct saa7134_dev *dev = fe->dvb->priv;
1093 static u8 tda8290_close[] = { 0x21, 0xc0}; 906 /* route TDA8275a AGC input to the analog IF chip*/
1094 static u8 tda8290_open[] = { 0x21, 0x80}; 907 saa7134_set_gpio(dev, 22, 0);
1095 struct i2c_msg tda8290_msg = {.addr = 0x4b,.flags = 0, .len = 2}; 908 philips_tda827x_tuner_sleep(fe);
1096 /* close tda8290 i2c bridge */ 909 return 0;
1097 tda8290_msg.buf = tda8290_close;
1098 ret = i2c_transfer(&dev->i2c_adap, &tda8290_msg, 1);
1099 if (ret != 1)
1100 return -EIO;
1101 msleep(20);
1102 ret = philips_tda827xa_pll_set(0x60, fe, params);
1103 if (ret != 0)
1104 return ret;
1105 /* open tda8290 i2c bridge */
1106 tda8290_msg.buf = tda8290_open;
1107 i2c_transfer(&dev->i2c_adap, &tda8290_msg, 1);
1108 return ret;
1109} 910}
1110 911
1111static struct tda1004x_config md8800_dvbt_config = { 912static struct tda827x_config ads_duo_cfg = {
913 .lna_gain = philips_tda827x_lna_gain,
914 .init = ads_duo_tuner_init,
915 .sleep = ads_duo_tuner_sleep
916};
917
918static struct tda1004x_config ads_tech_duo_config = {
1112 .demod_address = 0x08, 919 .demod_address = 0x08,
1113 .invert = 1, 920 .invert = 1,
1114 .invert_oclk = 0, 921 .invert_oclk = 0,
1115 .xtal_freq = TDA10046_XTAL_16M, 922 .xtal_freq = TDA10046_XTAL_16M,
1116 .agc_config = TDA10046_AGC_TDA827X_GP11, 923 .agc_config = TDA10046_AGC_TDA827X,
924 .gpio_config = TDA10046_GP00_I,
1117 .if_freq = TDA10046_FREQ_045, 925 .if_freq = TDA10046_FREQ_045,
1118 .request_firmware = NULL, 926 .tuner_address = 0x61,
927 .request_firmware = philips_tda1004x_request_firmware
1119}; 928};
1120 929
930/* ==================================================================
931 * tda10086 based DVB-S cards, helper functions
932 */
933
1121static struct tda10086_config flydvbs = { 934static struct tda10086_config flydvbs = {
1122 .demod_address = 0x0e, 935 .demod_address = 0x0e,
1123 .invert = 0, 936 .invert = 0,
1124}; 937};
1125 938
1126/* ------------------------------------------------------------------ */ 939/* ==================================================================
940 * nxt200x based ATSC cards, helper functions
941 */
1127 942
1128static struct nxt200x_config avertvhda180 = { 943static struct nxt200x_config avertvhda180 = {
1129 .demod_address = 0x0a, 944 .demod_address = 0x0a,
@@ -1143,10 +958,13 @@ static struct nxt200x_config kworldatsc110 = {
1143 .set_pll_input = nxt200x_set_pll_input, 958 .set_pll_input = nxt200x_set_pll_input,
1144}; 959};
1145 960
1146/* ------------------------------------------------------------------ */ 961/* ==================================================================
962 * Core code
963 */
1147 964
1148static int dvb_init(struct saa7134_dev *dev) 965static int dvb_init(struct saa7134_dev *dev)
1149{ 966{
967 int ret;
1150 /* init struct videobuf_dvb */ 968 /* init struct videobuf_dvb */
1151 dev->ts.nr_bufs = 32; 969 dev->ts.nr_bufs = 32;
1152 dev->ts.nr_packets = 32*4; 970 dev->ts.nr_packets = 32*4;
@@ -1160,7 +978,7 @@ static int dvb_init(struct saa7134_dev *dev)
1160 978
1161 switch (dev->board) { 979 switch (dev->board) {
1162 case SAA7134_BOARD_PINNACLE_300I_DVBT_PAL: 980 case SAA7134_BOARD_PINNACLE_300I_DVBT_PAL:
1163 printk("%s: pinnacle 300i dvb setup\n",dev->name); 981 dprintk("pinnacle 300i dvb setup\n");
1164 dev->dvb.frontend = dvb_attach(mt352_attach, &pinnacle_300i, 982 dev->dvb.frontend = dvb_attach(mt352_attach, &pinnacle_300i,
1165 &dev->i2c_adap); 983 &dev->i2c_adap);
1166 if (dev->dvb.frontend) { 984 if (dev->dvb.frontend) {
@@ -1169,7 +987,7 @@ static int dvb_init(struct saa7134_dev *dev)
1169 break; 987 break;
1170 case SAA7134_BOARD_AVERMEDIA_777: 988 case SAA7134_BOARD_AVERMEDIA_777:
1171 case SAA7134_BOARD_AVERMEDIA_A16AR: 989 case SAA7134_BOARD_AVERMEDIA_A16AR:
1172 printk("%s: avertv 777 dvb setup\n",dev->name); 990 dprintk("avertv 777 dvb setup\n");
1173 dev->dvb.frontend = dvb_attach(mt352_attach, &avermedia_777, 991 dev->dvb.frontend = dvb_attach(mt352_attach, &avermedia_777,
1174 &dev->i2c_adap); 992 &dev->i2c_adap);
1175 if (dev->dvb.frontend) { 993 if (dev->dvb.frontend) {
@@ -1191,42 +1009,15 @@ static int dvb_init(struct saa7134_dev *dev)
1191 &philips_tu1216_60_config, 1009 &philips_tu1216_60_config,
1192 &dev->i2c_adap); 1010 &dev->i2c_adap);
1193 if (dev->dvb.frontend) { 1011 if (dev->dvb.frontend) {
1194 dev->dvb.frontend->ops.tuner_ops.init = philips_tu1216_tuner_60_init; 1012 dev->dvb.frontend->ops.tuner_ops.init = philips_tu1216_init;
1195 dev->dvb.frontend->ops.tuner_ops.set_params = philips_tu1216_tuner_60_set_params; 1013 dev->dvb.frontend->ops.tuner_ops.set_params = philips_tda6651_pll_set;
1196 } 1014 }
1197 break; 1015 break;
1198 case SAA7134_BOARD_FLYDVBTDUO: 1016 case SAA7134_BOARD_FLYDVBTDUO:
1199 dev->dvb.frontend = dvb_attach(tda10046_attach,
1200 &tda827x_lifeview_config,
1201 &dev->i2c_adap);
1202 if (dev->dvb.frontend) {
1203 dev->dvb.frontend->ops.tuner_ops.init = philips_tda827x_tuner_init;
1204 dev->dvb.frontend->ops.tuner_ops.sleep = philips_tda827x_tuner_sleep;
1205 dev->dvb.frontend->ops.tuner_ops.set_params = philips_tda827x_tuner_set_params;
1206 }
1207 break;
1208 case SAA7134_BOARD_FLYDVBT_DUO_CARDBUS: 1017 case SAA7134_BOARD_FLYDVBT_DUO_CARDBUS:
1209 dev->dvb.frontend = dvb_attach(tda10046_attach, 1018 configure_tda827x_fe(dev, &tda827x_lifeview_config);
1210 &tda827x_lifeview_config,
1211 &dev->i2c_adap);
1212 if (dev->dvb.frontend) {
1213 dev->dvb.frontend->ops.tuner_ops.init = philips_tda827x_tuner_init;
1214 dev->dvb.frontend->ops.tuner_ops.sleep = philips_tda827x_tuner_sleep;
1215 dev->dvb.frontend->ops.tuner_ops.set_params = philips_tda827x_tuner_set_params;
1216 }
1217 break; 1019 break;
1218 case SAA7134_BOARD_PHILIPS_EUROPA: 1020 case SAA7134_BOARD_PHILIPS_EUROPA:
1219 dev->dvb.frontend = dvb_attach(tda10046_attach,
1220 &philips_europa_config,
1221 &dev->i2c_adap);
1222 if (dev->dvb.frontend) {
1223 dev->original_demod_sleep = dev->dvb.frontend->ops.sleep;
1224 dev->dvb.frontend->ops.sleep = philips_europa_demod_sleep;
1225 dev->dvb.frontend->ops.tuner_ops.init = philips_europa_tuner_init;
1226 dev->dvb.frontend->ops.tuner_ops.sleep = philips_europa_tuner_sleep;
1227 dev->dvb.frontend->ops.tuner_ops.set_params = philips_td1316_tuner_set_params;
1228 }
1229 break;
1230 case SAA7134_BOARD_VIDEOMATE_DVBT_300: 1021 case SAA7134_BOARD_VIDEOMATE_DVBT_300:
1231 dev->dvb.frontend = dvb_attach(tda10046_attach, 1022 dev->dvb.frontend = dvb_attach(tda10046_attach,
1232 &philips_europa_config, 1023 &philips_europa_config,
@@ -1244,125 +1035,61 @@ static int dvb_init(struct saa7134_dev *dev)
1244 &philips_tu1216_61_config, 1035 &philips_tu1216_61_config,
1245 &dev->i2c_adap); 1036 &dev->i2c_adap);
1246 if (dev->dvb.frontend) { 1037 if (dev->dvb.frontend) {
1247 dev->dvb.frontend->ops.tuner_ops.init = philips_tu1216_tuner_61_init; 1038 dev->dvb.frontend->ops.tuner_ops.init = philips_tu1216_init;
1248 dev->dvb.frontend->ops.tuner_ops.set_params = philips_tu1216_tuner_61_set_params; 1039 dev->dvb.frontend->ops.tuner_ops.set_params = philips_tda6651_pll_set;
1249 } 1040 }
1250 break; 1041 break;
1251 case SAA7134_BOARD_PHILIPS_TIGER: 1042 case SAA7134_BOARD_PHILIPS_TIGER:
1252 dev->dvb.frontend = dvb_attach(tda10046_attach, 1043 configure_tda827x_fe(dev, &philips_tiger_config);
1253 &philips_tiger_config,
1254 &dev->i2c_adap);
1255 if (dev->dvb.frontend) {
1256 dev->dvb.frontend->ops.i2c_gate_ctrl = tda8290_i2c_gate_ctrl;
1257 dev->dvb.frontend->ops.tuner_ops.init = philips_tiger_tuner_init;
1258 dev->dvb.frontend->ops.tuner_ops.sleep = philips_tiger_tuner_sleep;
1259 dev->dvb.frontend->ops.tuner_ops.set_params = philips_tiger_tuner_set_params;
1260 }
1261 break; 1044 break;
1262 case SAA7134_BOARD_PINNACLE_PCTV_310i: 1045 case SAA7134_BOARD_PINNACLE_PCTV_310i:
1263 dev->dvb.frontend = dvb_attach(tda10046_attach, 1046 configure_tda827x_fe(dev, &pinnacle_pctv_310i_config);
1264 &pinnacle_pctv_310i_config,
1265 &dev->i2c_adap);
1266 if (dev->dvb.frontend) {
1267 dev->dvb.frontend->ops.i2c_gate_ctrl = tda8290_i2c_gate_ctrl;
1268 dev->dvb.frontend->ops.tuner_ops.init = philips_tiger_tuner_init;
1269 dev->dvb.frontend->ops.tuner_ops.sleep = philips_tiger_tuner_sleep;
1270 dev->dvb.frontend->ops.tuner_ops.set_params = philips_tiger_tuner_set_params;
1271 }
1272 break; 1047 break;
1273 case SAA7134_BOARD_HAUPPAUGE_HVR1110: 1048 case SAA7134_BOARD_HAUPPAUGE_HVR1110:
1274 dev->dvb.frontend = dvb_attach(tda10046_attach, 1049 configure_tda827x_fe(dev, &hauppauge_hvr_1110_config);
1275 &hauppauge_hvr_1110_config,
1276 &dev->i2c_adap);
1277 if (dev->dvb.frontend) {
1278 dev->dvb.frontend->ops.i2c_gate_ctrl = tda8290_i2c_gate_ctrl;
1279 dev->dvb.frontend->ops.tuner_ops.init = philips_tiger_tuner_init;
1280 dev->dvb.frontend->ops.tuner_ops.sleep = philips_tiger_tuner_sleep;
1281 dev->dvb.frontend->ops.tuner_ops.set_params = philips_tiger_tuner_set_params;
1282 }
1283 break; 1050 break;
1284 case SAA7134_BOARD_ASUSTeK_P7131_DUAL: 1051 case SAA7134_BOARD_ASUSTeK_P7131_DUAL:
1285 dev->dvb.frontend = dvb_attach(tda10046_attach, 1052 configure_tda827x_fe(dev, &asus_p7131_dual_config);
1286 &asus_p7131_dual_config,
1287 &dev->i2c_adap);
1288 if (dev->dvb.frontend) {
1289 dev->dvb.frontend->ops.i2c_gate_ctrl = tda8290_i2c_gate_ctrl;
1290 dev->dvb.frontend->ops.tuner_ops.init = asus_p7131_dual_tuner_init;
1291 dev->dvb.frontend->ops.tuner_ops.sleep = asus_p7131_dual_tuner_sleep;
1292 dev->dvb.frontend->ops.tuner_ops.set_params = philips_tiger_tuner_set_params;
1293 }
1294 break; 1053 break;
1295 case SAA7134_BOARD_FLYDVBT_LR301: 1054 case SAA7134_BOARD_FLYDVBT_LR301:
1296 dev->dvb.frontend = dvb_attach(tda10046_attach, 1055 configure_tda827x_fe(dev, &tda827x_lifeview_config);
1297 &tda827x_lifeview_config,
1298 &dev->i2c_adap);
1299 if (dev->dvb.frontend) {
1300 dev->dvb.frontend->ops.tuner_ops.init = philips_tda827x_tuner_init;
1301 dev->dvb.frontend->ops.tuner_ops.sleep = philips_tda827x_tuner_sleep;
1302 dev->dvb.frontend->ops.tuner_ops.set_params = philips_tda827x_tuner_set_params;
1303 }
1304 break; 1056 break;
1305 case SAA7134_BOARD_FLYDVB_TRIO: 1057 case SAA7134_BOARD_FLYDVB_TRIO:
1306 if(! use_frontend) { //terrestrial 1058 if(! use_frontend) { //terrestrial
1307 dev->dvb.frontend = dvb_attach(tda10046_attach, 1059 configure_tda827x_fe(dev, &lifeview_trio_config);
1308 &lifeview_trio_config,
1309 &dev->i2c_adap);
1310 if (dev->dvb.frontend) {
1311 dev->dvb.frontend->ops.tuner_ops.sleep = lifeview_trio_tuner_sleep;
1312 dev->dvb.frontend->ops.tuner_ops.set_params =
1313 lifeview_trio_tuner_set_params;
1314 }
1315 } else { //satellite 1060 } else { //satellite
1316 dev->dvb.frontend = dvb_attach(tda10086_attach, &flydvbs, &dev->i2c_adap); 1061 dev->dvb.frontend = dvb_attach(tda10086_attach, &flydvbs, &dev->i2c_adap);
1317 if (dev->dvb.frontend) { 1062 if (dev->dvb.frontend) {
1318 if (dvb_attach(tda826x_attach, dev->dvb.frontend, 0x63, 1063 if (dvb_attach(tda826x_attach, dev->dvb.frontend, 0x63,
1319 &dev->i2c_adap, 0) == NULL) { 1064 &dev->i2c_adap, 0) == NULL) {
1320 printk("%s: Lifeview Trio, No tda826x found!\n", __FUNCTION__); 1065 wprintk("%s: Lifeview Trio, No tda826x found!\n", __FUNCTION__);
1321 } 1066 }
1322 if (dvb_attach(isl6421_attach, dev->dvb.frontend, &dev->i2c_adap, 1067 if (dvb_attach(isl6421_attach, dev->dvb.frontend, &dev->i2c_adap,
1323 0x08, 0, 0) == NULL) { 1068 0x08, 0, 0) == NULL) {
1324 printk("%s: Lifeview Trio, No ISL6421 found!\n", __FUNCTION__); 1069 wprintk("%s: Lifeview Trio, No ISL6421 found!\n", __FUNCTION__);
1325 } 1070 }
1326 } 1071 }
1327 } 1072 }
1328 break; 1073 break;
1329 case SAA7134_BOARD_ADS_DUO_CARDBUS_PTV331: 1074 case SAA7134_BOARD_ADS_DUO_CARDBUS_PTV331:
1075 case SAA7134_BOARD_FLYDVBT_HYBRID_CARDBUS:
1330 dev->dvb.frontend = dvb_attach(tda10046_attach, 1076 dev->dvb.frontend = dvb_attach(tda10046_attach,
1331 &ads_tech_duo_config, 1077 &ads_tech_duo_config,
1332 &dev->i2c_adap); 1078 &dev->i2c_adap);
1333 if (dev->dvb.frontend) { 1079 if (dev->dvb.frontend) {
1334 dev->dvb.frontend->ops.tuner_ops.init = ads_duo_tuner_init; 1080 if (dvb_attach(tda827x_attach,dev->dvb.frontend,
1335 dev->dvb.frontend->ops.tuner_ops.sleep = ads_duo_tuner_sleep; 1081 ads_tech_duo_config.tuner_address,
1336 dev->dvb.frontend->ops.tuner_ops.set_params = ads_duo_tuner_set_params; 1082 &dev->i2c_adap,&ads_duo_cfg) == NULL) {
1083 wprintk("no tda827x tuner found at addr: %02x\n",
1084 ads_tech_duo_config.tuner_address);
1085 }
1337 } 1086 }
1338 break; 1087 break;
1339 case SAA7134_BOARD_TEVION_DVBT_220RF: 1088 case SAA7134_BOARD_TEVION_DVBT_220RF:
1340 dev->dvb.frontend = dvb_attach(tda10046_attach, 1089 configure_tda827x_fe(dev, &tevion_dvbt220rf_config);
1341 &tevion_dvbt220rf_config,
1342 &dev->i2c_adap);
1343 if (dev->dvb.frontend) {
1344 dev->dvb.frontend->ops.tuner_ops.sleep = tevion_dvb220rf_tuner_sleep;
1345 dev->dvb.frontend->ops.tuner_ops.set_params = tevion_dvb220rf_tuner_set_params;
1346 }
1347 break;
1348 case SAA7134_BOARD_FLYDVBT_HYBRID_CARDBUS:
1349 dev->dvb.frontend = dvb_attach(tda10046_attach,
1350 &ads_tech_duo_config,
1351 &dev->i2c_adap);
1352 if (dev->dvb.frontend) {
1353 dev->dvb.frontend->ops.tuner_ops.init = ads_duo_tuner_init;
1354 dev->dvb.frontend->ops.tuner_ops.sleep = ads_duo_tuner_sleep;
1355 dev->dvb.frontend->ops.tuner_ops.set_params = ads_duo_tuner_set_params;
1356 }
1357 break; 1090 break;
1358 case SAA7134_BOARD_MEDION_MD8800_QUADRO: 1091 case SAA7134_BOARD_MEDION_MD8800_QUADRO:
1359 dev->dvb.frontend = tda10046_attach(&md8800_dvbt_config, 1092 configure_tda827x_fe(dev, &md8800_dvbt_config);
1360 &dev->i2c_adap);
1361 if (dev->dvb.frontend) {
1362 dev->dvb.frontend->ops.tuner_ops.init = philips_tiger_tuner_init;
1363 dev->dvb.frontend->ops.tuner_ops.sleep = md8800_dvbt_analog_mode;
1364 dev->dvb.frontend->ops.tuner_ops.set_params = md8800_dvbt_pll_set;
1365 }
1366 break; 1093 break;
1367 case SAA7134_BOARD_AVERMEDIA_AVERTVHD_A180: 1094 case SAA7134_BOARD_AVERMEDIA_AVERTVHD_A180:
1368 dev->dvb.frontend = dvb_attach(nxt200x_attach, &avertvhda180, 1095 dev->dvb.frontend = dvb_attach(nxt200x_attach, &avertvhda180,
@@ -1386,11 +1113,11 @@ static int dvb_init(struct saa7134_dev *dev)
1386 if (dev->dvb.frontend) { 1113 if (dev->dvb.frontend) {
1387 if (dvb_attach(tda826x_attach, dev->dvb.frontend, 0x60, 1114 if (dvb_attach(tda826x_attach, dev->dvb.frontend, 0x60,
1388 &dev->i2c_adap, 0) == NULL) { 1115 &dev->i2c_adap, 0) == NULL) {
1389 printk("%s: No tda826x found!\n", __FUNCTION__); 1116 wprintk("%s: No tda826x found!\n", __FUNCTION__);
1390 } 1117 }
1391 if (dvb_attach(isl6421_attach, dev->dvb.frontend, 1118 if (dvb_attach(isl6421_attach, dev->dvb.frontend,
1392 &dev->i2c_adap, 0x08, 0, 0) == NULL) { 1119 &dev->i2c_adap, 0x08, 0, 0) == NULL) {
1393 printk("%s: No ISL6421 found!\n", __FUNCTION__); 1120 wprintk("%s: No ISL6421 found!\n", __FUNCTION__);
1394 } 1121 }
1395 } 1122 }
1396 break; 1123 break;
@@ -1415,41 +1142,45 @@ static int dvb_init(struct saa7134_dev *dev)
1415 } 1142 }
1416 break; 1143 break;
1417 case SAA7134_BOARD_CINERGY_HT_PCMCIA: 1144 case SAA7134_BOARD_CINERGY_HT_PCMCIA:
1418 dev->dvb.frontend = dvb_attach(tda10046_attach, 1145 configure_tda827x_fe(dev, &cinergy_ht_config);
1419 &cinergy_ht_config,
1420 &dev->i2c_adap);
1421 if (dev->dvb.frontend) {
1422 dev->dvb.frontend->ops.i2c_gate_ctrl = tda8290_i2c_gate_ctrl;
1423 dev->dvb.frontend->ops.tuner_ops.init = cinergy_ht_tuner_init;
1424 dev->dvb.frontend->ops.tuner_ops.sleep = cinergy_ht_tuner_sleep;
1425 dev->dvb.frontend->ops.tuner_ops.set_params = philips_tiger_tuner_set_params;
1426
1427 }
1428 break; 1146 break;
1429 case SAA7134_BOARD_CINERGY_HT_PCI: 1147 case SAA7134_BOARD_CINERGY_HT_PCI:
1430 dev->dvb.frontend = dvb_attach(tda10046_attach, 1148 configure_tda827x_fe(dev, &cinergy_ht_pci_config);
1431 &cinergy_ht_config, 1149 break;
1432 &dev->i2c_adap); 1150 case SAA7134_BOARD_PHILIPS_TIGER_S:
1433 if (dev->dvb.frontend) { 1151 configure_tda827x_fe(dev, &philips_tiger_s_config);
1434 dev->dvb.frontend->ops.i2c_gate_ctrl = tda8290_i2c_gate_ctrl; 1152 break;
1435 dev->dvb.frontend->ops.tuner_ops.init = cinergy_ht_tuner_init; 1153 case SAA7134_BOARD_ASUS_P7131_4871:
1436 dev->dvb.frontend->ops.tuner_ops.sleep = cinergy_ht_tuner_sleep; 1154 configure_tda827x_fe(dev, &asus_p7131_4871_config);
1437 dev->dvb.frontend->ops.tuner_ops.set_params = md8800_dvbt_pll_set; 1155 break;
1438 1156 case SAA7134_BOARD_ASUSTeK_P7131_HYBRID_LNA:
1439 } 1157 configure_tda827x_fe(dev, &asus_p7131_hybrid_lna_config);
1440 break; 1158 break;
1441 default: 1159 default:
1442 printk("%s: Huh? unknown DVB card?\n",dev->name); 1160 wprintk("Huh? unknown DVB card?\n");
1443 break; 1161 break;
1444 } 1162 }
1445 1163
1446 if (NULL == dev->dvb.frontend) { 1164 if (NULL == dev->dvb.frontend) {
1447 printk("%s: frontend initialization failed\n",dev->name); 1165 printk(KERN_ERR "%s/dvb: frontend initialization failed\n", dev->name);
1448 return -1; 1166 return -1;
1449 } 1167 }
1450 1168
1451 /* register everything else */ 1169 /* register everything else */
1452 return videobuf_dvb_register(&dev->dvb, THIS_MODULE, dev, &dev->pci->dev); 1170 ret = videobuf_dvb_register(&dev->dvb, THIS_MODULE, dev, &dev->pci->dev);
1171
1172 /* this sequence is necessary to make the tda1004x load its firmware
1173 * and to enter analog mode of hybrid boards
1174 */
1175 if (!ret) {
1176 if (dev->dvb.frontend->ops.init)
1177 dev->dvb.frontend->ops.init(dev->dvb.frontend);
1178 if (dev->dvb.frontend->ops.sleep)
1179 dev->dvb.frontend->ops.sleep(dev->dvb.frontend);
1180 if (dev->dvb.frontend->ops.tuner_ops.sleep)
1181 dev->dvb.frontend->ops.tuner_ops.sleep(dev->dvb.frontend);
1182 }
1183 return ret;
1453} 1184}
1454 1185
1455static int dvb_fini(struct saa7134_dev *dev) 1186static int dvb_fini(struct saa7134_dev *dev)
diff --git a/drivers/media/video/saa7134/saa7134-i2c.c b/drivers/media/video/saa7134/saa7134-i2c.c
index cce8da6a4f94..1cb8c709ca90 100644
--- a/drivers/media/video/saa7134/saa7134-i2c.c
+++ b/drivers/media/video/saa7134/saa7134-i2c.c
@@ -370,6 +370,8 @@ static int attach_inform(struct i2c_client *client)
370 370
371 tun_setup.type = tuner; 371 tun_setup.type = tuner;
372 tun_setup.addr = saa7134_boards[dev->board].tuner_addr; 372 tun_setup.addr = saa7134_boards[dev->board].tuner_addr;
373 tun_setup.config = saa7134_boards[dev->board].tuner_config;
374 tun_setup.tuner_callback = saa7134_tuner_callback;
373 375
374 if ((tun_setup.addr == ADDR_UNSET)||(tun_setup.addr == client->addr)) { 376 if ((tun_setup.addr == ADDR_UNSET)||(tun_setup.addr == client->addr)) {
375 377
@@ -445,7 +447,7 @@ static void do_i2c_scan(char *name, struct i2c_client *c)
445 unsigned char buf; 447 unsigned char buf;
446 int i,rc; 448 int i,rc;
447 449
448 for (i = 0; i < 128; i++) { 450 for (i = 0; i < ARRAY_SIZE(i2c_devs); i++) {
449 c->addr = i; 451 c->addr = i;
450 rc = i2c_master_recv(c,&buf,0); 452 rc = i2c_master_recv(c,&buf,0);
451 if (rc < 0) 453 if (rc < 0)
diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c
index 46c583f1e788..c0de37e3f5c6 100644
--- a/drivers/media/video/saa7134/saa7134-input.c
+++ b/drivers/media/video/saa7134/saa7134-input.c
@@ -321,6 +321,7 @@ int saa7134_input_init1(struct saa7134_dev *dev)
321 mask_keydown = 0x0040000; 321 mask_keydown = 0x0040000;
322 break; 322 break;
323 case SAA7134_BOARD_ASUSTeK_P7131_DUAL: 323 case SAA7134_BOARD_ASUSTeK_P7131_DUAL:
324 case SAA7134_BOARD_ASUSTeK_P7131_HYBRID_LNA:
324 ir_codes = ir_codes_asus_pc39; 325 ir_codes = ir_codes_asus_pc39;
325 mask_keydown = 0x0040000; 326 mask_keydown = 0x0040000;
326 rc5_gpio = 1; 327 rc5_gpio = 1;
diff --git a/drivers/media/video/saa7134/saa7134-video.c b/drivers/media/video/saa7134/saa7134-video.c
index f2cb63053041..9985ded20950 100644
--- a/drivers/media/video/saa7134/saa7134-video.c
+++ b/drivers/media/video/saa7134/saa7134-video.c
@@ -26,6 +26,7 @@
26#include <linux/moduleparam.h> 26#include <linux/moduleparam.h>
27#include <linux/kernel.h> 27#include <linux/kernel.h>
28#include <linux/slab.h> 28#include <linux/slab.h>
29#include <linux/sort.h>
29 30
30#include "saa7134-reg.h" 31#include "saa7134-reg.h"
31#include "saa7134.h" 32#include "saa7134.h"
@@ -516,14 +517,12 @@ static int res_get(struct saa7134_dev *dev, struct saa7134_fh *fh, unsigned int
516 return 1; 517 return 1;
517} 518}
518 519
519static 520static int res_check(struct saa7134_fh *fh, unsigned int bit)
520int res_check(struct saa7134_fh *fh, unsigned int bit)
521{ 521{
522 return (fh->resources & bit); 522 return (fh->resources & bit);
523} 523}
524 524
525static 525static int res_locked(struct saa7134_dev *dev, unsigned int bit)
526int res_locked(struct saa7134_dev *dev, unsigned int bit)
527{ 526{
528 return (dev->resources & bit); 527 return (dev->resources & bit);
529} 528}
@@ -603,7 +602,14 @@ static void set_tvnorm(struct saa7134_dev *dev, struct saa7134_tvnorm *norm)
603 saa_writeb(SAA7134_RAW_DATA_GAIN, 0x40); 602 saa_writeb(SAA7134_RAW_DATA_GAIN, 0x40);
604 saa_writeb(SAA7134_RAW_DATA_OFFSET, 0x80); 603 saa_writeb(SAA7134_RAW_DATA_OFFSET, 0x80);
605 604
606 saa7134_i2c_call_clients(dev,VIDIOC_S_STD,&norm->id); 605 /* only tell the tuner if this is a tv input */
606 if (card_in(dev,dev->ctl_input).tv) {
607 if ((card(dev).tuner_type == TUNER_PHILIPS_TDA8290)
608 && ((card(dev).tuner_config == 1)
609 || (card(dev).tuner_config == 2)))
610 saa7134_set_gpio(dev, 22, 5);
611 saa7134_i2c_call_clients(dev,VIDIOC_S_STD,&norm->id);
612 }
607} 613}
608 614
609static void video_mux(struct saa7134_dev *dev, int input) 615static void video_mux(struct saa7134_dev *dev, int input)
@@ -732,25 +738,6 @@ struct cliplist {
732 __u8 disable; 738 __u8 disable;
733}; 739};
734 740
735static void sort_cliplist(struct cliplist *cl, int entries)
736{
737 struct cliplist swap;
738 int i,j,n;
739
740 for (i = entries-2; i >= 0; i--) {
741 for (n = 0, j = 0; j <= i; j++) {
742 if (cl[j].position > cl[j+1].position) {
743 swap = cl[j];
744 cl[j] = cl[j+1];
745 cl[j+1] = swap;
746 n++;
747 }
748 }
749 if (0 == n)
750 break;
751 }
752}
753
754static void set_cliplist(struct saa7134_dev *dev, int reg, 741static void set_cliplist(struct saa7134_dev *dev, int reg,
755 struct cliplist *cl, int entries, char *name) 742 struct cliplist *cl, int entries, char *name)
756{ 743{
@@ -784,15 +771,27 @@ static int clip_range(int val)
784 return val; 771 return val;
785} 772}
786 773
774/* Sort into smallest position first order */
775static int cliplist_cmp(const void *a, const void *b)
776{
777 const struct cliplist *cla = a;
778 const struct cliplist *clb = b;
779 if (cla->position < clb->position)
780 return -1;
781 if (cla->position > clb->position)
782 return 1;
783 return 0;
784}
785
787static int setup_clipping(struct saa7134_dev *dev, struct v4l2_clip *clips, 786static int setup_clipping(struct saa7134_dev *dev, struct v4l2_clip *clips,
788 int nclips, int interlace) 787 int nclips, int interlace)
789{ 788{
790 struct cliplist col[16], row[16]; 789 struct cliplist col[16], row[16];
791 int cols, rows, i; 790 int cols = 0, rows = 0, i;
792 int div = interlace ? 2 : 1; 791 int div = interlace ? 2 : 1;
793 792
794 memset(col,0,sizeof(col)); cols = 0; 793 memset(col, 0, sizeof(col));
795 memset(row,0,sizeof(row)); rows = 0; 794 memset(row, 0, sizeof(row));
796 for (i = 0; i < nclips && i < 8; i++) { 795 for (i = 0; i < nclips && i < 8; i++) {
797 col[cols].position = clip_range(clips[i].c.left); 796 col[cols].position = clip_range(clips[i].c.left);
798 col[cols].enable = (1 << i); 797 col[cols].enable = (1 << i);
@@ -808,8 +807,8 @@ static int setup_clipping(struct saa7134_dev *dev, struct v4l2_clip *clips,
808 row[rows].disable = (1 << i); 807 row[rows].disable = (1 << i);
809 rows++; 808 rows++;
810 } 809 }
811 sort_cliplist(col,cols); 810 sort(col, cols, sizeof col[0], cliplist_cmp, NULL);
812 sort_cliplist(row,rows); 811 sort(row, rows, sizeof row[0], cliplist_cmp, NULL);
813 set_cliplist(dev,0x380,col,cols,"cols"); 812 set_cliplist(dev,0x380,col,cols,"cols");
814 set_cliplist(dev,0x384,row,rows,"rows"); 813 set_cliplist(dev,0x384,row,rows,"rows");
815 return 0; 814 return 0;
@@ -1261,19 +1260,14 @@ static struct videobuf_queue* saa7134_queue(struct saa7134_fh *fh)
1261 1260
1262static int saa7134_resource(struct saa7134_fh *fh) 1261static int saa7134_resource(struct saa7134_fh *fh)
1263{ 1262{
1264 int res = 0; 1263 if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
1264 return RESOURCE_VIDEO;
1265 1265
1266 switch (fh->type) { 1266 if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE)
1267 case V4L2_BUF_TYPE_VIDEO_CAPTURE: 1267 return RESOURCE_VBI;
1268 res = RESOURCE_VIDEO; 1268
1269 break; 1269 BUG();
1270 case V4L2_BUF_TYPE_VBI_CAPTURE: 1270 return 0;
1271 res = RESOURCE_VBI;
1272 break;
1273 default:
1274 BUG();
1275 }
1276 return res;
1277} 1271}
1278 1272
1279static int video_open(struct inode *inode, struct file *file) 1273static int video_open(struct inode *inode, struct file *file)
@@ -1461,8 +1455,7 @@ static int video_release(struct inode *inode, struct file *file)
1461 return 0; 1455 return 0;
1462} 1456}
1463 1457
1464static int 1458static int video_mmap(struct file *file, struct vm_area_struct * vma)
1465video_mmap(struct file *file, struct vm_area_struct * vma)
1466{ 1459{
1467 struct saa7134_fh *fh = file->private_data; 1460 struct saa7134_fh *fh = file->private_data;
1468 1461
@@ -2461,12 +2454,6 @@ int saa7134_video_init2(struct saa7134_dev *dev)
2461 return 0; 2454 return 0;
2462} 2455}
2463 2456
2464int saa7134_video_fini(struct saa7134_dev *dev)
2465{
2466 /* nothing */
2467 return 0;
2468}
2469
2470void saa7134_irq_video_intl(struct saa7134_dev *dev) 2457void saa7134_irq_video_intl(struct saa7134_dev *dev)
2471{ 2458{
2472 static const char *st[] = { 2459 static const char *st[] = {
diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h
index b3e3957c89b5..62224cc958f1 100644
--- a/drivers/media/video/saa7134/saa7134.h
+++ b/drivers/media/video/saa7134/saa7134.h
@@ -231,6 +231,10 @@ struct saa7134_format {
231#define SAA7134_BOARD_ENCORE_ENLTV 106 231#define SAA7134_BOARD_ENCORE_ENLTV 106
232#define SAA7134_BOARD_ENCORE_ENLTV_FM 107 232#define SAA7134_BOARD_ENCORE_ENLTV_FM 107
233#define SAA7134_BOARD_CINERGY_HT_PCI 108 233#define SAA7134_BOARD_CINERGY_HT_PCI 108
234#define SAA7134_BOARD_PHILIPS_TIGER_S 109
235#define SAA7134_BOARD_AVERMEDIA_M102 110
236#define SAA7134_BOARD_ASUS_P7131_4871 111
237#define SAA7134_BOARD_ASUSTeK_P7131_HYBRID_LNA 112
234 238
235#define SAA7134_MAXBOARDS 8 239#define SAA7134_MAXBOARDS 8
236#define SAA7134_INPUT_MAX 8 240#define SAA7134_INPUT_MAX 8
@@ -280,6 +284,7 @@ struct saa7134_board {
280 unsigned char radio_addr; 284 unsigned char radio_addr;
281 285
282 unsigned int tda9887_conf; 286 unsigned int tda9887_conf;
287 unsigned int tuner_config;
283 288
284 /* peripheral I/O */ 289 /* peripheral I/O */
285 enum saa7134_video_out video_out; 290 enum saa7134_video_out video_out;
@@ -435,6 +440,8 @@ struct saa7134_dev {
435#ifdef VIDIOC_G_PRIORITY 440#ifdef VIDIOC_G_PRIORITY
436 struct v4l2_prio_state prio; 441 struct v4l2_prio_state prio;
437#endif 442#endif
443 /* workstruct for loading modules */
444 struct work_struct request_module_wk;
438 445
439 /* insmod option/autodetected */ 446 /* insmod option/autodetected */
440 int autodetected; 447 int autodetected;
@@ -562,6 +569,8 @@ extern struct list_head saa7134_devlist;
562extern int saa7134_no_overlay; 569extern int saa7134_no_overlay;
563 570
564void saa7134_track_gpio(struct saa7134_dev *dev, char *msg); 571void saa7134_track_gpio(struct saa7134_dev *dev, char *msg);
572void saa7134_set_gpio(struct saa7134_dev *dev, int bit_no, int value);
573int saa7134_tuner_callback(void *ptr, int command, int arg);
565 574
566#define SAA7134_PGTABLE_SIZE 4096 575#define SAA7134_PGTABLE_SIZE 4096
567 576
@@ -620,7 +629,6 @@ int saa7134_common_ioctl(struct saa7134_dev *dev,
620 629
621int saa7134_video_init1(struct saa7134_dev *dev); 630int saa7134_video_init1(struct saa7134_dev *dev);
622int saa7134_video_init2(struct saa7134_dev *dev); 631int saa7134_video_init2(struct saa7134_dev *dev);
623int saa7134_video_fini(struct saa7134_dev *dev);
624void saa7134_irq_video_intl(struct saa7134_dev *dev); 632void saa7134_irq_video_intl(struct saa7134_dev *dev);
625void saa7134_irq_video_done(struct saa7134_dev *dev, unsigned long status); 633void saa7134_irq_video_done(struct saa7134_dev *dev, unsigned long status);
626 634
diff --git a/drivers/media/video/se401.c b/drivers/media/video/se401.c
index 038448f5a978..93fb04ed99a0 100644
--- a/drivers/media/video/se401.c
+++ b/drivers/media/video/se401.c
@@ -450,6 +450,13 @@ static int se401_start_stream(struct usb_se401 *se401)
450 } 450 }
451 for (i=0; i<SE401_NUMSBUF; i++) { 451 for (i=0; i<SE401_NUMSBUF; i++) {
452 se401->sbuf[i].data=kmalloc(SE401_PACKETSIZE, GFP_KERNEL); 452 se401->sbuf[i].data=kmalloc(SE401_PACKETSIZE, GFP_KERNEL);
453 if (!se401->sbuf[i].data) {
454 for(i = i - 1; i >= 0; i--) {
455 kfree(se401->sbuf[i].data);
456 se401->sbuf[i].data = NULL;
457 }
458 return -ENOMEM;
459 }
453 } 460 }
454 461
455 se401->bayeroffset=0; 462 se401->bayeroffset=0;
@@ -458,13 +465,26 @@ static int se401_start_stream(struct usb_se401 *se401)
458 se401->scratch_overflow=0; 465 se401->scratch_overflow=0;
459 for (i=0; i<SE401_NUMSCRATCH; i++) { 466 for (i=0; i<SE401_NUMSCRATCH; i++) {
460 se401->scratch[i].data=kmalloc(SE401_PACKETSIZE, GFP_KERNEL); 467 se401->scratch[i].data=kmalloc(SE401_PACKETSIZE, GFP_KERNEL);
468 if (!se401->scratch[i].data) {
469 for(i = i - 1; i >= 0; i--) {
470 kfree(se401->scratch[i].data);
471 se401->scratch[i].data = NULL;
472 }
473 goto nomem_sbuf;
474 }
461 se401->scratch[i].state=BUFFER_UNUSED; 475 se401->scratch[i].state=BUFFER_UNUSED;
462 } 476 }
463 477
464 for (i=0; i<SE401_NUMSBUF; i++) { 478 for (i=0; i<SE401_NUMSBUF; i++) {
465 urb=usb_alloc_urb(0, GFP_KERNEL); 479 urb=usb_alloc_urb(0, GFP_KERNEL);
466 if(!urb) 480 if(!urb) {
467 return -ENOMEM; 481 for(i = i - 1; i >= 0; i--) {
482 usb_kill_urb(se401->urb[i]);
483 usb_free_urb(se401->urb[i]);
484 se401->urb[i] = NULL;
485 }
486 goto nomem_scratch;
487 }
468 488
469 usb_fill_bulk_urb(urb, se401->dev, 489 usb_fill_bulk_urb(urb, se401->dev,
470 usb_rcvbulkpipe(se401->dev, SE401_VIDEO_ENDPOINT), 490 usb_rcvbulkpipe(se401->dev, SE401_VIDEO_ENDPOINT),
@@ -482,6 +502,18 @@ static int se401_start_stream(struct usb_se401 *se401)
482 se401->framecount=0; 502 se401->framecount=0;
483 503
484 return 0; 504 return 0;
505
506 nomem_scratch:
507 for (i=0; i<SE401_NUMSCRATCH; i++) {
508 kfree(se401->scratch[i].data);
509 se401->scratch[i].data = NULL;
510 }
511 nomem_sbuf:
512 for (i=0; i<SE401_NUMSBUF; i++) {
513 kfree(se401->sbuf[i].data);
514 se401->sbuf[i].data = NULL;
515 }
516 return -ENOMEM;
485} 517}
486 518
487static int se401_stop_stream(struct usb_se401 *se401) 519static int se401_stop_stream(struct usb_se401 *se401)
diff --git a/drivers/media/video/sn9c102/Kconfig b/drivers/media/video/sn9c102/Kconfig
index 1a7ccb666ab0..19204f5686e1 100644
--- a/drivers/media/video/sn9c102/Kconfig
+++ b/drivers/media/video/sn9c102/Kconfig
@@ -1,6 +1,6 @@
1config USB_SN9C102 1config USB_SN9C102
2 tristate "USB SN9C1xx PC Camera Controller support" 2 tristate "USB SN9C1xx PC Camera Controller support"
3 depends on USB && VIDEO_V4L1 3 depends on USB && VIDEO_V4L2
4 ---help--- 4 ---help---
5 Say Y here if you want support for cameras based on SONiX SN9C101, 5 Say Y here if you want support for cameras based on SONiX SN9C101,
6 SN9C102, SN9C103, SN9C105 and SN9C120 PC Camera Controllers. 6 SN9C102, SN9C103, SN9C105 and SN9C120 PC Camera Controllers.
diff --git a/drivers/media/video/sn9c102/Makefile b/drivers/media/video/sn9c102/Makefile
index 30e3dfe537fe..a56d16f69c71 100644
--- a/drivers/media/video/sn9c102/Makefile
+++ b/drivers/media/video/sn9c102/Makefile
@@ -1,7 +1,14 @@
1sn9c102-objs := sn9c102_core.o sn9c102_hv7131d.o sn9c102_mi0343.o \ 1sn9c102-objs := sn9c102_core.o \
2 sn9c102_ov7630.o sn9c102_ov7660.o sn9c102_pas106b.o \ 2 sn9c102_hv7131d.o \
3 sn9c102_pas202bcb.o sn9c102_tas5110c1b.o \ 3 sn9c102_hv7131r.o \
4 sn9c102_tas5130d1b.o 4 sn9c102_mi0343.o \
5 sn9c102_mi0360.o \
6 sn9c102_ov7630.o \
7 sn9c102_ov7660.o \
8 sn9c102_pas106b.o \
9 sn9c102_pas202bcb.o \
10 sn9c102_tas5110c1b.o \
11 sn9c102_tas5110d.o \
12 sn9c102_tas5130d1b.o
5 13
6obj-$(CONFIG_USB_SN9C102) += sn9c102.o 14obj-$(CONFIG_USB_SN9C102) += sn9c102.o
7
diff --git a/drivers/media/video/sn9c102/sn9c102.h b/drivers/media/video/sn9c102/sn9c102.h
index 5428f34e7c5b..680e74634527 100644
--- a/drivers/media/video/sn9c102/sn9c102.h
+++ b/drivers/media/video/sn9c102/sn9c102.h
@@ -78,8 +78,13 @@ enum sn9c102_stream_state {
78 78
79typedef char sn9c102_sof_header_t[62]; 79typedef char sn9c102_sof_header_t[62];
80 80
81struct sn9c102_sof_t {
82 sn9c102_sof_header_t header;
83 u16 bytesread;
84};
85
81struct sn9c102_sysfs_attr { 86struct sn9c102_sysfs_attr {
82 u8 reg, i2c_reg; 87 u16 reg, i2c_reg;
83 sn9c102_sof_header_t frame_header; 88 sn9c102_sof_header_t frame_header;
84}; 89};
85 90
@@ -112,7 +117,7 @@ struct sn9c102_device {
112 struct v4l2_jpegcompression compression; 117 struct v4l2_jpegcompression compression;
113 118
114 struct sn9c102_sysfs_attr sysfs; 119 struct sn9c102_sysfs_attr sysfs;
115 sn9c102_sof_header_t sof_header; 120 struct sn9c102_sof_t sof;
116 u16 reg[384]; 121 u16 reg[384];
117 122
118 struct sn9c102_module_param module_param; 123 struct sn9c102_module_param module_param;
@@ -182,8 +187,8 @@ do { \
182 if ((level) == 1 || (level) == 2) \ 187 if ((level) == 1 || (level) == 2) \
183 pr_info("sn9c102: " fmt "\n", ## args); \ 188 pr_info("sn9c102: " fmt "\n", ## args); \
184 else if ((level) == 3) \ 189 else if ((level) == 3) \
185 pr_debug("sn9c102: [%s:%d] " fmt "\n", __FUNCTION__, \ 190 pr_debug("sn9c102: [%s:%d] " fmt "\n", \
186 __LINE__ , ## args); \ 191 __FUNCTION__, __LINE__ , ## args); \
187 } \ 192 } \
188} while (0) 193} while (0)
189#else 194#else
@@ -194,8 +199,8 @@ do { \
194 199
195#undef PDBG 200#undef PDBG
196#define PDBG(fmt, args...) \ 201#define PDBG(fmt, args...) \
197dev_info(&cam->usbdev->dev, "[%s:%d] " fmt "\n", \ 202dev_info(&cam->usbdev->dev, "[%s:%s:%d] " fmt "\n", __FILE__, __FUNCTION__, \
198 __FUNCTION__, __LINE__ , ## args) 203 __LINE__ , ## args)
199 204
200#undef PDBGG 205#undef PDBGG
201#define PDBGG(fmt, args...) do {;} while(0) /* placeholder */ 206#define PDBGG(fmt, args...) do {;} while(0) /* placeholder */
diff --git a/drivers/media/video/sn9c102/sn9c102_core.c b/drivers/media/video/sn9c102/sn9c102_core.c
index d0e2b40a7725..89f83354de3b 100644
--- a/drivers/media/video/sn9c102/sn9c102_core.c
+++ b/drivers/media/video/sn9c102/sn9c102_core.c
@@ -44,11 +44,12 @@
44/*****************************************************************************/ 44/*****************************************************************************/
45 45
46#define SN9C102_MODULE_NAME "V4L2 driver for SN9C1xx PC Camera Controllers" 46#define SN9C102_MODULE_NAME "V4L2 driver for SN9C1xx PC Camera Controllers"
47#define SN9C102_MODULE_AUTHOR "(C) 2004-2006 Luca Risolia" 47#define SN9C102_MODULE_ALIAS "sn9c1xx"
48#define SN9C102_MODULE_AUTHOR "(C) 2004-2007 Luca Risolia"
48#define SN9C102_AUTHOR_EMAIL "<luca.risolia@studio.unibo.it>" 49#define SN9C102_AUTHOR_EMAIL "<luca.risolia@studio.unibo.it>"
49#define SN9C102_MODULE_LICENSE "GPL" 50#define SN9C102_MODULE_LICENSE "GPL"
50#define SN9C102_MODULE_VERSION "1:1.34" 51#define SN9C102_MODULE_VERSION "1:1.39"
51#define SN9C102_MODULE_VERSION_CODE KERNEL_VERSION(1, 1, 34) 52#define SN9C102_MODULE_VERSION_CODE KERNEL_VERSION(1, 1, 39)
52 53
53/*****************************************************************************/ 54/*****************************************************************************/
54 55
@@ -56,6 +57,7 @@ MODULE_DEVICE_TABLE(usb, sn9c102_id_table);
56 57
57MODULE_AUTHOR(SN9C102_MODULE_AUTHOR " " SN9C102_AUTHOR_EMAIL); 58MODULE_AUTHOR(SN9C102_MODULE_AUTHOR " " SN9C102_AUTHOR_EMAIL);
58MODULE_DESCRIPTION(SN9C102_MODULE_NAME); 59MODULE_DESCRIPTION(SN9C102_MODULE_NAME);
60MODULE_ALIAS(SN9C102_MODULE_ALIAS);
59MODULE_VERSION(SN9C102_MODULE_VERSION); 61MODULE_VERSION(SN9C102_MODULE_VERSION);
60MODULE_LICENSE(SN9C102_MODULE_LICENSE); 62MODULE_LICENSE(SN9C102_MODULE_LICENSE);
61 63
@@ -106,8 +108,7 @@ MODULE_PARM_DESC(debug,
106 "\n1 = critical errors" 108 "\n1 = critical errors"
107 "\n2 = significant informations" 109 "\n2 = significant informations"
108 "\n3 = more verbose messages" 110 "\n3 = more verbose messages"
109 "\nLevel 3 is useful for testing only, when only " 111 "\nLevel 3 is useful for testing only."
110 "one device is used."
111 "\nDefault value is "__MODULE_STRING(SN9C102_DEBUG_LEVEL)"." 112 "\nDefault value is "__MODULE_STRING(SN9C102_DEBUG_LEVEL)"."
112 "\n"); 113 "\n");
113#endif 114#endif
@@ -121,8 +122,8 @@ sn9c102_request_buffers(struct sn9c102_device* cam, u32 count,
121 struct v4l2_pix_format* p = &(cam->sensor.pix_format); 122 struct v4l2_pix_format* p = &(cam->sensor.pix_format);
122 struct v4l2_rect* r = &(cam->sensor.cropcap.bounds); 123 struct v4l2_rect* r = &(cam->sensor.cropcap.bounds);
123 size_t imagesize = cam->module_param.force_munmap || io == IO_READ ? 124 size_t imagesize = cam->module_param.force_munmap || io == IO_READ ?
124 (p->width * p->height * p->priv) / 8 : 125 (p->width * p->height * p->priv) / 8 :
125 (r->width * r->height * p->priv) / 8; 126 (r->width * r->height * p->priv) / 8;
126 void* buff = NULL; 127 void* buff = NULL;
127 u32 i; 128 u32 i;
128 129
@@ -208,27 +209,40 @@ static void sn9c102_queue_unusedframes(struct sn9c102_device* cam)
208} 209}
209 210
210/*****************************************************************************/ 211/*****************************************************************************/
211 212/*
212int sn9c102_write_regs(struct sn9c102_device* cam, u8* buff, u16 index) 213 * Write a sequence of count value/register pairs. Returns -1 after the
214 * first failed write, or 0 for no errors.
215 */
216int sn9c102_write_regs(struct sn9c102_device* cam, const u8 valreg[][2],
217 int count)
213{ 218{
214 struct usb_device* udev = cam->usbdev; 219 struct usb_device* udev = cam->usbdev;
220 u8* value = cam->control_buffer; /* Needed for DMA'able memory */
215 int i, res; 221 int i, res;
216 222
217 if (index + sizeof(buff) >= ARRAY_SIZE(cam->reg)) 223 for (i = 0; i < count; i++) {
218 return -1; 224 u8 index = valreg[i][1];
225
226 /*
227 * index is a u8, so it must be <256 and can't be out of range.
228 * If we put in a check anyway, gcc annoys us with a warning
229 * that our check is useless. People get all uppity when they
230 * see warnings in the kernel compile.
231 */
232
233 *value = valreg[i][0];
234 res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
235 0x08, 0x41, index, 0,
236 value, 1, SN9C102_CTRL_TIMEOUT);
237 if (res < 0) {
238 DBG(3, "Failed to write a register (value 0x%02X, "
239 "index 0x%02X, error %d)", *value, index, res);
240 return -1;
241 }
219 242
220 res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x08, 0x41, 243 cam->reg[index] = *value;
221 index, 0, buff, sizeof(buff),
222 SN9C102_CTRL_TIMEOUT*sizeof(buff));
223 if (res < 0) {
224 DBG(3, "Failed to write registers (index 0x%02X, error %d)",
225 index, res);
226 return -1;
227 } 244 }
228 245
229 for (i = 0; i < sizeof(buff); i++)
230 cam->reg[index+i] = buff[i];
231
232 return 0; 246 return 0;
233} 247}
234 248
@@ -485,18 +499,43 @@ static size_t sn9c102_sof_length(struct sn9c102_device* cam)
485static void* 499static void*
486sn9c102_find_sof_header(struct sn9c102_device* cam, void* mem, size_t len) 500sn9c102_find_sof_header(struct sn9c102_device* cam, void* mem, size_t len)
487{ 501{
488 char sof_header[6] = {0xff, 0xff, 0x00, 0xc4, 0xc4, 0x96}; 502 static const char marker[6] = {0xff, 0xff, 0x00, 0xc4, 0xc4, 0x96};
489 size_t soflen = 0, i; 503 const char *m = mem;
504 size_t soflen = 0, i, j;
490 505
491 soflen = sn9c102_sof_length(cam); 506 soflen = sn9c102_sof_length(cam);
492 507
493 for (i = 0; (len >= soflen) && (i <= len - soflen); i++) 508 for (i = 0; i < len; i++) {
494 if (!memcmp(mem + i, sof_header, sizeof(sof_header))) { 509 size_t b;
495 memcpy(cam->sof_header, mem + i, 510
496 sizeof(sn9c102_sof_header_t)); 511 /* Read the variable part of the header */
497 /* Skip the header */ 512 if (unlikely(cam->sof.bytesread >= sizeof(marker))) {
498 return mem + i + soflen; 513 cam->sof.header[cam->sof.bytesread] = *(m+i);
514 if (++cam->sof.bytesread == soflen) {
515 cam->sof.bytesread = 0;
516 return mem + i;
517 }
518 continue;
519 }
520
521 /* Search for the SOF marker (fixed part) in the header */
522 for (j = 0, b=cam->sof.bytesread; j+b < sizeof(marker); j++) {
523 if (unlikely(i+j) == len)
524 return NULL;
525 if (*(m+i+j) == marker[cam->sof.bytesread]) {
526 cam->sof.header[cam->sof.bytesread] = *(m+i+j);
527 if (++cam->sof.bytesread == sizeof(marker)) {
528 PDBGG("Bytes to analyze: %zd. SOF "
529 "starts at byte #%zd", len, i);
530 i += j+1;
531 break;
532 }
533 } else {
534 cam->sof.bytesread = 0;
535 break;
499 } 536 }
537 }
538 }
500 539
501 return NULL; 540 return NULL;
502} 541}
@@ -505,7 +544,7 @@ sn9c102_find_sof_header(struct sn9c102_device* cam, void* mem, size_t len)
505static void* 544static void*
506sn9c102_find_eof_header(struct sn9c102_device* cam, void* mem, size_t len) 545sn9c102_find_eof_header(struct sn9c102_device* cam, void* mem, size_t len)
507{ 546{
508 char eof_header[4][4] = { 547 static const u8 eof_header[4][4] = {
509 {0x00, 0x00, 0x00, 0x00}, 548 {0x00, 0x00, 0x00, 0x00},
510 {0x40, 0x00, 0x00, 0x00}, 549 {0x40, 0x00, 0x00, 0x00},
511 {0x80, 0x00, 0x00, 0x00}, 550 {0x80, 0x00, 0x00, 0x00},
@@ -513,10 +552,16 @@ sn9c102_find_eof_header(struct sn9c102_device* cam, void* mem, size_t len)
513 }; 552 };
514 size_t i, j; 553 size_t i, j;
515 554
555 /* The EOF header does not exist in compressed data */
516 if (cam->sensor.pix_format.pixelformat == V4L2_PIX_FMT_SN9C10X || 556 if (cam->sensor.pix_format.pixelformat == V4L2_PIX_FMT_SN9C10X ||
517 cam->sensor.pix_format.pixelformat == V4L2_PIX_FMT_JPEG) 557 cam->sensor.pix_format.pixelformat == V4L2_PIX_FMT_JPEG)
518 return NULL; /* EOF header does not exist in compressed data */ 558 return NULL;
519 559
560 /*
561 The EOF header might cross the packet boundary, but this is not a
562 problem, since the end of a frame is determined by checking its size
563 in the first place.
564 */
520 for (i = 0; (len >= 4) && (i <= len - 4); i++) 565 for (i = 0; (len >= 4) && (i <= len - 4); i++)
521 for (j = 0; j < ARRAY_SIZE(eof_header); j++) 566 for (j = 0; j < ARRAY_SIZE(eof_header); j++)
522 if (!memcmp(mem + i, eof_header[j], 4)) 567 if (!memcmp(mem + i, eof_header[j], 4))
@@ -529,7 +574,7 @@ sn9c102_find_eof_header(struct sn9c102_device* cam, void* mem, size_t len)
529static void 574static void
530sn9c102_write_jpegheader(struct sn9c102_device* cam, struct sn9c102_frame_t* f) 575sn9c102_write_jpegheader(struct sn9c102_device* cam, struct sn9c102_frame_t* f)
531{ 576{
532 static u8 jpeg_header[589] = { 577 static const u8 jpeg_header[589] = {
533 0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x06, 0x04, 0x05, 578 0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x06, 0x04, 0x05,
534 0x06, 0x05, 0x04, 0x06, 0x06, 0x05, 0x06, 0x07, 0x07, 0x06, 579 0x06, 0x05, 0x04, 0x06, 0x06, 0x05, 0x06, 0x07, 0x07, 0x06,
535 0x08, 0x0a, 0x10, 0x0a, 0x0a, 0x09, 0x09, 0x0a, 0x14, 0x0e, 580 0x08, 0x0a, 0x10, 0x0a, 0x0a, 0x09, 0x09, 0x0a, 0x14, 0x0e,
@@ -639,6 +684,7 @@ static void sn9c102_urb_complete(struct urb *urb)
639 cam->stream = STREAM_OFF; 684 cam->stream = STREAM_OFF;
640 if ((*f)) 685 if ((*f))
641 (*f)->state = F_QUEUED; 686 (*f)->state = F_QUEUED;
687 cam->sof.bytesread = 0;
642 DBG(3, "Stream interrupted by application"); 688 DBG(3, "Stream interrupted by application");
643 wake_up(&cam->wait_stream); 689 wake_up(&cam->wait_stream);
644 } 690 }
@@ -676,6 +722,7 @@ static void sn9c102_urb_complete(struct urb *urb)
676 if (status) { 722 if (status) {
677 DBG(3, "Error in isochronous frame"); 723 DBG(3, "Error in isochronous frame");
678 (*f)->state = F_ERROR; 724 (*f)->state = F_ERROR;
725 cam->sof.bytesread = 0;
679 continue; 726 continue;
680 } 727 }
681 728
@@ -692,13 +739,13 @@ end_of_frame:
692 if (eof) 739 if (eof)
693 img = (eof > pos) ? eof - pos - 1 : 0; 740 img = (eof > pos) ? eof - pos - 1 : 0;
694 741
695 if ((*f)->buf.bytesused+img > imagesize) { 742 if ((*f)->buf.bytesused + img > imagesize) {
696 u32 b; 743 u32 b;
697 b = (*f)->buf.bytesused + img - 744 b = (*f)->buf.bytesused + img -
698 imagesize; 745 imagesize;
699 img = imagesize - (*f)->buf.bytesused; 746 img = imagesize - (*f)->buf.bytesused;
700 DBG(3, "Expected EOF not found: " 747 PDBGG("Expected EOF not found: video "
701 "video frame cut"); 748 "frame cut");
702 if (eof) 749 if (eof)
703 DBG(3, "Exceeded limit: +%u " 750 DBG(3, "Exceeded limit: +%u "
704 "bytes", (unsigned)(b)); 751 "bytes", (unsigned)(b));
@@ -719,11 +766,6 @@ end_of_frame:
719 V4L2_PIX_FMT_JPEG) && eof)) { 766 V4L2_PIX_FMT_JPEG) && eof)) {
720 u32 b; 767 u32 b;
721 768
722 if (cam->sensor.pix_format.pixelformat
723 == V4L2_PIX_FMT_JPEG)
724 sn9c102_write_eoimarker(cam,
725 (*f));
726
727 b = (*f)->buf.bytesused; 769 b = (*f)->buf.bytesused;
728 (*f)->state = F_DONE; 770 (*f)->state = F_DONE;
729 (*f)->buf.sequence= ++cam->frame_count; 771 (*f)->buf.sequence= ++cam->frame_count;
@@ -741,7 +783,7 @@ end_of_frame:
741 spin_unlock(&cam->queue_lock); 783 spin_unlock(&cam->queue_lock);
742 784
743 memcpy(cam->sysfs.frame_header, 785 memcpy(cam->sysfs.frame_header,
744 cam->sof_header, soflen); 786 cam->sof.header, soflen);
745 787
746 DBG(3, "Video frame captured: %lu " 788 DBG(3, "Video frame captured: %lu "
747 "bytes", (unsigned long)(b)); 789 "bytes", (unsigned long)(b));
@@ -791,7 +833,13 @@ start_of_frame:
791 V4L2_PIX_FMT_SN9C10X || 833 V4L2_PIX_FMT_SN9C10X ||
792 cam->sensor.pix_format.pixelformat == 834 cam->sensor.pix_format.pixelformat ==
793 V4L2_PIX_FMT_JPEG) { 835 V4L2_PIX_FMT_JPEG) {
794 eof = sof - soflen; 836 if (sof - pos >= soflen) {
837 eof = sof - soflen;
838 } else { /* remove header */
839 eof = pos;
840 (*f)->buf.bytesused -=
841 (soflen - (sof - pos));
842 }
795 goto end_of_frame; 843 goto end_of_frame;
796 } else { 844 } else {
797 DBG(3, "SOF before expected EOF after " 845 DBG(3, "SOF before expected EOF after "
@@ -878,6 +926,7 @@ static int sn9c102_start_transfer(struct sn9c102_device* cam)
878 } 926 }
879 927
880 cam->frame_current = NULL; 928 cam->frame_current = NULL;
929 cam->sof.bytesread = 0;
881 930
882 for (i = 0; i < SN9C102_URBS; i++) { 931 for (i = 0; i < SN9C102_URBS; i++) {
883 err = usb_submit_urb(cam->urb[i], GFP_KERNEL); 932 err = usb_submit_urb(cam->urb[i], GFP_KERNEL);
@@ -959,9 +1008,9 @@ static u16 sn9c102_strtou16(const char* buff, size_t len, ssize_t* count)
959 1008
960 if (len < 6) { 1009 if (len < 6) {
961 strncpy(str, buff, len); 1010 strncpy(str, buff, len);
962 str[len+1] = '\0'; 1011 str[len] = '\0';
963 } else { 1012 } else {
964 strncpy(str, buff, 4); 1013 strncpy(str, buff, 6);
965 str[6] = '\0'; 1014 str[6] = '\0';
966 } 1015 }
967 1016
@@ -1062,7 +1111,7 @@ static ssize_t sn9c102_show_val(struct class_device* cd, char* buf)
1062 1111
1063 count = sprintf(buf, "%d\n", val); 1112 count = sprintf(buf, "%d\n", val);
1064 1113
1065 DBG(3, "Read bytes: %zd", count); 1114 DBG(3, "Read bytes: %zd, value: %d", count, val);
1066 1115
1067 mutex_unlock(&sn9c102_sysfs_lock); 1116 mutex_unlock(&sn9c102_sysfs_lock);
1068 1117
@@ -1197,7 +1246,7 @@ static ssize_t sn9c102_show_i2c_val(struct class_device* cd, char* buf)
1197 1246
1198 count = sprintf(buf, "%d\n", val); 1247 count = sprintf(buf, "%d\n", val);
1199 1248
1200 DBG(3, "Read bytes: %zd", count); 1249 DBG(3, "Read bytes: %zd, value: %d", count, val);
1201 1250
1202 mutex_unlock(&sn9c102_sysfs_lock); 1251 mutex_unlock(&sn9c102_sysfs_lock);
1203 1252
@@ -1371,35 +1420,35 @@ static CLASS_DEVICE_ATTR(frame_header, S_IRUGO,
1371 1420
1372static int sn9c102_create_sysfs(struct sn9c102_device* cam) 1421static int sn9c102_create_sysfs(struct sn9c102_device* cam)
1373{ 1422{
1374 struct video_device *v4ldev = cam->v4ldev; 1423 struct class_device *classdev = &(cam->v4ldev->class_dev);
1375 int err = 0; 1424 int err = 0;
1376 1425
1377 if ((err = video_device_create_file(v4ldev, &class_device_attr_reg))) 1426 if ((err = class_device_create_file(classdev, &class_device_attr_reg)))
1378 goto err_out; 1427 goto err_out;
1379 if ((err = video_device_create_file(v4ldev, &class_device_attr_val))) 1428 if ((err = class_device_create_file(classdev, &class_device_attr_val)))
1380 goto err_reg; 1429 goto err_reg;
1381 if ((err = video_device_create_file(v4ldev, 1430 if ((err = class_device_create_file(classdev,
1382 &class_device_attr_frame_header))) 1431 &class_device_attr_frame_header)))
1383 goto err_val; 1432 goto err_val;
1384 1433
1385 if (cam->sensor.sysfs_ops) { 1434 if (cam->sensor.sysfs_ops) {
1386 if ((err = video_device_create_file(v4ldev, 1435 if ((err = class_device_create_file(classdev,
1387 &class_device_attr_i2c_reg))) 1436 &class_device_attr_i2c_reg)))
1388 goto err_frame_header; 1437 goto err_frame_header;
1389 if ((err = video_device_create_file(v4ldev, 1438 if ((err = class_device_create_file(classdev,
1390 &class_device_attr_i2c_val))) 1439 &class_device_attr_i2c_val)))
1391 goto err_i2c_reg; 1440 goto err_i2c_reg;
1392 } 1441 }
1393 1442
1394 if (cam->bridge == BRIDGE_SN9C101 || cam->bridge == BRIDGE_SN9C102) { 1443 if (cam->bridge == BRIDGE_SN9C101 || cam->bridge == BRIDGE_SN9C102) {
1395 if ((err = video_device_create_file(v4ldev, 1444 if ((err = class_device_create_file(classdev,
1396 &class_device_attr_green))) 1445 &class_device_attr_green)))
1397 goto err_i2c_val; 1446 goto err_i2c_val;
1398 } else { 1447 } else {
1399 if ((err = video_device_create_file(v4ldev, 1448 if ((err = class_device_create_file(classdev,
1400 &class_device_attr_blue))) 1449 &class_device_attr_blue)))
1401 goto err_i2c_val; 1450 goto err_i2c_val;
1402 if ((err = video_device_create_file(v4ldev, 1451 if ((err = class_device_create_file(classdev,
1403 &class_device_attr_red))) 1452 &class_device_attr_red)))
1404 goto err_blue; 1453 goto err_blue;
1405 } 1454 }
@@ -1407,19 +1456,19 @@ static int sn9c102_create_sysfs(struct sn9c102_device* cam)
1407 return 0; 1456 return 0;
1408 1457
1409err_blue: 1458err_blue:
1410 video_device_remove_file(v4ldev, &class_device_attr_blue); 1459 class_device_remove_file(classdev, &class_device_attr_blue);
1411err_i2c_val: 1460err_i2c_val:
1412 if (cam->sensor.sysfs_ops) 1461 if (cam->sensor.sysfs_ops)
1413 video_device_remove_file(v4ldev, &class_device_attr_i2c_val); 1462 class_device_remove_file(classdev, &class_device_attr_i2c_val);
1414err_i2c_reg: 1463err_i2c_reg:
1415 if (cam->sensor.sysfs_ops) 1464 if (cam->sensor.sysfs_ops)
1416 video_device_remove_file(v4ldev, &class_device_attr_i2c_reg); 1465 class_device_remove_file(classdev, &class_device_attr_i2c_reg);
1417err_frame_header: 1466err_frame_header:
1418 video_device_remove_file(v4ldev, &class_device_attr_frame_header); 1467 class_device_remove_file(classdev, &class_device_attr_frame_header);
1419err_val: 1468err_val:
1420 video_device_remove_file(v4ldev, &class_device_attr_val); 1469 class_device_remove_file(classdev, &class_device_attr_val);
1421err_reg: 1470err_reg:
1422 video_device_remove_file(v4ldev, &class_device_attr_reg); 1471 class_device_remove_file(classdev, &class_device_attr_reg);
1423err_out: 1472err_out:
1424 return err; 1473 return err;
1425} 1474}
@@ -1477,10 +1526,10 @@ sn9c102_set_compression(struct sn9c102_device* cam,
1477 case BRIDGE_SN9C101: 1526 case BRIDGE_SN9C101:
1478 case BRIDGE_SN9C102: 1527 case BRIDGE_SN9C102:
1479 case BRIDGE_SN9C103: 1528 case BRIDGE_SN9C103:
1480 if (compression->quality == 0) 1529 if (compression->quality == 0)
1481 err += sn9c102_write_reg(cam, cam->reg[0x17] | 0x01, 1530 err += sn9c102_write_reg(cam, cam->reg[0x17] | 0x01,
1482 0x17); 1531 0x17);
1483 else if (compression->quality == 1) 1532 else if (compression->quality == 1)
1484 err += sn9c102_write_reg(cam, cam->reg[0x17] & 0xfe, 1533 err += sn9c102_write_reg(cam, cam->reg[0x17] & 0xfe,
1485 0x17); 1534 0x17);
1486 break; 1535 break;
@@ -1489,10 +1538,10 @@ sn9c102_set_compression(struct sn9c102_device* cam,
1489 if (compression->quality == 0) { 1538 if (compression->quality == 0) {
1490 for (i = 0; i <= 63; i++) { 1539 for (i = 0; i <= 63; i++) {
1491 err += sn9c102_write_reg(cam, 1540 err += sn9c102_write_reg(cam,
1492 SN9C102_Y_QTABLE0[i], 1541 SN9C102_Y_QTABLE1[i],
1493 0x100 + i); 1542 0x100 + i);
1494 err += sn9c102_write_reg(cam, 1543 err += sn9c102_write_reg(cam,
1495 SN9C102_UV_QTABLE0[i], 1544 SN9C102_UV_QTABLE1[i],
1496 0x140 + i); 1545 0x140 + i);
1497 } 1546 }
1498 err += sn9c102_write_reg(cam, cam->reg[0x18] & 0xbf, 1547 err += sn9c102_write_reg(cam, cam->reg[0x18] & 0xbf,
@@ -1597,9 +1646,13 @@ static int sn9c102_init(struct sn9c102_device* cam)
1597 if (cam->bridge == BRIDGE_SN9C101 || 1646 if (cam->bridge == BRIDGE_SN9C101 ||
1598 cam->bridge == BRIDGE_SN9C102 || 1647 cam->bridge == BRIDGE_SN9C102 ||
1599 cam->bridge == BRIDGE_SN9C103) { 1648 cam->bridge == BRIDGE_SN9C103) {
1649 if (s->pix_format.pixelformat == V4L2_PIX_FMT_JPEG)
1650 s->pix_format.pixelformat= V4L2_PIX_FMT_SBGGR8;
1600 cam->compression.quality = cam->reg[0x17] & 0x01 ? 1651 cam->compression.quality = cam->reg[0x17] & 0x01 ?
1601 0 : 1; 1652 0 : 1;
1602 } else { 1653 } else {
1654 if (s->pix_format.pixelformat == V4L2_PIX_FMT_SN9C10X)
1655 s->pix_format.pixelformat = V4L2_PIX_FMT_JPEG;
1603 cam->compression.quality = cam->reg[0x18] & 0x40 ? 1656 cam->compression.quality = cam->reg[0x18] & 0x40 ?
1604 0 : 1; 1657 0 : 1;
1605 err += sn9c102_set_compression(cam, &cam->compression); 1658 err += sn9c102_set_compression(cam, &cam->compression);
@@ -1805,7 +1858,7 @@ sn9c102_read(struct file* filp, char __user * buf, size_t count, loff_t* f_pos)
1805 DBG(3, "Close and open the device again to choose " 1858 DBG(3, "Close and open the device again to choose "
1806 "the read method"); 1859 "the read method");
1807 mutex_unlock(&cam->fileop_mutex); 1860 mutex_unlock(&cam->fileop_mutex);
1808 return -EINVAL; 1861 return -EBUSY;
1809 } 1862 }
1810 1863
1811 if (cam->io == IO_NONE) { 1864 if (cam->io == IO_NONE) {
@@ -1845,16 +1898,16 @@ sn9c102_read(struct file* filp, char __user * buf, size_t count, loff_t* f_pos)
1845 return err; 1898 return err;
1846 } 1899 }
1847 } else { 1900 } else {
1848 timeout = wait_event_interruptible_timeout 1901 timeout = wait_event_interruptible_timeout
1849 ( cam->wait_frame, 1902 ( cam->wait_frame,
1850 (!list_empty(&cam->outqueue)) || 1903 (!list_empty(&cam->outqueue)) ||
1851 (cam->state & DEV_DISCONNECTED) || 1904 (cam->state & DEV_DISCONNECTED) ||
1852 (cam->state & DEV_MISCONFIGURED), 1905 (cam->state & DEV_MISCONFIGURED),
1853 cam->module_param.frame_timeout * 1906 cam->module_param.frame_timeout *
1854 1000 * msecs_to_jiffies(1) ); 1907 1000 * msecs_to_jiffies(1) );
1855 if (timeout < 0) { 1908 if (timeout < 0) {
1856 mutex_unlock(&cam->fileop_mutex); 1909 mutex_unlock(&cam->fileop_mutex);
1857 return timeout; 1910 return timeout;
1858 } else if (timeout == 0 && 1911 } else if (timeout == 0 &&
1859 !(cam->state & DEV_DISCONNECTED)) { 1912 !(cam->state & DEV_DISCONNECTED)) {
1860 DBG(1, "Video frame timeout elapsed"); 1913 DBG(1, "Video frame timeout elapsed");
@@ -2001,7 +2054,12 @@ static int sn9c102_mmap(struct file* filp, struct vm_area_struct *vma)
2001 return -EIO; 2054 return -EIO;
2002 } 2055 }
2003 2056
2004 if (cam->io != IO_MMAP || !(vma->vm_flags & VM_WRITE) || 2057 if (!(vma->vm_flags & (VM_WRITE | VM_READ))) {
2058 mutex_unlock(&cam->fileop_mutex);
2059 return -EACCES;
2060 }
2061
2062 if (cam->io != IO_MMAP ||
2005 size != PAGE_ALIGN(cam->frame[0].buf.length)) { 2063 size != PAGE_ALIGN(cam->frame[0].buf.length)) {
2006 mutex_unlock(&cam->fileop_mutex); 2064 mutex_unlock(&cam->fileop_mutex);
2007 return -EINVAL; 2065 return -EINVAL;
@@ -2267,7 +2325,7 @@ sn9c102_vidioc_s_crop(struct sn9c102_device* cam, void __user * arg)
2267 if (cam->frame[i].vma_use_count) { 2325 if (cam->frame[i].vma_use_count) {
2268 DBG(3, "VIDIOC_S_CROP failed. " 2326 DBG(3, "VIDIOC_S_CROP failed. "
2269 "Unmap the buffers first."); 2327 "Unmap the buffers first.");
2270 return -EINVAL; 2328 return -EBUSY;
2271 } 2329 }
2272 2330
2273 /* Preserve R,G or B origin */ 2331 /* Preserve R,G or B origin */
@@ -2410,8 +2468,8 @@ sn9c102_vidioc_enum_fmt(struct sn9c102_device* cam, void __user * arg)
2410 case BRIDGE_SN9C101: 2468 case BRIDGE_SN9C101:
2411 case BRIDGE_SN9C102: 2469 case BRIDGE_SN9C102:
2412 case BRIDGE_SN9C103: 2470 case BRIDGE_SN9C103:
2413 strcpy(fmtd.description, "compressed"); 2471 strcpy(fmtd.description, "compressed");
2414 fmtd.pixelformat = V4L2_PIX_FMT_SN9C10X; 2472 fmtd.pixelformat = V4L2_PIX_FMT_SN9C10X;
2415 break; 2473 break;
2416 case BRIDGE_SN9C105: 2474 case BRIDGE_SN9C105:
2417 case BRIDGE_SN9C120: 2475 case BRIDGE_SN9C120:
@@ -2445,8 +2503,10 @@ sn9c102_vidioc_g_fmt(struct sn9c102_device* cam, void __user * arg)
2445 if (format.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 2503 if (format.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
2446 return -EINVAL; 2504 return -EINVAL;
2447 2505
2448 pfmt->bytesperline = (pfmt->pixelformat==V4L2_PIX_FMT_SN9C10X || 2506 pfmt->colorspace = (pfmt->pixelformat == V4L2_PIX_FMT_JPEG) ?
2449 pfmt->pixelformat==V4L2_PIX_FMT_JPEG) 2507 V4L2_COLORSPACE_JPEG : V4L2_COLORSPACE_SRGB;
2508 pfmt->bytesperline = (pfmt->pixelformat == V4L2_PIX_FMT_SN9C10X ||
2509 pfmt->pixelformat == V4L2_PIX_FMT_JPEG)
2450 ? 0 : (pfmt->width * pfmt->priv) / 8; 2510 ? 0 : (pfmt->width * pfmt->priv) / 8;
2451 pfmt->sizeimage = pfmt->height * ((pfmt->width*pfmt->priv)/8); 2511 pfmt->sizeimage = pfmt->height * ((pfmt->width*pfmt->priv)/8);
2452 pfmt->field = V4L2_FIELD_NONE; 2512 pfmt->field = V4L2_FIELD_NONE;
@@ -2521,9 +2581,9 @@ sn9c102_vidioc_try_s_fmt(struct sn9c102_device* cam, unsigned int cmd,
2521 case BRIDGE_SN9C101: 2581 case BRIDGE_SN9C101:
2522 case BRIDGE_SN9C102: 2582 case BRIDGE_SN9C102:
2523 case BRIDGE_SN9C103: 2583 case BRIDGE_SN9C103:
2524 if (pix->pixelformat != V4L2_PIX_FMT_SN9C10X && 2584 if (pix->pixelformat != V4L2_PIX_FMT_SN9C10X &&
2525 pix->pixelformat != V4L2_PIX_FMT_SBGGR8) 2585 pix->pixelformat != V4L2_PIX_FMT_SBGGR8)
2526 pix->pixelformat = pfmt->pixelformat; 2586 pix->pixelformat = pfmt->pixelformat;
2527 break; 2587 break;
2528 case BRIDGE_SN9C105: 2588 case BRIDGE_SN9C105:
2529 case BRIDGE_SN9C120: 2589 case BRIDGE_SN9C120:
@@ -2533,7 +2593,8 @@ sn9c102_vidioc_try_s_fmt(struct sn9c102_device* cam, unsigned int cmd,
2533 break; 2593 break;
2534 } 2594 }
2535 pix->priv = pfmt->priv; /* bpp */ 2595 pix->priv = pfmt->priv; /* bpp */
2536 pix->colorspace = pfmt->colorspace; 2596 pix->colorspace = (pix->pixelformat == V4L2_PIX_FMT_JPEG) ?
2597 V4L2_COLORSPACE_JPEG : V4L2_COLORSPACE_SRGB;
2537 pix->bytesperline = (pix->pixelformat == V4L2_PIX_FMT_SN9C10X || 2598 pix->bytesperline = (pix->pixelformat == V4L2_PIX_FMT_SN9C10X ||
2538 pix->pixelformat == V4L2_PIX_FMT_JPEG) 2599 pix->pixelformat == V4L2_PIX_FMT_JPEG)
2539 ? 0 : (pix->width * pix->priv) / 8; 2600 ? 0 : (pix->width * pix->priv) / 8;
@@ -2551,7 +2612,7 @@ sn9c102_vidioc_try_s_fmt(struct sn9c102_device* cam, unsigned int cmd,
2551 if (cam->frame[i].vma_use_count) { 2612 if (cam->frame[i].vma_use_count) {
2552 DBG(3, "VIDIOC_S_FMT failed. Unmap the " 2613 DBG(3, "VIDIOC_S_FMT failed. Unmap the "
2553 "buffers first."); 2614 "buffers first.");
2554 return -EINVAL; 2615 return -EBUSY;
2555 } 2616 }
2556 2617
2557 if (cam->stream == STREAM_ON) 2618 if (cam->stream == STREAM_ON)
@@ -2666,14 +2727,14 @@ sn9c102_vidioc_reqbufs(struct sn9c102_device* cam, void __user * arg)
2666 if (cam->io == IO_READ) { 2727 if (cam->io == IO_READ) {
2667 DBG(3, "Close and open the device again to choose the mmap " 2728 DBG(3, "Close and open the device again to choose the mmap "
2668 "I/O method"); 2729 "I/O method");
2669 return -EINVAL; 2730 return -EBUSY;
2670 } 2731 }
2671 2732
2672 for (i = 0; i < cam->nbuffers; i++) 2733 for (i = 0; i < cam->nbuffers; i++)
2673 if (cam->frame[i].vma_use_count) { 2734 if (cam->frame[i].vma_use_count) {
2674 DBG(3, "VIDIOC_REQBUFS failed. Previous buffers are " 2735 DBG(3, "VIDIOC_REQBUFS failed. Previous buffers are "
2675 "still mapped."); 2736 "still mapped.");
2676 return -EINVAL; 2737 return -EBUSY;
2677 } 2738 }
2678 2739
2679 if (cam->stream == STREAM_ON) 2740 if (cam->stream == STREAM_ON)
@@ -2785,15 +2846,15 @@ sn9c102_vidioc_dqbuf(struct sn9c102_device* cam, struct file* filp,
2785 if (err) 2846 if (err)
2786 return err; 2847 return err;
2787 } else { 2848 } else {
2788 timeout = wait_event_interruptible_timeout 2849 timeout = wait_event_interruptible_timeout
2789 ( cam->wait_frame, 2850 ( cam->wait_frame,
2790 (!list_empty(&cam->outqueue)) || 2851 (!list_empty(&cam->outqueue)) ||
2791 (cam->state & DEV_DISCONNECTED) || 2852 (cam->state & DEV_DISCONNECTED) ||
2792 (cam->state & DEV_MISCONFIGURED), 2853 (cam->state & DEV_MISCONFIGURED),
2793 cam->module_param.frame_timeout * 2854 cam->module_param.frame_timeout *
2794 1000 * msecs_to_jiffies(1) ); 2855 1000 * msecs_to_jiffies(1) );
2795 if (timeout < 0) 2856 if (timeout < 0)
2796 return timeout; 2857 return timeout;
2797 else if (timeout == 0 && 2858 else if (timeout == 0 &&
2798 !(cam->state & DEV_DISCONNECTED)) { 2859 !(cam->state & DEV_DISCONNECTED)) {
2799 DBG(1, "Video frame timeout elapsed"); 2860 DBG(1, "Video frame timeout elapsed");
@@ -2837,9 +2898,6 @@ sn9c102_vidioc_streamon(struct sn9c102_device* cam, void __user * arg)
2837 if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE || cam->io != IO_MMAP) 2898 if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE || cam->io != IO_MMAP)
2838 return -EINVAL; 2899 return -EINVAL;
2839 2900
2840 if (list_empty(&cam->inqueue))
2841 return -EINVAL;
2842
2843 cam->stream = STREAM_ON; 2901 cam->stream = STREAM_ON;
2844 2902
2845 DBG(3, "Stream on"); 2903 DBG(3, "Stream on");
@@ -3166,8 +3224,8 @@ sn9c102_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
3166 3224
3167 r = sn9c102_read_reg(cam, 0x00); 3225 r = sn9c102_read_reg(cam, 0x00);
3168 if (r < 0 || (r != 0x10 && r != 0x11 && r != 0x12)) { 3226 if (r < 0 || (r != 0x10 && r != 0x11 && r != 0x12)) {
3169 DBG(1, "Sorry, this is not a SN9C1xx based camera " 3227 DBG(1, "Sorry, this is not a SN9C1xx-based camera "
3170 "(vid/pid 0x%04X:0x%04X)", id->idVendor, id->idProduct); 3228 "(vid:pid 0x%04X:0x%04X)", id->idVendor, id->idProduct);
3171 err = -ENODEV; 3229 err = -ENODEV;
3172 goto fail; 3230 goto fail;
3173 } 3231 }
@@ -3177,19 +3235,19 @@ sn9c102_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
3177 case BRIDGE_SN9C101: 3235 case BRIDGE_SN9C101:
3178 case BRIDGE_SN9C102: 3236 case BRIDGE_SN9C102:
3179 DBG(2, "SN9C10[12] PC Camera Controller detected " 3237 DBG(2, "SN9C10[12] PC Camera Controller detected "
3180 "(vid/pid 0x%04X:0x%04X)", id->idVendor, id->idProduct); 3238 "(vid:pid 0x%04X:0x%04X)", id->idVendor, id->idProduct);
3181 break; 3239 break;
3182 case BRIDGE_SN9C103: 3240 case BRIDGE_SN9C103:
3183 DBG(2, "SN9C103 PC Camera Controller detected " 3241 DBG(2, "SN9C103 PC Camera Controller detected "
3184 "(vid/pid 0x%04X:0x%04X)", id->idVendor, id->idProduct); 3242 "(vid:pid 0x%04X:0x%04X)", id->idVendor, id->idProduct);
3185 break; 3243 break;
3186 case BRIDGE_SN9C105: 3244 case BRIDGE_SN9C105:
3187 DBG(2, "SN9C105 PC Camera Controller detected " 3245 DBG(2, "SN9C105 PC Camera Controller detected "
3188 "(vid/pid 0x%04X:0x%04X)", id->idVendor, id->idProduct); 3246 "(vid:pid 0x%04X:0x%04X)", id->idVendor, id->idProduct);
3189 break; 3247 break;
3190 case BRIDGE_SN9C120: 3248 case BRIDGE_SN9C120:
3191 DBG(2, "SN9C120 PC Camera Controller detected " 3249 DBG(2, "SN9C120 PC Camera Controller detected "
3192 "(vid/pid 0x%04X:0x%04X)", id->idVendor, id->idProduct); 3250 "(vid:pid 0x%04X:0x%04X)", id->idVendor, id->idProduct);
3193 break; 3251 break;
3194 } 3252 }
3195 3253
@@ -3260,6 +3318,8 @@ sn9c102_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
3260 "device controlling. Error #%d", err); 3318 "device controlling. Error #%d", err);
3261#else 3319#else
3262 DBG(2, "Optional device control through 'sysfs' interface disabled"); 3320 DBG(2, "Optional device control through 'sysfs' interface disabled");
3321 DBG(3, "Compile the kernel with the 'CONFIG_VIDEO_ADV_DEBUG' "
3322 "configuration option to enable it.");
3263#endif 3323#endif
3264 3324
3265 usb_set_intfdata(intf, cam); 3325 usb_set_intfdata(intf, cam);
diff --git a/drivers/media/video/sn9c102/sn9c102_devtable.h b/drivers/media/video/sn9c102/sn9c102_devtable.h
index 3a682eca6c65..f49bd8c5b86e 100644
--- a/drivers/media/video/sn9c102/sn9c102_devtable.h
+++ b/drivers/media/video/sn9c102/sn9c102_devtable.h
@@ -89,16 +89,22 @@ static const struct usb_device_id sn9c102_id_table[] = {
89 { SN9C102_USB_DEVICE(0x0471, 0x0327, BRIDGE_SN9C105), }, 89 { SN9C102_USB_DEVICE(0x0471, 0x0327, BRIDGE_SN9C105), },
90 { SN9C102_USB_DEVICE(0x0471, 0x0328, BRIDGE_SN9C105), }, 90 { SN9C102_USB_DEVICE(0x0471, 0x0328, BRIDGE_SN9C105), },
91 { SN9C102_USB_DEVICE(0x0c45, 0x60c0, BRIDGE_SN9C105), }, 91 { SN9C102_USB_DEVICE(0x0c45, 0x60c0, BRIDGE_SN9C105), },
92 { SN9C102_USB_DEVICE(0x0c45, 0x60c2, BRIDGE_SN9C105), },
92 { SN9C102_USB_DEVICE(0x0c45, 0x60c8, BRIDGE_SN9C105), }, 93 { SN9C102_USB_DEVICE(0x0c45, 0x60c8, BRIDGE_SN9C105), },
93 { SN9C102_USB_DEVICE(0x0c45, 0x60cc, BRIDGE_SN9C105), }, 94 { SN9C102_USB_DEVICE(0x0c45, 0x60cc, BRIDGE_SN9C105), },
94 { SN9C102_USB_DEVICE(0x0c45, 0x60ea, BRIDGE_SN9C105), }, 95 { SN9C102_USB_DEVICE(0x0c45, 0x60ea, BRIDGE_SN9C105), },
95 { SN9C102_USB_DEVICE(0x0c45, 0x60ec, BRIDGE_SN9C105), }, 96 { SN9C102_USB_DEVICE(0x0c45, 0x60ec, BRIDGE_SN9C105), },
97 { SN9C102_USB_DEVICE(0x0c45, 0x60ef, BRIDGE_SN9C105), },
96 { SN9C102_USB_DEVICE(0x0c45, 0x60fa, BRIDGE_SN9C105), }, 98 { SN9C102_USB_DEVICE(0x0c45, 0x60fa, BRIDGE_SN9C105), },
97 { SN9C102_USB_DEVICE(0x0c45, 0x60fb, BRIDGE_SN9C105), }, 99 { SN9C102_USB_DEVICE(0x0c45, 0x60fb, BRIDGE_SN9C105), },
98 { SN9C102_USB_DEVICE(0x0c45, 0x60fc, BRIDGE_SN9C105), }, 100 { SN9C102_USB_DEVICE(0x0c45, 0x60fc, BRIDGE_SN9C105), },
99 { SN9C102_USB_DEVICE(0x0c45, 0x60fe, BRIDGE_SN9C105), }, 101 { SN9C102_USB_DEVICE(0x0c45, 0x60fe, BRIDGE_SN9C105), },
100 /* SN9C120 */ 102 /* SN9C120 */
103 { SN9C102_USB_DEVICE(0x0c45, 0x6102, BRIDGE_SN9C120), },
104 { SN9C102_USB_DEVICE(0x0c45, 0x6108, BRIDGE_SN9C120), },
105 { SN9C102_USB_DEVICE(0x0c45, 0x610f, BRIDGE_SN9C120), },
101 { SN9C102_USB_DEVICE(0x0c45, 0x6130, BRIDGE_SN9C120), }, 106 { SN9C102_USB_DEVICE(0x0c45, 0x6130, BRIDGE_SN9C120), },
107 { SN9C102_USB_DEVICE(0x0c45, 0x6138, BRIDGE_SN9C120), },
102 { SN9C102_USB_DEVICE(0x0c45, 0x613a, BRIDGE_SN9C120), }, 108 { SN9C102_USB_DEVICE(0x0c45, 0x613a, BRIDGE_SN9C120), },
103 { SN9C102_USB_DEVICE(0x0c45, 0x613b, BRIDGE_SN9C120), }, 109 { SN9C102_USB_DEVICE(0x0c45, 0x613b, BRIDGE_SN9C120), },
104 { SN9C102_USB_DEVICE(0x0c45, 0x613c, BRIDGE_SN9C120), }, 110 { SN9C102_USB_DEVICE(0x0c45, 0x613c, BRIDGE_SN9C120), },
@@ -114,12 +120,15 @@ static const struct usb_device_id sn9c102_id_table[] = {
114 Functions must return 0 on success, the appropriate error otherwise. 120 Functions must return 0 on success, the appropriate error otherwise.
115*/ 121*/
116extern int sn9c102_probe_hv7131d(struct sn9c102_device* cam); 122extern int sn9c102_probe_hv7131d(struct sn9c102_device* cam);
123extern int sn9c102_probe_hv7131r(struct sn9c102_device* cam);
117extern int sn9c102_probe_mi0343(struct sn9c102_device* cam); 124extern int sn9c102_probe_mi0343(struct sn9c102_device* cam);
125extern int sn9c102_probe_mi0360(struct sn9c102_device* cam);
118extern int sn9c102_probe_ov7630(struct sn9c102_device* cam); 126extern int sn9c102_probe_ov7630(struct sn9c102_device* cam);
119extern int sn9c102_probe_ov7660(struct sn9c102_device* cam); 127extern int sn9c102_probe_ov7660(struct sn9c102_device* cam);
120extern int sn9c102_probe_pas106b(struct sn9c102_device* cam); 128extern int sn9c102_probe_pas106b(struct sn9c102_device* cam);
121extern int sn9c102_probe_pas202bcb(struct sn9c102_device* cam); 129extern int sn9c102_probe_pas202bcb(struct sn9c102_device* cam);
122extern int sn9c102_probe_tas5110c1b(struct sn9c102_device* cam); 130extern int sn9c102_probe_tas5110c1b(struct sn9c102_device* cam);
131extern int sn9c102_probe_tas5110d(struct sn9c102_device* cam);
123extern int sn9c102_probe_tas5130d1b(struct sn9c102_device* cam); 132extern int sn9c102_probe_tas5130d1b(struct sn9c102_device* cam);
124 133
125/* 134/*
@@ -128,13 +137,16 @@ extern int sn9c102_probe_tas5130d1b(struct sn9c102_device* cam);
128 the order of the list below, from top to bottom. 137 the order of the list below, from top to bottom.
129*/ 138*/
130static int (*sn9c102_sensor_table[])(struct sn9c102_device*) = { 139static int (*sn9c102_sensor_table[])(struct sn9c102_device*) = {
140 &sn9c102_probe_hv7131d, /* strong detection based on SENSOR ids */
141 &sn9c102_probe_hv7131r, /* strong detection based on SENSOR ids */
131 &sn9c102_probe_mi0343, /* strong detection based on SENSOR ids */ 142 &sn9c102_probe_mi0343, /* strong detection based on SENSOR ids */
143 &sn9c102_probe_mi0360, /* strong detection based on SENSOR ids */
132 &sn9c102_probe_pas106b, /* strong detection based on SENSOR ids */ 144 &sn9c102_probe_pas106b, /* strong detection based on SENSOR ids */
133 &sn9c102_probe_pas202bcb, /* strong detection based on SENSOR ids */ 145 &sn9c102_probe_pas202bcb, /* strong detection based on SENSOR ids */
134 &sn9c102_probe_hv7131d, /* strong detection based on SENSOR ids */
135 &sn9c102_probe_ov7630, /* strong detection based on SENSOR ids */ 146 &sn9c102_probe_ov7630, /* strong detection based on SENSOR ids */
136 &sn9c102_probe_ov7660, /* strong detection based on SENSOR ids */ 147 &sn9c102_probe_ov7660, /* strong detection based on SENSOR ids */
137 &sn9c102_probe_tas5110c1b, /* detection based on USB pid/vid */ 148 &sn9c102_probe_tas5110c1b, /* detection based on USB pid/vid */
149 &sn9c102_probe_tas5110d, /* detection based on USB pid/vid */
138 &sn9c102_probe_tas5130d1b, /* detection based on USB pid/vid */ 150 &sn9c102_probe_tas5130d1b, /* detection based on USB pid/vid */
139 NULL, 151 NULL,
140}; 152};
diff --git a/drivers/media/video/sn9c102/sn9c102_hv7131d.c b/drivers/media/video/sn9c102/sn9c102_hv7131d.c
index 7ae368f60d89..28a861aed044 100644
--- a/drivers/media/video/sn9c102/sn9c102_hv7131d.c
+++ b/drivers/media/video/sn9c102/sn9c102_hv7131d.c
@@ -22,19 +22,13 @@
22#include "sn9c102_sensor.h" 22#include "sn9c102_sensor.h"
23 23
24 24
25static struct sn9c102_sensor hv7131d;
26
27
28static int hv7131d_init(struct sn9c102_device* cam) 25static int hv7131d_init(struct sn9c102_device* cam)
29{ 26{
30 int err = 0; 27 int err;
31 28
32 err += sn9c102_write_reg(cam, 0x00, 0x10); 29 err = sn9c102_write_const_regs(cam, {0x00, 0x10}, {0x00, 0x11},
33 err += sn9c102_write_reg(cam, 0x00, 0x11); 30 {0x00, 0x14}, {0x60, 0x17},
34 err += sn9c102_write_reg(cam, 0x00, 0x14); 31 {0x0e, 0x18}, {0xf2, 0x19});
35 err += sn9c102_write_reg(cam, 0x60, 0x17);
36 err += sn9c102_write_reg(cam, 0x0e, 0x18);
37 err += sn9c102_write_reg(cam, 0xf2, 0x19);
38 32
39 err += sn9c102_i2c_write(cam, 0x01, 0x04); 33 err += sn9c102_i2c_write(cam, 0x01, 0x04);
40 err += sn9c102_i2c_write(cam, 0x02, 0x00); 34 err += sn9c102_i2c_write(cam, 0x02, 0x00);
@@ -153,7 +147,7 @@ static int hv7131d_set_pix_format(struct sn9c102_device* cam,
153static struct sn9c102_sensor hv7131d = { 147static struct sn9c102_sensor hv7131d = {
154 .name = "HV7131D", 148 .name = "HV7131D",
155 .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>", 149 .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
156 .supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102 | BRIDGE_SN9C103, 150 .supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102,
157 .sysfs_ops = SN9C102_I2C_READ | SN9C102_I2C_WRITE, 151 .sysfs_ops = SN9C102_I2C_READ | SN9C102_I2C_WRITE,
158 .frequency = SN9C102_I2C_100KHZ, 152 .frequency = SN9C102_I2C_100KHZ,
159 .interface = SN9C102_I2C_2WIRES, 153 .interface = SN9C102_I2C_2WIRES,
@@ -250,11 +244,10 @@ static struct sn9c102_sensor hv7131d = {
250 244
251int sn9c102_probe_hv7131d(struct sn9c102_device* cam) 245int sn9c102_probe_hv7131d(struct sn9c102_device* cam)
252{ 246{
253 int r0 = 0, r1 = 0, err = 0; 247 int r0 = 0, r1 = 0, err;
254 248
255 err += sn9c102_write_reg(cam, 0x01, 0x01); 249 err = sn9c102_write_const_regs(cam, {0x01, 0x01}, {0x00, 0x01},
256 err += sn9c102_write_reg(cam, 0x00, 0x01); 250 {0x28, 0x17});
257 err += sn9c102_write_reg(cam, 0x28, 0x17);
258 if (err) 251 if (err)
259 return -EIO; 252 return -EIO;
260 253
@@ -263,7 +256,7 @@ int sn9c102_probe_hv7131d(struct sn9c102_device* cam)
263 if (r0 < 0 || r1 < 0) 256 if (r0 < 0 || r1 < 0)
264 return -EIO; 257 return -EIO;
265 258
266 if (r0 != 0x00 && r1 != 0x04) 259 if (r0 != 0x00 || r1 != 0x04)
267 return -ENODEV; 260 return -ENODEV;
268 261
269 sn9c102_attach_sensor(cam, &hv7131d); 262 sn9c102_attach_sensor(cam, &hv7131d);
diff --git a/drivers/media/video/sn9c102/sn9c102_hv7131r.c b/drivers/media/video/sn9c102/sn9c102_hv7131r.c
new file mode 100644
index 000000000000..5a495baa5f95
--- /dev/null
+++ b/drivers/media/video/sn9c102/sn9c102_hv7131r.c
@@ -0,0 +1,366 @@
1/***************************************************************************
2 * Plug-in for HV7131R image sensor connected to the SN9C1xx PC Camera *
3 * Controllers *
4 * *
5 * Copyright (C) 2007 by Luca Risolia <luca.risolia@studio.unibo.it> *
6 * *
7 * This program is free software; you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation; either version 2 of the License, or *
10 * (at your option) any later version. *
11 * *
12 * This program is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 * GNU General Public License for more details. *
16 * *
17 * You should have received a copy of the GNU General Public License *
18 * along with this program; if not, write to the Free Software *
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
20 ***************************************************************************/
21
22#include "sn9c102_sensor.h"
23
24
25static int hv7131r_init(struct sn9c102_device* cam)
26{
27 int err = 0;
28
29 switch (sn9c102_get_bridge(cam)) {
30 case BRIDGE_SN9C103:
31 err = sn9c102_write_const_regs(cam, {0x00, 0x03}, {0x1a, 0x04},
32 {0x20, 0x05}, {0x20, 0x06},
33 {0x03, 0x10}, {0x00, 0x14},
34 {0x60, 0x17}, {0x0a, 0x18},
35 {0xf0, 0x19}, {0x1d, 0x1a},
36 {0x10, 0x1b}, {0x02, 0x1c},
37 {0x03, 0x1d}, {0x0f, 0x1e},
38 {0x0c, 0x1f}, {0x00, 0x20},
39 {0x10, 0x21}, {0x20, 0x22},
40 {0x30, 0x23}, {0x40, 0x24},
41 {0x50, 0x25}, {0x60, 0x26},
42 {0x70, 0x27}, {0x80, 0x28},
43 {0x90, 0x29}, {0xa0, 0x2a},
44 {0xb0, 0x2b}, {0xc0, 0x2c},
45 {0xd0, 0x2d}, {0xe0, 0x2e},
46 {0xf0, 0x2f}, {0xff, 0x30});
47
48 break;
49 case BRIDGE_SN9C105:
50 case BRIDGE_SN9C120:
51 err = sn9c102_write_const_regs(cam, {0x44, 0x01}, {0x40, 0x02},
52 {0x00, 0x03}, {0x1a, 0x04},
53 {0x44, 0x05}, {0x3e, 0x06},
54 {0x1a, 0x07}, {0x03, 0x10},
55 {0x08, 0x14}, {0xa3, 0x17},
56 {0x4b, 0x18}, {0x00, 0x19},
57 {0x1d, 0x1a}, {0x10, 0x1b},
58 {0x02, 0x1c}, {0x03, 0x1d},
59 {0x0f, 0x1e}, {0x0c, 0x1f},
60 {0x00, 0x20}, {0x29, 0x21},
61 {0x40, 0x22}, {0x54, 0x23},
62 {0x66, 0x24}, {0x76, 0x25},
63 {0x85, 0x26}, {0x94, 0x27},
64 {0xa1, 0x28}, {0xae, 0x29},
65 {0xbb, 0x2a}, {0xc7, 0x2b},
66 {0xd3, 0x2c}, {0xde, 0x2d},
67 {0xea, 0x2e}, {0xf4, 0x2f},
68 {0xff, 0x30}, {0x00, 0x3F},
69 {0xC7, 0x40}, {0x01, 0x41},
70 {0x44, 0x42}, {0x00, 0x43},
71 {0x44, 0x44}, {0x00, 0x45},
72 {0x44, 0x46}, {0x00, 0x47},
73 {0xC7, 0x48}, {0x01, 0x49},
74 {0xC7, 0x4A}, {0x01, 0x4B},
75 {0xC7, 0x4C}, {0x01, 0x4D},
76 {0x44, 0x4E}, {0x00, 0x4F},
77 {0x44, 0x50}, {0x00, 0x51},
78 {0x44, 0x52}, {0x00, 0x53},
79 {0xC7, 0x54}, {0x01, 0x55},
80 {0xC7, 0x56}, {0x01, 0x57},
81 {0xC7, 0x58}, {0x01, 0x59},
82 {0x44, 0x5A}, {0x00, 0x5B},
83 {0x44, 0x5C}, {0x00, 0x5D},
84 {0x44, 0x5E}, {0x00, 0x5F},
85 {0xC7, 0x60}, {0x01, 0x61},
86 {0xC7, 0x62}, {0x01, 0x63},
87 {0xC7, 0x64}, {0x01, 0x65},
88 {0x44, 0x66}, {0x00, 0x67},
89 {0x44, 0x68}, {0x00, 0x69},
90 {0x44, 0x6A}, {0x00, 0x6B},
91 {0xC7, 0x6C}, {0x01, 0x6D},
92 {0xC7, 0x6E}, {0x01, 0x6F},
93 {0xC7, 0x70}, {0x01, 0x71},
94 {0x44, 0x72}, {0x00, 0x73},
95 {0x44, 0x74}, {0x00, 0x75},
96 {0x44, 0x76}, {0x00, 0x77},
97 {0xC7, 0x78}, {0x01, 0x79},
98 {0xC7, 0x7A}, {0x01, 0x7B},
99 {0xC7, 0x7C}, {0x01, 0x7D},
100 {0x44, 0x7E}, {0x00, 0x7F},
101 {0x14, 0x84}, {0x00, 0x85},
102 {0x27, 0x86}, {0x00, 0x87},
103 {0x07, 0x88}, {0x00, 0x89},
104 {0xEC, 0x8A}, {0x0f, 0x8B},
105 {0xD8, 0x8C}, {0x0f, 0x8D},
106 {0x3D, 0x8E}, {0x00, 0x8F},
107 {0x3D, 0x90}, {0x00, 0x91},
108 {0xCD, 0x92}, {0x0f, 0x93},
109 {0xf7, 0x94}, {0x0f, 0x95},
110 {0x0C, 0x96}, {0x00, 0x97},
111 {0x00, 0x98}, {0x66, 0x99},
112 {0x05, 0x9A}, {0x00, 0x9B},
113 {0x04, 0x9C}, {0x00, 0x9D},
114 {0x08, 0x9E}, {0x00, 0x9F},
115 {0x2D, 0xC0}, {0x2D, 0xC1},
116 {0x3A, 0xC2}, {0x05, 0xC3},
117 {0x04, 0xC4}, {0x3F, 0xC5},
118 {0x00, 0xC6}, {0x00, 0xC7},
119 {0x50, 0xC8}, {0x3C, 0xC9},
120 {0x28, 0xCA}, {0xD8, 0xCB},
121 {0x14, 0xCC}, {0xEC, 0xCD},
122 {0x32, 0xCE}, {0xDD, 0xCF},
123 {0x32, 0xD0}, {0xDD, 0xD1},
124 {0x6A, 0xD2}, {0x50, 0xD3},
125 {0x00, 0xD4}, {0x00, 0xD5},
126 {0x00, 0xD6});
127 break;
128 default:
129 break;
130 }
131
132 err += sn9c102_i2c_write(cam, 0x20, 0x00);
133 err += sn9c102_i2c_write(cam, 0x21, 0xd6);
134 err += sn9c102_i2c_write(cam, 0x25, 0x06);
135
136 return err;
137}
138
139
140static int hv7131r_get_ctrl(struct sn9c102_device* cam,
141 struct v4l2_control* ctrl)
142{
143 switch (ctrl->id) {
144 case V4L2_CID_GAIN:
145 if ((ctrl->value = sn9c102_i2c_read(cam, 0x30)) < 0)
146 return -EIO;
147 return 0;
148 case V4L2_CID_RED_BALANCE:
149 if ((ctrl->value = sn9c102_i2c_read(cam, 0x31)) < 0)
150 return -EIO;
151 ctrl->value = ctrl->value & 0x3f;
152 return 0;
153 case V4L2_CID_BLUE_BALANCE:
154 if ((ctrl->value = sn9c102_i2c_read(cam, 0x33)) < 0)
155 return -EIO;
156 ctrl->value = ctrl->value & 0x3f;
157 return 0;
158 case SN9C102_V4L2_CID_GREEN_BALANCE:
159 if ((ctrl->value = sn9c102_i2c_read(cam, 0x32)) < 0)
160 return -EIO;
161 ctrl->value = ctrl->value & 0x3f;
162 return 0;
163 case V4L2_CID_BLACK_LEVEL:
164 if ((ctrl->value = sn9c102_i2c_read(cam, 0x01)) < 0)
165 return -EIO;
166 ctrl->value = (ctrl->value & 0x08) ? 1 : 0;
167 return 0;
168 default:
169 return -EINVAL;
170 }
171}
172
173
174static int hv7131r_set_ctrl(struct sn9c102_device* cam,
175 const struct v4l2_control* ctrl)
176{
177 int err = 0;
178
179 switch (ctrl->id) {
180 case V4L2_CID_GAIN:
181 err += sn9c102_i2c_write(cam, 0x30, ctrl->value);
182 break;
183 case V4L2_CID_RED_BALANCE:
184 err += sn9c102_i2c_write(cam, 0x31, ctrl->value);
185 break;
186 case V4L2_CID_BLUE_BALANCE:
187 err += sn9c102_i2c_write(cam, 0x33, ctrl->value);
188 break;
189 case SN9C102_V4L2_CID_GREEN_BALANCE:
190 err += sn9c102_i2c_write(cam, 0x32, ctrl->value);
191 break;
192 case V4L2_CID_BLACK_LEVEL:
193 {
194 int r = sn9c102_i2c_read(cam, 0x01);
195 if (r < 0)
196 return -EIO;
197 err += sn9c102_i2c_write(cam, 0x01,
198 (ctrl->value<<3) | (r&0xf7));
199 }
200 break;
201 default:
202 return -EINVAL;
203 }
204
205 return err ? -EIO : 0;
206}
207
208
209static int hv7131r_set_crop(struct sn9c102_device* cam,
210 const struct v4l2_rect* rect)
211{
212 struct sn9c102_sensor* s = sn9c102_get_sensor(cam);
213 int err = 0;
214 u8 h_start = (u8)(rect->left - s->cropcap.bounds.left) + 1,
215 v_start = (u8)(rect->top - s->cropcap.bounds.top) + 1;
216
217 err += sn9c102_write_reg(cam, h_start, 0x12);
218 err += sn9c102_write_reg(cam, v_start, 0x13);
219
220 return err;
221}
222
223
224static int hv7131r_set_pix_format(struct sn9c102_device* cam,
225 const struct v4l2_pix_format* pix)
226{
227 int err = 0;
228
229 switch (sn9c102_get_bridge(cam)) {
230 case BRIDGE_SN9C103:
231 if (pix->pixelformat == V4L2_PIX_FMT_SBGGR8) {
232 err += sn9c102_write_reg(cam, 0xa0, 0x19);
233 err += sn9c102_i2c_write(cam, 0x01, 0x04);
234 } else {
235 err += sn9c102_write_reg(cam, 0x30, 0x19);
236 err += sn9c102_i2c_write(cam, 0x01, 0x04);
237 }
238 break;
239 case BRIDGE_SN9C105:
240 case BRIDGE_SN9C120:
241 if (pix->pixelformat == V4L2_PIX_FMT_SBGGR8) {
242 err += sn9c102_write_reg(cam, 0xa5, 0x17);
243 err += sn9c102_i2c_write(cam, 0x01, 0x24);
244 } else {
245 err += sn9c102_write_reg(cam, 0xa3, 0x17);
246 err += sn9c102_i2c_write(cam, 0x01, 0x04);
247 }
248 break;
249 default:
250 break;
251 }
252
253 return err;
254}
255
256
257static struct sn9c102_sensor hv7131r = {
258 .name = "HV7131R",
259 .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
260 .supported_bridge = BRIDGE_SN9C103 | BRIDGE_SN9C105 | BRIDGE_SN9C120,
261 .sysfs_ops = SN9C102_I2C_READ | SN9C102_I2C_WRITE,
262 .frequency = SN9C102_I2C_100KHZ,
263 .interface = SN9C102_I2C_2WIRES,
264 .i2c_slave_id = 0x11,
265 .init = &hv7131r_init,
266 .qctrl = {
267 {
268 .id = V4L2_CID_GAIN,
269 .type = V4L2_CTRL_TYPE_INTEGER,
270 .name = "global gain",
271 .minimum = 0x00,
272 .maximum = 0xff,
273 .step = 0x01,
274 .default_value = 0x40,
275 .flags = 0,
276 },
277 {
278 .id = V4L2_CID_RED_BALANCE,
279 .type = V4L2_CTRL_TYPE_INTEGER,
280 .name = "red balance",
281 .minimum = 0x00,
282 .maximum = 0x3f,
283 .step = 0x01,
284 .default_value = 0x08,
285 .flags = 0,
286 },
287 {
288 .id = V4L2_CID_BLUE_BALANCE,
289 .type = V4L2_CTRL_TYPE_INTEGER,
290 .name = "blue balance",
291 .minimum = 0x00,
292 .maximum = 0x3f,
293 .step = 0x01,
294 .default_value = 0x1a,
295 .flags = 0,
296 },
297 {
298 .id = SN9C102_V4L2_CID_GREEN_BALANCE,
299 .type = V4L2_CTRL_TYPE_INTEGER,
300 .name = "green balance",
301 .minimum = 0x00,
302 .maximum = 0x3f,
303 .step = 0x01,
304 .default_value = 0x2f,
305 .flags = 0,
306 },
307 {
308 .id = V4L2_CID_BLACK_LEVEL,
309 .type = V4L2_CTRL_TYPE_BOOLEAN,
310 .name = "auto black level compensation",
311 .minimum = 0x00,
312 .maximum = 0x01,
313 .step = 0x01,
314 .default_value = 0x00,
315 .flags = 0,
316 },
317 },
318 .get_ctrl = &hv7131r_get_ctrl,
319 .set_ctrl = &hv7131r_set_ctrl,
320 .cropcap = {
321 .bounds = {
322 .left = 0,
323 .top = 0,
324 .width = 640,
325 .height = 480,
326 },
327 .defrect = {
328 .left = 0,
329 .top = 0,
330 .width = 640,
331 .height = 480,
332 },
333 },
334 .set_crop = &hv7131r_set_crop,
335 .pix_format = {
336 .width = 640,
337 .height = 480,
338 .pixelformat = V4L2_PIX_FMT_SBGGR8,
339 .priv = 8,
340 },
341 .set_pix_format = &hv7131r_set_pix_format
342};
343
344
345int sn9c102_probe_hv7131r(struct sn9c102_device* cam)
346{
347 int devid, err;
348
349 err = sn9c102_write_const_regs(cam, {0x09, 0x01}, {0x44, 0x02},
350 {0x34, 0x01}, {0x20, 0x17},
351 {0x34, 0x01}, {0x46, 0x01});
352
353 if (err)
354 return -EIO;
355
356 devid = sn9c102_i2c_try_read(cam, &hv7131r, 0x00);
357 if (devid < 0)
358 return -EIO;
359
360 if (devid != 0x02)
361 return -ENODEV;
362
363 sn9c102_attach_sensor(cam, &hv7131r);
364
365 return 0;
366}
diff --git a/drivers/media/video/sn9c102/sn9c102_mi0343.c b/drivers/media/video/sn9c102/sn9c102_mi0343.c
index a33d1bc10f90..9200845d011b 100644
--- a/drivers/media/video/sn9c102/sn9c102_mi0343.c
+++ b/drivers/media/video/sn9c102/sn9c102_mi0343.c
@@ -22,36 +22,30 @@
22#include "sn9c102_sensor.h" 22#include "sn9c102_sensor.h"
23 23
24 24
25static struct sn9c102_sensor mi0343;
26static u8 mi0343_i2c_data[5+1];
27
28
29static int mi0343_init(struct sn9c102_device* cam) 25static int mi0343_init(struct sn9c102_device* cam)
30{ 26{
27 struct sn9c102_sensor* s = sn9c102_get_sensor(cam);
31 int err = 0; 28 int err = 0;
32 29
33 err += sn9c102_write_reg(cam, 0x00, 0x10); 30 err = sn9c102_write_const_regs(cam, {0x00, 0x10}, {0x00, 0x11},
34 err += sn9c102_write_reg(cam, 0x00, 0x11); 31 {0x0a, 0x14}, {0x40, 0x01},
35 err += sn9c102_write_reg(cam, 0x0a, 0x14); 32 {0x20, 0x17}, {0x07, 0x18},
36 err += sn9c102_write_reg(cam, 0x40, 0x01); 33 {0xa0, 0x19});
37 err += sn9c102_write_reg(cam, 0x20, 0x17); 34
38 err += sn9c102_write_reg(cam, 0x07, 0x18); 35 err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x0d,
39 err += sn9c102_write_reg(cam, 0xa0, 0x19); 36 0x00, 0x01, 0, 0);
40 37 err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x0d,
41 err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4, mi0343.i2c_slave_id, 38 0x00, 0x00, 0, 0);
42 0x0d, 0x00, 0x01, 0, 0); 39 err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x03,
43 err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4, mi0343.i2c_slave_id, 40 0x01, 0xe1, 0, 0);
44 0x0d, 0x00, 0x00, 0, 0); 41 err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x04,
45 err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4, mi0343.i2c_slave_id, 42 0x02, 0x81, 0, 0);
46 0x03, 0x01, 0xe1, 0, 0); 43 err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x05,
47 err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4, mi0343.i2c_slave_id, 44 0x00, 0x17, 0, 0);
48 0x04, 0x02, 0x81, 0, 0); 45 err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x06,
49 err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4, mi0343.i2c_slave_id, 46 0x00, 0x11, 0, 0);
50 0x05, 0x00, 0x17, 0, 0); 47 err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x62,
51 err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4, mi0343.i2c_slave_id, 48 0x04, 0x9a, 0, 0);
52 0x06, 0x00, 0x11, 0, 0);
53 err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4, mi0343.i2c_slave_id,
54 0x62, 0x04, 0x9a, 0, 0);
55 49
56 return err; 50 return err;
57} 51}
@@ -60,43 +54,46 @@ static int mi0343_init(struct sn9c102_device* cam)
60static int mi0343_get_ctrl(struct sn9c102_device* cam, 54static int mi0343_get_ctrl(struct sn9c102_device* cam,
61 struct v4l2_control* ctrl) 55 struct v4l2_control* ctrl)
62{ 56{
57 struct sn9c102_sensor* s = sn9c102_get_sensor(cam);
58 u8 data[5+1];
59
63 switch (ctrl->id) { 60 switch (ctrl->id) {
64 case V4L2_CID_EXPOSURE: 61 case V4L2_CID_EXPOSURE:
65 if (sn9c102_i2c_try_raw_read(cam, &mi0343, mi0343.i2c_slave_id, 62 if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x09,
66 0x09, 2+1, mi0343_i2c_data) < 0) 63 2+1, data) < 0)
67 return -EIO; 64 return -EIO;
68 ctrl->value = mi0343_i2c_data[2]; 65 ctrl->value = data[2];
69 return 0; 66 return 0;
70 case V4L2_CID_GAIN: 67 case V4L2_CID_GAIN:
71 if (sn9c102_i2c_try_raw_read(cam, &mi0343, mi0343.i2c_slave_id, 68 if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x35,
72 0x35, 2+1, mi0343_i2c_data) < 0) 69 2+1, data) < 0)
73 return -EIO; 70 return -EIO;
74 break; 71 break;
75 case V4L2_CID_HFLIP: 72 case V4L2_CID_HFLIP:
76 if (sn9c102_i2c_try_raw_read(cam, &mi0343, mi0343.i2c_slave_id, 73 if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x20,
77 0x20, 2+1, mi0343_i2c_data) < 0) 74 2+1, data) < 0)
78 return -EIO; 75 return -EIO;
79 ctrl->value = mi0343_i2c_data[3] & 0x20 ? 1 : 0; 76 ctrl->value = data[3] & 0x20 ? 1 : 0;
80 return 0; 77 return 0;
81 case V4L2_CID_VFLIP: 78 case V4L2_CID_VFLIP:
82 if (sn9c102_i2c_try_raw_read(cam, &mi0343, mi0343.i2c_slave_id, 79 if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x20,
83 0x20, 2+1, mi0343_i2c_data) < 0) 80 2+1, data) < 0)
84 return -EIO; 81 return -EIO;
85 ctrl->value = mi0343_i2c_data[3] & 0x80 ? 1 : 0; 82 ctrl->value = data[3] & 0x80 ? 1 : 0;
86 return 0; 83 return 0;
87 case V4L2_CID_RED_BALANCE: 84 case V4L2_CID_RED_BALANCE:
88 if (sn9c102_i2c_try_raw_read(cam, &mi0343, mi0343.i2c_slave_id, 85 if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x2d,
89 0x2d, 2+1, mi0343_i2c_data) < 0) 86 2+1, data) < 0)
90 return -EIO; 87 return -EIO;
91 break; 88 break;
92 case V4L2_CID_BLUE_BALANCE: 89 case V4L2_CID_BLUE_BALANCE:
93 if (sn9c102_i2c_try_raw_read(cam, &mi0343, mi0343.i2c_slave_id, 90 if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x2c,
94 0x2c, 2+1, mi0343_i2c_data) < 0) 91 2+1, data) < 0)
95 return -EIO; 92 return -EIO;
96 break; 93 break;
97 case SN9C102_V4L2_CID_GREEN_BALANCE: 94 case SN9C102_V4L2_CID_GREEN_BALANCE:
98 if (sn9c102_i2c_try_raw_read(cam, &mi0343, mi0343.i2c_slave_id, 95 if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x2e,
99 0x2e, 2+1, mi0343_i2c_data) < 0) 96 2+1, data) < 0)
100 return -EIO; 97 return -EIO;
101 break; 98 break;
102 default: 99 default:
@@ -108,7 +105,7 @@ static int mi0343_get_ctrl(struct sn9c102_device* cam,
108 case V4L2_CID_RED_BALANCE: 105 case V4L2_CID_RED_BALANCE:
109 case V4L2_CID_BLUE_BALANCE: 106 case V4L2_CID_BLUE_BALANCE:
110 case SN9C102_V4L2_CID_GREEN_BALANCE: 107 case SN9C102_V4L2_CID_GREEN_BALANCE:
111 ctrl->value = mi0343_i2c_data[3] | (mi0343_i2c_data[2] << 8); 108 ctrl->value = data[3] | (data[2] << 8);
112 if (ctrl->value >= 0x10 && ctrl->value <= 0x3f) 109 if (ctrl->value >= 0x10 && ctrl->value <= 0x3f)
113 ctrl->value -= 0x10; 110 ctrl->value -= 0x10;
114 else if (ctrl->value >= 0x60 && ctrl->value <= 0x7f) 111 else if (ctrl->value >= 0x60 && ctrl->value <= 0x7f)
@@ -124,6 +121,7 @@ static int mi0343_get_ctrl(struct sn9c102_device* cam,
124static int mi0343_set_ctrl(struct sn9c102_device* cam, 121static int mi0343_set_ctrl(struct sn9c102_device* cam,
125 const struct v4l2_control* ctrl) 122 const struct v4l2_control* ctrl)
126{ 123{
124 struct sn9c102_sensor* s = sn9c102_get_sensor(cam);
127 u16 reg = 0; 125 u16 reg = 0;
128 int err = 0; 126 int err = 0;
129 127
@@ -143,50 +141,42 @@ static int mi0343_set_ctrl(struct sn9c102_device* cam,
143 141
144 switch (ctrl->id) { 142 switch (ctrl->id) {
145 case V4L2_CID_EXPOSURE: 143 case V4L2_CID_EXPOSURE:
146 err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4, 144 err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
147 mi0343.i2c_slave_id,
148 0x09, ctrl->value, 0x00, 145 0x09, ctrl->value, 0x00,
149 0, 0); 146 0, 0);
150 break; 147 break;
151 case V4L2_CID_GAIN: 148 case V4L2_CID_GAIN:
152 err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4, 149 err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
153 mi0343.i2c_slave_id,
154 0x35, reg >> 8, reg & 0xff, 150 0x35, reg >> 8, reg & 0xff,
155 0, 0); 151 0, 0);
156 break; 152 break;
157 case V4L2_CID_HFLIP: 153 case V4L2_CID_HFLIP:
158 err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4, 154 err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
159 mi0343.i2c_slave_id,
160 0x20, ctrl->value ? 0x40:0x00, 155 0x20, ctrl->value ? 0x40:0x00,
161 ctrl->value ? 0x20:0x00, 156 ctrl->value ? 0x20:0x00,
162 0, 0); 157 0, 0);
163 break; 158 break;
164 case V4L2_CID_VFLIP: 159 case V4L2_CID_VFLIP:
165 err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4, 160 err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
166 mi0343.i2c_slave_id,
167 0x20, ctrl->value ? 0x80:0x00, 161 0x20, ctrl->value ? 0x80:0x00,
168 ctrl->value ? 0x80:0x00, 162 ctrl->value ? 0x80:0x00,
169 0, 0); 163 0, 0);
170 break; 164 break;
171 case V4L2_CID_RED_BALANCE: 165 case V4L2_CID_RED_BALANCE:
172 err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4, 166 err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
173 mi0343.i2c_slave_id,
174 0x2d, reg >> 8, reg & 0xff, 167 0x2d, reg >> 8, reg & 0xff,
175 0, 0); 168 0, 0);
176 break; 169 break;
177 case V4L2_CID_BLUE_BALANCE: 170 case V4L2_CID_BLUE_BALANCE:
178 err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4, 171 err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
179 mi0343.i2c_slave_id,
180 0x2c, reg >> 8, reg & 0xff, 172 0x2c, reg >> 8, reg & 0xff,
181 0, 0); 173 0, 0);
182 break; 174 break;
183 case SN9C102_V4L2_CID_GREEN_BALANCE: 175 case SN9C102_V4L2_CID_GREEN_BALANCE:
184 err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4, 176 err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
185 mi0343.i2c_slave_id,
186 0x2b, reg >> 8, reg & 0xff, 177 0x2b, reg >> 8, reg & 0xff,
187 0, 0); 178 0, 0);
188 err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4, 179 err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
189 mi0343.i2c_slave_id,
190 0x2e, reg >> 8, reg & 0xff, 180 0x2e, reg >> 8, reg & 0xff,
191 0, 0); 181 0, 0);
192 break; 182 break;
@@ -216,16 +206,15 @@ static int mi0343_set_crop(struct sn9c102_device* cam,
216static int mi0343_set_pix_format(struct sn9c102_device* cam, 206static int mi0343_set_pix_format(struct sn9c102_device* cam,
217 const struct v4l2_pix_format* pix) 207 const struct v4l2_pix_format* pix)
218{ 208{
209 struct sn9c102_sensor* s = sn9c102_get_sensor(cam);
219 int err = 0; 210 int err = 0;
220 211
221 if (pix->pixelformat == V4L2_PIX_FMT_SN9C10X) { 212 if (pix->pixelformat == V4L2_PIX_FMT_SN9C10X) {
222 err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4, 213 err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
223 mi0343.i2c_slave_id,
224 0x0a, 0x00, 0x03, 0, 0); 214 0x0a, 0x00, 0x03, 0, 0);
225 err += sn9c102_write_reg(cam, 0x20, 0x19); 215 err += sn9c102_write_reg(cam, 0x20, 0x19);
226 } else { 216 } else {
227 err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4, 217 err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
228 mi0343.i2c_slave_id,
229 0x0a, 0x00, 0x05, 0, 0); 218 0x0a, 0x00, 0x05, 0, 0);
230 err += sn9c102_write_reg(cam, 0xa0, 0x19); 219 err += sn9c102_write_reg(cam, 0xa0, 0x19);
231 } 220 }
@@ -237,7 +226,7 @@ static int mi0343_set_pix_format(struct sn9c102_device* cam,
237static struct sn9c102_sensor mi0343 = { 226static struct sn9c102_sensor mi0343 = {
238 .name = "MI-0343", 227 .name = "MI-0343",
239 .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>", 228 .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
240 .supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102 | BRIDGE_SN9C103, 229 .supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102,
241 .frequency = SN9C102_I2C_100KHZ, 230 .frequency = SN9C102_I2C_100KHZ,
242 .interface = SN9C102_I2C_2WIRES, 231 .interface = SN9C102_I2C_2WIRES,
243 .i2c_slave_id = 0x5d, 232 .i2c_slave_id = 0x5d,
@@ -343,19 +332,20 @@ static struct sn9c102_sensor mi0343 = {
343 332
344int sn9c102_probe_mi0343(struct sn9c102_device* cam) 333int sn9c102_probe_mi0343(struct sn9c102_device* cam)
345{ 334{
335 u8 data[5+1];
346 int err = 0; 336 int err = 0;
347 337
348 err += sn9c102_write_reg(cam, 0x01, 0x01); 338 err = sn9c102_write_const_regs(cam, {0x01, 0x01}, {0x00, 0x01},
349 err += sn9c102_write_reg(cam, 0x00, 0x01); 339 {0x28, 0x17});
350 err += sn9c102_write_reg(cam, 0x28, 0x17); 340
351 if (err) 341 if (err)
352 return -EIO; 342 return -EIO;
353 343
354 if (sn9c102_i2c_try_raw_read(cam, &mi0343, mi0343.i2c_slave_id, 0x00, 344 if (sn9c102_i2c_try_raw_read(cam, &mi0343, mi0343.i2c_slave_id, 0x00,
355 2, mi0343_i2c_data) < 0) 345 2, data) < 0)
356 return -EIO; 346 return -EIO;
357 347
358 if (mi0343_i2c_data[4] != 0x32 && mi0343_i2c_data[3] != 0xe3) 348 if (data[4] != 0x32 || data[3] != 0xe3)
359 return -ENODEV; 349 return -ENODEV;
360 350
361 sn9c102_attach_sensor(cam, &mi0343); 351 sn9c102_attach_sensor(cam, &mi0343);
diff --git a/drivers/media/video/sn9c102/sn9c102_mi0360.c b/drivers/media/video/sn9c102/sn9c102_mi0360.c
new file mode 100644
index 000000000000..64698acb0b15
--- /dev/null
+++ b/drivers/media/video/sn9c102/sn9c102_mi0360.c
@@ -0,0 +1,338 @@
1/***************************************************************************
2 * Plug-in for MI-0360 image sensor connected to the SN9C1xx PC Camera *
3 * Controllers *
4 * *
5 * Copyright (C) 2007 by Luca Risolia <luca.risolia@studio.unibo.it> *
6 * *
7 * This program is free software; you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation; either version 2 of the License, or *
10 * (at your option) any later version. *
11 * *
12 * This program is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 * GNU General Public License for more details. *
16 * *
17 * You should have received a copy of the GNU General Public License *
18 * along with this program; if not, write to the Free Software *
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
20 ***************************************************************************/
21
22#include "sn9c102_sensor.h"
23
24
25static int mi0360_init(struct sn9c102_device* cam)
26{
27 struct sn9c102_sensor* s = sn9c102_get_sensor(cam);
28 int err = 0;
29
30 err = sn9c102_write_const_regs(cam, {0x00, 0x10}, {0x00, 0x11},
31 {0x0a, 0x14}, {0x40, 0x01},
32 {0x20, 0x17}, {0x07, 0x18},
33 {0xa0, 0x19}, {0x02, 0x1c},
34 {0x03, 0x1d}, {0x0f, 0x1e},
35 {0x0c, 0x1f}, {0x00, 0x20},
36 {0x10, 0x21}, {0x20, 0x22},
37 {0x30, 0x23}, {0x40, 0x24},
38 {0x50, 0x25}, {0x60, 0x26},
39 {0x70, 0x27}, {0x80, 0x28},
40 {0x90, 0x29}, {0xa0, 0x2a},
41 {0xb0, 0x2b}, {0xc0, 0x2c},
42 {0xd0, 0x2d}, {0xe0, 0x2e},
43 {0xf0, 0x2f}, {0xff, 0x30});
44
45 err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x0d,
46 0x00, 0x01, 0, 0);
47 err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x0d,
48 0x00, 0x00, 0, 0);
49 err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x03,
50 0x01, 0xe1, 0, 0);
51 err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x04,
52 0x02, 0x81, 0, 0);
53 err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x05,
54 0x00, 0x17, 0, 0);
55 err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x06,
56 0x00, 0x11, 0, 0);
57 err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x62,
58 0x04, 0x9a, 0, 0);
59
60 return err;
61}
62
63
64static int mi0360_get_ctrl(struct sn9c102_device* cam,
65 struct v4l2_control* ctrl)
66{
67 struct sn9c102_sensor* s = sn9c102_get_sensor(cam);
68 u8 data[5+1];
69
70 switch (ctrl->id) {
71 case V4L2_CID_EXPOSURE:
72 if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x09,
73 2+1, data) < 0)
74 return -EIO;
75 ctrl->value = data[2];
76 return 0;
77 case V4L2_CID_GAIN:
78 if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x35,
79 2+1, data) < 0)
80 return -EIO;
81 ctrl->value = data[3];
82 return 0;
83 case V4L2_CID_RED_BALANCE:
84 if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x2c,
85 2+1, data) < 0)
86 return -EIO;
87 ctrl->value = data[3];
88 return 0;
89 case V4L2_CID_BLUE_BALANCE:
90 if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x2d,
91 2+1, data) < 0)
92 return -EIO;
93 ctrl->value = data[3];
94 return 0;
95 case SN9C102_V4L2_CID_GREEN_BALANCE:
96 if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x2e,
97 2+1, data) < 0)
98 return -EIO;
99 ctrl->value = data[3];
100 return 0;
101 case V4L2_CID_HFLIP:
102 if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x20,
103 2+1, data) < 0)
104 return -EIO;
105 ctrl->value = data[3] & 0x20 ? 1 : 0;
106 return 0;
107 case V4L2_CID_VFLIP:
108 if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x20,
109 2+1, data) < 0)
110 return -EIO;
111 ctrl->value = data[3] & 0x80 ? 1 : 0;
112 return 0;
113 default:
114 return -EINVAL;
115 }
116
117 return 0;
118}
119
120
121static int mi0360_set_ctrl(struct sn9c102_device* cam,
122 const struct v4l2_control* ctrl)
123{
124 struct sn9c102_sensor* s = sn9c102_get_sensor(cam);
125 int err = 0;
126
127 switch (ctrl->id) {
128 case V4L2_CID_EXPOSURE:
129 err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
130 0x09, ctrl->value, 0x00,
131 0, 0);
132 break;
133 case V4L2_CID_GAIN:
134 err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
135 0x35, 0x03, ctrl->value,
136 0, 0);
137 break;
138 case V4L2_CID_RED_BALANCE:
139 err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
140 0x2c, 0x03, ctrl->value,
141 0, 0);
142 break;
143 case V4L2_CID_BLUE_BALANCE:
144 err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
145 0x2d, 0x03, ctrl->value,
146 0, 0);
147 break;
148 case SN9C102_V4L2_CID_GREEN_BALANCE:
149 err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
150 0x2b, 0x03, ctrl->value,
151 0, 0);
152 err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
153 0x2e, 0x03, ctrl->value,
154 0, 0);
155 break;
156 case V4L2_CID_HFLIP:
157 err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
158 0x20, ctrl->value ? 0x40:0x00,
159 ctrl->value ? 0x20:0x00,
160 0, 0);
161 break;
162 case V4L2_CID_VFLIP:
163 err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
164 0x20, ctrl->value ? 0x80:0x00,
165 ctrl->value ? 0x80:0x00,
166 0, 0);
167 break;
168 default:
169 return -EINVAL;
170 }
171
172 return err ? -EIO : 0;
173}
174
175
176static int mi0360_set_crop(struct sn9c102_device* cam,
177 const struct v4l2_rect* rect)
178{
179 struct sn9c102_sensor* s = sn9c102_get_sensor(cam);
180 int err = 0;
181 u8 h_start = (u8)(rect->left - s->cropcap.bounds.left) + 0,
182 v_start = (u8)(rect->top - s->cropcap.bounds.top) + 1;
183
184 err += sn9c102_write_reg(cam, h_start, 0x12);
185 err += sn9c102_write_reg(cam, v_start, 0x13);
186
187 return err;
188}
189
190
191static int mi0360_set_pix_format(struct sn9c102_device* cam,
192 const struct v4l2_pix_format* pix)
193{
194 struct sn9c102_sensor* s = sn9c102_get_sensor(cam);
195 int err = 0;
196
197 if (pix->pixelformat == V4L2_PIX_FMT_SN9C10X) {
198 err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
199 0x0a, 0x00, 0x02, 0, 0);
200 err += sn9c102_write_reg(cam, 0x20, 0x19);
201 } else {
202 err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
203 0x0a, 0x00, 0x05, 0, 0);
204 err += sn9c102_write_reg(cam, 0x60, 0x19);
205 }
206
207 return err;
208}
209
210
211static struct sn9c102_sensor mi0360 = {
212 .name = "MI-0360",
213 .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
214 .supported_bridge = BRIDGE_SN9C103,
215 .frequency = SN9C102_I2C_100KHZ,
216 .interface = SN9C102_I2C_2WIRES,
217 .i2c_slave_id = 0x5d,
218 .init = &mi0360_init,
219 .qctrl = {
220 {
221 .id = V4L2_CID_EXPOSURE,
222 .type = V4L2_CTRL_TYPE_INTEGER,
223 .name = "exposure",
224 .minimum = 0x00,
225 .maximum = 0x0f,
226 .step = 0x01,
227 .default_value = 0x05,
228 .flags = 0,
229 },
230 {
231 .id = V4L2_CID_GAIN,
232 .type = V4L2_CTRL_TYPE_INTEGER,
233 .name = "global gain",
234 .minimum = 0x00,
235 .maximum = 0x7f,
236 .step = 0x01,
237 .default_value = 0x25,
238 .flags = 0,
239 },
240 {
241 .id = V4L2_CID_HFLIP,
242 .type = V4L2_CTRL_TYPE_BOOLEAN,
243 .name = "horizontal mirror",
244 .minimum = 0,
245 .maximum = 1,
246 .step = 1,
247 .default_value = 0,
248 .flags = 0,
249 },
250 {
251 .id = V4L2_CID_VFLIP,
252 .type = V4L2_CTRL_TYPE_BOOLEAN,
253 .name = "vertical mirror",
254 .minimum = 0,
255 .maximum = 1,
256 .step = 1,
257 .default_value = 0,
258 .flags = 0,
259 },
260 {
261 .id = V4L2_CID_BLUE_BALANCE,
262 .type = V4L2_CTRL_TYPE_INTEGER,
263 .name = "blue balance",
264 .minimum = 0x00,
265 .maximum = 0x7f,
266 .step = 0x01,
267 .default_value = 0x0f,
268 .flags = 0,
269 },
270 {
271 .id = V4L2_CID_RED_BALANCE,
272 .type = V4L2_CTRL_TYPE_INTEGER,
273 .name = "red balance",
274 .minimum = 0x00,
275 .maximum = 0x7f,
276 .step = 0x01,
277 .default_value = 0x32,
278 .flags = 0,
279 },
280 {
281 .id = SN9C102_V4L2_CID_GREEN_BALANCE,
282 .type = V4L2_CTRL_TYPE_INTEGER,
283 .name = "green balance",
284 .minimum = 0x00,
285 .maximum = 0x7f,
286 .step = 0x01,
287 .default_value = 0x25,
288 .flags = 0,
289 },
290 },
291 .get_ctrl = &mi0360_get_ctrl,
292 .set_ctrl = &mi0360_set_ctrl,
293 .cropcap = {
294 .bounds = {
295 .left = 0,
296 .top = 0,
297 .width = 640,
298 .height = 480,
299 },
300 .defrect = {
301 .left = 0,
302 .top = 0,
303 .width = 640,
304 .height = 480,
305 },
306 },
307 .set_crop = &mi0360_set_crop,
308 .pix_format = {
309 .width = 640,
310 .height = 480,
311 .pixelformat = V4L2_PIX_FMT_SBGGR8,
312 .priv = 8,
313 },
314 .set_pix_format = &mi0360_set_pix_format
315};
316
317
318int sn9c102_probe_mi0360(struct sn9c102_device* cam)
319{
320 u8 data[5+1];
321 int err;
322
323 err = sn9c102_write_const_regs(cam, {0x01, 0x01}, {0x00, 0x01},
324 {0x28, 0x17});
325 if (err)
326 return -EIO;
327
328 if (sn9c102_i2c_try_raw_read(cam, &mi0360, mi0360.i2c_slave_id, 0x00,
329 2+1, data) < 0)
330 return -EIO;
331
332 if (data[2] != 0x82 || data[3] != 0x43)
333 return -ENODEV;
334
335 sn9c102_attach_sensor(cam, &mi0360);
336
337 return 0;
338}
diff --git a/drivers/media/video/sn9c102/sn9c102_ov7630.c b/drivers/media/video/sn9c102/sn9c102_ov7630.c
index 7df09ff38e63..31b6080b0615 100644
--- a/drivers/media/video/sn9c102/sn9c102_ov7630.c
+++ b/drivers/media/video/sn9c102/sn9c102_ov7630.c
@@ -22,9 +22,6 @@
22#include "sn9c102_sensor.h" 22#include "sn9c102_sensor.h"
23 23
24 24
25static struct sn9c102_sensor ov7630;
26
27
28static int ov7630_init(struct sn9c102_device* cam) 25static int ov7630_init(struct sn9c102_device* cam)
29{ 26{
30 int err = 0; 27 int err = 0;
@@ -32,21 +29,20 @@ static int ov7630_init(struct sn9c102_device* cam)
32 switch (sn9c102_get_bridge(cam)) { 29 switch (sn9c102_get_bridge(cam)) {
33 case BRIDGE_SN9C101: 30 case BRIDGE_SN9C101:
34 case BRIDGE_SN9C102: 31 case BRIDGE_SN9C102:
35 err += sn9c102_write_reg(cam, 0x00, 0x14); 32 err = sn9c102_write_const_regs(cam, {0x00, 0x14},
36 err += sn9c102_write_reg(cam, 0x60, 0x17); 33 {0x60, 0x17}, {0x0f, 0x18},
37 err += sn9c102_write_reg(cam, 0x0f, 0x18); 34 {0x50, 0x19});
38 err += sn9c102_write_reg(cam, 0x50, 0x19);
39 35
40 err += sn9c102_i2c_write(cam, 0x12, 0x8d); 36 err += sn9c102_i2c_write(cam, 0x12, 0x8d);
41 err += sn9c102_i2c_write(cam, 0x12, 0x0d); 37 err += sn9c102_i2c_write(cam, 0x12, 0x0d);
42 err += sn9c102_i2c_write(cam, 0x11, 0x00); 38 err += sn9c102_i2c_write(cam, 0x11, 0x00);
43 err += sn9c102_i2c_write(cam, 0x15, 0x34); 39 err += sn9c102_i2c_write(cam, 0x15, 0x35);
44 err += sn9c102_i2c_write(cam, 0x16, 0x03); 40 err += sn9c102_i2c_write(cam, 0x16, 0x03);
45 err += sn9c102_i2c_write(cam, 0x17, 0x1c); 41 err += sn9c102_i2c_write(cam, 0x17, 0x1c);
46 err += sn9c102_i2c_write(cam, 0x18, 0xbd); 42 err += sn9c102_i2c_write(cam, 0x18, 0xbd);
47 err += sn9c102_i2c_write(cam, 0x19, 0x06); 43 err += sn9c102_i2c_write(cam, 0x19, 0x06);
48 err += sn9c102_i2c_write(cam, 0x1a, 0xf6); 44 err += sn9c102_i2c_write(cam, 0x1a, 0xf6);
49 err += sn9c102_i2c_write(cam, 0x1b, 0x04); 45 err += sn9c102_i2c_write(cam, 0x1b, 0x04);
50 err += sn9c102_i2c_write(cam, 0x20, 0x44); 46 err += sn9c102_i2c_write(cam, 0x20, 0x44);
51 err += sn9c102_i2c_write(cam, 0x23, 0xee); 47 err += sn9c102_i2c_write(cam, 0x23, 0xee);
52 err += sn9c102_i2c_write(cam, 0x26, 0xa0); 48 err += sn9c102_i2c_write(cam, 0x26, 0xa0);
@@ -65,42 +61,26 @@ static int ov7630_init(struct sn9c102_device* cam)
65 err += sn9c102_i2c_write(cam, 0x71, 0x00); 61 err += sn9c102_i2c_write(cam, 0x71, 0x00);
66 err += sn9c102_i2c_write(cam, 0x74, 0x21); 62 err += sn9c102_i2c_write(cam, 0x74, 0x21);
67 err += sn9c102_i2c_write(cam, 0x7d, 0xf7); 63 err += sn9c102_i2c_write(cam, 0x7d, 0xf7);
64
68 break; 65 break;
69 case BRIDGE_SN9C103: 66 case BRIDGE_SN9C103:
70 err += sn9c102_write_reg(cam, 0x00, 0x02); 67 err = sn9c102_write_const_regs(cam, {0x00, 0x02}, {0x00, 0x03},
71 err += sn9c102_write_reg(cam, 0x00, 0x03); 68 {0x1a, 0x04}, {0x20, 0x05},
72 err += sn9c102_write_reg(cam, 0x1a, 0x04); 69 {0x20, 0x06}, {0x20, 0x07},
73 err += sn9c102_write_reg(cam, 0x20, 0x05); 70 {0x03, 0x10}, {0x0a, 0x14},
74 err += sn9c102_write_reg(cam, 0x20, 0x06); 71 {0x60, 0x17}, {0x0f, 0x18},
75 err += sn9c102_write_reg(cam, 0x20, 0x07); 72 {0x50, 0x19}, {0x1d, 0x1a},
76 err += sn9c102_write_reg(cam, 0x03, 0x10); 73 {0x10, 0x1b}, {0x02, 0x1c},
77 err += sn9c102_write_reg(cam, 0x0a, 0x14); 74 {0x03, 0x1d}, {0x0f, 0x1e},
78 err += sn9c102_write_reg(cam, 0x60, 0x17); 75 {0x0c, 0x1f}, {0x00, 0x20},
79 err += sn9c102_write_reg(cam, 0x0f, 0x18); 76 {0x10, 0x21}, {0x20, 0x22},
80 err += sn9c102_write_reg(cam, 0x50, 0x19); 77 {0x30, 0x23}, {0x40, 0x24},
81 err += sn9c102_write_reg(cam, 0x1d, 0x1a); 78 {0x50, 0x25}, {0x60, 0x26},
82 err += sn9c102_write_reg(cam, 0x10, 0x1b); 79 {0x70, 0x27}, {0x80, 0x28},
83 err += sn9c102_write_reg(cam, 0x02, 0x1c); 80 {0x90, 0x29}, {0xa0, 0x2a},
84 err += sn9c102_write_reg(cam, 0x03, 0x1d); 81 {0xb0, 0x2b}, {0xc0, 0x2c},
85 err += sn9c102_write_reg(cam, 0x0f, 0x1e); 82 {0xd0, 0x2d}, {0xe0, 0x2e},
86 err += sn9c102_write_reg(cam, 0x0c, 0x1f); 83 {0xf0, 0x2f}, {0xff, 0x30});
87 err += sn9c102_write_reg(cam, 0x00, 0x20);
88 err += sn9c102_write_reg(cam, 0x10, 0x21);
89 err += sn9c102_write_reg(cam, 0x20, 0x22);
90 err += sn9c102_write_reg(cam, 0x30, 0x23);
91 err += sn9c102_write_reg(cam, 0x40, 0x24);
92 err += sn9c102_write_reg(cam, 0x50, 0x25);
93 err += sn9c102_write_reg(cam, 0x60, 0x26);
94 err += sn9c102_write_reg(cam, 0x70, 0x27);
95 err += sn9c102_write_reg(cam, 0x80, 0x28);
96 err += sn9c102_write_reg(cam, 0x90, 0x29);
97 err += sn9c102_write_reg(cam, 0xa0, 0x2a);
98 err += sn9c102_write_reg(cam, 0xb0, 0x2b);
99 err += sn9c102_write_reg(cam, 0xc0, 0x2c);
100 err += sn9c102_write_reg(cam, 0xd0, 0x2d);
101 err += sn9c102_write_reg(cam, 0xe0, 0x2e);
102 err += sn9c102_write_reg(cam, 0xf0, 0x2f);
103 err += sn9c102_write_reg(cam, 0xff, 0x30);
104 84
105 err += sn9c102_i2c_write(cam, 0x12, 0x8d); 85 err += sn9c102_i2c_write(cam, 0x12, 0x8d);
106 err += sn9c102_i2c_write(cam, 0x12, 0x0d); 86 err += sn9c102_i2c_write(cam, 0x12, 0x0d);
@@ -108,23 +88,23 @@ static int ov7630_init(struct sn9c102_device* cam)
108 err += sn9c102_i2c_write(cam, 0x11, 0x01); 88 err += sn9c102_i2c_write(cam, 0x11, 0x01);
109 err += sn9c102_i2c_write(cam, 0x1b, 0x04); 89 err += sn9c102_i2c_write(cam, 0x1b, 0x04);
110 err += sn9c102_i2c_write(cam, 0x20, 0x44); 90 err += sn9c102_i2c_write(cam, 0x20, 0x44);
111 err += sn9c102_i2c_write(cam, 0x23, 0xee); 91 err += sn9c102_i2c_write(cam, 0x23, 0xee);
112 err += sn9c102_i2c_write(cam, 0x26, 0xa0); 92 err += sn9c102_i2c_write(cam, 0x26, 0xa0);
113 err += sn9c102_i2c_write(cam, 0x27, 0x9a); 93 err += sn9c102_i2c_write(cam, 0x27, 0x9a);
114 err += sn9c102_i2c_write(cam, 0x28, 0x20); 94 err += sn9c102_i2c_write(cam, 0x28, 0x20);
115 err += sn9c102_i2c_write(cam, 0x29, 0x30); 95 err += sn9c102_i2c_write(cam, 0x29, 0x30);
116 err += sn9c102_i2c_write(cam, 0x2f, 0x3d); 96 err += sn9c102_i2c_write(cam, 0x2f, 0x3d);
117 err += sn9c102_i2c_write(cam, 0x30, 0x24); 97 err += sn9c102_i2c_write(cam, 0x30, 0x24);
118 err += sn9c102_i2c_write(cam, 0x32, 0x86); 98 err += sn9c102_i2c_write(cam, 0x32, 0x86);
119 err += sn9c102_i2c_write(cam, 0x60, 0xa9); 99 err += sn9c102_i2c_write(cam, 0x60, 0xa9);
120 err += sn9c102_i2c_write(cam, 0x61, 0x42); 100 err += sn9c102_i2c_write(cam, 0x61, 0x42);
121 err += sn9c102_i2c_write(cam, 0x65, 0x00); 101 err += sn9c102_i2c_write(cam, 0x65, 0x00);
122 err += sn9c102_i2c_write(cam, 0x69, 0x38); 102 err += sn9c102_i2c_write(cam, 0x69, 0x38);
123 err += sn9c102_i2c_write(cam, 0x6f, 0x88); 103 err += sn9c102_i2c_write(cam, 0x6f, 0x88);
124 err += sn9c102_i2c_write(cam, 0x70, 0x0b); 104 err += sn9c102_i2c_write(cam, 0x70, 0x0b);
125 err += sn9c102_i2c_write(cam, 0x71, 0x00); 105 err += sn9c102_i2c_write(cam, 0x71, 0x00);
126 err += sn9c102_i2c_write(cam, 0x74, 0x21); 106 err += sn9c102_i2c_write(cam, 0x74, 0x21);
127 err += sn9c102_i2c_write(cam, 0x7d, 0xf7); 107 err += sn9c102_i2c_write(cam, 0x7d, 0xf7);
128 break; 108 break;
129 default: 109 default:
130 break; 110 break;
@@ -428,15 +408,14 @@ int sn9c102_probe_ov7630(struct sn9c102_device* cam)
428 switch (sn9c102_get_bridge(cam)) { 408 switch (sn9c102_get_bridge(cam)) {
429 case BRIDGE_SN9C101: 409 case BRIDGE_SN9C101:
430 case BRIDGE_SN9C102: 410 case BRIDGE_SN9C102:
431 err += sn9c102_write_reg(cam, 0x01, 0x01); 411 err = sn9c102_write_const_regs(cam, {0x01, 0x01},
432 err += sn9c102_write_reg(cam, 0x00, 0x01); 412 {0x00, 0x01}, {0x28, 0x17});
433 err += sn9c102_write_reg(cam, 0x28, 0x17); 413
434 break; 414 break;
435 case BRIDGE_SN9C103: /* do _not_ change anything! */ 415 case BRIDGE_SN9C103: /* do _not_ change anything! */
436 err += sn9c102_write_reg(cam, 0x09, 0x01); 416 err = sn9c102_write_const_regs(cam, {0x09, 0x01},
437 err += sn9c102_write_reg(cam, 0x42, 0x01); 417 {0x42, 0x01}, {0x28, 0x17},
438 err += sn9c102_write_reg(cam, 0x28, 0x17); 418 {0x44, 0x02});
439 err += sn9c102_write_reg(cam, 0x44, 0x02);
440 pid = sn9c102_i2c_try_read(cam, &ov7630, 0x0a); 419 pid = sn9c102_i2c_try_read(cam, &ov7630, 0x0a);
441 if (err || pid < 0) { /* try a different initialization */ 420 if (err || pid < 0) { /* try a different initialization */
442 err = sn9c102_write_reg(cam, 0x01, 0x01); 421 err = sn9c102_write_reg(cam, 0x01, 0x01);
diff --git a/drivers/media/video/sn9c102/sn9c102_ov7660.c b/drivers/media/video/sn9c102/sn9c102_ov7660.c
index d670c24d4435..c898e948fe8d 100644
--- a/drivers/media/video/sn9c102/sn9c102_ov7660.c
+++ b/drivers/media/video/sn9c102/sn9c102_ov7660.c
@@ -22,160 +22,84 @@
22#include "sn9c102_sensor.h" 22#include "sn9c102_sensor.h"
23 23
24 24
25static struct sn9c102_sensor ov7660;
26
27
28static int ov7660_init(struct sn9c102_device* cam) 25static int ov7660_init(struct sn9c102_device* cam)
29{ 26{
30 int err = 0; 27 int err = 0;
31 28
32 err += sn9c102_write_reg(cam, 0x40, 0x02); 29 err = sn9c102_write_const_regs(cam, {0x40, 0x02}, {0x00, 0x03},
33 err += sn9c102_write_reg(cam, 0x00, 0x03); 30 {0x1a, 0x04}, {0x03, 0x10},
34 err += sn9c102_write_reg(cam, 0x1a, 0x04); 31 {0x08, 0x14}, {0x20, 0x17},
35 err += sn9c102_write_reg(cam, 0x03, 0x10); 32 {0x8b, 0x18}, {0x00, 0x19},
36 err += sn9c102_write_reg(cam, 0x08, 0x14); 33 {0x1d, 0x1a}, {0x10, 0x1b},
37 err += sn9c102_write_reg(cam, 0x20, 0x17); 34 {0x02, 0x1c}, {0x03, 0x1d},
38 err += sn9c102_write_reg(cam, 0x8b, 0x18); 35 {0x0f, 0x1e}, {0x0c, 0x1f},
39 err += sn9c102_write_reg(cam, 0x00, 0x19); 36 {0x00, 0x20}, {0x29, 0x21},
40 err += sn9c102_write_reg(cam, 0x1d, 0x1a); 37 {0x40, 0x22}, {0x54, 0x23},
41 err += sn9c102_write_reg(cam, 0x10, 0x1b); 38 {0x66, 0x24}, {0x76, 0x25},
42 err += sn9c102_write_reg(cam, 0x02, 0x1c); 39 {0x85, 0x26}, {0x94, 0x27},
43 err += sn9c102_write_reg(cam, 0x03, 0x1d); 40 {0xa1, 0x28}, {0xae, 0x29},
44 err += sn9c102_write_reg(cam, 0x0f, 0x1e); 41 {0xbb, 0x2a}, {0xc7, 0x2b},
45 err += sn9c102_write_reg(cam, 0x0c, 0x1f); 42 {0xd3, 0x2c}, {0xde, 0x2d},
46 err += sn9c102_write_reg(cam, 0x00, 0x20); 43 {0xea, 0x2e}, {0xf4, 0x2f},
47 err += sn9c102_write_reg(cam, 0x29, 0x21); 44 {0xff, 0x30}, {0x00, 0x3F},
48 err += sn9c102_write_reg(cam, 0x40, 0x22); 45 {0xC7, 0x40}, {0x01, 0x41},
49 err += sn9c102_write_reg(cam, 0x54, 0x23); 46 {0x44, 0x42}, {0x00, 0x43},
50 err += sn9c102_write_reg(cam, 0x66, 0x24); 47 {0x44, 0x44}, {0x00, 0x45},
51 err += sn9c102_write_reg(cam, 0x76, 0x25); 48 {0x44, 0x46}, {0x00, 0x47},
52 err += sn9c102_write_reg(cam, 0x85, 0x26); 49 {0xC7, 0x48}, {0x01, 0x49},
53 err += sn9c102_write_reg(cam, 0x94, 0x27); 50 {0xC7, 0x4A}, {0x01, 0x4B},
54 err += sn9c102_write_reg(cam, 0xa1, 0x28); 51 {0xC7, 0x4C}, {0x01, 0x4D},
55 err += sn9c102_write_reg(cam, 0xae, 0x29); 52 {0x44, 0x4E}, {0x00, 0x4F},
56 err += sn9c102_write_reg(cam, 0xbb, 0x2a); 53 {0x44, 0x50}, {0x00, 0x51},
57 err += sn9c102_write_reg(cam, 0xc7, 0x2b); 54 {0x44, 0x52}, {0x00, 0x53},
58 err += sn9c102_write_reg(cam, 0xd3, 0x2c); 55 {0xC7, 0x54}, {0x01, 0x55},
59 err += sn9c102_write_reg(cam, 0xde, 0x2d); 56 {0xC7, 0x56}, {0x01, 0x57},
60 err += sn9c102_write_reg(cam, 0xea, 0x2e); 57 {0xC7, 0x58}, {0x01, 0x59},
61 err += sn9c102_write_reg(cam, 0xf4, 0x2f); 58 {0x44, 0x5A}, {0x00, 0x5B},
62 err += sn9c102_write_reg(cam, 0xff, 0x30); 59 {0x44, 0x5C}, {0x00, 0x5D},
63 err += sn9c102_write_reg(cam, 0x00, 0x3F); 60 {0x44, 0x5E}, {0x00, 0x5F},
64 err += sn9c102_write_reg(cam, 0xC7, 0x40); 61 {0xC7, 0x60}, {0x01, 0x61},
65 err += sn9c102_write_reg(cam, 0x01, 0x41); 62 {0xC7, 0x62}, {0x01, 0x63},
66 err += sn9c102_write_reg(cam, 0x44, 0x42); 63 {0xC7, 0x64}, {0x01, 0x65},
67 err += sn9c102_write_reg(cam, 0x00, 0x43); 64 {0x44, 0x66}, {0x00, 0x67},
68 err += sn9c102_write_reg(cam, 0x44, 0x44); 65 {0x44, 0x68}, {0x00, 0x69},
69 err += sn9c102_write_reg(cam, 0x00, 0x45); 66 {0x44, 0x6A}, {0x00, 0x6B},
70 err += sn9c102_write_reg(cam, 0x44, 0x46); 67 {0xC7, 0x6C}, {0x01, 0x6D},
71 err += sn9c102_write_reg(cam, 0x00, 0x47); 68 {0xC7, 0x6E}, {0x01, 0x6F},
72 err += sn9c102_write_reg(cam, 0xC7, 0x48); 69 {0xC7, 0x70}, {0x01, 0x71},
73 err += sn9c102_write_reg(cam, 0x01, 0x49); 70 {0x44, 0x72}, {0x00, 0x73},
74 err += sn9c102_write_reg(cam, 0xC7, 0x4A); 71 {0x44, 0x74}, {0x00, 0x75},
75 err += sn9c102_write_reg(cam, 0x01, 0x4B); 72 {0x44, 0x76}, {0x00, 0x77},
76 err += sn9c102_write_reg(cam, 0xC7, 0x4C); 73 {0xC7, 0x78}, {0x01, 0x79},
77 err += sn9c102_write_reg(cam, 0x01, 0x4D); 74 {0xC7, 0x7A}, {0x01, 0x7B},
78 err += sn9c102_write_reg(cam, 0x44, 0x4E); 75 {0xC7, 0x7C}, {0x01, 0x7D},
79 err += sn9c102_write_reg(cam, 0x00, 0x4F); 76 {0x44, 0x7E}, {0x00, 0x7F},
80 err += sn9c102_write_reg(cam, 0x44, 0x50); 77 {0x14, 0x84}, {0x00, 0x85},
81 err += sn9c102_write_reg(cam, 0x00, 0x51); 78 {0x27, 0x86}, {0x00, 0x87},
82 err += sn9c102_write_reg(cam, 0x44, 0x52); 79 {0x07, 0x88}, {0x00, 0x89},
83 err += sn9c102_write_reg(cam, 0x00, 0x53); 80 {0xEC, 0x8A}, {0x0f, 0x8B},
84 err += sn9c102_write_reg(cam, 0xC7, 0x54); 81 {0xD8, 0x8C}, {0x0f, 0x8D},
85 err += sn9c102_write_reg(cam, 0x01, 0x55); 82 {0x3D, 0x8E}, {0x00, 0x8F},
86 err += sn9c102_write_reg(cam, 0xC7, 0x56); 83 {0x3D, 0x90}, {0x00, 0x91},
87 err += sn9c102_write_reg(cam, 0x01, 0x57); 84 {0xCD, 0x92}, {0x0f, 0x93},
88 err += sn9c102_write_reg(cam, 0xC7, 0x58); 85 {0xf7, 0x94}, {0x0f, 0x95},
89 err += sn9c102_write_reg(cam, 0x01, 0x59); 86 {0x0C, 0x96}, {0x00, 0x97},
90 err += sn9c102_write_reg(cam, 0x44, 0x5A); 87 {0x00, 0x98}, {0x66, 0x99},
91 err += sn9c102_write_reg(cam, 0x00, 0x5B); 88 {0x05, 0x9A}, {0x00, 0x9B},
92 err += sn9c102_write_reg(cam, 0x44, 0x5C); 89 {0x04, 0x9C}, {0x00, 0x9D},
93 err += sn9c102_write_reg(cam, 0x00, 0x5D); 90 {0x08, 0x9E}, {0x00, 0x9F},
94 err += sn9c102_write_reg(cam, 0x44, 0x5E); 91 {0x2D, 0xC0}, {0x2D, 0xC1},
95 err += sn9c102_write_reg(cam, 0x00, 0x5F); 92 {0x3A, 0xC2}, {0x05, 0xC3},
96 err += sn9c102_write_reg(cam, 0xC7, 0x60); 93 {0x04, 0xC4}, {0x3F, 0xC5},
97 err += sn9c102_write_reg(cam, 0x01, 0x61); 94 {0x00, 0xC6}, {0x00, 0xC7},
98 err += sn9c102_write_reg(cam, 0xC7, 0x62); 95 {0x50, 0xC8}, {0x3C, 0xC9},
99 err += sn9c102_write_reg(cam, 0x01, 0x63); 96 {0x28, 0xCA}, {0xD8, 0xCB},
100 err += sn9c102_write_reg(cam, 0xC7, 0x64); 97 {0x14, 0xCC}, {0xEC, 0xCD},
101 err += sn9c102_write_reg(cam, 0x01, 0x65); 98 {0x32, 0xCE}, {0xDD, 0xCF},
102 err += sn9c102_write_reg(cam, 0x44, 0x66); 99 {0x32, 0xD0}, {0xDD, 0xD1},
103 err += sn9c102_write_reg(cam, 0x00, 0x67); 100 {0x6A, 0xD2}, {0x50, 0xD3},
104 err += sn9c102_write_reg(cam, 0x44, 0x68); 101 {0x00, 0xD4}, {0x00, 0xD5},
105 err += sn9c102_write_reg(cam, 0x00, 0x69); 102 {0x00, 0xD6});
106 err += sn9c102_write_reg(cam, 0x44, 0x6A);
107 err += sn9c102_write_reg(cam, 0x00, 0x6B);
108 err += sn9c102_write_reg(cam, 0xC7, 0x6C);
109 err += sn9c102_write_reg(cam, 0x01, 0x6D);
110 err += sn9c102_write_reg(cam, 0xC7, 0x6E);
111 err += sn9c102_write_reg(cam, 0x01, 0x6F);
112 err += sn9c102_write_reg(cam, 0xC7, 0x70);
113 err += sn9c102_write_reg(cam, 0x01, 0x71);
114 err += sn9c102_write_reg(cam, 0x44, 0x72);
115 err += sn9c102_write_reg(cam, 0x00, 0x73);
116 err += sn9c102_write_reg(cam, 0x44, 0x74);
117 err += sn9c102_write_reg(cam, 0x00, 0x75);
118 err += sn9c102_write_reg(cam, 0x44, 0x76);
119 err += sn9c102_write_reg(cam, 0x00, 0x77);
120 err += sn9c102_write_reg(cam, 0xC7, 0x78);
121 err += sn9c102_write_reg(cam, 0x01, 0x79);
122 err += sn9c102_write_reg(cam, 0xC7, 0x7A);
123 err += sn9c102_write_reg(cam, 0x01, 0x7B);
124 err += sn9c102_write_reg(cam, 0xC7, 0x7C);
125 err += sn9c102_write_reg(cam, 0x01, 0x7D);
126 err += sn9c102_write_reg(cam, 0x44, 0x7E);
127 err += sn9c102_write_reg(cam, 0x00, 0x7F);
128 err += sn9c102_write_reg(cam, 0x14, 0x84);
129 err += sn9c102_write_reg(cam, 0x00, 0x85);
130 err += sn9c102_write_reg(cam, 0x27, 0x86);
131 err += sn9c102_write_reg(cam, 0x00, 0x87);
132 err += sn9c102_write_reg(cam, 0x07, 0x88);
133 err += sn9c102_write_reg(cam, 0x00, 0x89);
134 err += sn9c102_write_reg(cam, 0xEC, 0x8A);
135 err += sn9c102_write_reg(cam, 0x0f, 0x8B);
136 err += sn9c102_write_reg(cam, 0xD8, 0x8C);
137 err += sn9c102_write_reg(cam, 0x0f, 0x8D);
138 err += sn9c102_write_reg(cam, 0x3D, 0x8E);
139 err += sn9c102_write_reg(cam, 0x00, 0x8F);
140 err += sn9c102_write_reg(cam, 0x3D, 0x90);
141 err += sn9c102_write_reg(cam, 0x00, 0x91);
142 err += sn9c102_write_reg(cam, 0xCD, 0x92);
143 err += sn9c102_write_reg(cam, 0x0f, 0x93);
144 err += sn9c102_write_reg(cam, 0xf7, 0x94);
145 err += sn9c102_write_reg(cam, 0x0f, 0x95);
146 err += sn9c102_write_reg(cam, 0x0C, 0x96);
147 err += sn9c102_write_reg(cam, 0x00, 0x97);
148 err += sn9c102_write_reg(cam, 0x00, 0x98);
149 err += sn9c102_write_reg(cam, 0x66, 0x99);
150 err += sn9c102_write_reg(cam, 0x05, 0x9A);
151 err += sn9c102_write_reg(cam, 0x00, 0x9B);
152 err += sn9c102_write_reg(cam, 0x04, 0x9C);
153 err += sn9c102_write_reg(cam, 0x00, 0x9D);
154 err += sn9c102_write_reg(cam, 0x08, 0x9E);
155 err += sn9c102_write_reg(cam, 0x00, 0x9F);
156 err += sn9c102_write_reg(cam, 0x2D, 0xC0);
157 err += sn9c102_write_reg(cam, 0x2D, 0xC1);
158 err += sn9c102_write_reg(cam, 0x3A, 0xC2);
159 err += sn9c102_write_reg(cam, 0x05, 0xC3);
160 err += sn9c102_write_reg(cam, 0x04, 0xC4);
161 err += sn9c102_write_reg(cam, 0x3F, 0xC5);
162 err += sn9c102_write_reg(cam, 0x00, 0xC6);
163 err += sn9c102_write_reg(cam, 0x00, 0xC7);
164 err += sn9c102_write_reg(cam, 0x50, 0xC8);
165 err += sn9c102_write_reg(cam, 0x3C, 0xC9);
166 err += sn9c102_write_reg(cam, 0x28, 0xCA);
167 err += sn9c102_write_reg(cam, 0xD8, 0xCB);
168 err += sn9c102_write_reg(cam, 0x14, 0xCC);
169 err += sn9c102_write_reg(cam, 0xEC, 0xCD);
170 err += sn9c102_write_reg(cam, 0x32, 0xCE);
171 err += sn9c102_write_reg(cam, 0xDD, 0xCF);
172 err += sn9c102_write_reg(cam, 0x32, 0xD0);
173 err += sn9c102_write_reg(cam, 0xDD, 0xD1);
174 err += sn9c102_write_reg(cam, 0x6A, 0xD2);
175 err += sn9c102_write_reg(cam, 0x50, 0xD3);
176 err += sn9c102_write_reg(cam, 0x00, 0xD4);
177 err += sn9c102_write_reg(cam, 0x00, 0xD5);
178 err += sn9c102_write_reg(cam, 0x00, 0xD6);
179 103
180 err += sn9c102_i2c_write(cam, 0x12, 0x80); 104 err += sn9c102_i2c_write(cam, 0x12, 0x80);
181 err += sn9c102_i2c_write(cam, 0x11, 0x09); 105 err += sn9c102_i2c_write(cam, 0x11, 0x09);
@@ -572,13 +496,11 @@ static struct sn9c102_sensor ov7660 = {
572 496
573int sn9c102_probe_ov7660(struct sn9c102_device* cam) 497int sn9c102_probe_ov7660(struct sn9c102_device* cam)
574{ 498{
575 int pid, ver, err = 0; 499 int pid, ver, err;
576 500
577 err += sn9c102_write_reg(cam, 0x01, 0xf1); 501 err = sn9c102_write_const_regs(cam, {0x01, 0xf1}, {0x00, 0xf1},
578 err += sn9c102_write_reg(cam, 0x00, 0xf1); 502 {0x01, 0x01}, {0x00, 0x01},
579 err += sn9c102_write_reg(cam, 0x01, 0x01); 503 {0x28, 0x17});
580 err += sn9c102_write_reg(cam, 0x00, 0x01);
581 err += sn9c102_write_reg(cam, 0x28, 0x17);
582 504
583 pid = sn9c102_i2c_try_read(cam, &ov7660, 0x0a); 505 pid = sn9c102_i2c_try_read(cam, &ov7660, 0x0a);
584 ver = sn9c102_i2c_try_read(cam, &ov7660, 0x0b); 506 ver = sn9c102_i2c_try_read(cam, &ov7660, 0x0b);
diff --git a/drivers/media/video/sn9c102/sn9c102_pas106b.c b/drivers/media/video/sn9c102/sn9c102_pas106b.c
index 8d79a5fae5de..67151964801f 100644
--- a/drivers/media/video/sn9c102/sn9c102_pas106b.c
+++ b/drivers/media/video/sn9c102/sn9c102_pas106b.c
@@ -23,19 +23,13 @@
23#include "sn9c102_sensor.h" 23#include "sn9c102_sensor.h"
24 24
25 25
26static struct sn9c102_sensor pas106b;
27
28
29static int pas106b_init(struct sn9c102_device* cam) 26static int pas106b_init(struct sn9c102_device* cam)
30{ 27{
31 int err = 0; 28 int err = 0;
32 29
33 err += sn9c102_write_reg(cam, 0x00, 0x10); 30 err = sn9c102_write_const_regs(cam, {0x00, 0x10}, {0x00, 0x11},
34 err += sn9c102_write_reg(cam, 0x00, 0x11); 31 {0x00, 0x14}, {0x20, 0x17},
35 err += sn9c102_write_reg(cam, 0x00, 0x14); 32 {0x20, 0x19}, {0x09, 0x18});
36 err += sn9c102_write_reg(cam, 0x20, 0x17);
37 err += sn9c102_write_reg(cam, 0x20, 0x19);
38 err += sn9c102_write_reg(cam, 0x09, 0x18);
39 33
40 err += sn9c102_i2c_write(cam, 0x02, 0x0c); 34 err += sn9c102_i2c_write(cam, 0x02, 0x0c);
41 err += sn9c102_i2c_write(cam, 0x05, 0x5a); 35 err += sn9c102_i2c_write(cam, 0x05, 0x5a);
@@ -172,7 +166,7 @@ static int pas106b_set_pix_format(struct sn9c102_device* cam,
172static struct sn9c102_sensor pas106b = { 166static struct sn9c102_sensor pas106b = {
173 .name = "PAS106B", 167 .name = "PAS106B",
174 .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>", 168 .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
175 .supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102 | BRIDGE_SN9C103, 169 .supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102,
176 .sysfs_ops = SN9C102_I2C_READ | SN9C102_I2C_WRITE, 170 .sysfs_ops = SN9C102_I2C_READ | SN9C102_I2C_WRITE,
177 .frequency = SN9C102_I2C_400KHZ | SN9C102_I2C_100KHZ, 171 .frequency = SN9C102_I2C_400KHZ | SN9C102_I2C_100KHZ,
178 .interface = SN9C102_I2C_2WIRES, 172 .interface = SN9C102_I2C_2WIRES,
@@ -279,16 +273,17 @@ static struct sn9c102_sensor pas106b = {
279 273
280int sn9c102_probe_pas106b(struct sn9c102_device* cam) 274int sn9c102_probe_pas106b(struct sn9c102_device* cam)
281{ 275{
282 int r0 = 0, r1 = 0, err = 0; 276 int r0 = 0, r1 = 0, err;
283 unsigned int pid = 0; 277 unsigned int pid = 0;
284 278
285 /* 279 /*
286 Minimal initialization to enable the I2C communication 280 Minimal initialization to enable the I2C communication
287 NOTE: do NOT change the values! 281 NOTE: do NOT change the values!
288 */ 282 */
289 err += sn9c102_write_reg(cam, 0x01, 0x01); /* sensor power down */ 283 err = sn9c102_write_const_regs(cam,
290 err += sn9c102_write_reg(cam, 0x00, 0x01); /* sensor power on */ 284 {0x01, 0x01}, /* sensor power down */
291 err += sn9c102_write_reg(cam, 0x28, 0x17); /* sensor clock at 24 MHz */ 285 {0x00, 0x01}, /* sensor power on */
286 {0x28, 0x17});/* sensor clock 24 MHz */
292 if (err) 287 if (err)
293 return -EIO; 288 return -EIO;
294 289
diff --git a/drivers/media/video/sn9c102/sn9c102_pas202bcb.c b/drivers/media/video/sn9c102/sn9c102_pas202bcb.c
index 7894f01b56e8..c1b8d6b63b47 100644
--- a/drivers/media/video/sn9c102/sn9c102_pas202bcb.c
+++ b/drivers/media/video/sn9c102/sn9c102_pas202bcb.c
@@ -28,9 +28,6 @@
28#include "sn9c102_sensor.h" 28#include "sn9c102_sensor.h"
29 29
30 30
31static struct sn9c102_sensor pas202bcb;
32
33
34static int pas202bcb_init(struct sn9c102_device* cam) 31static int pas202bcb_init(struct sn9c102_device* cam)
35{ 32{
36 int err = 0; 33 int err = 0;
@@ -38,47 +35,29 @@ static int pas202bcb_init(struct sn9c102_device* cam)
38 switch (sn9c102_get_bridge(cam)) { 35 switch (sn9c102_get_bridge(cam)) {
39 case BRIDGE_SN9C101: 36 case BRIDGE_SN9C101:
40 case BRIDGE_SN9C102: 37 case BRIDGE_SN9C102:
41 err += sn9c102_write_reg(cam, 0x00, 0x10); 38 err = sn9c102_write_const_regs(cam, {0x00, 0x10},
42 err += sn9c102_write_reg(cam, 0x00, 0x11); 39 {0x00, 0x11}, {0x00, 0x14},
43 err += sn9c102_write_reg(cam, 0x00, 0x14); 40 {0x20, 0x17}, {0x30, 0x19},
44 err += sn9c102_write_reg(cam, 0x20, 0x17); 41 {0x09, 0x18});
45 err += sn9c102_write_reg(cam, 0x30, 0x19);
46 err += sn9c102_write_reg(cam, 0x09, 0x18);
47 break; 42 break;
48 case BRIDGE_SN9C103: 43 case BRIDGE_SN9C103:
49 err += sn9c102_write_reg(cam, 0x00, 0x02); 44 err = sn9c102_write_const_regs(cam, {0x00, 0x02},
50 err += sn9c102_write_reg(cam, 0x00, 0x03); 45 {0x00, 0x03}, {0x1a, 0x04},
51 err += sn9c102_write_reg(cam, 0x1a, 0x04); 46 {0x20, 0x05}, {0x20, 0x06},
52 err += sn9c102_write_reg(cam, 0x20, 0x05); 47 {0x20, 0x07}, {0x00, 0x10},
53 err += sn9c102_write_reg(cam, 0x20, 0x06); 48 {0x00, 0x11}, {0x00, 0x14},
54 err += sn9c102_write_reg(cam, 0x20, 0x07); 49 {0x20, 0x17}, {0x30, 0x19},
55 err += sn9c102_write_reg(cam, 0x00, 0x10); 50 {0x09, 0x18}, {0x02, 0x1c},
56 err += sn9c102_write_reg(cam, 0x00, 0x11); 51 {0x03, 0x1d}, {0x0f, 0x1e},
57 err += sn9c102_write_reg(cam, 0x00, 0x14); 52 {0x0c, 0x1f}, {0x00, 0x20},
58 err += sn9c102_write_reg(cam, 0x20, 0x17); 53 {0x10, 0x21}, {0x20, 0x22},
59 err += sn9c102_write_reg(cam, 0x30, 0x19); 54 {0x30, 0x23}, {0x40, 0x24},
60 err += sn9c102_write_reg(cam, 0x09, 0x18); 55 {0x50, 0x25}, {0x60, 0x26},
61 err += sn9c102_write_reg(cam, 0x02, 0x1c); 56 {0x70, 0x27}, {0x80, 0x28},
62 err += sn9c102_write_reg(cam, 0x03, 0x1d); 57 {0x90, 0x29}, {0xa0, 0x2a},
63 err += sn9c102_write_reg(cam, 0x0f, 0x1e); 58 {0xb0, 0x2b}, {0xc0, 0x2c},
64 err += sn9c102_write_reg(cam, 0x0c, 0x1f); 59 {0xd0, 0x2d}, {0xe0, 0x2e},
65 err += sn9c102_write_reg(cam, 0x00, 0x20); 60 {0xf0, 0x2f}, {0xff, 0x30});
66 err += sn9c102_write_reg(cam, 0x10, 0x21);
67 err += sn9c102_write_reg(cam, 0x20, 0x22);
68 err += sn9c102_write_reg(cam, 0x30, 0x23);
69 err += sn9c102_write_reg(cam, 0x40, 0x24);
70 err += sn9c102_write_reg(cam, 0x50, 0x25);
71 err += sn9c102_write_reg(cam, 0x60, 0x26);
72 err += sn9c102_write_reg(cam, 0x70, 0x27);
73 err += sn9c102_write_reg(cam, 0x80, 0x28);
74 err += sn9c102_write_reg(cam, 0x90, 0x29);
75 err += sn9c102_write_reg(cam, 0xa0, 0x2a);
76 err += sn9c102_write_reg(cam, 0xb0, 0x2b);
77 err += sn9c102_write_reg(cam, 0xc0, 0x2c);
78 err += sn9c102_write_reg(cam, 0xd0, 0x2d);
79 err += sn9c102_write_reg(cam, 0xe0, 0x2e);
80 err += sn9c102_write_reg(cam, 0xf0, 0x2f);
81 err += sn9c102_write_reg(cam, 0xff, 0x30);
82 break; 61 break;
83 default: 62 default:
84 break; 63 break;
@@ -328,15 +307,15 @@ int sn9c102_probe_pas202bcb(struct sn9c102_device* cam)
328 switch (sn9c102_get_bridge(cam)) { 307 switch (sn9c102_get_bridge(cam)) {
329 case BRIDGE_SN9C101: 308 case BRIDGE_SN9C101:
330 case BRIDGE_SN9C102: 309 case BRIDGE_SN9C102:
331 err += sn9c102_write_reg(cam, 0x01, 0x01); /* power down */ 310 err = sn9c102_write_const_regs(cam,
332 err += sn9c102_write_reg(cam, 0x40, 0x01); /* power on */ 311 {0x01, 0x01}, /* power down */
333 err += sn9c102_write_reg(cam, 0x28, 0x17); /* clock 24 MHz */ 312 {0x40, 0x01}, /* power on */
313 {0x28, 0x17});/* clock 24 MHz */
334 break; 314 break;
335 case BRIDGE_SN9C103: /* do _not_ change anything! */ 315 case BRIDGE_SN9C103: /* do _not_ change anything! */
336 err += sn9c102_write_reg(cam, 0x09, 0x01); 316 err = sn9c102_write_const_regs(cam, {0x09, 0x01},
337 err += sn9c102_write_reg(cam, 0x44, 0x01); 317 {0x44, 0x01}, {0x44, 0x02},
338 err += sn9c102_write_reg(cam, 0x44, 0x02); 318 {0x29, 0x17});
339 err += sn9c102_write_reg(cam, 0x29, 0x17);
340 break; 319 break;
341 default: 320 default:
342 break; 321 break;
diff --git a/drivers/media/video/sn9c102/sn9c102_sensor.h b/drivers/media/video/sn9c102/sn9c102_sensor.h
index 05f2942639c3..1bbf64c897a2 100644
--- a/drivers/media/video/sn9c102/sn9c102_sensor.h
+++ b/drivers/media/video/sn9c102/sn9c102_sensor.h
@@ -114,9 +114,17 @@ extern int sn9c102_i2c_write(struct sn9c102_device*, u8 address, u8 value);
114extern int sn9c102_i2c_read(struct sn9c102_device*, u8 address); 114extern int sn9c102_i2c_read(struct sn9c102_device*, u8 address);
115 115
116/* I/O on registers in the bridge. Could be used by the sensor methods too */ 116/* I/O on registers in the bridge. Could be used by the sensor methods too */
117extern int sn9c102_write_regs(struct sn9c102_device*, u8* buff, u16 index);
118extern int sn9c102_write_reg(struct sn9c102_device*, u8 value, u16 index);
119extern int sn9c102_pread_reg(struct sn9c102_device*, u16 index); 117extern int sn9c102_pread_reg(struct sn9c102_device*, u16 index);
118extern int sn9c102_write_reg(struct sn9c102_device*, u8 value, u16 index);
119extern int sn9c102_write_regs(struct sn9c102_device*, const u8 valreg[][2],
120 int count);
121/*
122 * Write multiple registers with constant values. For example:
123 * sn9c102_write_const_regs(cam, {0x00, 0x14}, {0x60, 0x17}, {0x0f, 0x18});
124 */
125#define sn9c102_write_const_regs(device, data...) \
126 ({ const static u8 _data[][2] = {data}; \
127 sn9c102_write_regs(device, _data, ARRAY_SIZE(_data)); })
120 128
121/*****************************************************************************/ 129/*****************************************************************************/
122 130
diff --git a/drivers/media/video/sn9c102/sn9c102_tas5110c1b.c b/drivers/media/video/sn9c102/sn9c102_tas5110c1b.c
index 90023ad63adc..0e7ec8662c70 100644
--- a/drivers/media/video/sn9c102/sn9c102_tas5110c1b.c
+++ b/drivers/media/video/sn9c102/sn9c102_tas5110c1b.c
@@ -22,21 +22,14 @@
22#include "sn9c102_sensor.h" 22#include "sn9c102_sensor.h"
23 23
24 24
25static struct sn9c102_sensor tas5110c1b;
26
27
28static int tas5110c1b_init(struct sn9c102_device* cam) 25static int tas5110c1b_init(struct sn9c102_device* cam)
29{ 26{
30 int err = 0; 27 int err = 0;
31 28
32 err += sn9c102_write_reg(cam, 0x01, 0x01); 29 err = sn9c102_write_const_regs(cam, {0x01, 0x01}, {0x44, 0x01},
33 err += sn9c102_write_reg(cam, 0x44, 0x01); 30 {0x00, 0x10}, {0x00, 0x11},
34 err += sn9c102_write_reg(cam, 0x00, 0x10); 31 {0x0a, 0x14}, {0x60, 0x17},
35 err += sn9c102_write_reg(cam, 0x00, 0x11); 32 {0x06, 0x18}, {0xfb, 0x19});
36 err += sn9c102_write_reg(cam, 0x0a, 0x14);
37 err += sn9c102_write_reg(cam, 0x60, 0x17);
38 err += sn9c102_write_reg(cam, 0x06, 0x18);
39 err += sn9c102_write_reg(cam, 0xfb, 0x19);
40 33
41 err += sn9c102_i2c_write(cam, 0xc0, 0x80); 34 err += sn9c102_i2c_write(cam, 0xc0, 0x80);
42 35
@@ -98,7 +91,7 @@ static int tas5110c1b_set_pix_format(struct sn9c102_device* cam,
98static struct sn9c102_sensor tas5110c1b = { 91static struct sn9c102_sensor tas5110c1b = {
99 .name = "TAS5110C1B", 92 .name = "TAS5110C1B",
100 .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>", 93 .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
101 .supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102 | BRIDGE_SN9C103, 94 .supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102,
102 .sysfs_ops = SN9C102_I2C_WRITE, 95 .sysfs_ops = SN9C102_I2C_WRITE,
103 .frequency = SN9C102_I2C_100KHZ, 96 .frequency = SN9C102_I2C_100KHZ,
104 .interface = SN9C102_I2C_3WIRES, 97 .interface = SN9C102_I2C_3WIRES,
@@ -146,7 +139,6 @@ int sn9c102_probe_tas5110c1b(struct sn9c102_device* cam)
146 const struct usb_device_id tas5110c1b_id_table[] = { 139 const struct usb_device_id tas5110c1b_id_table[] = {
147 { USB_DEVICE(0x0c45, 0x6001), }, 140 { USB_DEVICE(0x0c45, 0x6001), },
148 { USB_DEVICE(0x0c45, 0x6005), }, 141 { USB_DEVICE(0x0c45, 0x6005), },
149 { USB_DEVICE(0x0c45, 0x6007), },
150 { USB_DEVICE(0x0c45, 0x60ab), }, 142 { USB_DEVICE(0x0c45, 0x60ab), },
151 { } 143 { }
152 }; 144 };
diff --git a/drivers/media/video/sn9c102/sn9c102_tas5110d.c b/drivers/media/video/sn9c102/sn9c102_tas5110d.c
new file mode 100644
index 000000000000..83a39e8b5e71
--- /dev/null
+++ b/drivers/media/video/sn9c102/sn9c102_tas5110d.c
@@ -0,0 +1,118 @@
1/***************************************************************************
2 * Plug-in for TAS5110D image sensor connected to the SN9C1xx PC Camera *
3 * Controllers *
4 * *
5 * Copyright (C) 2007 by Luca Risolia <luca.risolia@studio.unibo.it> *
6 * *
7 * This program is free software; you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation; either version 2 of the License, or *
10 * (at your option) any later version. *
11 * *
12 * This program is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 * GNU General Public License for more details. *
16 * *
17 * You should have received a copy of the GNU General Public License *
18 * along with this program; if not, write to the Free Software *
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
20 ***************************************************************************/
21
22#include "sn9c102_sensor.h"
23
24
25static int tas5110d_init(struct sn9c102_device* cam)
26{
27 int err;
28
29 err = sn9c102_write_const_regs(cam, {0x01, 0x01}, {0x04, 0x01},
30 {0x0a, 0x14}, {0x60, 0x17},
31 {0x06, 0x18}, {0xfb, 0x19});
32
33 err += sn9c102_i2c_write(cam, 0x9a, 0xca);
34
35 return err;
36}
37
38
39static int tas5110d_set_crop(struct sn9c102_device* cam,
40 const struct v4l2_rect* rect)
41{
42 struct sn9c102_sensor* s = sn9c102_get_sensor(cam);
43 int err = 0;
44 u8 h_start = (u8)(rect->left - s->cropcap.bounds.left) + 69,
45 v_start = (u8)(rect->top - s->cropcap.bounds.top) + 9;
46
47 err += sn9c102_write_reg(cam, h_start, 0x12);
48 err += sn9c102_write_reg(cam, v_start, 0x13);
49
50 err += sn9c102_write_reg(cam, 0x14, 0x1a);
51 err += sn9c102_write_reg(cam, 0x0a, 0x1b);
52
53 return err;
54}
55
56
57static int tas5110d_set_pix_format(struct sn9c102_device* cam,
58 const struct v4l2_pix_format* pix)
59{
60 int err = 0;
61
62 if (pix->pixelformat == V4L2_PIX_FMT_SN9C10X)
63 err += sn9c102_write_reg(cam, 0x3b, 0x19);
64 else
65 err += sn9c102_write_reg(cam, 0xfb, 0x19);
66
67 return err;
68}
69
70
71static struct sn9c102_sensor tas5110d = {
72 .name = "TAS5110D",
73 .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
74 .supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102,
75 .sysfs_ops = SN9C102_I2C_WRITE,
76 .frequency = SN9C102_I2C_100KHZ,
77 .interface = SN9C102_I2C_2WIRES,
78 .i2c_slave_id = 0x61,
79 .init = &tas5110d_init,
80 .cropcap = {
81 .bounds = {
82 .left = 0,
83 .top = 0,
84 .width = 352,
85 .height = 288,
86 },
87 .defrect = {
88 .left = 0,
89 .top = 0,
90 .width = 352,
91 .height = 288,
92 },
93 },
94 .set_crop = &tas5110d_set_crop,
95 .pix_format = {
96 .width = 352,
97 .height = 288,
98 .pixelformat = V4L2_PIX_FMT_SBGGR8,
99 .priv = 8,
100 },
101 .set_pix_format = &tas5110d_set_pix_format
102};
103
104
105int sn9c102_probe_tas5110d(struct sn9c102_device* cam)
106{
107 const struct usb_device_id tas5110d_id_table[] = {
108 { USB_DEVICE(0x0c45, 0x6007), },
109 { }
110 };
111
112 if (!sn9c102_match_id(cam, tas5110d_id_table))
113 return -ENODEV;
114
115 sn9c102_attach_sensor(cam, &tas5110d);
116
117 return 0;
118}
diff --git a/drivers/media/video/sn9c102/sn9c102_tas5130d1b.c b/drivers/media/video/sn9c102/sn9c102_tas5130d1b.c
index cb1b318bc1ff..50406503fc40 100644
--- a/drivers/media/video/sn9c102/sn9c102_tas5130d1b.c
+++ b/drivers/media/video/sn9c102/sn9c102_tas5130d1b.c
@@ -22,21 +22,14 @@
22#include "sn9c102_sensor.h" 22#include "sn9c102_sensor.h"
23 23
24 24
25static struct sn9c102_sensor tas5130d1b;
26
27
28static int tas5130d1b_init(struct sn9c102_device* cam) 25static int tas5130d1b_init(struct sn9c102_device* cam)
29{ 26{
30 int err = 0; 27 int err;
31 28
32 err += sn9c102_write_reg(cam, 0x01, 0x01); 29 err = sn9c102_write_const_regs(cam, {0x01, 0x01}, {0x20, 0x17},
33 err += sn9c102_write_reg(cam, 0x20, 0x17); 30 {0x04, 0x01}, {0x01, 0x10},
34 err += sn9c102_write_reg(cam, 0x04, 0x01); 31 {0x00, 0x11}, {0x00, 0x14},
35 err += sn9c102_write_reg(cam, 0x01, 0x10); 32 {0x60, 0x17}, {0x07, 0x18});
36 err += sn9c102_write_reg(cam, 0x00, 0x11);
37 err += sn9c102_write_reg(cam, 0x00, 0x14);
38 err += sn9c102_write_reg(cam, 0x60, 0x17);
39 err += sn9c102_write_reg(cam, 0x07, 0x18);
40 33
41 return err; 34 return err;
42} 35}
@@ -99,7 +92,7 @@ static int tas5130d1b_set_pix_format(struct sn9c102_device* cam,
99static struct sn9c102_sensor tas5130d1b = { 92static struct sn9c102_sensor tas5130d1b = {
100 .name = "TAS5130D1B", 93 .name = "TAS5130D1B",
101 .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>", 94 .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
102 .supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102 | BRIDGE_SN9C103, 95 .supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102,
103 .sysfs_ops = SN9C102_I2C_WRITE, 96 .sysfs_ops = SN9C102_I2C_WRITE,
104 .frequency = SN9C102_I2C_100KHZ, 97 .frequency = SN9C102_I2C_100KHZ,
105 .interface = SN9C102_I2C_3WIRES, 98 .interface = SN9C102_I2C_3WIRES,
diff --git a/drivers/media/video/tda7432.c b/drivers/media/video/tda7432.c
index d1ccc064206f..43225802a551 100644
--- a/drivers/media/video/tda7432.c
+++ b/drivers/media/video/tda7432.c
@@ -45,7 +45,6 @@
45#include <linux/slab.h> 45#include <linux/slab.h>
46#include <linux/videodev.h> 46#include <linux/videodev.h>
47#include <linux/i2c.h> 47#include <linux/i2c.h>
48#include <linux/i2c-algo-bit.h>
49 48
50#include <media/v4l2-common.h> 49#include <media/v4l2-common.h>
51#include <media/i2c-addr.h> 50#include <media/i2c-addr.h>
diff --git a/drivers/media/video/tda8290.c b/drivers/media/video/tda8290.c
index 027c8a074dfe..1a1bef0e9c3d 100644
--- a/drivers/media/video/tda8290.c
+++ b/drivers/media/video/tda8290.c
@@ -192,14 +192,52 @@ static struct tda827xa_data tda827xa_analog[] = {
192 { .lomax = 0, .svco = 0, .spd = 0, .scr = 0, .sbs = 0, .gc3 = 0} /* End */ 192 { .lomax = 0, .svco = 0, .spd = 0, .scr = 0, .sbs = 0, .gc3 = 0} /* End */
193}; 193};
194 194
195static void tda827xa_lna_gain(struct i2c_client *c, int high)
196{
197 struct tuner *t = i2c_get_clientdata(c);
198 unsigned char buf[] = {0x22, 0x01};
199 int arg;
200 struct i2c_msg msg = {.addr = c->addr, .flags = 0, .buf = buf, .len = sizeof(buf)};
201 if (t->config) {
202 if (high)
203 tuner_dbg("setting LNA to high gain\n");
204 else
205 tuner_dbg("setting LNA to low gain\n");
206 }
207 switch (t->config) {
208 case 0: /* no LNA */
209 break;
210 case 1: /* switch is GPIO 0 of tda8290 */
211 case 2:
212 /* turn Vsync on */
213 if (t->std & V4L2_STD_MN)
214 arg = 1;
215 else
216 arg = 0;
217 if (t->tuner_callback)
218 t->tuner_callback(c->adapter->algo_data, 1, arg);
219 buf[1] = high ? 0 : 1;
220 if (t->config == 2)
221 buf[1] = high ? 1 : 0;
222 i2c_transfer(c->adapter, &msg, 1);
223 break;
224 case 3: /* switch with GPIO of saa713x */
225 if (t->tuner_callback)
226 t->tuner_callback(c->adapter->algo_data, 0, high);
227 break;
228 }
229}
230
195static void tda827xa_tune(struct i2c_client *c, u16 ifc, unsigned int freq) 231static void tda827xa_tune(struct i2c_client *c, u16 ifc, unsigned int freq)
196{ 232{
197 unsigned char tuner_reg[14]; 233 unsigned char tuner_reg[11];
198 unsigned char reg2[2];
199 u32 N; 234 u32 N;
200 int i; 235 int i;
201 struct tuner *t = i2c_get_clientdata(c); 236 struct tuner *t = i2c_get_clientdata(c);
202 struct i2c_msg msg = {.addr = t->tda827x_addr, .flags = 0}; 237 struct i2c_msg msg = {.addr = t->tda827x_addr, .flags = 0, .buf = tuner_reg};
238
239 tda827xa_lna_gain( c, 1);
240 msleep(10);
203 241
204 if (t->mode == V4L2_TUNER_RADIO) 242 if (t->mode == V4L2_TUNER_RADIO)
205 freq = freq / 1000; 243 freq = freq / 1000;
@@ -222,48 +260,58 @@ static void tda827xa_tune(struct i2c_client *c, u16 ifc, unsigned int freq)
222 tuner_reg[5] = (tda827xa_analog[i].spd << 5) + (tda827xa_analog[i].svco << 3) + 260 tuner_reg[5] = (tda827xa_analog[i].spd << 5) + (tda827xa_analog[i].svco << 3) +
223 tda827xa_analog[i].sbs; 261 tda827xa_analog[i].sbs;
224 tuner_reg[6] = 0x8b + (tda827xa_analog[i].gc3 << 4); 262 tuner_reg[6] = 0x8b + (tda827xa_analog[i].gc3 << 4);
225 tuner_reg[7] = 0x0c; 263 tuner_reg[7] = 0x1c;
226 tuner_reg[8] = 4; 264 tuner_reg[8] = 4;
227 tuner_reg[9] = 0x20; 265 tuner_reg[9] = 0x20;
228 tuner_reg[10] = 0xff; 266 tuner_reg[10] = 0x00;
229 tuner_reg[11] = 0xe0; 267 msg.len = 11;
230 tuner_reg[12] = 0; 268 i2c_transfer(c->adapter, &msg, 1);
231 tuner_reg[13] = 0x39 + (t->tda827x_lpsel << 1);
232 269
233 msg.buf = tuner_reg; 270 tuner_reg[0] = 0x90;
234 msg.len = 14; 271 tuner_reg[1] = 0xff;
272 tuner_reg[2] = 0xe0;
273 tuner_reg[3] = 0;
274 tuner_reg[4] = 0x99 + (t->tda827x_lpsel << 1);
275 msg.len = 5;
235 i2c_transfer(c->adapter, &msg, 1); 276 i2c_transfer(c->adapter, &msg, 1);
236 277
237 msg.buf= reg2; 278 tuner_reg[0] = 0xa0;
279 tuner_reg[1] = 0xc0;
238 msg.len = 2; 280 msg.len = 2;
239 reg2[0] = 0x60;
240 reg2[1] = 0x3c;
241 i2c_transfer(c->adapter, &msg, 1); 281 i2c_transfer(c->adapter, &msg, 1);
242 282
243 reg2[0] = 0xa0; 283 tuner_reg[0] = 0x30;
244 reg2[1] = 0xc0; 284 tuner_reg[1] = 0x10 + tda827xa_analog[i].scr;
245 i2c_transfer(c->adapter, &msg, 1); 285 i2c_transfer(c->adapter, &msg, 1);
246 286
247 msleep(2); 287 msg.flags = I2C_M_RD;
248 reg2[0] = 0x30; 288 i2c_transfer(c->adapter, &msg, 1);
249 reg2[1] = 0x10 + tda827xa_analog[i].scr; 289 msg.flags = 0;
290 tuner_reg[1] >>= 4;
291 tuner_dbg("AGC2 gain is: %d\n", tuner_reg[1]);
292 if (tuner_reg[1] < 1)
293 tda827xa_lna_gain( c, 0);
294
295 msleep(100);
296 tuner_reg[0] = 0x60;
297 tuner_reg[1] = 0x3c;
250 i2c_transfer(c->adapter, &msg, 1); 298 i2c_transfer(c->adapter, &msg, 1);
251 299
252 msleep(550); 300 msleep(163);
253 reg2[0] = 0x50; 301 tuner_reg[0] = 0x50;
254 reg2[1] = 0x8f + (tda827xa_analog[i].gc3 << 4); 302 tuner_reg[1] = 0x8f + (tda827xa_analog[i].gc3 << 4);
255 i2c_transfer(c->adapter, &msg, 1); 303 i2c_transfer(c->adapter, &msg, 1);
256 304
257 reg2[0] = 0x80; 305 tuner_reg[0] = 0x80;
258 reg2[1] = 0x28; 306 tuner_reg[1] = 0x28;
259 i2c_transfer(c->adapter, &msg, 1); 307 i2c_transfer(c->adapter, &msg, 1);
260 308
261 reg2[0] = 0xb0; 309 tuner_reg[0] = 0xb0;
262 reg2[1] = 0x01; 310 tuner_reg[1] = 0x01;
263 i2c_transfer(c->adapter, &msg, 1); 311 i2c_transfer(c->adapter, &msg, 1);
264 312
265 reg2[0] = 0xc0; 313 tuner_reg[0] = 0xc0;
266 reg2[1] = 0x19 + (t->tda827x_lpsel << 1); 314 tuner_reg[1] = 0x19 + (t->tda827x_lpsel << 1);
267 i2c_transfer(c->adapter, &msg, 1); 315 i2c_transfer(c->adapter, &msg, 1);
268} 316}
269 317
@@ -319,7 +367,9 @@ static int tda8290_tune(struct i2c_client *c, u16 ifc, unsigned int freq)
319 unsigned char addr_pll_stat = 0x1b; 367 unsigned char addr_pll_stat = 0x1b;
320 unsigned char adc_sat, agc_stat, 368 unsigned char adc_sat, agc_stat,
321 pll_stat; 369 pll_stat;
370 int i;
322 371
372 tuner_dbg("tda827xa config is 0x%02x\n", t->config);
323 i2c_master_send(c, easy_mode, 2); 373 i2c_master_send(c, easy_mode, 2);
324 i2c_master_send(c, agc_out_on, 2); 374 i2c_master_send(c, agc_out_on, 2);
325 i2c_master_send(c, soft_reset, 2); 375 i2c_master_send(c, soft_reset, 2);
@@ -340,17 +390,22 @@ static int tda8290_tune(struct i2c_client *c, u16 ifc, unsigned int freq)
340 tda827xa_tune(c, ifc, freq); 390 tda827xa_tune(c, ifc, freq);
341 else 391 else
342 tda827x_tune(c, ifc, freq); 392 tda827x_tune(c, ifc, freq);
393 for (i = 0; i < 3; i++) {
394 i2c_master_send(c, &addr_pll_stat, 1);
395 i2c_master_recv(c, &pll_stat, 1);
396 if (pll_stat & 0x80) {
397 i2c_master_send(c, &addr_adc_sat, 1);
398 i2c_master_recv(c, &adc_sat, 1);
399 i2c_master_send(c, &addr_agc_stat, 1);
400 i2c_master_recv(c, &agc_stat, 1);
401 tuner_dbg("tda8290 is locked, AGC: %d\n", agc_stat);
402 break;
403 } else {
404 tuner_dbg("tda8290 not locked, no signal?\n");
405 msleep(100);
406 }
407 }
343 /* adjust headroom resp. gain */ 408 /* adjust headroom resp. gain */
344 i2c_master_send(c, &addr_adc_sat, 1);
345 i2c_master_recv(c, &adc_sat, 1);
346 i2c_master_send(c, &addr_agc_stat, 1);
347 i2c_master_recv(c, &agc_stat, 1);
348 i2c_master_send(c, &addr_pll_stat, 1);
349 i2c_master_recv(c, &pll_stat, 1);
350 if (pll_stat & 0x80)
351 tuner_dbg("tda8290 is locked, AGC: %d\n", agc_stat);
352 else
353 tuner_dbg("tda8290 not locked, no signal?\n");
354 if ((agc_stat > 115) || (!(pll_stat & 0x80) && (adc_sat < 20))) { 409 if ((agc_stat > 115) || (!(pll_stat & 0x80) && (adc_sat < 20))) {
355 tuner_dbg("adjust gain, step 1. Agc: %d, ADC stat: %d, lock: %d\n", 410 tuner_dbg("adjust gain, step 1. Agc: %d, ADC stat: %d, lock: %d\n",
356 agc_stat, adc_sat, pll_stat & 0x80); 411 agc_stat, adc_sat, pll_stat & 0x80);
@@ -407,7 +462,6 @@ static void set_audio(struct tuner *t)
407 char* mode; 462 char* mode;
408 463
409 t->tda827x_lpsel = 0; 464 t->tda827x_lpsel = 0;
410 mode = "xx";
411 if (t->std & V4L2_STD_MN) { 465 if (t->std & V4L2_STD_MN) {
412 t->sgIF = 92; 466 t->sgIF = 92;
413 t->tda8290_easy_mode = 0x01; 467 t->tda8290_easy_mode = 0x01;
@@ -437,8 +491,12 @@ static void set_audio(struct tuner *t)
437 t->sgIF = 20; 491 t->sgIF = 20;
438 t->tda8290_easy_mode = 0x40; 492 t->tda8290_easy_mode = 0x40;
439 mode = "LC"; 493 mode = "LC";
494 } else {
495 t->sgIF = 124;
496 t->tda8290_easy_mode = 0x10;
497 mode = "xx";
440 } 498 }
441 tuner_dbg("setting tda8290 to system %s\n", mode); 499 tuner_dbg("setting tda8290 to system %s\n", mode);
442} 500}
443 501
444static void set_tv_freq(struct i2c_client *c, unsigned int freq) 502static void set_tv_freq(struct i2c_client *c, unsigned int freq)
@@ -487,11 +545,16 @@ static void standby(struct i2c_client *c)
487 545
488static void tda8290_init_if(struct i2c_client *c) 546static void tda8290_init_if(struct i2c_client *c)
489{ 547{
548 struct tuner *t = i2c_get_clientdata(c);
490 unsigned char set_VS[] = { 0x30, 0x6F }; 549 unsigned char set_VS[] = { 0x30, 0x6F };
550 unsigned char set_GP00_CF[] = { 0x20, 0x01 };
491 unsigned char set_GP01_CF[] = { 0x20, 0x0B }; 551 unsigned char set_GP01_CF[] = { 0x20, 0x0B };
492 552
553 if ((t->config == 1) || (t->config == 2))
554 i2c_master_send(c, set_GP00_CF, 2);
555 else
556 i2c_master_send(c, set_GP01_CF, 2);
493 i2c_master_send(c, set_VS, 2); 557 i2c_master_send(c, set_VS, 2);
494 i2c_master_send(c, set_GP01_CF, 2);
495} 558}
496 559
497static void tda8290_init_tuner(struct i2c_client *c) 560static void tda8290_init_tuner(struct i2c_client *c)
@@ -576,6 +639,7 @@ int tda8290_init(struct i2c_client *c)
576 t->has_signal = has_signal; 639 t->has_signal = has_signal;
577 t->standby = standby; 640 t->standby = standby;
578 t->tda827x_lpsel = 0; 641 t->tda827x_lpsel = 0;
642 t->mode = V4L2_TUNER_ANALOG_TV;
579 643
580 tda8290_init_tuner(c); 644 tda8290_init_tuner(c);
581 tda8290_init_if(c); 645 tda8290_init_if(c);
diff --git a/drivers/media/video/tda9875.c b/drivers/media/video/tda9875.c
index 00f0e8b6e03b..d11044170872 100644
--- a/drivers/media/video/tda9875.c
+++ b/drivers/media/video/tda9875.c
@@ -27,7 +27,6 @@
27#include <linux/videodev.h> 27#include <linux/videodev.h>
28#include <media/v4l2-common.h> 28#include <media/v4l2-common.h>
29#include <linux/i2c.h> 29#include <linux/i2c.h>
30#include <linux/i2c-algo-bit.h>
31#include <linux/init.h> 30#include <linux/init.h>
32 31
33 32
diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c
index 15dbc6bf42a7..505591a7abe9 100644
--- a/drivers/media/video/tuner-core.c
+++ b/drivers/media/video/tuner-core.c
@@ -144,7 +144,8 @@ static void set_freq(struct i2c_client *c, unsigned long freq)
144} 144}
145 145
146static void set_type(struct i2c_client *c, unsigned int type, 146static void set_type(struct i2c_client *c, unsigned int type,
147 unsigned int new_mode_mask) 147 unsigned int new_mode_mask, unsigned int new_config,
148 int (*tuner_callback) (void *dev, int command,int arg))
148{ 149{
149 struct tuner *t = i2c_get_clientdata(c); 150 struct tuner *t = i2c_get_clientdata(c);
150 unsigned char buffer[4]; 151 unsigned char buffer[4];
@@ -159,15 +160,20 @@ static void set_type(struct i2c_client *c, unsigned int type,
159 return; 160 return;
160 } 161 }
161 162
163 t->type = type;
164 t->config = new_config;
165 if (tuner_callback != NULL) {
166 tuner_dbg("defining GPIO callback\n");
167 t->tuner_callback = tuner_callback;
168 }
169
162 /* This code detects calls by card attach_inform */ 170 /* This code detects calls by card attach_inform */
163 if (NULL == t->i2c.dev.driver) { 171 if (NULL == t->i2c.dev.driver) {
164 tuner_dbg ("tuner 0x%02x: called during i2c_client register by adapter's attach_inform\n", c->addr); 172 tuner_dbg ("tuner 0x%02x: called during i2c_client register by adapter's attach_inform\n", c->addr);
165 173
166 t->type=type;
167 return; 174 return;
168 } 175 }
169 176
170 t->type = type;
171 switch (t->type) { 177 switch (t->type) {
172 case TUNER_MT2032: 178 case TUNER_MT2032:
173 microtune_init(c); 179 microtune_init(c);
@@ -234,10 +240,11 @@ static void set_addr(struct i2c_client *c, struct tuner_setup *tun_setup)
234 240
235 tuner_dbg("set addr for type %i\n", t->type); 241 tuner_dbg("set addr for type %i\n", t->type);
236 242
237 if ( t->type == UNSET && ((tun_setup->addr == ADDR_UNSET && 243 if ( (t->type == UNSET && ((tun_setup->addr == ADDR_UNSET) &&
238 (t->mode_mask & tun_setup->mode_mask)) || 244 (t->mode_mask & tun_setup->mode_mask))) ||
239 tun_setup->addr == c->addr)) { 245 (tun_setup->addr == c->addr)) {
240 set_type(c, tun_setup->type, tun_setup->mode_mask); 246 set_type(c, tun_setup->type, tun_setup->mode_mask,
247 tun_setup->config, tun_setup->tuner_callback);
241 } 248 }
242} 249}
243 250
@@ -496,7 +503,7 @@ static int tuner_attach(struct i2c_adapter *adap, int addr, int kind)
496register_client: 503register_client:
497 tuner_info("chip found @ 0x%x (%s)\n", addr << 1, adap->name); 504 tuner_info("chip found @ 0x%x (%s)\n", addr << 1, adap->name);
498 i2c_attach_client (&t->i2c); 505 i2c_attach_client (&t->i2c);
499 set_type (&t->i2c,t->type, t->mode_mask); 506 set_type (&t->i2c,t->type, t->mode_mask, t->config, t->tuner_callback);
500 return 0; 507 return 0;
501} 508}
502 509
@@ -576,10 +583,11 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
576 switch (cmd) { 583 switch (cmd) {
577 /* --- configuration --- */ 584 /* --- configuration --- */
578 case TUNER_SET_TYPE_ADDR: 585 case TUNER_SET_TYPE_ADDR:
579 tuner_dbg ("Calling set_type_addr for type=%d, addr=0x%02x, mode=0x%02x\n", 586 tuner_dbg ("Calling set_type_addr for type=%d, addr=0x%02x, mode=0x%02x, config=0x%02x\n",
580 ((struct tuner_setup *)arg)->type, 587 ((struct tuner_setup *)arg)->type,
581 ((struct tuner_setup *)arg)->addr, 588 ((struct tuner_setup *)arg)->addr,
582 ((struct tuner_setup *)arg)->mode_mask); 589 ((struct tuner_setup *)arg)->mode_mask,
590 ((struct tuner_setup *)arg)->config);
583 591
584 set_addr(client, (struct tuner_setup *)arg); 592 set_addr(client, (struct tuner_setup *)arg);
585 break; 593 break;
diff --git a/drivers/media/video/tvaudio.c b/drivers/media/video/tvaudio.c
index d506dfaa45a9..a2da5d2affff 100644
--- a/drivers/media/video/tvaudio.c
+++ b/drivers/media/video/tvaudio.c
@@ -25,7 +25,6 @@
25#include <linux/slab.h> 25#include <linux/slab.h>
26#include <linux/videodev.h> 26#include <linux/videodev.h>
27#include <linux/i2c.h> 27#include <linux/i2c.h>
28#include <linux/i2c-algo-bit.h>
29#include <linux/init.h> 28#include <linux/init.h>
30#include <linux/smp_lock.h> 29#include <linux/smp_lock.h>
31#include <linux/kthread.h> 30#include <linux/kthread.h>
@@ -33,6 +32,7 @@
33 32
34#include <media/tvaudio.h> 33#include <media/tvaudio.h>
35#include <media/v4l2-common.h> 34#include <media/v4l2-common.h>
35#include <media/v4l2-chip-ident.h>
36 36
37#include <media/i2c-addr.h> 37#include <media/i2c-addr.h>
38 38
@@ -1775,6 +1775,9 @@ static int chip_command(struct i2c_client *client,
1775 /* the thread will call checkmode() later */ 1775 /* the thread will call checkmode() later */
1776 } 1776 }
1777 break; 1777 break;
1778
1779 case VIDIOC_G_CHIP_IDENT:
1780 return v4l2_chip_ident_i2c_client(client, arg, V4L2_IDENT_TVAUDIO, 0);
1778 } 1781 }
1779 return 0; 1782 return 0;
1780} 1783}
diff --git a/drivers/media/video/tveeprom.c b/drivers/media/video/tveeprom.c
index 4e7c1fa668d3..a1136da74ba8 100644
--- a/drivers/media/video/tveeprom.c
+++ b/drivers/media/video/tveeprom.c
@@ -163,7 +163,7 @@ hauppauge_tuner[] =
163 /* 60-69 */ 163 /* 60-69 */
164 { TUNER_PHILIPS_FM1216ME_MK3, "LG S001D MK3"}, 164 { TUNER_PHILIPS_FM1216ME_MK3, "LG S001D MK3"},
165 { TUNER_ABSENT, "LG M001D MK3"}, 165 { TUNER_ABSENT, "LG M001D MK3"},
166 { TUNER_ABSENT, "LG S701D MK3"}, 166 { TUNER_PHILIPS_FM1216ME_MK3, "LG S701D MK3"},
167 { TUNER_ABSENT, "LG M701D MK3"}, 167 { TUNER_ABSENT, "LG M701D MK3"},
168 { TUNER_ABSENT, "Temic 4146FM5"}, 168 { TUNER_ABSENT, "Temic 4146FM5"},
169 { TUNER_ABSENT, "Temic 4136FY5"}, 169 { TUNER_ABSENT, "Temic 4136FY5"},
@@ -229,6 +229,36 @@ hauppauge_tuner[] =
229 /* 120-129 */ 229 /* 120-129 */
230 { TUNER_ABSENT, "Xceive XC3028"}, 230 { TUNER_ABSENT, "Xceive XC3028"},
231 { TUNER_ABSENT, "Philips FQ1216LME MK5"}, 231 { TUNER_ABSENT, "Philips FQ1216LME MK5"},
232 { TUNER_ABSENT, "Philips FQD1216LME"},
233 { TUNER_ABSENT, "Conexant CX24118A"},
234 { TUNER_ABSENT, "TCL DMF11WIP"},
235 { TUNER_ABSENT, "TCL MFNM05_4H_E"},
236 { TUNER_ABSENT, "TCL MNM05_4H_E"},
237 { TUNER_ABSENT, "TCL MPE05_2H_E"},
238 { TUNER_ABSENT, "TCL MQNM05_4_U"},
239 { TUNER_ABSENT, "TCL M2523_5NH_E"},
240 /* 130-139 */
241 { TUNER_ABSENT, "TCL M2523_3DBH_E"},
242 { TUNER_ABSENT, "TCL M2523_3DIH_E"},
243 { TUNER_ABSENT, "TCL MFPE05_2_U"},
244 { TUNER_ABSENT, "Philips FMD1216MEX"},
245 { TUNER_ABSENT, "Philips FRH2036B"},
246 { TUNER_ABSENT, "Panasonic ENGF75_01GF"},
247 { TUNER_ABSENT, "MaxLinear MXL5005"},
248 { TUNER_ABSENT, "MaxLinear MXL5003"},
249 { TUNER_ABSENT, "Xceive XC2028"},
250 { TUNER_ABSENT, "Microtune MT2131"},
251 /* 140-149 */
252 { TUNER_ABSENT, "Philips 8275A_8295"},
253 { TUNER_ABSENT, "TCL MF02GIP_5N_E"},
254 { TUNER_ABSENT, "TCL MF02GIP_3DB_E"},
255 { TUNER_ABSENT, "TCL MF02GIP_3DI_E"},
256 { TUNER_ABSENT, "Microtune MT2266"},
257 { TUNER_ABSENT, "TCL MF10WPP_4N_E"},
258 { TUNER_ABSENT, "LG TAPQ_H702F"},
259 { TUNER_ABSENT, "TCL M09WPP_4N_E"},
260 { TUNER_ABSENT, "MaxLinear MXL5005_v2"},
261 { TUNER_ABSENT, "Philips 18271_8295"},
232}; 262};
233 263
234static struct HAUPPAUGE_AUDIOIC 264static struct HAUPPAUGE_AUDIOIC
@@ -280,11 +310,16 @@ audioIC[] =
280 {AUDIO_CHIP_INTERNAL, "CX883"}, 310 {AUDIO_CHIP_INTERNAL, "CX883"},
281 {AUDIO_CHIP_INTERNAL, "CX882"}, 311 {AUDIO_CHIP_INTERNAL, "CX882"},
282 {AUDIO_CHIP_INTERNAL, "CX25840"}, 312 {AUDIO_CHIP_INTERNAL, "CX25840"},
283 /* 35-38 */ 313 /* 35-39 */
284 {AUDIO_CHIP_INTERNAL, "CX25841"}, 314 {AUDIO_CHIP_INTERNAL, "CX25841"},
285 {AUDIO_CHIP_INTERNAL, "CX25842"}, 315 {AUDIO_CHIP_INTERNAL, "CX25842"},
286 {AUDIO_CHIP_INTERNAL, "CX25843"}, 316 {AUDIO_CHIP_INTERNAL, "CX25843"},
287 {AUDIO_CHIP_INTERNAL, "CX23418"}, 317 {AUDIO_CHIP_INTERNAL, "CX23418"},
318 {AUDIO_CHIP_INTERNAL, "CX23885"},
319 /* 40-42 */
320 {AUDIO_CHIP_INTERNAL, "CX23888"},
321 {AUDIO_CHIP_INTERNAL, "SAA7131"},
322 {AUDIO_CHIP_INTERNAL, "CX23887"},
288}; 323};
289 324
290/* This list is supplied by Hauppauge. Thanks! */ 325/* This list is supplied by Hauppauge. Thanks! */
@@ -301,8 +336,10 @@ static const char *decoderIC[] = {
301 "CX880", "CX881", "CX883", "SAA7111", "SAA7113", 336 "CX880", "CX881", "CX883", "SAA7111", "SAA7113",
302 /* 25-29 */ 337 /* 25-29 */
303 "CX882", "TVP5150A", "CX25840", "CX25841", "CX25842", 338 "CX882", "TVP5150A", "CX25840", "CX25841", "CX25842",
304 /* 30-31 */ 339 /* 30-34 */
305 "CX25843", "CX23418", 340 "CX25843", "CX23418", "NEC61153", "CX23885", "CX23888",
341 /* 35-37 */
342 "SAA7131", "CX25837", "CX23887"
306}; 343};
307 344
308static int hasRadioTuner(int tunerType) 345static int hasRadioTuner(int tunerType)
diff --git a/drivers/media/video/upd64031a.c b/drivers/media/video/upd64031a.c
index 28d1133a3b7a..0b2a961efd22 100644
--- a/drivers/media/video/upd64031a.c
+++ b/drivers/media/video/upd64031a.c
@@ -27,6 +27,7 @@
27#include <linux/i2c.h> 27#include <linux/i2c.h>
28#include <linux/videodev2.h> 28#include <linux/videodev2.h>
29#include <media/v4l2-common.h> 29#include <media/v4l2-common.h>
30#include <media/v4l2-chip-ident.h>
30#include <media/upd64031a.h> 31#include <media/upd64031a.h>
31 32
32// --------------------- read registers functions define ----------------------- 33// --------------------- read registers functions define -----------------------
@@ -179,6 +180,9 @@ static int upd64031a_command(struct i2c_client *client, unsigned int cmd, void *
179 } 180 }
180#endif 181#endif
181 182
183 case VIDIOC_G_CHIP_IDENT:
184 return v4l2_chip_ident_i2c_client(client, arg, V4L2_IDENT_UPD64031A, 0);
185
182 default: 186 default:
183 break; 187 break;
184 } 188 }
diff --git a/drivers/media/video/upd64083.c b/drivers/media/video/upd64083.c
index fe38224150d8..401bd21f46eb 100644
--- a/drivers/media/video/upd64083.c
+++ b/drivers/media/video/upd64083.c
@@ -26,6 +26,7 @@
26#include <linux/i2c.h> 26#include <linux/i2c.h>
27#include <linux/videodev2.h> 27#include <linux/videodev2.h>
28#include <media/v4l2-common.h> 28#include <media/v4l2-common.h>
29#include <media/v4l2-chip-ident.h>
29#include <media/upd64083.h> 30#include <media/upd64083.h>
30 31
31MODULE_DESCRIPTION("uPD64083 driver"); 32MODULE_DESCRIPTION("uPD64083 driver");
@@ -155,6 +156,10 @@ static int upd64083_command(struct i2c_client *client, unsigned int cmd, void *a
155 break; 156 break;
156 } 157 }
157#endif 158#endif
159
160 case VIDIOC_G_CHIP_IDENT:
161 return v4l2_chip_ident_i2c_client(client, arg, V4L2_IDENT_UPD64083, 0);
162
158 default: 163 default:
159 break; 164 break;
160 } 165 }
diff --git a/drivers/media/video/usbvideo/usbvideo.c b/drivers/media/video/usbvideo/usbvideo.c
index d34d8c8b7376..687f026753b2 100644
--- a/drivers/media/video/usbvideo/usbvideo.c
+++ b/drivers/media/video/usbvideo/usbvideo.c
@@ -628,24 +628,21 @@ EXPORT_SYMBOL(usbvideo_HexDump);
628/* ******************************************************************** */ 628/* ******************************************************************** */
629 629
630/* XXX: this piece of crap really wants some error handling.. */ 630/* XXX: this piece of crap really wants some error handling.. */
631static void usbvideo_ClientIncModCount(struct uvd *uvd) 631static int usbvideo_ClientIncModCount(struct uvd *uvd)
632{ 632{
633 if (uvd == NULL) { 633 if (uvd == NULL) {
634 err("%s: uvd == NULL", __FUNCTION__); 634 err("%s: uvd == NULL", __FUNCTION__);
635 return; 635 return -EINVAL;
636 } 636 }
637 if (uvd->handle == NULL) { 637 if (uvd->handle == NULL) {
638 err("%s: uvd->handle == NULL", __FUNCTION__); 638 err("%s: uvd->handle == NULL", __FUNCTION__);
639 return; 639 return -EINVAL;
640 }
641 if (uvd->handle->md_module == NULL) {
642 err("%s: uvd->handle->md_module == NULL", __FUNCTION__);
643 return;
644 } 640 }
645 if (!try_module_get(uvd->handle->md_module)) { 641 if (!try_module_get(uvd->handle->md_module)) {
646 err("%s: try_module_get() == 0", __FUNCTION__); 642 err("%s: try_module_get() == 0", __FUNCTION__);
647 return; 643 return -ENODEV;
648 } 644 }
645 return 0;
649} 646}
650 647
651static void usbvideo_ClientDecModCount(struct uvd *uvd) 648static void usbvideo_ClientDecModCount(struct uvd *uvd)
@@ -712,8 +709,6 @@ int usbvideo_register(
712 cams->num_cameras = num_cams; 709 cams->num_cameras = num_cams;
713 cams->cam = (struct uvd *) &cams[1]; 710 cams->cam = (struct uvd *) &cams[1];
714 cams->md_module = md; 711 cams->md_module = md;
715 if (cams->md_module == NULL)
716 warn("%s: module == NULL!", __FUNCTION__);
717 mutex_init(&cams->lock); /* to 1 == available */ 712 mutex_init(&cams->lock); /* to 1 == available */
718 713
719 for (i = 0; i < num_cams; i++) { 714 for (i = 0; i < num_cams; i++) {
@@ -1119,7 +1114,8 @@ static int usbvideo_v4l_open(struct inode *inode, struct file *file)
1119 if (uvd->debug > 1) 1114 if (uvd->debug > 1)
1120 info("%s($%p)", __FUNCTION__, dev); 1115 info("%s($%p)", __FUNCTION__, dev);
1121 1116
1122 usbvideo_ClientIncModCount(uvd); 1117 if (0 < usbvideo_ClientIncModCount(uvd))
1118 return -ENODEV;
1123 mutex_lock(&uvd->lock); 1119 mutex_lock(&uvd->lock);
1124 1120
1125 if (uvd->user) { 1121 if (uvd->user) {
diff --git a/drivers/media/video/usbvision/usbvision-cards.c b/drivers/media/video/usbvision/usbvision-cards.c
index a40e5838515b..13f69fe6360d 100644
--- a/drivers/media/video/usbvision/usbvision-cards.c
+++ b/drivers/media/video/usbvision/usbvision-cards.c
@@ -1,6 +1,6 @@
1/* 1/*
2 * USBVISION.H 2 * usbvision-cards.c
3 * usbvision header file 3 * usbvision cards definition file
4 * 4 *
5 * Copyright (c) 1999-2005 Joerg Heckenbach <joerg@heckenbach-aw.de> 5 * Copyright (c) 1999-2005 Joerg Heckenbach <joerg@heckenbach-aw.de>
6 * 6 *
@@ -28,129 +28,1060 @@
28#include <media/v4l2-dev.h> 28#include <media/v4l2-dev.h>
29#include <media/tuner.h> 29#include <media/tuner.h>
30#include "usbvision.h" 30#include "usbvision.h"
31#include "usbvision-cards.h"
31 32
32/* Supported Devices: A table for usbvision.c*/ 33/* Supported Devices: A table for usbvision.c*/
33struct usbvision_device_data_st usbvision_device_data[] = { 34struct usbvision_device_data_st usbvision_device_data[] = {
34 {0xFFF0, 0xFFF0, -1, CODEC_SAA7111, 3, V4L2_STD_NTSC, 1, 1, 1, 1, TUNER_PHILIPS_NTSC_M, -1, -1, -1, -1, -1, "Custom Dummy USBVision Device"}, 35 [XANBOO] = {
35 {0x0A6F, 0x0400, -1, CODEC_SAA7113, 4, V4L2_STD_NTSC, 1, 0, 1, 0, 0, -1, -1, -1, -1, -1, "Xanboo"}, 36 .Interface = -1,
36 {0x050D, 0x0208, -1, CODEC_SAA7113, 2, V4L2_STD_PAL, 1, 0, 1, 0, 0, -1, -1, 0, 3, 7, "Belkin USBView II"}, 37 .Codec = CODEC_SAA7113,
37 {0x0571, 0x0002, 0, CODEC_SAA7111, 2, V4L2_STD_PAL, 0, 0, 1, 0, 0, -1, -1, -1, -1, 7, "echoFX InterView Lite"}, 38 .VideoChannels = 4,
38 {0x0573, 0x0003, -1, CODEC_SAA7111, 2, V4L2_STD_NTSC, 1, 0, 1, 0, 0, -1, -1, -1, -1, -1, "USBGear USBG-V1 resp. HAMA USB"}, 39 .VideoNorm = V4L2_STD_NTSC,
39 {0x0573, 0x0400, -1, CODEC_SAA7113, 4, V4L2_STD_NTSC, 0, 0, 1, 0, 0, -1, -1, 0, 3, 7, "D-Link V100"}, 40 .AudioChannels = 1,
40 {0x0573, 0x2000, -1, CODEC_SAA7111, 2, V4L2_STD_NTSC, 1, 0, 1, 0, 0, -1, -1, -1, -1, -1, "X10 USB Camera"}, 41 .Radio = 0,
41 {0x0573, 0x2d00, -1, CODEC_SAA7111, 2, V4L2_STD_PAL, 1, 0, 1, 0, 0, -1, -1, -1, 3, 7, "Osprey 50"}, 42 .vbi = 1,
42 {0x0573, 0x2d01, -1, CODEC_SAA7113, 2, V4L2_STD_NTSC, 0, 0, 1, 0, 0, -1, -1, 0, 3, 7, "Hauppauge USB-Live Model 600"}, 43 .Tuner = 0,
43 {0x0573, 0x2101, -1, CODEC_SAA7113, 2, V4L2_STD_PAL, 2, 0, 1, 0, 0, -1, -1, 0, 3, 7, "Zoran Co. PMD (Nogatech) AV-grabber Manhattan"}, 44 .TunerType = 0,
44 {0x0573, 0x4100, -1, CODEC_SAA7111, 3, V4L2_STD_NTSC, 1, 1, 1, 1, TUNER_PHILIPS_NTSC_M, -1, -1, -1, 20, -1, "Nogatech USB-TV (NTSC) FM"}, 45 .X_Offset = -1,
45 {0x0573, 0x4110, -1, CODEC_SAA7111, 3, V4L2_STD_NTSC, 1, 1, 1, 1, TUNER_PHILIPS_NTSC_M, -1, -1, -1, 20, -1, "PNY USB-TV (NTSC) FM"}, 46 .Y_Offset = -1,
46 {0x0573, 0x4450, 0, CODEC_SAA7113, 3, V4L2_STD_PAL, 1, 1, 1, 1, TUNER_PHILIPS_PAL, -1, -1, 0, 3, 7, "PixelView PlayTv-USB PRO (PAL) FM"}, 47 .ModelString = "Xanboo",
47 {0x0573, 0x4550, 0, CODEC_SAA7113, 3, V4L2_STD_PAL, 1, 1, 1, 1, TUNER_PHILIPS_PAL, -1, -1, 0, 3, 7, "ZTV ZT-721 2.4GHz USB A/V Receiver"}, 48 },
48 {0x0573, 0x4d00, -1, CODEC_SAA7111, 3, V4L2_STD_NTSC, 1, 0, 1, 1, TUNER_PHILIPS_NTSC_M, -1, -1, -1, 20, -1, "Hauppauge WinTv-USB USA"}, 49 [BELKIN_VIDEOBUS_II] = {
49 {0x0573, 0x4d01, -1, CODEC_SAA7111, 3, V4L2_STD_NTSC, 1, 0, 1, 1, TUNER_PHILIPS_NTSC_M, -1, -1, -1, -1, -1, "Hauppauge WinTv-USB"}, 50 .Interface = -1,
50 {0x0573, 0x4d02, -1, CODEC_SAA7111, 3, V4L2_STD_NTSC, 1, 0, 1, 1, TUNER_PHILIPS_NTSC_M, -1, -1, -1, -1, -1, "Hauppauge WinTv-USB (NTSC)"}, 51 .Codec = CODEC_SAA7113,
51 {0x0573, 0x4d03, -1, CODEC_SAA7111, 3, V4L2_STD_SECAM, 1, 0, 1, 1, TUNER_PHILIPS_SECAM, -1, -1, -1, -1, -1, "Hauppauge WinTv-USB (SECAM) "}, 52 .VideoChannels = 2,
52 {0x0573, 0x4d10, -1, CODEC_SAA7111, 3, V4L2_STD_NTSC, 1, 1, 1, 1, TUNER_PHILIPS_NTSC_M, -1, -1, -1, -1, -1, "Hauppauge WinTv-USB (NTSC) FM"}, 53 .VideoNorm = V4L2_STD_PAL,
53 {0x0573, 0x4d11, -1, CODEC_SAA7111, 3, V4L2_STD_PAL, 1, 1, 1, 1, TUNER_PHILIPS_PAL, -1, -1, -1, -1, -1, "Hauppauge WinTv-USB (PAL) FM"}, 54 .AudioChannels = 1,
54 {0x0573, 0x4d12, -1, CODEC_SAA7111, 3, V4L2_STD_PAL, 1, 1, 1, 1, TUNER_PHILIPS_PAL, -1, -1, -1, -1, -1, "Hauppauge WinTv-USB (PAL) FM"}, 55 .Radio = 0,
55 {0x0573, 0x4d2a, 0, CODEC_SAA7113, 3, V4L2_STD_NTSC, 1, 1, 1, 1, TUNER_MICROTUNE_4049FM5, -1, -1, 0, 3, 7, "Hauppauge WinTv USB (NTSC) FM Model 602 40201 Rev B285"}, 56 .vbi = 1,
56 {0x0573, 0x4d2b, 0, CODEC_SAA7113, 3, V4L2_STD_NTSC, 1, 1, 1, 1, TUNER_MICROTUNE_4049FM5, -1, -1, 0, 3, 7, "Hauppauge WinTv USB (NTSC) FM Model 602 40201 Rev B282"}, 57 .Tuner = 0,
57 {0x0573, 0x4d2c, 0, CODEC_SAA7113, 3, V4L2_STD_PAL, 1, 0, 1, 1, TUNER_PHILIPS_FM1216ME_MK3, -1, -1, 0, 3, 7, "Hauppauge WinTv USB (PAL/SECAM) 40209 Rev E1A5"}, 58 .TunerType = 0,
58 {0x0573, 0x4d20, 0, CODEC_SAA7113, 3, V4L2_STD_PAL, 1, 1, 1, 1, TUNER_PHILIPS_PAL, -1, -1, 0, 3, 7, "Hauppauge WinTv-USB II (PAL) FM Model 40201 Rev B226"}, 59 .X_Offset = 0,
59 {0x0573, 0x4d21, 0, CODEC_SAA7113, 3, V4L2_STD_PAL, 1, 0, 1, 1, TUNER_PHILIPS_PAL, -1, -1, 0, 3, 7, "Hauppauge WinTv-USB II (PAL)"}, 60 .Y_Offset = 3,
60 {0x0573, 0x4d22, 0, CODEC_SAA7113, 3, V4L2_STD_PAL, 1, 0, 1, 1, TUNER_PHILIPS_PAL, -1, -1, 0, 3, 7, "Hauppauge WinTv-USB II (PAL) MODEL 566"}, 61 .Dvi_yuv_override = 1,
61 {0x0573, 0x4d23, -1, CODEC_SAA7113, 3, V4L2_STD_SECAM, 1, 0, 1, 1, TUNER_PHILIPS_SECAM, -1, -1, 0, 3, 7, "Hauppauge WinTv-USB (SECAM) 4D23"}, 62 .Dvi_yuv = 7,
62 {0x0573, 0x4d25, -1, CODEC_SAA7113, 3, V4L2_STD_SECAM, 1, 0, 1, 1, TUNER_PHILIPS_SECAM, -1, -1, 0, 3, 7, "Hauppauge WinTv-USB (SECAM) Model 40209 Rev B234"}, 63 .ModelString = "Belkin USB VideoBus II Adapter",
63 {0x0573, 0x4d26, -1, CODEC_SAA7113, 3, V4L2_STD_SECAM, 1, 0, 1, 1, TUNER_PHILIPS_SECAM, -1, -1, 0, 3, 7, "Hauppauge WinTv-USB (SECAM) Model 40209 Rev B243"}, 64 },
64 {0x0573, 0x4d27, -1, CODEC_SAA7113, 3, V4L2_STD_PAL, 1, 0, 1, 1, TUNER_ALPS_TSBE1_PAL, -1, -1, 0, 3, 7, "Hauppauge WinTv-USB Model 40204 Rev B281"}, 65 [BELKIN_VIDEOBUS] = {
65 {0x0573, 0x4d28, -1, CODEC_SAA7113, 3, V4L2_STD_PAL, 1, 0, 1, 1, TUNER_ALPS_TSBE1_PAL, -1, -1, 0, 3, 7, "Hauppauge WinTv-USB Model 40204 Rev B283"}, 66 .Interface = -1,
66 {0x0573, 0x4d29, -1, CODEC_SAA7113, 3, V4L2_STD_PAL, 1, 0, 1, 1, TUNER_PHILIPS_PAL, -1, -1, 0, 3, 7, "Hauppauge WinTv-USB Model 40205 Rev B298"}, 67 .Codec = CODEC_SAA7111,
67 {0x0573, 0x4d30, -1, CODEC_SAA7113, 3, V4L2_STD_NTSC, 1, 1, 1, 1, TUNER_PHILIPS_NTSC_M, -1, -1, 0, 3, 7, "Hauppauge WinTv-USB FM Model 40211 Rev B123"}, 68 .VideoChannels = 2,
68 {0x0573, 0x4d31, 0, CODEC_SAA7113, 3, V4L2_STD_PAL, 1, 1, 1, 1, TUNER_PHILIPS_PAL, -1, -1, 0, 3, 7, "Hauppauge WinTv-USB III (PAL) FM Model 568"}, 69 .VideoNorm = V4L2_STD_NTSC,
69 {0x0573, 0x4d32, 0, CODEC_SAA7113, 3, V4L2_STD_PAL, 1, 1, 1, 1, TUNER_PHILIPS_PAL, -1, -1, 0, 3, 7, "Hauppauge WinTv-USB III (PAL) FM Model 573"}, 70 .AudioChannels = 1,
70 {0x0573, 0x4d35, 0, CODEC_SAA7113, 3, V4L2_STD_PAL, 1, 1, 1, 1, TUNER_MICROTUNE_4049FM5, -1, -1, 0, 3, 7, "Hauppauge WinTv-USB III (PAL) FM Model 40219 Rev B252"}, 71 .Radio = 0,
71 {0x0573, 0x4d37, 0, CODEC_SAA7113, 3, V4L2_STD_PAL, 1, 1, 1, 1, TUNER_PHILIPS_FM1216ME_MK3, -1, -1, 0, 3, 7, "Hauppauge WinTV USB device Model 40219 Rev E189"}, 72 .vbi = 1,
72 {0x0768, 0x0006, -1, CODEC_SAA7113, 3, V4L2_STD_NTSC, 1, 1, 1, 1, TUNER_PHILIPS_NTSC_M, -1, -1, 5, 5, -1, "Camtel Technology USB TV Genie Pro FM Model TVB330"}, 73 .Tuner = 0,
73 {0x07d0, 0x0001, -1, CODEC_SAA7113, 2, V4L2_STD_PAL, 0, 0, 1, 0, 0, -1, -1, 0, 3, 7, "Digital Video Creator I"}, 74 .TunerType = 0,
74 {0x07d0, 0x0002, -1, CODEC_SAA7111, 2, V4L2_STD_NTSC, 0, 0, 1, 0, 0, -1, -1, 82, 20, 7, "Global Village GV-007 (NTSC)"}, 75 .X_Offset = -1,
75 {0x07d0, 0x0003, 0, CODEC_SAA7113, 2, V4L2_STD_NTSC, 0, 0, 1, 0, 0, -1, -1, 0, 3, 7, "Dazzle Fusion Model DVC-50 Rev 1 (NTSC)"}, 76 .Y_Offset = -1,
76 {0x07d0, 0x0004, 0, CODEC_SAA7113, 2, V4L2_STD_PAL, 0, 0, 1, 0, 0, -1, -1, 0, 3, 7, "Dazzle Fusion Model DVC-80 Rev 1 (PAL)"}, 77 .ModelString = "Belkin Components USB VideoBus",
77 {0x07d0, 0x0005, 0, CODEC_SAA7113, 2, V4L2_STD_SECAM, 0, 0, 1, 0, 0, -1, -1, 0, 3, 7, "Dazzle Fusion Model DVC-90 Rev 1 (SECAM)"}, 78 },
78 {0x2304, 0x010d, -1, CODEC_SAA7111, 3, V4L2_STD_PAL, 1, 0, 0, 1, TUNER_TEMIC_4066FY5_PAL_I, -1, -1, -1, -1, -1, "Pinnacle Studio PCTV USB (PAL)"}, 79 [BELKIN_USB_VIDEOBUS_II] = {
79 {0x2304, 0x0109, -1, CODEC_SAA7111, 3, V4L2_STD_SECAM, 1, 0, 1, 1, TUNER_PHILIPS_SECAM, -1, -1, -1, -1, -1, "Pinnacle Studio PCTV USB (SECAM)"}, 80 .Interface = -1,
80 {0x2304, 0x0110, -1, CODEC_SAA7111, 3, V4L2_STD_PAL, 1, 1, 1, 1, TUNER_PHILIPS_PAL, -1, -1,128, 23, -1, "Pinnacle Studio PCTV USB (PAL) FM"}, 81 .Codec = CODEC_SAA7113,
81 {0x2304, 0x0111, -1, CODEC_SAA7111, 3, V4L2_STD_PAL, 1, 0, 1, 1, TUNER_PHILIPS_PAL, -1, -1, -1, -1, -1, "Miro PCTV USB"}, 82 .VideoChannels = 2,
82 {0x2304, 0x0112, -1, CODEC_SAA7111, 3, V4L2_STD_NTSC, 1, 1, 1, 1, TUNER_PHILIPS_NTSC_M, -1, -1, -1, -1, -1, "Pinnacle Studio PCTV USB (NTSC) FM"}, 83 .VideoNorm = V4L2_STD_PAL,
83 {0x2304, 0x0210, -1, CODEC_SAA7113, 3, V4L2_STD_PAL, 1, 1, 1, 1, TUNER_TEMIC_4009FR5_PAL, -1, -1, 0, 3, 7, "Pinnacle Studio PCTV USB (PAL) FM"}, 84 .AudioChannels = 1,
84 {0x2304, 0x0212, -1, CODEC_SAA7111, 3, V4L2_STD_NTSC, 1, 1, 1, 1, TUNER_TEMIC_4039FR5_NTSC, -1, -1, 0, 3, 7, "Pinnacle Studio PCTV USB (NTSC) FM"}, 85 .Radio = 0,
85 {0x2304, 0x0214, -1, CODEC_SAA7113, 3, V4L2_STD_PAL, 1, 1, 1, 1, TUNER_TEMIC_4009FR5_PAL, -1, -1, 0, 3, 7, "Pinnacle Studio PCTV USB (PAL) FM"}, 86 .vbi = 1,
86 {0x2304, 0x0300, -1, CODEC_SAA7113, 2, V4L2_STD_NTSC, 1, 0, 1, 0, 0, -1, -1, 0, 3, 7, "Pinnacle Studio Linx Video input cable (NTSC)"}, 87 .Tuner = 0,
87 {0x2304, 0x0301, -1, CODEC_SAA7113, 2, V4L2_STD_PAL, 1, 0, 1, 0, 0, -1, -1, 0, 3, 7, "Pinnacle Studio Linx Video input cable (PAL)"}, 88 .TunerType = 0,
88 {0x2304, 0x0419, -1, CODEC_SAA7113, 3, V4L2_STD_PAL, 1, 1, 1, 1, TUNER_TEMIC_4009FR5_PAL, -1, -1, 0, 3, 7, "Pinnacle PCTV Bungee USB (PAL) FM"}, 89 .X_Offset = 0,
89 {0x2400, 0x4200, -1, CODEC_SAA7111, 3, V4L2_STD_NTSC, 1, 0, 1, 1, TUNER_PHILIPS_NTSC_M, -1, -1, -1, -1, -1, "Hauppauge WinTv-USB"}, 90 .Y_Offset = 3,
90 {} /* Terminating entry */ 91 .Dvi_yuv_override = 1,
92 .Dvi_yuv = 7,
93 .ModelString = "Belkin USB VideoBus II",
94 },
95 [ECHOFX_INTERVIEW_LITE] = {
96 .Interface = 0,
97 .Codec = CODEC_SAA7111,
98 .VideoChannels = 2,
99 .VideoNorm = V4L2_STD_PAL,
100 .AudioChannels = 0,
101 .Radio = 0,
102 .vbi = 1,
103 .Tuner = 0,
104 .TunerType = 0,
105 .X_Offset = -1,
106 .Y_Offset = -1,
107 .Dvi_yuv_override = 1,
108 .Dvi_yuv = 7,
109 .ModelString = "echoFX InterView Lite",
110 },
111 [USBGEAR_USBG_V1] = {
112 .Interface = -1,
113 .Codec = CODEC_SAA7111,
114 .VideoChannels = 2,
115 .VideoNorm = V4L2_STD_NTSC,
116 .AudioChannels = 1,
117 .Radio = 0,
118 .vbi = 1,
119 .Tuner = 0,
120 .TunerType = 0,
121 .X_Offset = -1,
122 .Y_Offset = -1,
123 .ModelString = "USBGear USBG-V1 resp. HAMA USB",
124 },
125 [D_LINK_V100] = {
126 .Interface = -1,
127 .Codec = CODEC_SAA7113,
128 .VideoChannels = 4,
129 .VideoNorm = V4L2_STD_NTSC,
130 .AudioChannels = 0,
131 .Radio = 0,
132 .vbi = 1,
133 .Tuner = 0,
134 .TunerType = 0,
135 .X_Offset = 0,
136 .Y_Offset = 3,
137 .Dvi_yuv_override = 1,
138 .Dvi_yuv = 7,
139 .ModelString = "D-Link V100",
140 },
141 [X10_USB_CAMERA] = {
142 .Interface = -1,
143 .Codec = CODEC_SAA7111,
144 .VideoChannels = 2,
145 .VideoNorm = V4L2_STD_NTSC,
146 .AudioChannels = 1,
147 .Radio = 0,
148 .vbi = 1,
149 .Tuner = 0,
150 .TunerType = 0,
151 .X_Offset = -1,
152 .Y_Offset = -1,
153 .ModelString = "X10 USB Camera",
154 },
155 [HPG_WINTV_LIVE_PAL_BG] = {
156 .Interface = -1,
157 .Codec = CODEC_SAA7111,
158 .VideoChannels = 2,
159 .VideoNorm = V4L2_STD_PAL,
160 .AudioChannels = 1,
161 .Radio = 0,
162 .vbi = 1,
163 .Tuner = 0,
164 .TunerType = 0,
165 .X_Offset = -1,
166 .Y_Offset = 3,
167 .Dvi_yuv_override = 1,
168 .Dvi_yuv = 7,
169 .ModelString = "Hauppauge WinTV USB Live (PAL B/G)",
170 },
171 [HPG_WINTV_LIVE_PRO_NTSC_MN] = {
172 .Interface = -1,
173 .Codec = CODEC_SAA7113,
174 .VideoChannels = 2,
175 .VideoNorm = V4L2_STD_NTSC,
176 .AudioChannels = 0,
177 .Radio = 0,
178 .vbi = 1,
179 .Tuner = 0,
180 .TunerType = 0,
181 .X_Offset = 0,
182 .Y_Offset = 3,
183 .Dvi_yuv_override = 1,
184 .Dvi_yuv = 7,
185 .ModelString = "Hauppauge WinTV USB Live Pro (NTSC M/N)",
186 },
187 [ZORAN_PMD_NOGATECH] = {
188 .Interface = -1,
189 .Codec = CODEC_SAA7113,
190 .VideoChannels = 2,
191 .VideoNorm = V4L2_STD_PAL,
192 .AudioChannels = 2,
193 .Radio = 0,
194 .vbi = 1,
195 .Tuner = 0,
196 .TunerType = 0,
197 .X_Offset = 0,
198 .Y_Offset = 3,
199 .Dvi_yuv_override = 1,
200 .Dvi_yuv = 7,
201 .ModelString = "Zoran Co. PMD (Nogatech) AV-grabber Manhattan",
202 },
203 [NOGATECH_USB_TV_NTSC_FM] = {
204 .Interface = -1,
205 .Codec = CODEC_SAA7111,
206 .VideoChannels = 3,
207 .VideoNorm = V4L2_STD_NTSC,
208 .AudioChannels = 1,
209 .Radio = 1,
210 .vbi = 1,
211 .Tuner = 1,
212 .TunerType = TUNER_PHILIPS_NTSC_M,
213 .X_Offset = -1,
214 .Y_Offset = 20,
215 .ModelString = "Nogatech USB-TV (NTSC) FM",
216 },
217 [PNY_USB_TV_NTSC_FM] = {
218 .Interface = -1,
219 .Codec = CODEC_SAA7111,
220 .VideoChannels = 3,
221 .VideoNorm = V4L2_STD_NTSC,
222 .AudioChannels = 1,
223 .Radio = 1,
224 .vbi = 1,
225 .Tuner = 1,
226 .TunerType = TUNER_PHILIPS_NTSC_M,
227 .X_Offset = -1,
228 .Y_Offset = 20,
229 .ModelString = "PNY USB-TV (NTSC) FM",
230 },
231 [PV_PLAYTV_USB_PRO_PAL_FM] = {
232 .Interface = 0,
233 .Codec = CODEC_SAA7113,
234 .VideoChannels = 3,
235 .VideoNorm = V4L2_STD_PAL,
236 .AudioChannels = 1,
237 .Radio = 1,
238 .vbi = 1,
239 .Tuner = 1,
240 .TunerType = TUNER_PHILIPS_PAL,
241 .X_Offset = 0,
242 .Y_Offset = 3,
243 .Dvi_yuv_override = 1,
244 .Dvi_yuv = 7,
245 .ModelString = "PixelView PlayTv-USB PRO (PAL) FM",
246 },
247 [ZT_721] = {
248 .Interface = 0,
249 .Codec = CODEC_SAA7113,
250 .VideoChannels = 3,
251 .VideoNorm = V4L2_STD_PAL,
252 .AudioChannels = 1,
253 .Radio = 1,
254 .vbi = 1,
255 .Tuner = 1,
256 .TunerType = TUNER_PHILIPS_PAL,
257 .X_Offset = 0,
258 .Y_Offset = 3,
259 .Dvi_yuv_override = 1,
260 .Dvi_yuv = 7,
261 .ModelString = "ZTV ZT-721 2.4GHz USB A/V Receiver",
262 },
263 [HPG_WINTV_NTSC_MN] = {
264 .Interface = -1,
265 .Codec = CODEC_SAA7111,
266 .VideoChannels = 3,
267 .VideoNorm = V4L2_STD_NTSC,
268 .AudioChannels = 1,
269 .Radio = 0,
270 .vbi = 1,
271 .Tuner = 1,
272 .TunerType = TUNER_PHILIPS_NTSC_M,
273 .X_Offset = -1,
274 .Y_Offset = 20,
275 .ModelString = "Hauppauge WinTV USB (NTSC M/N)",
276 },
277 [HPG_WINTV_PAL_BG] = {
278 .Interface = -1,
279 .Codec = CODEC_SAA7111,
280 .VideoChannels = 3,
281 .VideoNorm = V4L2_STD_PAL,
282 .AudioChannels = 1,
283 .Radio = 0,
284 .vbi = 1,
285 .Tuner = 1,
286 .TunerType = TUNER_PHILIPS_PAL,
287 .X_Offset = -1,
288 .Y_Offset = -1,
289 .ModelString = "Hauppauge WinTV USB (PAL B/G)",
290 },
291 [HPG_WINTV_PAL_I] = {
292 .Interface = -1,
293 .Codec = CODEC_SAA7111,
294 .VideoChannels = 3,
295 .VideoNorm = V4L2_STD_PAL,
296 .AudioChannels = 1,
297 .Radio = 0,
298 .vbi = 1,
299 .Tuner = 1,
300 .TunerType = TUNER_PHILIPS_PAL,
301 .X_Offset = -1,
302 .Y_Offset = -1,
303 .ModelString = "Hauppauge WinTV USB (PAL I)",
304 },
305 [HPG_WINTV_PAL_SECAM_L] = {
306 .Interface = -1,
307 .Codec = CODEC_SAA7111,
308 .VideoChannels = 3,
309 .VideoNorm = V4L2_STD_SECAM,
310 .AudioChannels = 1,
311 .Radio = 0,
312 .vbi = 1,
313 .Tuner = 1,
314 .TunerType = TUNER_PHILIPS_SECAM,
315 .X_Offset = -1,
316 .Y_Offset = -1,
317 .ModelString = "Hauppauge WinTV USB (PAL/SECAM L)",
318 },
319 [HPG_WINTV_PAL_D_K] = {
320 .Interface = -1,
321 .Codec = CODEC_SAA7111,
322 .VideoChannels = 3,
323 .VideoNorm = V4L2_STD_PAL,
324 .AudioChannels = 1,
325 .Radio = 0,
326 .vbi = 1,
327 .Tuner = 1,
328 .TunerType = TUNER_PHILIPS_PAL,
329 .X_Offset = -1,
330 .Y_Offset = -1,
331 .ModelString = "Hauppauge WinTV USB (PAL D/K)",
332 },
333 [HPG_WINTV_NTSC_FM] = {
334 .Interface = -1,
335 .Codec = CODEC_SAA7111,
336 .VideoChannels = 3,
337 .VideoNorm = V4L2_STD_NTSC,
338 .AudioChannels = 1,
339 .Radio = 1,
340 .vbi = 1,
341 .Tuner = 1,
342 .TunerType = TUNER_PHILIPS_NTSC_M,
343 .X_Offset = -1,
344 .Y_Offset = -1,
345 .ModelString = "Hauppauge WinTV USB (NTSC FM)",
346 },
347 [HPG_WINTV_PAL_BG_FM] = {
348 .Interface = -1,
349 .Codec = CODEC_SAA7111,
350 .VideoChannels = 3,
351 .VideoNorm = V4L2_STD_PAL,
352 .AudioChannels = 1,
353 .Radio = 1,
354 .vbi = 1,
355 .Tuner = 1,
356 .TunerType = TUNER_PHILIPS_PAL,
357 .X_Offset = -1,
358 .Y_Offset = -1,
359 .ModelString = "Hauppauge WinTV USB (PAL B/G FM)",
360 },
361 [HPG_WINTV_PAL_I_FM] = {
362 .Interface = -1,
363 .Codec = CODEC_SAA7111,
364 .VideoChannels = 3,
365 .VideoNorm = V4L2_STD_PAL,
366 .AudioChannels = 1,
367 .Radio = 1,
368 .vbi = 1,
369 .Tuner = 1,
370 .TunerType = TUNER_PHILIPS_PAL,
371 .X_Offset = -1,
372 .Y_Offset = -1,
373 .ModelString = "Hauppauge WinTV USB (PAL I FM)",
374 },
375 [HPG_WINTV_PAL_D_K_FM] = {
376 .Interface = -1,
377 .Codec = CODEC_SAA7111,
378 .VideoChannels = 3,
379 .VideoNorm = V4L2_STD_PAL,
380 .AudioChannels = 1,
381 .Radio = 1,
382 .vbi = 1,
383 .Tuner = 1,
384 .TunerType = TUNER_PHILIPS_PAL,
385 .X_Offset = -1,
386 .Y_Offset = -1,
387 .ModelString = "Hauppauge WinTV USB (PAL D/K FM)",
388 },
389 [HPG_WINTV_PRO_NTSC_MN] = {
390 .Interface = 0,
391 .Codec = CODEC_SAA7113,
392 .VideoChannels = 3,
393 .VideoNorm = V4L2_STD_NTSC,
394 .AudioChannels = 1,
395 .Radio = 1,
396 .vbi = 1,
397 .Tuner = 1,
398 .TunerType = TUNER_MICROTUNE_4049FM5,
399 .X_Offset = 0,
400 .Y_Offset = 3,
401 .Dvi_yuv_override = 1,
402 .Dvi_yuv = 7,
403 .ModelString = "Hauppauge WinTV USB Pro (NTSC M/N)",
404 },
405 [HPG_WINTV_PRO_NTSC_MN_V2] = {
406 .Interface = 0,
407 .Codec = CODEC_SAA7113,
408 .VideoChannels = 3,
409 .VideoNorm = V4L2_STD_NTSC,
410 .AudioChannels = 1,
411 .Radio = 1,
412 .vbi = 1,
413 .Tuner = 1,
414 .TunerType = TUNER_MICROTUNE_4049FM5,
415 .X_Offset = 0,
416 .Y_Offset = 3,
417 .Dvi_yuv_override = 1,
418 .Dvi_yuv = 7,
419 .ModelString = "Hauppauge WinTV USB Pro (NTSC M/N) V2",
420 },
421 [HPG_WINTV_PRO_PAL] = {
422 .Interface = 0,
423 .Codec = CODEC_SAA7113,
424 .VideoChannels = 3,
425 .VideoNorm = V4L2_STD_PAL,
426 .AudioChannels = 1,
427 .Radio = 0,
428 .vbi = 1,
429 .Tuner = 1,
430 .TunerType = TUNER_PHILIPS_FM1216ME_MK3,
431 .X_Offset = 0,
432 .Y_Offset = 3,
433 .Dvi_yuv_override = 1,
434 .Dvi_yuv = 7,
435 .ModelString = "Hauppauge WinTV USB Pro (PAL/SECAM B/G/I/D/K/L)",
436 },
437 [HPG_WINTV_PRO_NTSC_MN_V3] = {
438 .Interface = 0,
439 .Codec = CODEC_SAA7113,
440 .VideoChannels = 3,
441 .VideoNorm = V4L2_STD_NTSC,
442 .AudioChannels = 1,
443 .Radio = 1,
444 .vbi = 1,
445 .Tuner = 1,
446 .TunerType = TUNER_PHILIPS_NTSC_M,
447 .X_Offset = 0,
448 .Y_Offset = 3,
449 .Dvi_yuv_override = 1,
450 .Dvi_yuv = 7,
451 .ModelString = "Hauppauge WinTV USB Pro (NTSC M/N) V3",
452 },
453 [HPG_WINTV_PRO_PAL_BG] = {
454 .Interface = 0,
455 .Codec = CODEC_SAA7113,
456 .VideoChannels = 3,
457 .VideoNorm = V4L2_STD_PAL,
458 .AudioChannels = 1,
459 .Radio = 0,
460 .vbi = 1,
461 .Tuner = 1,
462 .TunerType = TUNER_PHILIPS_PAL,
463 .X_Offset = 0,
464 .Y_Offset = 3,
465 .Dvi_yuv_override = 1,
466 .Dvi_yuv = 7,
467 .ModelString = "Hauppauge WinTV USB Pro (PAL B/G)",
468 },
469 [HPG_WINTV_PRO_PAL_I] = {
470 .Interface = 0,
471 .Codec = CODEC_SAA7113,
472 .VideoChannels = 3,
473 .VideoNorm = V4L2_STD_PAL,
474 .AudioChannels = 1,
475 .Radio = 0,
476 .vbi = 1,
477 .Tuner = 1,
478 .TunerType = TUNER_PHILIPS_PAL,
479 .X_Offset = 0,
480 .Y_Offset = 3,
481 .Dvi_yuv_override = 1,
482 .Dvi_yuv = 7,
483 .ModelString = "Hauppauge WinTV USB Pro (PAL I)",
484 },
485 [HPG_WINTV_PRO_PAL_SECAM_L] = {
486 .Interface = -1,
487 .Codec = CODEC_SAA7113,
488 .VideoChannels = 3,
489 .VideoNorm = V4L2_STD_SECAM,
490 .AudioChannels = 1,
491 .Radio = 0,
492 .vbi = 1,
493 .Tuner = 1,
494 .TunerType = TUNER_PHILIPS_SECAM,
495 .X_Offset = 0,
496 .Y_Offset = 3,
497 .Dvi_yuv_override = 1,
498 .Dvi_yuv = 7,
499 .ModelString = "Hauppauge WinTV USB Pro (PAL/SECAM L)",
500 },
501 [HPG_WINTV_PRO_PAL_D_K] = {
502 .Interface = -1,
503 .Codec = CODEC_SAA7113,
504 .VideoChannels = 3,
505 .VideoNorm = V4L2_STD_PAL,
506 .AudioChannels = 1,
507 .Radio = 0,
508 .vbi = 1,
509 .Tuner = 1,
510 .TunerType = TUNER_PHILIPS_PAL,
511 .X_Offset = 0,
512 .Y_Offset = 3,
513 .Dvi_yuv_override = 1,
514 .Dvi_yuv = 7,
515 .ModelString = "Hauppauge WinTV USB Pro (PAL D/K)",
516 },
517 [HPG_WINTV_PRO_PAL_SECAM] = {
518 .Interface = -1,
519 .Codec = CODEC_SAA7113,
520 .VideoChannels = 3,
521 .VideoNorm = V4L2_STD_SECAM,
522 .AudioChannels = 1,
523 .Radio = 0,
524 .vbi = 1,
525 .Tuner = 1,
526 .TunerType = TUNER_PHILIPS_SECAM,
527 .X_Offset = 0,
528 .Y_Offset = 3,
529 .Dvi_yuv_override = 1,
530 .Dvi_yuv = 7,
531 .ModelString = "Hauppauge WinTV USB Pro (PAL/SECAM BGDK/I/L)",
532 },
533 [HPG_WINTV_PRO_PAL_SECAM_V2] = {
534 .Interface = -1,
535 .Codec = CODEC_SAA7113,
536 .VideoChannels = 3,
537 .VideoNorm = V4L2_STD_SECAM,
538 .AudioChannels = 1,
539 .Radio = 0,
540 .vbi = 1,
541 .Tuner = 1,
542 .TunerType = TUNER_PHILIPS_SECAM,
543 .X_Offset = 0,
544 .Y_Offset = 3,
545 .Dvi_yuv_override = 1,
546 .Dvi_yuv = 7,
547 .ModelString = "Hauppauge WinTV USB Pro (PAL/SECAM BGDK/I/L) V2",
548 },
549 [HPG_WINTV_PRO_PAL_BG_V2] = {
550 .Interface = -1,
551 .Codec = CODEC_SAA7113,
552 .VideoChannels = 3,
553 .VideoNorm = V4L2_STD_PAL,
554 .AudioChannels = 1,
555 .Radio = 0,
556 .vbi = 1,
557 .Tuner = 1,
558 .TunerType = TUNER_ALPS_TSBE1_PAL,
559 .X_Offset = 0,
560 .Y_Offset = 3,
561 .Dvi_yuv_override = 1,
562 .Dvi_yuv = 7,
563 .ModelString = "Hauppauge WinTV USB Pro (PAL B/G) V2",
564 },
565 [HPG_WINTV_PRO_PAL_BG_D_K] = {
566 .Interface = -1,
567 .Codec = CODEC_SAA7113,
568 .VideoChannels = 3,
569 .VideoNorm = V4L2_STD_PAL,
570 .AudioChannels = 1,
571 .Radio = 0,
572 .vbi = 1,
573 .Tuner = 1,
574 .TunerType = TUNER_ALPS_TSBE1_PAL,
575 .X_Offset = 0,
576 .Y_Offset = 3,
577 .Dvi_yuv_override = 1,
578 .Dvi_yuv = 7,
579 .ModelString = "Hauppauge WinTV USB Pro (PAL B/G,D/K)",
580 },
581 [HPG_WINTV_PRO_PAL_I_D_K] = {
582 .Interface = -1,
583 .Codec = CODEC_SAA7113,
584 .VideoChannels = 3,
585 .VideoNorm = V4L2_STD_PAL,
586 .AudioChannels = 1,
587 .Radio = 0,
588 .vbi = 1,
589 .Tuner = 1,
590 .TunerType = TUNER_PHILIPS_PAL,
591 .X_Offset = 0,
592 .Y_Offset = 3,
593 .Dvi_yuv_override = 1,
594 .Dvi_yuv = 7,
595 .ModelString = "Hauppauge WinTV USB Pro (PAL I,D/K)",
596 },
597 [HPG_WINTV_PRO_NTSC_MN_FM] = {
598 .Interface = -1,
599 .Codec = CODEC_SAA7113,
600 .VideoChannels = 3,
601 .VideoNorm = V4L2_STD_NTSC,
602 .AudioChannels = 1,
603 .Radio = 1,
604 .vbi = 1,
605 .Tuner = 1,
606 .TunerType = TUNER_PHILIPS_NTSC_M,
607 .X_Offset = 0,
608 .Y_Offset = 3,
609 .Dvi_yuv_override = 1,
610 .Dvi_yuv = 7,
611 .ModelString = "Hauppauge WinTV USB Pro (NTSC M/N FM)",
612 },
613 [HPG_WINTV_PRO_PAL_BG_FM] = {
614 .Interface = 0,
615 .Codec = CODEC_SAA7113,
616 .VideoChannels = 3,
617 .VideoNorm = V4L2_STD_PAL,
618 .AudioChannels = 1,
619 .Radio = 1,
620 .vbi = 1,
621 .Tuner = 1,
622 .TunerType = TUNER_PHILIPS_PAL,
623 .X_Offset = 0,
624 .Y_Offset = 3,
625 .Dvi_yuv_override = 1,
626 .Dvi_yuv = 7,
627 .ModelString = "Hauppauge WinTV USB Pro (PAL B/G FM)",
628 },
629 [HPG_WINTV_PRO_PAL_I_FM] = {
630 .Interface = 0,
631 .Codec = CODEC_SAA7113,
632 .VideoChannels = 3,
633 .VideoNorm = V4L2_STD_PAL,
634 .AudioChannels = 1,
635 .Radio = 1,
636 .vbi = 1,
637 .Tuner = 1,
638 .TunerType = TUNER_PHILIPS_PAL,
639 .X_Offset = 0,
640 .Y_Offset = 3,
641 .Dvi_yuv_override = 1,
642 .Dvi_yuv = 7,
643 .ModelString = "Hauppauge WinTV USB Pro (PAL I FM)",
644 },
645 [HPG_WINTV_PRO_PAL_D_K_FM] = {
646 .Interface = 0,
647 .Codec = CODEC_SAA7113,
648 .VideoChannels = 3,
649 .VideoNorm = V4L2_STD_PAL,
650 .AudioChannels = 1,
651 .Radio = 1,
652 .vbi = 1,
653 .Tuner = 1,
654 .TunerType = TUNER_PHILIPS_PAL,
655 .X_Offset = 0,
656 .Y_Offset = 3,
657 .Dvi_yuv_override = 1,
658 .Dvi_yuv = 7,
659 .ModelString = "Hauppauge WinTV USB Pro (PAL D/K FM)",
660 },
661 [HPG_WINTV_PRO_TEMIC_PAL_FM] = {
662 .Interface = 0,
663 .Codec = CODEC_SAA7113,
664 .VideoChannels = 3,
665 .VideoNorm = V4L2_STD_PAL,
666 .AudioChannels = 1,
667 .Radio = 1,
668 .vbi = 1,
669 .Tuner = 1,
670 .TunerType = TUNER_MICROTUNE_4049FM5,
671 .X_Offset = 0,
672 .Y_Offset = 3,
673 .Dvi_yuv_override = 1,
674 .Dvi_yuv = 7,
675 .ModelString = "Hauppauge WinTV USB Pro (Temic PAL/SECAM B/G/I/D/K/L FM)",
676 },
677 [HPG_WINTV_PRO_TEMIC_PAL_BG_FM] = {
678 .Interface = 0,
679 .Codec = CODEC_SAA7113,
680 .VideoChannels = 3,
681 .VideoNorm = V4L2_STD_PAL,
682 .AudioChannels = 1,
683 .Radio = 1,
684 .vbi = 1,
685 .Tuner = 1,
686 .TunerType = TUNER_MICROTUNE_4049FM5,
687 .X_Offset = 0,
688 .Y_Offset = 3,
689 .Dvi_yuv_override = 1,
690 .Dvi_yuv = 7,
691 .ModelString = "Hauppauge WinTV USB Pro (Temic PAL B/G FM)",
692 },
693 [HPG_WINTV_PRO_PAL_FM] = {
694 .Interface = 0,
695 .Codec = CODEC_SAA7113,
696 .VideoChannels = 3,
697 .VideoNorm = V4L2_STD_PAL,
698 .AudioChannels = 1,
699 .Radio = 1,
700 .vbi = 1,
701 .Tuner = 1,
702 .TunerType = TUNER_PHILIPS_FM1216ME_MK3,
703 .X_Offset = 0,
704 .Y_Offset = 3,
705 .Dvi_yuv_override = 1,
706 .Dvi_yuv = 7,
707 .ModelString = "Hauppauge WinTV USB Pro (PAL/SECAM B/G/I/D/K/L FM)",
708 },
709 [HPG_WINTV_PRO_NTSC_MN_FM_V2] = {
710 .Interface = 0,
711 .Codec = CODEC_SAA7113,
712 .VideoChannels = 3,
713 .VideoNorm = V4L2_STD_NTSC,
714 .AudioChannels = 1,
715 .Radio = 1,
716 .vbi = 1,
717 .Tuner = 1,
718 .TunerType = TUNER_PHILIPS_NTSC_M,
719 .X_Offset = 0,
720 .Y_Offset = 3,
721 .Dvi_yuv_override = 1,
722 .Dvi_yuv = 7,
723 .ModelString = "Hauppauge WinTV USB Pro (NTSC M/N FM) V2",
724 },
725 [CAMTEL_TVB330] = {
726 .Interface = -1,
727 .Codec = CODEC_SAA7113,
728 .VideoChannels = 3,
729 .VideoNorm = V4L2_STD_NTSC,
730 .AudioChannels = 1,
731 .Radio = 1,
732 .vbi = 1,
733 .Tuner = 1,
734 .TunerType = TUNER_PHILIPS_NTSC_M,
735 .X_Offset = 5,
736 .Y_Offset = 5,
737 .ModelString = "Camtel Technology USB TV Genie Pro FM Model TVB330",
738 },
739 [DIGITAL_VIDEO_CREATOR_I] = {
740 .Interface = -1,
741 .Codec = CODEC_SAA7113,
742 .VideoChannels = 2,
743 .VideoNorm = V4L2_STD_PAL,
744 .AudioChannels = 0,
745 .Radio = 0,
746 .vbi = 1,
747 .Tuner = 0,
748 .TunerType = 0,
749 .X_Offset = 0,
750 .Y_Offset = 3,
751 .Dvi_yuv_override = 1,
752 .Dvi_yuv = 7,
753 .ModelString = "Digital Video Creator I",
754 },
755 [GLOBAL_VILLAGE_GV_007_NTSC] = {
756 .Interface = -1,
757 .Codec = CODEC_SAA7111,
758 .VideoChannels = 2,
759 .VideoNorm = V4L2_STD_NTSC,
760 .AudioChannels = 0,
761 .Radio = 0,
762 .vbi = 1,
763 .Tuner = 0,
764 .TunerType = 0,
765 .X_Offset = 82,
766 .Y_Offset = 20,
767 .Dvi_yuv_override = 1,
768 .Dvi_yuv = 7,
769 .ModelString = "Global Village GV-007 (NTSC)",
770 },
771 [DAZZLE_DVC_50_REV_1_NTSC] = {
772 .Interface = 0,
773 .Codec = CODEC_SAA7113,
774 .VideoChannels = 2,
775 .VideoNorm = V4L2_STD_NTSC,
776 .AudioChannels = 0,
777 .Radio = 0,
778 .vbi = 1,
779 .Tuner = 0,
780 .TunerType = 0,
781 .X_Offset = 0,
782 .Y_Offset = 3,
783 .Dvi_yuv_override = 1,
784 .Dvi_yuv = 7,
785 .ModelString = "Dazzle Fusion Model DVC-50 Rev 1 (NTSC)",
786 },
787 [DAZZLE_DVC_80_REV_1_PAL] = {
788 .Interface = 0,
789 .Codec = CODEC_SAA7113,
790 .VideoChannels = 2,
791 .VideoNorm = V4L2_STD_PAL,
792 .AudioChannels = 0,
793 .Radio = 0,
794 .vbi = 1,
795 .Tuner = 0,
796 .TunerType = 0,
797 .X_Offset = 0,
798 .Y_Offset = 3,
799 .Dvi_yuv_override = 1,
800 .Dvi_yuv = 7,
801 .ModelString = "Dazzle Fusion Model DVC-80 Rev 1 (PAL)",
802 },
803 [DAZZLE_DVC_90_REV_1_SECAM] = {
804 .Interface = 0,
805 .Codec = CODEC_SAA7113,
806 .VideoChannels = 2,
807 .VideoNorm = V4L2_STD_SECAM,
808 .AudioChannels = 0,
809 .Radio = 0,
810 .vbi = 1,
811 .Tuner = 0,
812 .TunerType = 0,
813 .X_Offset = 0,
814 .Y_Offset = 3,
815 .Dvi_yuv_override = 1,
816 .Dvi_yuv = 7,
817 .ModelString = "Dazzle Fusion Model DVC-90 Rev 1 (SECAM)",
818 },
819 [ESKAPE_LABS_MYTV2GO] = {
820 .Interface = 0,
821 .Codec = CODEC_SAA7113,
822 .VideoChannels = 2,
823 .VideoNorm = V4L2_STD_PAL,
824 .AudioChannels = 1,
825 .Radio = 1,
826 .vbi = 1,
827 .Tuner = 1,
828 .TunerType = TUNER_PHILIPS_FM1216ME_MK3,
829 .X_Offset = 0,
830 .Y_Offset = 3,
831 .Dvi_yuv_override = 1,
832 .Dvi_yuv = 7,
833 .ModelString = "Eskape Labs MyTV2Go",
834 },
835 [PINNA_PCTV_USB_PAL] = {
836 .Interface = -1,
837 .Codec = CODEC_SAA7111,
838 .VideoChannels = 3,
839 .VideoNorm = V4L2_STD_PAL,
840 .AudioChannels = 1,
841 .Radio = 0,
842 .vbi = 0,
843 .Tuner = 1,
844 .TunerType = TUNER_TEMIC_4066FY5_PAL_I,
845 .X_Offset = -1,
846 .Y_Offset = -1,
847 .ModelString = "Pinnacle Studio PCTV USB (PAL)",
848 },
849 [PINNA_PCTV_USB_SECAM] = {
850 .Interface = -1,
851 .Codec = CODEC_SAA7111,
852 .VideoChannels = 3,
853 .VideoNorm = V4L2_STD_SECAM,
854 .AudioChannels = 1,
855 .Radio = 0,
856 .vbi = 1,
857 .Tuner = 1,
858 .TunerType = TUNER_PHILIPS_SECAM,
859 .X_Offset = -1,
860 .Y_Offset = -1,
861 .ModelString = "Pinnacle Studio PCTV USB (SECAM)",
862 },
863 [PINNA_PCTV_USB_PAL_FM] = {
864 .Interface = -1,
865 .Codec = CODEC_SAA7111,
866 .VideoChannels = 3,
867 .VideoNorm = V4L2_STD_PAL,
868 .AudioChannels = 1,
869 .Radio = 1,
870 .vbi = 1,
871 .Tuner = 1,
872 .TunerType = TUNER_PHILIPS_PAL,
873 .X_Offset = 128,
874 .Y_Offset = 23,
875 .ModelString = "Pinnacle Studio PCTV USB (PAL) FM",
876 },
877 [MIRO_PCTV_USB] = {
878 .Interface = -1,
879 .Codec = CODEC_SAA7111,
880 .VideoChannels = 3,
881 .VideoNorm = V4L2_STD_PAL,
882 .AudioChannels = 1,
883 .Radio = 0,
884 .vbi = 1,
885 .Tuner = 1,
886 .TunerType = TUNER_PHILIPS_PAL,
887 .X_Offset = -1,
888 .Y_Offset = -1,
889 .ModelString = "Miro PCTV USB",
890 },
891 [PINNA_PCTV_USB_NTSC_FM] = {
892 .Interface = -1,
893 .Codec = CODEC_SAA7111,
894 .VideoChannels = 3,
895 .VideoNorm = V4L2_STD_NTSC,
896 .AudioChannels = 1,
897 .Radio = 1,
898 .vbi = 1,
899 .Tuner = 1,
900 .TunerType = TUNER_PHILIPS_NTSC_M,
901 .X_Offset = -1,
902 .Y_Offset = -1,
903 .ModelString = "Pinnacle Studio PCTV USB (NTSC) FM",
904 },
905 [PINNA_PCTV_USB_PAL_FM_V2] = {
906 .Interface = -1,
907 .Codec = CODEC_SAA7113,
908 .VideoChannels = 3,
909 .VideoNorm = V4L2_STD_PAL,
910 .AudioChannels = 1,
911 .Radio = 1,
912 .vbi = 1,
913 .Tuner = 1,
914 .TunerType = TUNER_TEMIC_4009FR5_PAL,
915 .X_Offset = 0,
916 .Y_Offset = 3,
917 .Dvi_yuv_override = 1,
918 .Dvi_yuv = 7,
919 .ModelString = "Pinnacle Studio PCTV USB (PAL) FM V2",
920 },
921 [PINNA_PCTV_USB_NTSC_FM_V2] = {
922 .Interface = -1,
923 .Codec = CODEC_SAA7111,
924 .VideoChannels = 3,
925 .VideoNorm = V4L2_STD_NTSC,
926 .AudioChannels = 1,
927 .Radio = 1,
928 .vbi = 1,
929 .Tuner = 1,
930 .TunerType = TUNER_TEMIC_4039FR5_NTSC,
931 .X_Offset = 0,
932 .Y_Offset = 3,
933 .Dvi_yuv_override = 1,
934 .Dvi_yuv = 7,
935 .ModelString = "Pinnacle Studio PCTV USB (NTSC) FM V2",
936 },
937 [PINNA_PCTV_USB_PAL_FM_V3] = {
938 .Interface = -1,
939 .Codec = CODEC_SAA7113,
940 .VideoChannels = 3,
941 .VideoNorm = V4L2_STD_PAL,
942 .AudioChannels = 1,
943 .Radio = 1,
944 .vbi = 1,
945 .Tuner = 1,
946 .TunerType = TUNER_TEMIC_4009FR5_PAL,
947 .X_Offset = 0,
948 .Y_Offset = 3,
949 .Dvi_yuv_override = 1,
950 .Dvi_yuv = 7,
951 .ModelString = "Pinnacle Studio PCTV USB (PAL) FM V3",
952 },
953 [PINNA_LINX_VD_IN_CAB_NTSC] = {
954 .Interface = -1,
955 .Codec = CODEC_SAA7113,
956 .VideoChannels = 2,
957 .VideoNorm = V4L2_STD_NTSC,
958 .AudioChannels = 1,
959 .Radio = 0,
960 .vbi = 1,
961 .Tuner = 0,
962 .TunerType = 0,
963 .X_Offset = 0,
964 .Y_Offset = 3,
965 .Dvi_yuv_override = 1,
966 .Dvi_yuv = 7,
967 .ModelString = "Pinnacle Studio Linx Video input cable (NTSC)",
968 },
969 [PINNA_LINX_VD_IN_CAB_PAL] = {
970 .Interface = -1,
971 .Codec = CODEC_SAA7113,
972 .VideoChannels = 2,
973 .VideoNorm = V4L2_STD_PAL,
974 .AudioChannels = 1,
975 .Radio = 0,
976 .vbi = 1,
977 .Tuner = 0,
978 .TunerType = 0,
979 .X_Offset = 0,
980 .Y_Offset = 3,
981 .Dvi_yuv_override = 1,
982 .Dvi_yuv = 7,
983 .ModelString = "Pinnacle Studio Linx Video input cable (PAL)",
984 },
985 [PINNA_PCTV_BUNGEE_PAL_FM] = {
986 .Interface = -1,
987 .Codec = CODEC_SAA7113,
988 .VideoChannels = 3,
989 .VideoNorm = V4L2_STD_PAL,
990 .AudioChannels = 1,
991 .Radio = 1,
992 .vbi = 1,
993 .Tuner = 1,
994 .TunerType = TUNER_TEMIC_4009FR5_PAL,
995 .X_Offset = 0,
996 .Y_Offset = 3,
997 .Dvi_yuv_override = 1,
998 .Dvi_yuv = 7,
999 .ModelString = "Pinnacle PCTV Bungee USB (PAL) FM",
1000 },
1001 [HPG_WINTV] = {
1002 .Interface = -1,
1003 .Codec = CODEC_SAA7111,
1004 .VideoChannels = 3,
1005 .VideoNorm = V4L2_STD_NTSC,
1006 .AudioChannels = 1,
1007 .Radio = 0,
1008 .vbi = 1,
1009 .Tuner = 1,
1010 .TunerType = TUNER_PHILIPS_NTSC_M,
1011 .X_Offset = -1,
1012 .Y_Offset = -1,
1013 .ModelString = "Hauppauge WinTv-USB",
1014 },
91}; 1015};
1016const int usbvision_device_data_size=ARRAY_SIZE(usbvision_device_data);
92 1017
93/* Supported Devices */ 1018/* Supported Devices */
94 1019
95struct usb_device_id usbvision_table [] = { 1020struct usb_device_id usbvision_table [] = {
96 { USB_DEVICE(0xFFF0, 0xFFF0) }, /* Custom Dummy USBVision Device */ 1021 { USB_DEVICE(0x0a6f, 0x0400), .driver_info=XANBOO },
97 { USB_DEVICE(0x0A6F, 0x0400) }, /* Xanboo */ 1022 { USB_DEVICE(0x050d, 0x0106), .driver_info=BELKIN_VIDEOBUS_II },
98 { USB_DEVICE(0x050d, 0x0208) }, /* Belkin USBView II */ 1023 { USB_DEVICE(0x050d, 0x0207), .driver_info=BELKIN_VIDEOBUS },
99 { USB_DEVICE(0x0571, 0x0002) }, /* echoFX InterView Lite */ 1024 { USB_DEVICE(0x050d, 0x0208), .driver_info=BELKIN_USB_VIDEOBUS_II },
100 { USB_DEVICE(0x0573, 0x0003) }, /* USBGear USBG-V1 */ 1025 { USB_DEVICE(0x0571, 0x0002), .driver_info=ECHOFX_INTERVIEW_LITE },
101 { USB_DEVICE(0x0573, 0x0400) }, /* D-Link V100 */ 1026 { USB_DEVICE(0x0573, 0x0003), .driver_info=USBGEAR_USBG_V1 },
102 { USB_DEVICE(0x0573, 0x2000) }, /* X10 USB Camera */ 1027 { USB_DEVICE(0x0573, 0x0400), .driver_info=D_LINK_V100 },
103 { USB_DEVICE(0x0573, 0x2d00) }, /* Osprey 50 */ 1028 { USB_DEVICE(0x0573, 0x2000), .driver_info=X10_USB_CAMERA },
104 { USB_DEVICE(0x0573, 0x2d01) }, /* Hauppauge USB-Live Model 600 */ 1029 { USB_DEVICE(0x0573, 0x2d00), .driver_info=HPG_WINTV_LIVE_PAL_BG },
105 { USB_DEVICE(0x0573, 0x2101) }, /* Zoran Co. PMD (Nogatech) AV-grabber Manhattan */ 1030 { USB_DEVICE(0x0573, 0x2d01), .driver_info=HPG_WINTV_LIVE_PRO_NTSC_MN },
106 { USB_DEVICE(0x0573, 0x4100) }, /* Nogatech USB-TV FM (NTSC) */ 1031 { USB_DEVICE(0x0573, 0x2101), .driver_info=ZORAN_PMD_NOGATECH },
107 { USB_DEVICE(0x0573, 0x4110) }, /* PNY USB-TV (NTSC) FM */ 1032 { USB_DEVICE(0x0573, 0x4100), .driver_info=NOGATECH_USB_TV_NTSC_FM },
108 { USB_DEVICE(0x0573, 0x4450) }, /* PixelView PlayTv-USB PRO (PAL) FM */ 1033 { USB_DEVICE(0x0573, 0x4110), .driver_info=PNY_USB_TV_NTSC_FM },
109 { USB_DEVICE(0x0573, 0x4550) }, /* ZTV ZT-721 2.4GHz USB A/V Receiver */ 1034 { USB_DEVICE(0x0573, 0x4450), .driver_info=PV_PLAYTV_USB_PRO_PAL_FM },
110 { USB_DEVICE(0x0573, 0x4d00) }, /* Hauppauge WinTv-USB USA */ 1035 { USB_DEVICE(0x0573, 0x4550), .driver_info=ZT_721 },
111 { USB_DEVICE(0x0573, 0x4d01) }, /* Hauppauge WinTv-USB */ 1036 { USB_DEVICE(0x0573, 0x4d00), .driver_info=HPG_WINTV_NTSC_MN },
112 { USB_DEVICE(0x0573, 0x4d02) }, /* Hauppauge WinTv-USB UK */ 1037 { USB_DEVICE(0x0573, 0x4d01), .driver_info=HPG_WINTV_PAL_BG },
113 { USB_DEVICE(0x0573, 0x4d03) }, /* Hauppauge WinTv-USB France */ 1038 { USB_DEVICE(0x0573, 0x4d02), .driver_info=HPG_WINTV_PAL_I },
114 { USB_DEVICE(0x0573, 0x4d10) }, /* Hauppauge WinTv-USB with FM USA radio */ 1039 { USB_DEVICE(0x0573, 0x4d03), .driver_info=HPG_WINTV_PAL_SECAM_L },
115 { USB_DEVICE(0x0573, 0x4d11) }, /* Hauppauge WinTv-USB (PAL) with FM radio */ 1040 { USB_DEVICE(0x0573, 0x4d04), .driver_info=HPG_WINTV_PAL_D_K },
116 { USB_DEVICE(0x0573, 0x4d12) }, /* Hauppauge WinTv-USB UK with FM Radio */ 1041 { USB_DEVICE(0x0573, 0x4d10), .driver_info=HPG_WINTV_NTSC_FM },
117 { USB_DEVICE(0x0573, 0x4d2a) }, /* Hauppague WinTv USB Model 602 40201 Rev B285 */ 1042 { USB_DEVICE(0x0573, 0x4d11), .driver_info=HPG_WINTV_PAL_BG_FM },
118 { USB_DEVICE(0x0573, 0x4d2b) }, /* Hauppague WinTv USB Model 602 40201 Rev B282 */ 1043 { USB_DEVICE(0x0573, 0x4d12), .driver_info=HPG_WINTV_PAL_I_FM },
119 { USB_DEVICE(0x0573, 0x4d2c) }, /* Hauppague WinTv USB Model 40209 Rev. E1A5 PAL*/ 1044 { USB_DEVICE(0x0573, 0x4d14), .driver_info=HPG_WINTV_PAL_D_K_FM },
120 { USB_DEVICE(0x0573, 0x4d20) }, /* Hauppauge WinTv-USB II (PAL) FM Model 40201 Rev B226 */ 1045 { USB_DEVICE(0x0573, 0x4d2a), .driver_info=HPG_WINTV_PRO_NTSC_MN },
121 { USB_DEVICE(0x0573, 0x4d21) }, /* Hauppauge WinTv-USB II (PAL) with FM radio*/ 1046 { USB_DEVICE(0x0573, 0x4d2b), .driver_info=HPG_WINTV_PRO_NTSC_MN_V2 },
122 { USB_DEVICE(0x0573, 0x4d22) }, /* Hauppauge WinTv-USB II (PAL) Model 566 */ 1047 { USB_DEVICE(0x0573, 0x4d2c), .driver_info=HPG_WINTV_PRO_PAL },
123 { USB_DEVICE(0x0573, 0x4d23) }, /* Hauppauge WinTv-USB France 4D23*/ 1048 { USB_DEVICE(0x0573, 0x4d20), .driver_info=HPG_WINTV_PRO_NTSC_MN_V3 },
124 { USB_DEVICE(0x0573, 0x4d25) }, /* Hauppauge WinTv-USB Model 40209 rev B234 */ 1049 { USB_DEVICE(0x0573, 0x4d21), .driver_info=HPG_WINTV_PRO_PAL_BG },
125 { USB_DEVICE(0x0573, 0x4d26) }, /* Hauppauge WinTv-USB Model 40209 Rev B243 */ 1050 { USB_DEVICE(0x0573, 0x4d22), .driver_info=HPG_WINTV_PRO_PAL_I },
126 { USB_DEVICE(0x0573, 0x4d27) }, /* Hauppauge WinTv-USB Model 40204 Rev B281 */ 1051 { USB_DEVICE(0x0573, 0x4d23), .driver_info=HPG_WINTV_PRO_PAL_SECAM_L },
127 { USB_DEVICE(0x0573, 0x4d28) }, /* Hauppauge WinTv-USB Model 40204 Rev B283 */ 1052 { USB_DEVICE(0x0573, 0x4d24), .driver_info=HPG_WINTV_PRO_PAL_D_K },
128 { USB_DEVICE(0x0573, 0x4d29) }, /* Hauppauge WinTv-USB Model 40205 Rev B298 */ 1053 { USB_DEVICE(0x0573, 0x4d25), .driver_info=HPG_WINTV_PRO_PAL_SECAM },
129 { USB_DEVICE(0x0573, 0x4d30) }, /* Hauppauge WinTv-USB FM Model 40211 Rev B123 */ 1054 { USB_DEVICE(0x0573, 0x4d26), .driver_info=HPG_WINTV_PRO_PAL_SECAM_V2 },
130 { USB_DEVICE(0x0573, 0x4d31) }, /* Hauppauge WinTv-USB III (PAL) with FM radio Model 568 */ 1055 { USB_DEVICE(0x0573, 0x4d27), .driver_info=HPG_WINTV_PRO_PAL_BG_V2 },
131 { USB_DEVICE(0x0573, 0x4d32) }, /* Hauppauge WinTv-USB III (PAL) FM Model 573 */ 1056 { USB_DEVICE(0x0573, 0x4d28), .driver_info=HPG_WINTV_PRO_PAL_BG_D_K },
132 { USB_DEVICE(0x0573, 0x4d35) }, /* Hauppauge WinTv-USB III (SECAM) FM Model 40219 Rev B252 */ 1057 { USB_DEVICE(0x0573, 0x4d29), .driver_info=HPG_WINTV_PRO_PAL_I_D_K },
133 { USB_DEVICE(0x0573, 0x4d37) }, /* Hauppauge WinTv-USB Model 40219 Rev E189 */ 1058 { USB_DEVICE(0x0573, 0x4d30), .driver_info=HPG_WINTV_PRO_NTSC_MN_FM },
134 { USB_DEVICE(0x0768, 0x0006) }, /* Camtel Technology USB TV Genie Pro FM Model TVB330 */ 1059 { USB_DEVICE(0x0573, 0x4d31), .driver_info=HPG_WINTV_PRO_PAL_BG_FM },
135 { USB_DEVICE(0x07d0, 0x0001) }, /* Digital Video Creator I */ 1060 { USB_DEVICE(0x0573, 0x4d32), .driver_info=HPG_WINTV_PRO_PAL_I_FM },
136 { USB_DEVICE(0x07d0, 0x0002) }, /* Global Village GV-007 (NTSC) */ 1061 { USB_DEVICE(0x0573, 0x4d34), .driver_info=HPG_WINTV_PRO_PAL_D_K_FM },
137 { USB_DEVICE(0x07d0, 0x0003) }, /* Dazzle Fusion Model DVC-50 Rev 1 (NTSC) */ 1062 { USB_DEVICE(0x0573, 0x4d35), .driver_info=HPG_WINTV_PRO_TEMIC_PAL_FM },
138 { USB_DEVICE(0x07d0, 0x0004) }, /* Dazzle Fusion Model DVC-80 Rev 1 (PAL) */ 1063 { USB_DEVICE(0x0573, 0x4d36), .driver_info=HPG_WINTV_PRO_TEMIC_PAL_BG_FM },
139 { USB_DEVICE(0x07d0, 0x0005) }, /* Dazzle Fusion Model DVC-90 Rev 1 (SECAM) */ 1064 { USB_DEVICE(0x0573, 0x4d37), .driver_info=HPG_WINTV_PRO_PAL_FM },
140 { USB_DEVICE(0x2304, 0x010d) }, /* Pinnacle Studio PCTV USB (PAL) */ 1065 { USB_DEVICE(0x0573, 0x4d38), .driver_info=HPG_WINTV_PRO_NTSC_MN_FM_V2 },
141 { USB_DEVICE(0x2304, 0x0109) }, /* Pinnacle Studio PCTV USB (SECAM) */ 1066 { USB_DEVICE(0x0768, 0x0006), .driver_info=CAMTEL_TVB330 },
142 { USB_DEVICE(0x2304, 0x0110) }, /* Pinnacle Studio PCTV USB (PAL) */ 1067 { USB_DEVICE(0x07d0, 0x0001), .driver_info=DIGITAL_VIDEO_CREATOR_I },
143 { USB_DEVICE(0x2304, 0x0111) }, /* Miro PCTV USB */ 1068 { USB_DEVICE(0x07d0, 0x0002), .driver_info=GLOBAL_VILLAGE_GV_007_NTSC },
144 { USB_DEVICE(0x2304, 0x0112) }, /* Pinnacle Studio PCTV USB (NTSC) with FM radio */ 1069 { USB_DEVICE(0x07d0, 0x0003), .driver_info=DAZZLE_DVC_50_REV_1_NTSC },
145 { USB_DEVICE(0x2304, 0x0210) }, /* Pinnacle Studio PCTV USB (PAL) with FM radio */ 1070 { USB_DEVICE(0x07d0, 0x0004), .driver_info=DAZZLE_DVC_80_REV_1_PAL },
146 { USB_DEVICE(0x2304, 0x0212) }, /* Pinnacle Studio PCTV USB (NTSC) with FM radio */ 1071 { USB_DEVICE(0x07d0, 0x0005), .driver_info=DAZZLE_DVC_90_REV_1_SECAM },
147 { USB_DEVICE(0x2304, 0x0214) }, /* Pinnacle Studio PCTV USB (PAL) with FM radio */ 1072 { USB_DEVICE(0x07f8, 0x9104), .driver_info=ESKAPE_LABS_MYTV2GO },
148 { USB_DEVICE(0x2304, 0x0300) }, /* Pinnacle Studio Linx Video input cable (NTSC) */ 1073 { USB_DEVICE(0x2304, 0x010d), .driver_info=PINNA_PCTV_USB_PAL },
149 { USB_DEVICE(0x2304, 0x0301) }, /* Pinnacle Studio Linx Video input cable (PAL) */ 1074 { USB_DEVICE(0x2304, 0x0109), .driver_info=PINNA_PCTV_USB_SECAM },
150 { USB_DEVICE(0x2304, 0x0419) }, /* Pinnacle PCTV Bungee USB (PAL) FM */ 1075 { USB_DEVICE(0x2304, 0x0110), .driver_info=PINNA_PCTV_USB_PAL_FM },
151 { USB_DEVICE(0x2400, 0x4200) }, /* Hauppauge WinTv-USB2 Model 42012 */ 1076 { USB_DEVICE(0x2304, 0x0111), .driver_info=MIRO_PCTV_USB },
152 1077 { USB_DEVICE(0x2304, 0x0112), .driver_info=PINNA_PCTV_USB_NTSC_FM },
153 { } /* Terminating entry */ 1078 { USB_DEVICE(0x2304, 0x0210), .driver_info=PINNA_PCTV_USB_PAL_FM_V2 },
1079 { USB_DEVICE(0x2304, 0x0212), .driver_info=PINNA_PCTV_USB_NTSC_FM_V2 },
1080 { USB_DEVICE(0x2304, 0x0214), .driver_info=PINNA_PCTV_USB_PAL_FM_V3 },
1081 { USB_DEVICE(0x2304, 0x0300), .driver_info=PINNA_LINX_VD_IN_CAB_NTSC },
1082 { USB_DEVICE(0x2304, 0x0301), .driver_info=PINNA_LINX_VD_IN_CAB_PAL },
1083 { USB_DEVICE(0x2304, 0x0419), .driver_info=PINNA_PCTV_BUNGEE_PAL_FM },
1084 { USB_DEVICE(0x2400, 0x4200), .driver_info=HPG_WINTV },
154}; 1085};
155 1086
156MODULE_DEVICE_TABLE (usb, usbvision_table); 1087MODULE_DEVICE_TABLE (usb, usbvision_table);
diff --git a/drivers/media/video/usbvision/usbvision-cards.h b/drivers/media/video/usbvision/usbvision-cards.h
new file mode 100644
index 000000000000..512c5cee4145
--- /dev/null
+++ b/drivers/media/video/usbvision/usbvision-cards.h
@@ -0,0 +1,66 @@
1#define XANBOO 0
2#define BELKIN_VIDEOBUS_II 1
3#define BELKIN_VIDEOBUS 2
4#define BELKIN_USB_VIDEOBUS_II 3
5#define ECHOFX_INTERVIEW_LITE 4
6#define USBGEAR_USBG_V1 5
7#define D_LINK_V100 6
8#define X10_USB_CAMERA 7
9#define HPG_WINTV_LIVE_PAL_BG 8
10#define HPG_WINTV_LIVE_PRO_NTSC_MN 9
11#define ZORAN_PMD_NOGATECH 10
12#define NOGATECH_USB_TV_NTSC_FM 11
13#define PNY_USB_TV_NTSC_FM 12
14#define PV_PLAYTV_USB_PRO_PAL_FM 13
15#define ZT_721 14
16#define HPG_WINTV_NTSC_MN 15
17#define HPG_WINTV_PAL_BG 16
18#define HPG_WINTV_PAL_I 17
19#define HPG_WINTV_PAL_SECAM_L 18
20#define HPG_WINTV_PAL_D_K 19
21#define HPG_WINTV_NTSC_FM 20
22#define HPG_WINTV_PAL_BG_FM 21
23#define HPG_WINTV_PAL_I_FM 22
24#define HPG_WINTV_PAL_D_K_FM 23
25#define HPG_WINTV_PRO_NTSC_MN 24
26#define HPG_WINTV_PRO_NTSC_MN_V2 25
27#define HPG_WINTV_PRO_PAL 26
28#define HPG_WINTV_PRO_NTSC_MN_V3 27
29#define HPG_WINTV_PRO_PAL_BG 28
30#define HPG_WINTV_PRO_PAL_I 29
31#define HPG_WINTV_PRO_PAL_SECAM_L 30
32#define HPG_WINTV_PRO_PAL_D_K 31
33#define HPG_WINTV_PRO_PAL_SECAM 32
34#define HPG_WINTV_PRO_PAL_SECAM_V2 33
35#define HPG_WINTV_PRO_PAL_BG_V2 34
36#define HPG_WINTV_PRO_PAL_BG_D_K 35
37#define HPG_WINTV_PRO_PAL_I_D_K 36
38#define HPG_WINTV_PRO_NTSC_MN_FM 37
39#define HPG_WINTV_PRO_PAL_BG_FM 38
40#define HPG_WINTV_PRO_PAL_I_FM 39
41#define HPG_WINTV_PRO_PAL_D_K_FM 40
42#define HPG_WINTV_PRO_TEMIC_PAL_FM 41
43#define HPG_WINTV_PRO_TEMIC_PAL_BG_FM 42
44#define HPG_WINTV_PRO_PAL_FM 43
45#define HPG_WINTV_PRO_NTSC_MN_FM_V2 44
46#define CAMTEL_TVB330 45
47#define DIGITAL_VIDEO_CREATOR_I 46
48#define GLOBAL_VILLAGE_GV_007_NTSC 47
49#define DAZZLE_DVC_50_REV_1_NTSC 48
50#define DAZZLE_DVC_80_REV_1_PAL 49
51#define DAZZLE_DVC_90_REV_1_SECAM 50
52#define ESKAPE_LABS_MYTV2GO 51
53#define PINNA_PCTV_USB_PAL 52
54#define PINNA_PCTV_USB_SECAM 53
55#define PINNA_PCTV_USB_PAL_FM 54
56#define MIRO_PCTV_USB 55
57#define PINNA_PCTV_USB_NTSC_FM 56
58#define PINNA_PCTV_USB_PAL_FM_V2 57
59#define PINNA_PCTV_USB_NTSC_FM_V2 58
60#define PINNA_PCTV_USB_PAL_FM_V3 59
61#define PINNA_LINX_VD_IN_CAB_NTSC 60
62#define PINNA_LINX_VD_IN_CAB_PAL 61
63#define PINNA_PCTV_BUNGEE_PAL_FM 62
64#define HPG_WINTV 63
65
66extern const int usbvision_device_data_size;
diff --git a/drivers/media/video/usbvision/usbvision-core.c b/drivers/media/video/usbvision/usbvision-core.c
index f2154dc072e2..bcb551adb7e6 100644
--- a/drivers/media/video/usbvision/usbvision-core.c
+++ b/drivers/media/video/usbvision/usbvision-core.c
@@ -2040,8 +2040,8 @@ int usbvision_set_input(struct usb_usbvision *usbvision)
2040 return 0; 2040 return 0;
2041 2041
2042 /* Set input format expected from decoder*/ 2042 /* Set input format expected from decoder*/
2043 if (usbvision_device_data[usbvision->DevModel].Vin_Reg1 >= 0) { 2043 if (usbvision_device_data[usbvision->DevModel].Vin_Reg1_override) {
2044 value[0] = usbvision_device_data[usbvision->DevModel].Vin_Reg1 & 0xff; 2044 value[0] = usbvision_device_data[usbvision->DevModel].Vin_Reg1;
2045 } else if(usbvision_device_data[usbvision->DevModel].Codec == CODEC_SAA7113) { 2045 } else if(usbvision_device_data[usbvision->DevModel].Codec == CODEC_SAA7113) {
2046 /* SAA7113 uses 8 bit output */ 2046 /* SAA7113 uses 8 bit output */
2047 value[0] = USBVISION_8_422_SYNC; 2047 value[0] = USBVISION_8_422_SYNC;
@@ -2112,8 +2112,8 @@ int usbvision_set_input(struct usb_usbvision *usbvision)
2112 2112
2113 dvi_yuv_value = 0x00; /* U comes after V, Ya comes after U/V, Yb comes after Yb */ 2113 dvi_yuv_value = 0x00; /* U comes after V, Ya comes after U/V, Yb comes after Yb */
2114 2114
2115 if(usbvision_device_data[usbvision->DevModel].Dvi_yuv >= 0){ 2115 if(usbvision_device_data[usbvision->DevModel].Dvi_yuv_override){
2116 dvi_yuv_value = usbvision_device_data[usbvision->DevModel].Dvi_yuv & 0xff; 2116 dvi_yuv_value = usbvision_device_data[usbvision->DevModel].Dvi_yuv;
2117 } 2117 }
2118 else if(usbvision_device_data[usbvision->DevModel].Codec == CODEC_SAA7113) { 2118 else if(usbvision_device_data[usbvision->DevModel].Codec == CODEC_SAA7113) {
2119 /* This changes as the fine sync control changes. Further investigation necessary */ 2119 /* This changes as the fine sync control changes. Further investigation necessary */
@@ -2238,7 +2238,7 @@ static void call_usbvision_power_off(struct work_struct *work)
2238 PDEBUG(DBG_FUNC, ""); 2238 PDEBUG(DBG_FUNC, "");
2239 down_interruptible(&usbvision->lock); 2239 down_interruptible(&usbvision->lock);
2240 if(usbvision->user == 0) { 2240 if(usbvision->user == 0) {
2241 usbvision_i2c_usb_del_bus(&usbvision->i2c_adap); 2241 usbvision_i2c_unregister(usbvision);
2242 2242
2243 usbvision_power_off(usbvision); 2243 usbvision_power_off(usbvision);
2244 usbvision->initialized = 0; 2244 usbvision->initialized = 0;
diff --git a/drivers/media/video/usbvision/usbvision-i2c.c b/drivers/media/video/usbvision/usbvision-i2c.c
index 609e1fd9c784..025be555194f 100644
--- a/drivers/media/video/usbvision/usbvision-i2c.c
+++ b/drivers/media/video/usbvision/usbvision-i2c.c
@@ -1,8 +1,8 @@
1/* 1/*
2 * I2C_ALGO_USB.C 2 * usbvision_i2c.c
3 * i2c algorithm for USB-I2C Bridges 3 * i2c algorithm for USB-I2C Bridges
4 * 4 *
5 * Copyright (c) 1999-2005 Joerg Heckenbach <joerg@heckenbach-aw.de> 5 * Copyright (c) 1999-2007 Joerg Heckenbach <joerg@heckenbach-aw.de>
6 * Dwaine Garden <dwainegarden@rogers.com> 6 * Dwaine Garden <dwainegarden@rogers.com>
7 * 7 *
8 * This module is part of usbvision driver project. 8 * This module is part of usbvision driver project.
@@ -39,7 +39,6 @@
39#include "usbvision.h" 39#include "usbvision.h"
40 40
41#define DBG_I2C 1<<0 41#define DBG_I2C 1<<0
42#define DBG_ALGO 1<<1
43 42
44static int i2c_debug = 0; 43static int i2c_debug = 0;
45 44
@@ -49,22 +48,22 @@ MODULE_PARM_DESC(i2c_debug, "enable debug messages [i2c]");
49#define PDEBUG(level, fmt, args...) \ 48#define PDEBUG(level, fmt, args...) \
50 if (i2c_debug & (level)) info("[%s:%d] " fmt, __PRETTY_FUNCTION__, __LINE__ , ## args) 49 if (i2c_debug & (level)) info("[%s:%d] " fmt, __PRETTY_FUNCTION__, __LINE__ , ## args)
51 50
52static int usbvision_i2c_write(void *data, unsigned char addr, char *buf, 51static int usbvision_i2c_write(struct usb_usbvision *usbvision, unsigned char addr, char *buf,
53 short len); 52 short len);
54static int usbvision_i2c_read(void *data, unsigned char addr, char *buf, 53static int usbvision_i2c_read(struct usb_usbvision *usbvision, unsigned char addr, char *buf,
55 short len); 54 short len);
56 55
57static inline int try_write_address(struct i2c_adapter *i2c_adap, 56static inline int try_write_address(struct i2c_adapter *i2c_adap,
58 unsigned char addr, int retries) 57 unsigned char addr, int retries)
59{ 58{
60 void *data; 59 struct usb_usbvision *usbvision;
61 int i, ret = -1; 60 int i, ret = -1;
62 char buf[4]; 61 char buf[4];
63 62
64 data = i2c_get_adapdata(i2c_adap); 63 usbvision = (struct usb_usbvision *)i2c_get_adapdata(i2c_adap);
65 buf[0] = 0x00; 64 buf[0] = 0x00;
66 for (i = 0; i <= retries; i++) { 65 for (i = 0; i <= retries; i++) {
67 ret = (usbvision_i2c_write(data, addr, buf, 1)); 66 ret = (usbvision_i2c_write(usbvision, addr, buf, 1));
68 if (ret == 1) 67 if (ret == 1)
69 break; /* success! */ 68 break; /* success! */
70 udelay(5); 69 udelay(5);
@@ -73,8 +72,8 @@ static inline int try_write_address(struct i2c_adapter *i2c_adap,
73 udelay(10); 72 udelay(10);
74 } 73 }
75 if (i) { 74 if (i) {
76 PDEBUG(DBG_ALGO,"Needed %d retries for address %#2x", i, addr); 75 PDEBUG(DBG_I2C,"Needed %d retries for address %#2x", i, addr);
77 PDEBUG(DBG_ALGO,"Maybe there's no device at this address"); 76 PDEBUG(DBG_I2C,"Maybe there's no device at this address");
78 } 77 }
79 return ret; 78 return ret;
80} 79}
@@ -82,13 +81,13 @@ static inline int try_write_address(struct i2c_adapter *i2c_adap,
82static inline int try_read_address(struct i2c_adapter *i2c_adap, 81static inline int try_read_address(struct i2c_adapter *i2c_adap,
83 unsigned char addr, int retries) 82 unsigned char addr, int retries)
84{ 83{
85 void *data; 84 struct usb_usbvision *usbvision;
86 int i, ret = -1; 85 int i, ret = -1;
87 char buf[4]; 86 char buf[4];
88 87
89 data = i2c_get_adapdata(i2c_adap); 88 usbvision = (struct usb_usbvision *)i2c_get_adapdata(i2c_adap);
90 for (i = 0; i <= retries; i++) { 89 for (i = 0; i <= retries; i++) {
91 ret = (usbvision_i2c_read(data, addr, buf, 1)); 90 ret = (usbvision_i2c_read(usbvision, addr, buf, 1));
92 if (ret == 1) 91 if (ret == 1)
93 break; /* success! */ 92 break; /* success! */
94 udelay(5); 93 udelay(5);
@@ -97,8 +96,8 @@ static inline int try_read_address(struct i2c_adapter *i2c_adap,
97 udelay(10); 96 udelay(10);
98 } 97 }
99 if (i) { 98 if (i) {
100 PDEBUG(DBG_ALGO,"Needed %d retries for address %#2x", i, addr); 99 PDEBUG(DBG_I2C,"Needed %d retries for address %#2x", i, addr);
101 PDEBUG(DBG_ALGO,"Maybe there's no device at this address"); 100 PDEBUG(DBG_I2C,"Maybe there's no device at this address");
102 } 101 }
103 return ret; 102 return ret;
104} 103}
@@ -152,32 +151,32 @@ static inline int usb_find_address(struct i2c_adapter *i2c_adap,
152} 151}
153 152
154static int 153static int
155usb_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msgs[], int num) 154usbvision_i2c_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msgs[], int num)
156{ 155{
157 struct i2c_msg *pmsg; 156 struct i2c_msg *pmsg;
158 void *data; 157 struct usb_usbvision *usbvision;
159 int i, ret; 158 int i, ret;
160 unsigned char addr; 159 unsigned char addr;
161 160
162 data = i2c_get_adapdata(i2c_adap); 161 usbvision = (struct usb_usbvision *)i2c_get_adapdata(i2c_adap);
163 162
164 for (i = 0; i < num; i++) { 163 for (i = 0; i < num; i++) {
165 pmsg = &msgs[i]; 164 pmsg = &msgs[i];
166 ret = usb_find_address(i2c_adap, pmsg, i2c_adap->retries, &addr); 165 ret = usb_find_address(i2c_adap, pmsg, i2c_adap->retries, &addr);
167 if (ret != 0) { 166 if (ret != 0) {
168 PDEBUG(DBG_ALGO,"got NAK from device, message #%d", i); 167 PDEBUG(DBG_I2C,"got NAK from device, message #%d", i);
169 return (ret < 0) ? ret : -EREMOTEIO; 168 return (ret < 0) ? ret : -EREMOTEIO;
170 } 169 }
171 170
172 if (pmsg->flags & I2C_M_RD) { 171 if (pmsg->flags & I2C_M_RD) {
173 /* read bytes into buffer */ 172 /* read bytes into buffer */
174 ret = (usbvision_i2c_read(data, addr, pmsg->buf, pmsg->len)); 173 ret = (usbvision_i2c_read(usbvision, addr, pmsg->buf, pmsg->len));
175 if (ret < pmsg->len) { 174 if (ret < pmsg->len) {
176 return (ret < 0) ? ret : -EREMOTEIO; 175 return (ret < 0) ? ret : -EREMOTEIO;
177 } 176 }
178 } else { 177 } else {
179 /* write bytes from buffer */ 178 /* write bytes from buffer */
180 ret = (usbvision_i2c_write(data, addr, pmsg->buf, pmsg->len)); 179 ret = (usbvision_i2c_write(usbvision, addr, pmsg->buf, pmsg->len));
181 if (ret < pmsg->len) { 180 if (ret < pmsg->len) {
182 return (ret < 0) ? ret : -EREMOTEIO; 181 return (ret < 0) ? ret : -EREMOTEIO;
183 } 182 }
@@ -191,7 +190,7 @@ static int algo_control(struct i2c_adapter *adapter, unsigned int cmd, unsigned
191 return 0; 190 return 0;
192} 191}
193 192
194static u32 usb_func(struct i2c_adapter *adap) 193static u32 functionality(struct i2c_adapter *adap)
195{ 194{
196 return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_10BIT_ADDR | I2C_FUNC_PROTOCOL_MANGLING; 195 return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_10BIT_ADDR | I2C_FUNC_PROTOCOL_MANGLING;
197} 196}
@@ -199,11 +198,11 @@ static u32 usb_func(struct i2c_adapter *adap)
199 198
200/* -----exported algorithm data: ------------------------------------- */ 199/* -----exported algorithm data: ------------------------------------- */
201 200
202static struct i2c_algorithm i2c_usb_algo = { 201static struct i2c_algorithm usbvision_algo = {
203 .master_xfer = usb_xfer, 202 .master_xfer = usbvision_i2c_xfer,
204 .smbus_xfer = NULL, 203 .smbus_xfer = NULL,
205 .algo_control = algo_control, 204 .algo_control = algo_control,
206 .functionality = usb_func, 205 .functionality = functionality,
207}; 206};
208 207
209 208
@@ -213,41 +212,29 @@ static struct i2c_algorithm i2c_usb_algo = {
213static int usbvision_i2c_usb_add_bus(struct i2c_adapter *adap) 212static int usbvision_i2c_usb_add_bus(struct i2c_adapter *adap)
214{ 213{
215 PDEBUG(DBG_I2C, "I2C debugging is enabled [i2c]"); 214 PDEBUG(DBG_I2C, "I2C debugging is enabled [i2c]");
216 PDEBUG(DBG_ALGO, "ALGO debugging is enabled [i2c]"); 215 PDEBUG(DBG_I2C, "ALGO debugging is enabled [i2c]");
217 216
218 /* register new adapter to i2c module... */ 217 /* register new adapter to i2c module... */
219 218
220 adap->algo = &i2c_usb_algo; 219 adap->algo = &usbvision_algo;
221 220
222 adap->timeout = 100; /* default values, should */ 221 adap->timeout = 100; /* default values, should */
223 adap->retries = 3; /* be replaced by defines */ 222 adap->retries = 3; /* be replaced by defines */
224 223
225 i2c_add_adapter(adap); 224 i2c_add_adapter(adap);
226 225
227 PDEBUG(DBG_ALGO,"i2c bus for %s registered", adap->name); 226 PDEBUG(DBG_I2C,"i2c bus for %s registered", adap->name);
228
229 return 0;
230}
231
232
233int usbvision_i2c_usb_del_bus(struct i2c_adapter *adap)
234{
235
236 i2c_del_adapter(adap);
237
238 PDEBUG(DBG_ALGO,"i2c bus for %s unregistered", adap->name);
239 227
240 return 0; 228 return 0;
241} 229}
242 230
243
244/* ----------------------------------------------------------------------- */ 231/* ----------------------------------------------------------------------- */
245/* usbvision specific I2C functions */ 232/* usbvision specific I2C functions */
246/* ----------------------------------------------------------------------- */ 233/* ----------------------------------------------------------------------- */
247static struct i2c_adapter i2c_adap_template; 234static struct i2c_adapter i2c_adap_template;
248static struct i2c_client i2c_client_template; 235static struct i2c_client i2c_client_template;
249 236
250int usbvision_init_i2c(struct usb_usbvision *usbvision) 237int usbvision_i2c_register(struct usb_usbvision *usbvision)
251{ 238{
252 memcpy(&usbvision->i2c_adap, &i2c_adap_template, 239 memcpy(&usbvision->i2c_adap, &i2c_adap_template,
253 sizeof(struct i2c_adapter)); 240 sizeof(struct i2c_adapter));
@@ -265,7 +252,7 @@ int usbvision_init_i2c(struct usb_usbvision *usbvision)
265 usbvision->i2c_client.adapter = &usbvision->i2c_adap; 252 usbvision->i2c_client.adapter = &usbvision->i2c_adap;
266 253
267 if (usbvision_write_reg(usbvision, USBVISION_SER_MODE, USBVISION_IIC_LRNACK) < 0) { 254 if (usbvision_write_reg(usbvision, USBVISION_SER_MODE, USBVISION_IIC_LRNACK) < 0) {
268 printk(KERN_ERR "usbvision_init_i2c: can't write reg\n"); 255 printk(KERN_ERR "usbvision_register: can't write reg\n");
269 return -EBUSY; 256 return -EBUSY;
270 } 257 }
271 258
@@ -287,6 +274,16 @@ int usbvision_init_i2c(struct usb_usbvision *usbvision)
287 return usbvision_i2c_usb_add_bus(&usbvision->i2c_adap); 274 return usbvision_i2c_usb_add_bus(&usbvision->i2c_adap);
288} 275}
289 276
277int usbvision_i2c_unregister(struct usb_usbvision *usbvision)
278{
279
280 i2c_del_adapter(&(usbvision->i2c_adap));
281
282 PDEBUG(DBG_I2C,"i2c bus for %s unregistered", usbvision->i2c_adap.name);
283
284 return 0;
285}
286
290void call_i2c_clients(struct usb_usbvision *usbvision, unsigned int cmd, 287void call_i2c_clients(struct usb_usbvision *usbvision, unsigned int cmd,
291 void *arg) 288 void *arg)
292{ 289{
@@ -300,19 +297,12 @@ static int attach_inform(struct i2c_client *client)
300 usbvision = (struct usb_usbvision *)i2c_get_adapdata(client->adapter); 297 usbvision = (struct usb_usbvision *)i2c_get_adapdata(client->adapter);
301 298
302 switch (client->addr << 1) { 299 switch (client->addr << 1) {
303 case 0x43: 300 case 0x42 << 1:
304 case 0x4b: 301 case 0x43 << 1:
305 { 302 case 0x4a << 1:
306 struct tuner_setup tun_setup; 303 case 0x4b << 1:
307 304 PDEBUG(DBG_I2C,"attach_inform: tda9887 detected.");
308 tun_setup.mode_mask = T_ANALOG_TV | T_RADIO;
309 tun_setup.type = TUNER_TDA9887;
310 tun_setup.addr = client->addr;
311
312 call_i2c_clients(usbvision, TUNER_SET_TYPE_ADDR, &tun_setup);
313
314 break; 305 break;
315 }
316 case 0x42: 306 case 0x42:
317 PDEBUG(DBG_I2C,"attach_inform: saa7114 detected."); 307 PDEBUG(DBG_I2C,"attach_inform: saa7114 detected.");
318 break; 308 break;
@@ -480,7 +470,7 @@ static int usbvision_i2c_write_max4(struct usb_usbvision *usbvision,
480 return len; 470 return len;
481} 471}
482 472
483static int usbvision_i2c_write(void *data, unsigned char addr, char *buf, 473static int usbvision_i2c_write(struct usb_usbvision *usbvision, unsigned char addr, char *buf,
484 short len) 474 short len)
485{ 475{
486 char *bufPtr = buf; 476 char *bufPtr = buf;
@@ -488,7 +478,6 @@ static int usbvision_i2c_write(void *data, unsigned char addr, char *buf,
488 int wrcount = 0; 478 int wrcount = 0;
489 int count; 479 int count;
490 int maxLen = 4; 480 int maxLen = 4;
491 struct usb_usbvision *usbvision = (struct usb_usbvision *) data;
492 481
493 while (len > 0) { 482 while (len > 0) {
494 count = (len > maxLen) ? maxLen : len; 483 count = (len > maxLen) ? maxLen : len;
@@ -503,14 +492,13 @@ static int usbvision_i2c_write(void *data, unsigned char addr, char *buf,
503 return wrcount; 492 return wrcount;
504} 493}
505 494
506static int usbvision_i2c_read(void *data, unsigned char addr, char *buf, 495static int usbvision_i2c_read(struct usb_usbvision *usbvision, unsigned char addr, char *buf,
507 short len) 496 short len)
508{ 497{
509 char temp[4]; 498 char temp[4];
510 int retval, i; 499 int retval, i;
511 int rdcount = 0; 500 int rdcount = 0;
512 int count; 501 int count;
513 struct usb_usbvision *usbvision = (struct usb_usbvision *) data;
514 502
515 while (len > 0) { 503 while (len > 0) {
516 count = (len > 3) ? 4 : len; 504 count = (len > 3) ? 4 : len;
diff --git a/drivers/media/video/usbvision/usbvision-video.c b/drivers/media/video/usbvision/usbvision-video.c
index 6fc14557d623..216704170a4c 100644
--- a/drivers/media/video/usbvision/usbvision-video.c
+++ b/drivers/media/video/usbvision/usbvision-video.c
@@ -76,6 +76,7 @@
76#endif 76#endif
77 77
78#include "usbvision.h" 78#include "usbvision.h"
79#include "usbvision-cards.h"
79 80
80#define DRIVER_AUTHOR "Joerg Heckenbach <joerg@heckenbach-aw.de>, Dwaine Garden <DwaineGarden@rogers.com>" 81#define DRIVER_AUTHOR "Joerg Heckenbach <joerg@heckenbach-aw.de>, Dwaine Garden <DwaineGarden@rogers.com>"
81#define DRIVER_NAME "usbvision" 82#define DRIVER_NAME "usbvision"
@@ -150,7 +151,6 @@ static int PowerOnAtOpen = 1; // Set the default device to power on at startu
150static int video_nr = -1; // Sequential Number of Video Device 151static int video_nr = -1; // Sequential Number of Video Device
151static int radio_nr = -1; // Sequential Number of Radio Device 152static int radio_nr = -1; // Sequential Number of Radio Device
152static int vbi_nr = -1; // Sequential Number of VBI Device 153static int vbi_nr = -1; // Sequential Number of VBI Device
153static char *CustomDevice=NULL; // Set as nothing....
154 154
155// Grab parameters for the device driver 155// Grab parameters for the device driver
156 156
@@ -161,7 +161,6 @@ module_param(PowerOnAtOpen, int, 0444);
161module_param(video_nr, int, 0444); 161module_param(video_nr, int, 0444);
162module_param(radio_nr, int, 0444); 162module_param(radio_nr, int, 0444);
163module_param(vbi_nr, int, 0444); 163module_param(vbi_nr, int, 0444);
164module_param(CustomDevice, charp, 0444);
165#else // Old Style 164#else // Old Style
166MODULE_PARAM(isocMode, "i"); 165MODULE_PARAM(isocMode, "i");
167MODULE_PARM(video_debug, "i"); // Grab the Debug Mode of the device driver 166MODULE_PARM(video_debug, "i"); // Grab the Debug Mode of the device driver
@@ -171,7 +170,6 @@ MODULE_PARM(SwitchSVideoInput, "i"); // To help people with Black and White ou
171MODULE_PARM(video_nr, "i"); // video_nr option allows to specify a certain /dev/videoX device (like /dev/video0 or /dev/video1 ...) 170MODULE_PARM(video_nr, "i"); // video_nr option allows to specify a certain /dev/videoX device (like /dev/video0 or /dev/video1 ...)
172MODULE_PARM(radio_nr, "i"); // radio_nr option allows to specify a certain /dev/radioX device (like /dev/radio0 or /dev/radio1 ...) 171MODULE_PARM(radio_nr, "i"); // radio_nr option allows to specify a certain /dev/radioX device (like /dev/radio0 or /dev/radio1 ...)
173MODULE_PARM(vbi_nr, "i"); // vbi_nr option allows to specify a certain /dev/vbiX device (like /dev/vbi0 or /dev/vbi1 ...) 172MODULE_PARM(vbi_nr, "i"); // vbi_nr option allows to specify a certain /dev/vbiX device (like /dev/vbi0 or /dev/vbi1 ...)
174MODULE_PARM(CustomDevice, "s"); // .... CustomDevice
175#endif 173#endif
176 174
177MODULE_PARM_DESC(isocMode, " Set the default format for ISOC endpoint. Default: 0x60 (Compression On)"); 175MODULE_PARM_DESC(isocMode, " Set the default format for ISOC endpoint. Default: 0x60 (Compression On)");
@@ -180,7 +178,6 @@ MODULE_PARM_DESC(PowerOnAtOpen, " Set the default device to power on when device
180MODULE_PARM_DESC(video_nr, "Set video device number (/dev/videoX). Default: -1 (autodetect)"); 178MODULE_PARM_DESC(video_nr, "Set video device number (/dev/videoX). Default: -1 (autodetect)");
181MODULE_PARM_DESC(radio_nr, "Set radio device number (/dev/radioX). Default: -1 (autodetect)"); 179MODULE_PARM_DESC(radio_nr, "Set radio device number (/dev/radioX). Default: -1 (autodetect)");
182MODULE_PARM_DESC(vbi_nr, "Set vbi device number (/dev/vbiX). Default: -1 (autodetect)"); 180MODULE_PARM_DESC(vbi_nr, "Set vbi device number (/dev/vbiX). Default: -1 (autodetect)");
183MODULE_PARM_DESC(CustomDevice, " Define the fine tuning parameters for the device. Default: null");
184 181
185 182
186// Misc stuff 183// Misc stuff
@@ -409,7 +406,7 @@ static int usbvision_v4l2_open(struct inode *inode, struct file *file)
409 down(&usbvision->lock); 406 down(&usbvision->lock);
410 if (usbvision->power == 0) { 407 if (usbvision->power == 0) {
411 usbvision_power_on(usbvision); 408 usbvision_power_on(usbvision);
412 usbvision_init_i2c(usbvision); 409 usbvision_i2c_register(usbvision);
413 } 410 }
414 411
415 /* Send init sequence only once, it's large! */ 412 /* Send init sequence only once, it's large! */
@@ -431,7 +428,7 @@ static int usbvision_v4l2_open(struct inode *inode, struct file *file)
431 } 428 }
432 else { 429 else {
433 if (PowerOnAtOpen) { 430 if (PowerOnAtOpen) {
434 usbvision_i2c_usb_del_bus(&usbvision->i2c_adap); 431 usbvision_i2c_unregister(usbvision);
435 usbvision_power_off(usbvision); 432 usbvision_power_off(usbvision);
436 usbvision->initialized = 0; 433 usbvision->initialized = 0;
437 } 434 }
@@ -1239,7 +1236,7 @@ static int usbvision_radio_open(struct inode *inode, struct file *file)
1239 usbvision_reset_powerOffTimer(usbvision); 1236 usbvision_reset_powerOffTimer(usbvision);
1240 if (usbvision->power == 0) { 1237 if (usbvision->power == 0) {
1241 usbvision_power_on(usbvision); 1238 usbvision_power_on(usbvision);
1242 usbvision_init_i2c(usbvision); 1239 usbvision_i2c_register(usbvision);
1243 } 1240 }
1244 } 1241 }
1245 1242
@@ -1261,7 +1258,7 @@ static int usbvision_radio_open(struct inode *inode, struct file *file)
1261 1258
1262 if (errCode) { 1259 if (errCode) {
1263 if (PowerOnAtOpen) { 1260 if (PowerOnAtOpen) {
1264 usbvision_i2c_usb_del_bus(&usbvision->i2c_adap); 1261 usbvision_i2c_unregister(usbvision);
1265 usbvision_power_off(usbvision); 1262 usbvision_power_off(usbvision);
1266 usbvision->initialized = 0; 1263 usbvision->initialized = 0;
1267 } 1264 }
@@ -1744,8 +1741,8 @@ static void usbvision_configure_video(struct usb_usbvision *usbvision)
1744 model = usbvision->DevModel; 1741 model = usbvision->DevModel;
1745 usbvision->palette = usbvision_v4l2_format[2]; // V4L2_PIX_FMT_RGB24; 1742 usbvision->palette = usbvision_v4l2_format[2]; // V4L2_PIX_FMT_RGB24;
1746 1743
1747 if (usbvision_device_data[usbvision->DevModel].Vin_Reg2 >= 0) { 1744 if (usbvision_device_data[usbvision->DevModel].Vin_Reg2_override) {
1748 usbvision->Vin_Reg2_Preset = usbvision_device_data[usbvision->DevModel].Vin_Reg2 & 0xff; 1745 usbvision->Vin_Reg2_Preset = usbvision_device_data[usbvision->DevModel].Vin_Reg2;
1749 } else { 1746 } else {
1750 usbvision->Vin_Reg2_Preset = 0; 1747 usbvision->Vin_Reg2_Preset = 0;
1751 } 1748 }
@@ -1764,7 +1761,7 @@ static void usbvision_configure_video(struct usb_usbvision *usbvision)
1764 usbvision_audio_off(usbvision); //first switch off audio 1761 usbvision_audio_off(usbvision); //first switch off audio
1765 if (!PowerOnAtOpen) { 1762 if (!PowerOnAtOpen) {
1766 usbvision_power_on(usbvision); //and then power up the noisy tuner 1763 usbvision_power_on(usbvision); //and then power up the noisy tuner
1767 usbvision_init_i2c(usbvision); 1764 usbvision_i2c_register(usbvision);
1768 } 1765 }
1769} 1766}
1770 1767
@@ -1775,7 +1772,8 @@ static void usbvision_configure_video(struct usb_usbvision *usbvision)
1775 * if it looks like USBVISION video device 1772 * if it looks like USBVISION video device
1776 * 1773 *
1777 */ 1774 */
1778static int __devinit usbvision_probe(struct usb_interface *intf, const struct usb_device_id *devid) 1775static int __devinit usbvision_probe(struct usb_interface *intf,
1776 const struct usb_device_id *devid)
1779{ 1777{
1780 struct usb_device *dev = usb_get_dev(interface_to_usbdev(intf)); 1778 struct usb_device *dev = usb_get_dev(interface_to_usbdev(intf));
1781 struct usb_interface *uif; 1779 struct usb_interface *uif;
@@ -1786,25 +1784,17 @@ static int __devinit usbvision_probe(struct usb_interface *intf, const struct us
1786 int model,i; 1784 int model,i;
1787 1785
1788 PDEBUG(DBG_PROBE, "VID=%#04x, PID=%#04x, ifnum=%u", 1786 PDEBUG(DBG_PROBE, "VID=%#04x, PID=%#04x, ifnum=%u",
1789 dev->descriptor.idVendor, dev->descriptor.idProduct, ifnum); 1787 dev->descriptor.idVendor,
1788 dev->descriptor.idProduct, ifnum);
1790 1789
1791 /* Is it an USBVISION video dev? */ 1790 model = devid->driver_info;
1792 model = 0; 1791 if ( (model<0) || (model>=usbvision_device_data_size) ) {
1793 for(model = 0; usbvision_device_data[model].idVendor; model++) { 1792 PDEBUG(DBG_PROBE, "model out of bounds %d",model);
1794 if (le16_to_cpu(dev->descriptor.idVendor) != usbvision_device_data[model].idVendor) { 1793 return -ENODEV;
1795 continue;
1796 }
1797 if (le16_to_cpu(dev->descriptor.idProduct) != usbvision_device_data[model].idProduct) {
1798 continue;
1799 }
1800
1801 printk(KERN_INFO "%s: %s found\n", __FUNCTION__, usbvision_device_data[model].ModelString);
1802 break;
1803 } 1794 }
1795 printk(KERN_INFO "%s: %s found\n", __FUNCTION__,
1796 usbvision_device_data[model].ModelString);
1804 1797
1805 if (usbvision_device_data[model].idVendor == 0) {
1806 return -ENODEV; //no matching device
1807 }
1808 if (usbvision_device_data[model].Interface >= 0) { 1798 if (usbvision_device_data[model].Interface >= 0) {
1809 interface = &dev->actconfig->interface[usbvision_device_data[model].Interface]->altsetting[0]; 1799 interface = &dev->actconfig->interface[usbvision_device_data[model].Interface]->altsetting[0];
1810 } 1800 }
@@ -1822,16 +1812,15 @@ static int __devinit usbvision_probe(struct usb_interface *intf, const struct us
1822 return -ENODEV; 1812 return -ENODEV;
1823 } 1813 }
1824 1814
1825 usb_get_dev(dev);
1826
1827 if ((usbvision = usbvision_alloc(dev)) == NULL) { 1815 if ((usbvision = usbvision_alloc(dev)) == NULL) {
1828 err("%s: couldn't allocate USBVision struct", __FUNCTION__); 1816 err("%s: couldn't allocate USBVision struct", __FUNCTION__);
1829 return -ENOMEM; 1817 return -ENOMEM;
1830 } 1818 }
1819
1831 if (dev->descriptor.bNumConfigurations > 1) { 1820 if (dev->descriptor.bNumConfigurations > 1) {
1832 usbvision->bridgeType = BRIDGE_NT1004; 1821 usbvision->bridgeType = BRIDGE_NT1004;
1833 } 1822 }
1834 else if (usbvision_device_data[model].ModelString == "Dazzle Fusion Model DVC-90 Rev 1 (SECAM)") { 1823 else if (model == DAZZLE_DVC_90_REV_1_SECAM) {
1835 usbvision->bridgeType = BRIDGE_NT1005; 1824 usbvision->bridgeType = BRIDGE_NT1005;
1836 } 1825 }
1837 else { 1826 else {
@@ -1920,7 +1909,7 @@ static void __devexit usbvision_disconnect(struct usb_interface *intf)
1920 usbvision_stop_isoc(usbvision); 1909 usbvision_stop_isoc(usbvision);
1921 1910
1922 if (usbvision->power) { 1911 if (usbvision->power) {
1923 usbvision_i2c_usb_del_bus(&usbvision->i2c_adap); 1912 usbvision_i2c_unregister(usbvision);
1924 usbvision_power_off(usbvision); 1913 usbvision_power_off(usbvision);
1925 } 1914 }
1926 usbvision->remove_pending = 1; // Now all ISO data will be ignored 1915 usbvision->remove_pending = 1; // Now all ISO data will be ignored
@@ -1951,124 +1940,6 @@ static struct usb_driver usbvision_driver = {
1951}; 1940};
1952 1941
1953/* 1942/*
1954 * customdevice_process()
1955 *
1956 * This procedure preprocesses CustomDevice parameter if any
1957 *
1958 */
1959static void customdevice_process(void)
1960{
1961 usbvision_device_data[0]=usbvision_device_data[1];
1962 usbvision_table[0]=usbvision_table[1];
1963
1964 if(CustomDevice)
1965 {
1966 char *parse=CustomDevice;
1967
1968 PDEBUG(DBG_PROBE, "CustomDevide=%s", CustomDevice);
1969
1970 /*format is CustomDevice="0x0573 0x4D31 0 7113 3 PAL 1 1 1 5 -1 -1 -1 -1 -1"
1971 usbvision_device_data[0].idVendor;
1972 usbvision_device_data[0].idProduct;
1973 usbvision_device_data[0].Interface;
1974 usbvision_device_data[0].Codec;
1975 usbvision_device_data[0].VideoChannels;
1976 usbvision_device_data[0].VideoNorm;
1977 usbvision_device_data[0].AudioChannels;
1978 usbvision_device_data[0].Radio;
1979 usbvision_device_data[0].Tuner;
1980 usbvision_device_data[0].TunerType;
1981 usbvision_device_data[0].Vin_Reg1;
1982 usbvision_device_data[0].Vin_Reg2;
1983 usbvision_device_data[0].X_Offset;
1984 usbvision_device_data[0].Y_Offset;
1985 usbvision_device_data[0].Dvi_yuv;
1986 usbvision_device_data[0].ModelString;
1987 */
1988
1989 rmspace(parse);
1990 usbvision_device_data[0].ModelString="USBVISION Custom Device";
1991
1992 parse+=2;
1993 sscanf(parse,"%x",&usbvision_device_data[0].idVendor);
1994 goto2next(parse);
1995 PDEBUG(DBG_PROBE, "idVendor=0x%.4X", usbvision_device_data[0].idVendor);
1996 parse+=2;
1997 sscanf(parse,"%x",&usbvision_device_data[0].idProduct);
1998 goto2next(parse);
1999 PDEBUG(DBG_PROBE, "idProduct=0x%.4X", usbvision_device_data[0].idProduct);
2000 sscanf(parse,"%d",&usbvision_device_data[0].Interface);
2001 goto2next(parse);
2002 PDEBUG(DBG_PROBE, "Interface=%d", usbvision_device_data[0].Interface);
2003 sscanf(parse,"%d",&usbvision_device_data[0].Codec);
2004 goto2next(parse);
2005 PDEBUG(DBG_PROBE, "Codec=%d", usbvision_device_data[0].Codec);
2006 sscanf(parse,"%d",&usbvision_device_data[0].VideoChannels);
2007 goto2next(parse);
2008 PDEBUG(DBG_PROBE, "VideoChannels=%d", usbvision_device_data[0].VideoChannels);
2009
2010 switch(*parse)
2011 {
2012 case 'P':
2013 PDEBUG(DBG_PROBE, "VideoNorm=PAL");
2014 usbvision_device_data[0].VideoNorm=V4L2_STD_PAL;
2015 break;
2016
2017 case 'S':
2018 PDEBUG(DBG_PROBE, "VideoNorm=SECAM");
2019 usbvision_device_data[0].VideoNorm=V4L2_STD_SECAM;
2020 break;
2021
2022 case 'N':
2023 PDEBUG(DBG_PROBE, "VideoNorm=NTSC");
2024 usbvision_device_data[0].VideoNorm=V4L2_STD_NTSC;
2025 break;
2026
2027 default:
2028 PDEBUG(DBG_PROBE, "VideoNorm=PAL (by default)");
2029 usbvision_device_data[0].VideoNorm=V4L2_STD_PAL;
2030 break;
2031 }
2032 goto2next(parse);
2033
2034 sscanf(parse,"%d",&usbvision_device_data[0].AudioChannels);
2035 goto2next(parse);
2036 PDEBUG(DBG_PROBE, "AudioChannels=%d", usbvision_device_data[0].AudioChannels);
2037 sscanf(parse,"%d",&usbvision_device_data[0].Radio);
2038 goto2next(parse);
2039 PDEBUG(DBG_PROBE, "Radio=%d", usbvision_device_data[0].Radio);
2040 sscanf(parse,"%d",&usbvision_device_data[0].Tuner);
2041 goto2next(parse);
2042 PDEBUG(DBG_PROBE, "Tuner=%d", usbvision_device_data[0].Tuner);
2043 sscanf(parse,"%d",&usbvision_device_data[0].TunerType);
2044 goto2next(parse);
2045 PDEBUG(DBG_PROBE, "TunerType=%d", usbvision_device_data[0].TunerType);
2046 sscanf(parse,"%d",&usbvision_device_data[0].Vin_Reg1);
2047 goto2next(parse);
2048 PDEBUG(DBG_PROBE, "Vin_Reg1=%d", usbvision_device_data[0].Vin_Reg1);
2049 sscanf(parse,"%d",&usbvision_device_data[0].Vin_Reg2);
2050 goto2next(parse);
2051 PDEBUG(DBG_PROBE, "Vin_Reg2=%d", usbvision_device_data[0].Vin_Reg2);
2052 sscanf(parse,"%d",&usbvision_device_data[0].X_Offset);
2053 goto2next(parse);
2054 PDEBUG(DBG_PROBE, "X_Offset=%d", usbvision_device_data[0].X_Offset);
2055 sscanf(parse,"%d",&usbvision_device_data[0].Y_Offset);
2056 goto2next(parse);
2057 PDEBUG(DBG_PROBE, "Y_Offset=%d", usbvision_device_data[0].Y_Offset);
2058 sscanf(parse,"%d",&usbvision_device_data[0].Dvi_yuv);
2059 PDEBUG(DBG_PROBE, "Dvi_yuv=%d", usbvision_device_data[0].Dvi_yuv);
2060
2061 //add to usbvision_table also
2062 usbvision_table[0].match_flags=USB_DEVICE_ID_MATCH_DEVICE;
2063 usbvision_table[0].idVendor=usbvision_device_data[0].idVendor;
2064 usbvision_table[0].idProduct=usbvision_device_data[0].idProduct;
2065
2066 }
2067}
2068
2069
2070
2071/*
2072 * usbvision_init() 1943 * usbvision_init()
2073 * 1944 *
2074 * This code is run to initialize the driver. 1945 * This code is run to initialize the driver.
@@ -2092,8 +1963,6 @@ static int __init usbvision_init(void)
2092 usbvision_v4l2_format[7].supported = 0; // V4L2_PIX_FMT_YUV422P 1963 usbvision_v4l2_format[7].supported = 0; // V4L2_PIX_FMT_YUV422P
2093 } 1964 }
2094 1965
2095 customdevice_process();
2096
2097 errCode = usb_register(&usbvision_driver); 1966 errCode = usb_register(&usbvision_driver);
2098 1967
2099 if (errCode == 0) { 1968 if (errCode == 0) {
diff --git a/drivers/media/video/usbvision/usbvision.h b/drivers/media/video/usbvision/usbvision.h
index ad6afd3e42a4..bd6f6422ed54 100644
--- a/drivers/media/video/usbvision/usbvision.h
+++ b/drivers/media/video/usbvision/usbvision.h
@@ -342,23 +342,24 @@ struct usbvision_frame {
342#define BRIDGE_NT1005 1005 342#define BRIDGE_NT1005 1005
343 343
344struct usbvision_device_data_st { 344struct usbvision_device_data_st {
345 int idVendor;
346 int idProduct;
347 int Interface; /* to handle special interface number like BELKIN and Hauppauge WinTV-USB II */
348 int Codec;
349 int VideoChannels;
350 __u64 VideoNorm; 345 __u64 VideoNorm;
351 int AudioChannels; 346 const char *ModelString;
352 int Radio; 347 int Interface; /* to handle special interface number like BELKIN and Hauppauge WinTV-USB II */
353 int vbi; 348 __u16 Codec;
354 int Tuner; 349 unsigned VideoChannels:3;
355 int TunerType; 350 unsigned AudioChannels:2;
356 int Vin_Reg1; 351 unsigned Radio:1;
357 int Vin_Reg2; 352 unsigned vbi:1;
358 int X_Offset; 353 unsigned Tuner:1;
359 int Y_Offset; 354 unsigned Vin_Reg1_override:1; /* Override default value with */
360 int Dvi_yuv; 355 unsigned Vin_Reg2_override:1; /* Vin_Reg1, Vin_Reg2, etc. */
361 char *ModelString; 356 unsigned Dvi_yuv_override:1;
357 __u8 Vin_Reg1;
358 __u8 Vin_Reg2;
359 __u8 Dvi_yuv;
360 __u8 TunerType;
361 __s16 X_Offset;
362 __s16 Y_Offset;
362}; 363};
363 364
364/* Declared on usbvision-cards.c */ 365/* Declared on usbvision-cards.c */
@@ -481,13 +482,11 @@ struct usb_usbvision {
481/* i2c-algo-usb declaration */ 482/* i2c-algo-usb declaration */
482/* --------------------------------------------------------------- */ 483/* --------------------------------------------------------------- */
483 484
484int usbvision_i2c_usb_del_bus(struct i2c_adapter *);
485
486
487/* ----------------------------------------------------------------------- */ 485/* ----------------------------------------------------------------------- */
488/* usbvision specific I2C functions */ 486/* usbvision specific I2C functions */
489/* ----------------------------------------------------------------------- */ 487/* ----------------------------------------------------------------------- */
490int usbvision_init_i2c(struct usb_usbvision *usbvision); 488int usbvision_i2c_register(struct usb_usbvision *usbvision);
489int usbvision_i2c_unregister(struct usb_usbvision *usbvision);
491void call_i2c_clients(struct usb_usbvision *usbvision, unsigned int cmd,void *arg); 490void call_i2c_clients(struct usb_usbvision *usbvision, unsigned int cmd,void *arg);
492 491
493/* defined in usbvision-core.c */ 492/* defined in usbvision-core.c */
diff --git a/drivers/media/video/v4l2-common.c b/drivers/media/video/v4l2-common.c
index 54747606eae1..49f1df74aa21 100644
--- a/drivers/media/video/v4l2-common.c
+++ b/drivers/media/video/v4l2-common.c
@@ -60,6 +60,7 @@
60#include <linux/video_decoder.h> 60#include <linux/video_decoder.h>
61#define __OLD_VIDIOC_ /* To allow fixing old calls*/ 61#define __OLD_VIDIOC_ /* To allow fixing old calls*/
62#include <media/v4l2-common.h> 62#include <media/v4l2-common.h>
63#include <media/v4l2-chip-ident.h>
63 64
64#ifdef CONFIG_KMOD 65#ifdef CONFIG_KMOD
65#include <linux/kmod.h> 66#include <linux/kmod.h>
@@ -260,6 +261,8 @@ char *v4l2_field_names[] = {
260 [V4L2_FIELD_SEQ_TB] = "seq-tb", 261 [V4L2_FIELD_SEQ_TB] = "seq-tb",
261 [V4L2_FIELD_SEQ_BT] = "seq-bt", 262 [V4L2_FIELD_SEQ_BT] = "seq-bt",
262 [V4L2_FIELD_ALTERNATE] = "alternate", 263 [V4L2_FIELD_ALTERNATE] = "alternate",
264 [V4L2_FIELD_INTERLACED_TB] = "interlaced-tb",
265 [V4L2_FIELD_INTERLACED_BT] = "interlaced-bt",
263}; 266};
264 267
265char *v4l2_type_names[] = { 268char *v4l2_type_names[] = {
@@ -269,7 +272,8 @@ char *v4l2_type_names[] = {
269 [V4L2_BUF_TYPE_VBI_CAPTURE] = "vbi-cap", 272 [V4L2_BUF_TYPE_VBI_CAPTURE] = "vbi-cap",
270 [V4L2_BUF_TYPE_VBI_OUTPUT] = "vbi-out", 273 [V4L2_BUF_TYPE_VBI_OUTPUT] = "vbi-out",
271 [V4L2_BUF_TYPE_SLICED_VBI_CAPTURE] = "sliced-vbi-cap", 274 [V4L2_BUF_TYPE_SLICED_VBI_CAPTURE] = "sliced-vbi-cap",
272 [V4L2_BUF_TYPE_SLICED_VBI_OUTPUT] = "slicec-vbi-out", 275 [V4L2_BUF_TYPE_SLICED_VBI_OUTPUT] = "sliced-vbi-out",
276 [V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY] = "video-out-over",
273}; 277};
274 278
275 279
@@ -380,6 +384,8 @@ static const char *v4l2_ioctls[] = {
380 384
381 [_IOC_NR(VIDIOC_DBG_S_REGISTER)] = "VIDIOC_DBG_S_REGISTER", 385 [_IOC_NR(VIDIOC_DBG_S_REGISTER)] = "VIDIOC_DBG_S_REGISTER",
382 [_IOC_NR(VIDIOC_DBG_G_REGISTER)] = "VIDIOC_DBG_G_REGISTER", 386 [_IOC_NR(VIDIOC_DBG_G_REGISTER)] = "VIDIOC_DBG_G_REGISTER",
387
388 [_IOC_NR(VIDIOC_G_CHIP_IDENT)] = "VIDIOC_G_CHIP_IDENT",
383#endif 389#endif
384}; 390};
385#define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls) 391#define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls)
@@ -410,14 +416,16 @@ static const char *v4l2_int_ioctls[] = {
410 [_IOC_NR(VIDIOC_INT_DECODE_VBI_LINE)] = "VIDIOC_INT_DECODE_VBI_LINE", 416 [_IOC_NR(VIDIOC_INT_DECODE_VBI_LINE)] = "VIDIOC_INT_DECODE_VBI_LINE",
411 [_IOC_NR(VIDIOC_INT_S_VBI_DATA)] = "VIDIOC_INT_S_VBI_DATA", 417 [_IOC_NR(VIDIOC_INT_S_VBI_DATA)] = "VIDIOC_INT_S_VBI_DATA",
412 [_IOC_NR(VIDIOC_INT_G_VBI_DATA)] = "VIDIOC_INT_G_VBI_DATA", 418 [_IOC_NR(VIDIOC_INT_G_VBI_DATA)] = "VIDIOC_INT_G_VBI_DATA",
413 [_IOC_NR(VIDIOC_INT_G_CHIP_IDENT)] = "VIDIOC_INT_G_CHIP_IDENT",
414 [_IOC_NR(VIDIOC_INT_I2S_CLOCK_FREQ)] = "VIDIOC_INT_I2S_CLOCK_FREQ", 419 [_IOC_NR(VIDIOC_INT_I2S_CLOCK_FREQ)] = "VIDIOC_INT_I2S_CLOCK_FREQ",
415 [_IOC_NR(VIDIOC_INT_S_STANDBY)] = "VIDIOC_INT_S_STANDBY", 420 [_IOC_NR(VIDIOC_INT_S_STANDBY)] = "VIDIOC_INT_S_STANDBY",
416 [_IOC_NR(VIDIOC_INT_S_AUDIO_ROUTING)] = "VIDIOC_INT_S_AUDIO_ROUTING", 421 [_IOC_NR(VIDIOC_INT_S_AUDIO_ROUTING)] = "VIDIOC_INT_S_AUDIO_ROUTING",
417 [_IOC_NR(VIDIOC_INT_G_AUDIO_ROUTING)] = "VIDIOC_INT_G_AUDIO_ROUTING", 422 [_IOC_NR(VIDIOC_INT_G_AUDIO_ROUTING)] = "VIDIOC_INT_G_AUDIO_ROUTING",
418 [_IOC_NR(VIDIOC_INT_S_VIDEO_ROUTING)] = "VIDIOC_INT_S_VIDEO_ROUTING", 423 [_IOC_NR(VIDIOC_INT_S_VIDEO_ROUTING)] = "VIDIOC_INT_S_VIDEO_ROUTING",
419 [_IOC_NR(VIDIOC_INT_G_VIDEO_ROUTING)] = "VIDIOC_INT_G_VIDEO_ROUTING", 424 [_IOC_NR(VIDIOC_INT_G_VIDEO_ROUTING)] = "VIDIOC_INT_G_VIDEO_ROUTING",
420 [_IOC_NR(VIDIOC_INT_S_CRYSTAL_FREQ)] = "VIDIOC_INT_S_CRYSTAL_FREQ" 425 [_IOC_NR(VIDIOC_INT_S_CRYSTAL_FREQ)] = "VIDIOC_INT_S_CRYSTAL_FREQ",
426 [_IOC_NR(VIDIOC_INT_INIT)] = "VIDIOC_INT_INIT",
427 [_IOC_NR(VIDIOC_INT_G_STD_OUTPUT)] = "VIDIOC_INT_G_STD_OUTPUT",
428 [_IOC_NR(VIDIOC_INT_S_STD_OUTPUT)] = "VIDIOC_INT_S_STD_OUTPUT",
421}; 429};
422#define V4L2_INT_IOCTLS ARRAY_SIZE(v4l2_int_ioctls) 430#define V4L2_INT_IOCTLS ARRAY_SIZE(v4l2_int_ioctls)
423 431
@@ -680,6 +688,7 @@ int v4l2_ctrl_query_fill(struct v4l2_queryctrl *qctrl, s32 min, s32 max, s32 ste
680 case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION: name = "Audio Stereo Mode Extension"; break; 688 case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION: name = "Audio Stereo Mode Extension"; break;
681 case V4L2_CID_MPEG_AUDIO_EMPHASIS: name = "Audio Emphasis"; break; 689 case V4L2_CID_MPEG_AUDIO_EMPHASIS: name = "Audio Emphasis"; break;
682 case V4L2_CID_MPEG_AUDIO_CRC: name = "Audio CRC"; break; 690 case V4L2_CID_MPEG_AUDIO_CRC: name = "Audio CRC"; break;
691 case V4L2_CID_MPEG_AUDIO_MUTE: name = "Audio Mute"; break;
683 case V4L2_CID_MPEG_VIDEO_ENCODING: name = "Video Encoding"; break; 692 case V4L2_CID_MPEG_VIDEO_ENCODING: name = "Video Encoding"; break;
684 case V4L2_CID_MPEG_VIDEO_ASPECT: name = "Video Aspect"; break; 693 case V4L2_CID_MPEG_VIDEO_ASPECT: name = "Video Aspect"; break;
685 case V4L2_CID_MPEG_VIDEO_B_FRAMES: name = "Video B Frames"; break; 694 case V4L2_CID_MPEG_VIDEO_B_FRAMES: name = "Video B Frames"; break;
@@ -690,6 +699,8 @@ int v4l2_ctrl_query_fill(struct v4l2_queryctrl *qctrl, s32 min, s32 max, s32 ste
690 case V4L2_CID_MPEG_VIDEO_BITRATE: name = "Video Bitrate"; break; 699 case V4L2_CID_MPEG_VIDEO_BITRATE: name = "Video Bitrate"; break;
691 case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK: name = "Video Peak Bitrate"; break; 700 case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK: name = "Video Peak Bitrate"; break;
692 case V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION: name = "Video Temporal Decimation"; break; 701 case V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION: name = "Video Temporal Decimation"; break;
702 case V4L2_CID_MPEG_VIDEO_MUTE: name = "Video Mute"; break;
703 case V4L2_CID_MPEG_VIDEO_MUTE_YUV: name = "Video Mute YUV"; break;
693 case V4L2_CID_MPEG_STREAM_TYPE: name = "Stream Type"; break; 704 case V4L2_CID_MPEG_STREAM_TYPE: name = "Stream Type"; break;
694 case V4L2_CID_MPEG_STREAM_PID_PMT: name = "Stream PMT Program ID"; break; 705 case V4L2_CID_MPEG_STREAM_PID_PMT: name = "Stream PMT Program ID"; break;
695 case V4L2_CID_MPEG_STREAM_PID_AUDIO: name = "Stream Audio Program ID"; break; 706 case V4L2_CID_MPEG_STREAM_PID_AUDIO: name = "Stream Audio Program ID"; break;
@@ -705,6 +716,7 @@ int v4l2_ctrl_query_fill(struct v4l2_queryctrl *qctrl, s32 min, s32 max, s32 ste
705 switch (qctrl->id) { 716 switch (qctrl->id) {
706 case V4L2_CID_AUDIO_MUTE: 717 case V4L2_CID_AUDIO_MUTE:
707 case V4L2_CID_AUDIO_LOUDNESS: 718 case V4L2_CID_AUDIO_LOUDNESS:
719 case V4L2_CID_MPEG_AUDIO_MUTE:
708 case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE: 720 case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE:
709 case V4L2_CID_MPEG_VIDEO_PULLDOWN: 721 case V4L2_CID_MPEG_VIDEO_PULLDOWN:
710 qctrl->type = V4L2_CTRL_TYPE_BOOLEAN; 722 qctrl->type = V4L2_CTRL_TYPE_BOOLEAN;
@@ -838,6 +850,8 @@ int v4l2_ctrl_query_fill_std(struct v4l2_queryctrl *qctrl)
838 V4L2_MPEG_AUDIO_CRC_NONE, 850 V4L2_MPEG_AUDIO_CRC_NONE,
839 V4L2_MPEG_AUDIO_CRC_CRC16, 1, 851 V4L2_MPEG_AUDIO_CRC_CRC16, 1,
840 V4L2_MPEG_AUDIO_CRC_NONE); 852 V4L2_MPEG_AUDIO_CRC_NONE);
853 case V4L2_CID_MPEG_AUDIO_MUTE:
854 return v4l2_ctrl_query_fill(qctrl, 0, 1, 1, 0);
841 case V4L2_CID_MPEG_VIDEO_ENCODING: 855 case V4L2_CID_MPEG_VIDEO_ENCODING:
842 return v4l2_ctrl_query_fill(qctrl, 856 return v4l2_ctrl_query_fill(qctrl,
843 V4L2_MPEG_VIDEO_ENCODING_MPEG_1, 857 V4L2_MPEG_VIDEO_ENCODING_MPEG_1,
@@ -867,6 +881,10 @@ int v4l2_ctrl_query_fill_std(struct v4l2_queryctrl *qctrl)
867 return v4l2_ctrl_query_fill(qctrl, 0, 27000000, 1, 8000000); 881 return v4l2_ctrl_query_fill(qctrl, 0, 27000000, 1, 8000000);
868 case V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION: 882 case V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION:
869 return v4l2_ctrl_query_fill(qctrl, 0, 255, 1, 0); 883 return v4l2_ctrl_query_fill(qctrl, 0, 255, 1, 0);
884 case V4L2_CID_MPEG_VIDEO_MUTE:
885 return v4l2_ctrl_query_fill(qctrl, 0, 1, 1, 0);
886 case V4L2_CID_MPEG_VIDEO_MUTE_YUV: /* Init YUV (really YCbCr) to black */
887 return v4l2_ctrl_query_fill(qctrl, 0, 0xffffff, 1, 0x008080);
870 case V4L2_CID_MPEG_STREAM_TYPE: 888 case V4L2_CID_MPEG_STREAM_TYPE:
871 return v4l2_ctrl_query_fill(qctrl, 889 return v4l2_ctrl_query_fill(qctrl,
872 V4L2_MPEG_STREAM_TYPE_MPEG2_PS, 890 V4L2_MPEG_STREAM_TYPE_MPEG2_PS,
@@ -965,6 +983,22 @@ int v4l2_chip_match_i2c_client(struct i2c_client *c, u32 match_type, u32 match_c
965 } 983 }
966} 984}
967 985
986int v4l2_chip_ident_i2c_client(struct i2c_client *c, struct v4l2_chip_ident *chip,
987 u32 ident, u32 revision)
988{
989 if (!v4l2_chip_match_i2c_client(c, chip->match_type, chip->match_chip))
990 return 0;
991 if (chip->ident == V4L2_IDENT_NONE) {
992 chip->ident = ident;
993 chip->revision = revision;
994 }
995 else {
996 chip->ident = V4L2_IDENT_AMBIGUOUS;
997 chip->revision = 0;
998 }
999 return 0;
1000}
1001
968int v4l2_chip_match_host(u32 match_type, u32 match_chip) 1002int v4l2_chip_match_host(u32 match_type, u32 match_chip)
969{ 1003{
970 switch (match_type) { 1004 switch (match_type) {
@@ -999,6 +1033,7 @@ EXPORT_SYMBOL(v4l2_ctrl_query_fill);
999EXPORT_SYMBOL(v4l2_ctrl_query_fill_std); 1033EXPORT_SYMBOL(v4l2_ctrl_query_fill_std);
1000 1034
1001EXPORT_SYMBOL(v4l2_chip_match_i2c_client); 1035EXPORT_SYMBOL(v4l2_chip_match_i2c_client);
1036EXPORT_SYMBOL(v4l2_chip_ident_i2c_client);
1002EXPORT_SYMBOL(v4l2_chip_match_host); 1037EXPORT_SYMBOL(v4l2_chip_match_host);
1003 1038
1004/* 1039/*
diff --git a/drivers/media/video/videocodec.c b/drivers/media/video/videocodec.c
index 290e64135650..f2bbd7a4d562 100644
--- a/drivers/media/video/videocodec.c
+++ b/drivers/media/video/videocodec.c
@@ -348,6 +348,9 @@ videocodec_build_table (void)
348 kfree(videocodec_buf); 348 kfree(videocodec_buf);
349 videocodec_buf = kmalloc(size, GFP_KERNEL); 349 videocodec_buf = kmalloc(size, GFP_KERNEL);
350 350
351 if (!videocodec_buf)
352 return 0;
353
351 i = 0; 354 i = 0;
352 i += scnprintf(videocodec_buf + i, size - 1, 355 i += scnprintf(videocodec_buf + i, size - 1,
353 "<S>lave or attached <M>aster name type flags magic "); 356 "<S>lave or attached <M>aster name type flags magic ");
diff --git a/drivers/media/video/videodev.c b/drivers/media/video/videodev.c
index 011938fb7e0e..80ac5f86d9e5 100644
--- a/drivers/media/video/videodev.c
+++ b/drivers/media/video/videodev.c
@@ -318,6 +318,7 @@ static char *v4l2_type_names_FIXME[] = {
318 [V4L2_BUF_TYPE_VBI_OUTPUT] = "vbi-out", 318 [V4L2_BUF_TYPE_VBI_OUTPUT] = "vbi-out",
319 [V4L2_BUF_TYPE_SLICED_VBI_OUTPUT] = "sliced-vbi-out", 319 [V4L2_BUF_TYPE_SLICED_VBI_OUTPUT] = "sliced-vbi-out",
320 [V4L2_BUF_TYPE_SLICED_VBI_CAPTURE] = "sliced-vbi-capture", 320 [V4L2_BUF_TYPE_SLICED_VBI_CAPTURE] = "sliced-vbi-capture",
321 [V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY] = "video-out-over",
321 [V4L2_BUF_TYPE_PRIVATE] = "private", 322 [V4L2_BUF_TYPE_PRIVATE] = "private",
322}; 323};
323 324
@@ -330,6 +331,8 @@ static char *v4l2_field_names_FIXME[] = {
330 [V4L2_FIELD_SEQ_TB] = "seq-tb", 331 [V4L2_FIELD_SEQ_TB] = "seq-tb",
331 [V4L2_FIELD_SEQ_BT] = "seq-bt", 332 [V4L2_FIELD_SEQ_BT] = "seq-bt",
332 [V4L2_FIELD_ALTERNATE] = "alternate", 333 [V4L2_FIELD_ALTERNATE] = "alternate",
334 [V4L2_FIELD_INTERLACED_TB] = "interlaced-tb",
335 [V4L2_FIELD_INTERLACED_BT] = "interlaced-bt",
333}; 336};
334 337
335#define prt_names(a,arr) (((a)>=0)&&((a)<ARRAY_SIZE(arr)))?arr[a]:"unknown" 338#define prt_names(a,arr) (((a)>=0)&&((a)<ARRAY_SIZE(arr)))?arr[a]:"unknown"
@@ -411,6 +414,10 @@ static int check_fmt (struct video_device *vfd, enum v4l2_buf_type type)
411 if (vfd->vidioc_try_fmt_vbi_output) 414 if (vfd->vidioc_try_fmt_vbi_output)
412 return (0); 415 return (0);
413 break; 416 break;
417 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
418 if (vfd->vidioc_try_fmt_output_overlay)
419 return (0);
420 break;
414 case V4L2_BUF_TYPE_PRIVATE: 421 case V4L2_BUF_TYPE_PRIVATE:
415 if (vfd->vidioc_try_fmt_type_private) 422 if (vfd->vidioc_try_fmt_type_private)
416 return (0); 423 return (0);
@@ -525,6 +532,10 @@ static int __video_do_ioctl(struct inode *inode, struct file *file,
525 ret=vfd->vidioc_enum_fmt_vbi_output(file, 532 ret=vfd->vidioc_enum_fmt_vbi_output(file,
526 fh, f); 533 fh, f);
527 break; 534 break;
535 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
536 if (vfd->vidioc_enum_fmt_output_overlay)
537 ret=vfd->vidioc_enum_fmt_output_overlay(file, fh, f);
538 break;
528 case V4L2_BUF_TYPE_PRIVATE: 539 case V4L2_BUF_TYPE_PRIVATE:
529 if (vfd->vidioc_enum_fmt_type_private) 540 if (vfd->vidioc_enum_fmt_type_private)
530 ret=vfd->vidioc_enum_fmt_type_private(file, 541 ret=vfd->vidioc_enum_fmt_type_private(file,
@@ -582,6 +593,10 @@ static int __video_do_ioctl(struct inode *inode, struct file *file,
582 ret=vfd->vidioc_g_fmt_video_output(file, 593 ret=vfd->vidioc_g_fmt_video_output(file,
583 fh, f); 594 fh, f);
584 break; 595 break;
596 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
597 if (vfd->vidioc_g_fmt_output_overlay)
598 ret=vfd->vidioc_g_fmt_output_overlay(file, fh, f);
599 break;
585 case V4L2_BUF_TYPE_VBI_OUTPUT: 600 case V4L2_BUF_TYPE_VBI_OUTPUT:
586 if (vfd->vidioc_g_fmt_vbi_output) 601 if (vfd->vidioc_g_fmt_vbi_output)
587 ret=vfd->vidioc_g_fmt_vbi_output(file, fh, f); 602 ret=vfd->vidioc_g_fmt_vbi_output(file, fh, f);
@@ -630,6 +645,10 @@ static int __video_do_ioctl(struct inode *inode, struct file *file,
630 ret=vfd->vidioc_s_fmt_video_output(file, 645 ret=vfd->vidioc_s_fmt_video_output(file,
631 fh, f); 646 fh, f);
632 break; 647 break;
648 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
649 if (vfd->vidioc_s_fmt_output_overlay)
650 ret=vfd->vidioc_s_fmt_output_overlay(file, fh, f);
651 break;
633 case V4L2_BUF_TYPE_VBI_OUTPUT: 652 case V4L2_BUF_TYPE_VBI_OUTPUT:
634 if (vfd->vidioc_s_fmt_vbi_output) 653 if (vfd->vidioc_s_fmt_vbi_output)
635 ret=vfd->vidioc_s_fmt_vbi_output(file, 654 ret=vfd->vidioc_s_fmt_vbi_output(file,
@@ -680,6 +699,10 @@ static int __video_do_ioctl(struct inode *inode, struct file *file,
680 ret=vfd->vidioc_try_fmt_video_output(file, 699 ret=vfd->vidioc_try_fmt_video_output(file,
681 fh, f); 700 fh, f);
682 break; 701 break;
702 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
703 if (vfd->vidioc_try_fmt_output_overlay)
704 ret=vfd->vidioc_try_fmt_output_overlay(file, fh, f);
705 break;
683 case V4L2_BUF_TYPE_VBI_OUTPUT: 706 case V4L2_BUF_TYPE_VBI_OUTPUT:
684 if (vfd->vidioc_try_fmt_vbi_output) 707 if (vfd->vidioc_try_fmt_vbi_output)
685 ret=vfd->vidioc_try_fmt_vbi_output(file, 708 ret=vfd->vidioc_try_fmt_vbi_output(file,
@@ -1381,6 +1404,11 @@ static int __video_do_ioctl(struct inode *inode, struct file *file,
1381 case VIDIOC_G_PARM: 1404 case VIDIOC_G_PARM:
1382 { 1405 {
1383 struct v4l2_streamparm *p=arg; 1406 struct v4l2_streamparm *p=arg;
1407 __u32 type=p->type;
1408
1409 memset(p,0,sizeof(*p));
1410 p->type=type;
1411
1384 if (vfd->vidioc_g_parm) { 1412 if (vfd->vidioc_g_parm) {
1385 ret=vfd->vidioc_g_parm(file, fh, p); 1413 ret=vfd->vidioc_g_parm(file, fh, p);
1386 } else { 1414 } else {
@@ -1392,8 +1420,6 @@ static int __video_do_ioctl(struct inode *inode, struct file *file,
1392 v4l2_video_std_construct(&s, vfd->current_norm, 1420 v4l2_video_std_construct(&s, vfd->current_norm,
1393 v4l2_norm_to_name(vfd->current_norm)); 1421 v4l2_norm_to_name(vfd->current_norm));
1394 1422
1395 memset(p,0,sizeof(*p));
1396
1397 p->parm.capture.timeperframe = s.frameperiod; 1423 p->parm.capture.timeperframe = s.frameperiod;
1398 ret=0; 1424 ret=0;
1399 } 1425 }
@@ -1509,6 +1535,16 @@ static int __video_do_ioctl(struct inode *inode, struct file *file,
1509 break; 1535 break;
1510 } 1536 }
1511#endif 1537#endif
1538 case VIDIOC_G_CHIP_IDENT:
1539 {
1540 struct v4l2_chip_ident *p=arg;
1541 if (!vfd->vidioc_g_chip_ident)
1542 break;
1543 ret=vfd->vidioc_g_chip_ident(file, fh, p);
1544 if (!ret)
1545 dbgarg (cmd, "chip_ident=%u, revision=0x%x\n", p->ident, p->revision);
1546 break;
1547 }
1512 } /* switch */ 1548 } /* switch */
1513 1549
1514 if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) { 1550 if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) {
diff --git a/drivers/media/video/wm8739.c b/drivers/media/video/wm8739.c
index a9b59c35cd67..8f6741a28a47 100644
--- a/drivers/media/video/wm8739.c
+++ b/drivers/media/video/wm8739.c
@@ -29,6 +29,7 @@
29#include <linux/i2c-id.h> 29#include <linux/i2c-id.h>
30#include <linux/videodev.h> 30#include <linux/videodev.h>
31#include <media/v4l2-common.h> 31#include <media/v4l2-common.h>
32#include <media/v4l2-chip-ident.h>
32 33
33MODULE_DESCRIPTION("wm8739 driver"); 34MODULE_DESCRIPTION("wm8739 driver");
34MODULE_AUTHOR("T. Adachi, Hans Verkuil"); 35MODULE_AUTHOR("T. Adachi, Hans Verkuil");
@@ -236,6 +237,9 @@ static int wm8739_command(struct i2c_client *client, unsigned int cmd, void *arg
236 return -EINVAL; 237 return -EINVAL;
237 } 238 }
238 239
240 case VIDIOC_G_CHIP_IDENT:
241 return v4l2_chip_ident_i2c_client(client, arg, V4L2_IDENT_WM8739, 0);
242
239 case VIDIOC_LOG_STATUS: 243 case VIDIOC_LOG_STATUS:
240 v4l_info(client, "Frequency: %u Hz\n", state->clock_freq); 244 v4l_info(client, "Frequency: %u Hz\n", state->clock_freq);
241 v4l_info(client, "Volume L: %02x%s\n", state->vol_l & 0x1f, 245 v4l_info(client, "Volume L: %02x%s\n", state->vol_l & 0x1f,
diff --git a/drivers/media/video/wm8775.c b/drivers/media/video/wm8775.c
index d81a88bbe43d..4df5d30d4d09 100644
--- a/drivers/media/video/wm8775.c
+++ b/drivers/media/video/wm8775.c
@@ -33,6 +33,7 @@
33#include <linux/i2c-id.h> 33#include <linux/i2c-id.h>
34#include <linux/videodev.h> 34#include <linux/videodev.h>
35#include <media/v4l2-common.h> 35#include <media/v4l2-common.h>
36#include <media/v4l2-chip-ident.h>
36 37
37MODULE_DESCRIPTION("wm8775 driver"); 38MODULE_DESCRIPTION("wm8775 driver");
38MODULE_AUTHOR("Ulf Eklund, Hans Verkuil"); 39MODULE_AUTHOR("Ulf Eklund, Hans Verkuil");
@@ -124,6 +125,9 @@ static int wm8775_command(struct i2c_client *client, unsigned int cmd,
124 wm8775_write(client, R21, 0x100 + state->input); 125 wm8775_write(client, R21, 0x100 + state->input);
125 break; 126 break;
126 127
128 case VIDIOC_G_CHIP_IDENT:
129 return v4l2_chip_ident_i2c_client(client, arg, V4L2_IDENT_WM8775, 0);
130
127 case VIDIOC_LOG_STATUS: 131 case VIDIOC_LOG_STATUS:
128 v4l_info(client, "Input: %d%s\n", state->input, 132 v4l_info(client, "Input: %d%s\n", state->input,
129 state->muted ? " (muted)" : ""); 133 state->muted ? " (muted)" : "");
diff --git a/drivers/media/video/zr364xx.c b/drivers/media/video/zr364xx.c
new file mode 100644
index 000000000000..b5d3364c94c7
--- /dev/null
+++ b/drivers/media/video/zr364xx.c
@@ -0,0 +1,929 @@
1/*
2 * Zoran 364xx based USB webcam module version 0.72
3 *
4 * Allows you to use your USB webcam with V4L2 applications
5 * This is still in heavy developpement !
6 *
7 * Copyright (C) 2004 Antoine Jacquet <royale@zerezo.com>
8 * http://royale.zerezo.com/zr364xx/
9 *
10 * Heavily inspired by usb-skeleton.c, vicam.c, cpia.c and spca50x.c drivers
11 * V4L2 version inspired by meye.c driver
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 */
27
28
29#include <linux/version.h>
30#include <linux/module.h>
31#include <linux/init.h>
32#include <linux/usb.h>
33#include <linux/vmalloc.h>
34#include <linux/slab.h>
35#include <linux/proc_fs.h>
36#include <linux/highmem.h>
37#include <media/v4l2-common.h>
38
39
40/* Version Information */
41#define DRIVER_VERSION "v0.72"
42#define DRIVER_AUTHOR "Antoine Jacquet, http://royale.zerezo.com/"
43#define DRIVER_DESC "Zoran 364xx"
44
45
46/* Camera */
47#define FRAMES 2
48#define MAX_FRAME_SIZE 100000
49#define BUFFER_SIZE 0x1000
50#define CTRL_TIMEOUT 500
51
52
53/* Debug macro */
54#define DBG(x...) if (debug) info(x)
55
56
57/* Init methods, need to find nicer names for these
58 * the exact names of the chipsets would be the best if someone finds it */
59#define METHOD0 0
60#define METHOD1 1
61#define METHOD2 2
62
63
64/* Module parameters */
65static int debug = 0;
66static int mode = 0;
67
68
69/* Module parameters interface */
70module_param(debug, int, 0644);
71MODULE_PARM_DESC(debug, "Debug level");
72module_param(mode, int, 0644);
73MODULE_PARM_DESC(mode, "0 = 320x240, 1 = 160x120, 2 = 640x480");
74
75
76/* Devices supported by this driver
77 * .driver_info contains the init method used by the camera */
78static struct usb_device_id device_table[] = {
79 {USB_DEVICE(0x08ca, 0x0109), .driver_info = METHOD0 },
80 {USB_DEVICE(0x041e, 0x4024), .driver_info = METHOD0 },
81 {USB_DEVICE(0x0d64, 0x0108), .driver_info = METHOD0 },
82 {USB_DEVICE(0x0546, 0x3187), .driver_info = METHOD0 },
83 {USB_DEVICE(0x0d64, 0x3108), .driver_info = METHOD0 },
84 {USB_DEVICE(0x0595, 0x4343), .driver_info = METHOD0 },
85 {USB_DEVICE(0x0bb0, 0x500d), .driver_info = METHOD0 },
86 {USB_DEVICE(0x0feb, 0x2004), .driver_info = METHOD0 },
87 {USB_DEVICE(0x055f, 0xb500), .driver_info = METHOD0 },
88 {USB_DEVICE(0x08ca, 0x2062), .driver_info = METHOD2 },
89 {USB_DEVICE(0x052b, 0x1a18), .driver_info = METHOD1 },
90 {USB_DEVICE(0x04c8, 0x0729), .driver_info = METHOD0 },
91 {USB_DEVICE(0x04f2, 0xa208), .driver_info = METHOD0 },
92 {USB_DEVICE(0x0784, 0x0040), .driver_info = METHOD1 },
93 {USB_DEVICE(0x06d6, 0x0034), .driver_info = METHOD0 },
94 {USB_DEVICE(0x0a17, 0x0062), .driver_info = METHOD2 },
95 {} /* Terminating entry */
96};
97
98MODULE_DEVICE_TABLE(usb, device_table);
99
100
101/* Camera stuff */
102struct zr364xx_camera {
103 struct usb_device *udev; /* save off the usb device pointer */
104 struct usb_interface *interface;/* the interface for this device */
105 struct video_device *vdev; /* v4l video device */
106 u8 *framebuf;
107 int nb;
108 unsigned char *buffer;
109 int skip;
110 int brightness;
111 int width;
112 int height;
113 int method;
114 struct mutex lock;
115};
116
117
118/* function used to send initialisation commands to the camera */
119static int send_control_msg(struct usb_device *udev, u8 request, u16 value,
120 u16 index, unsigned char *cp, u16 size)
121{
122 int status;
123
124 unsigned char *transfer_buffer = kmalloc(size, GFP_KERNEL);
125 if (!transfer_buffer) {
126 info("kmalloc(%d) failed", size);
127 return -ENOMEM;
128 }
129
130 memcpy(transfer_buffer, cp, size);
131
132 status = usb_control_msg(udev,
133 usb_sndctrlpipe(udev, 0),
134 request,
135 USB_DIR_OUT | USB_TYPE_VENDOR |
136 USB_RECIP_DEVICE, value, index,
137 transfer_buffer, size, CTRL_TIMEOUT);
138
139 kfree(transfer_buffer);
140
141 if (status < 0)
142 info("Failed sending control message, error %d.", status);
143
144 return status;
145}
146
147
148/* Control messages sent to the camera to initialize it
149 * and launch the capture */
150typedef struct {
151 unsigned int value;
152 unsigned int size;
153 unsigned char *bytes;
154} message;
155
156/* method 0 */
157static unsigned char m0d1[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
158static unsigned char m0d2[] = { 0, 0, 0, 0, 0, 0 };
159static unsigned char m0d3[] = { 0, 0 };
160static message m0[] = {
161 {0x1f30, 0, NULL},
162 {0xd000, 0, NULL},
163 {0x3370, sizeof(m0d1), m0d1},
164 {0x2000, 0, NULL},
165 {0x2f0f, 0, NULL},
166 {0x2610, sizeof(m0d2), m0d2},
167 {0xe107, 0, NULL},
168 {0x2502, 0, NULL},
169 {0x1f70, 0, NULL},
170 {0xd000, 0, NULL},
171 {0x9a01, sizeof(m0d3), m0d3},
172 {-1, -1, NULL}
173};
174
175/* method 1 */
176static unsigned char m1d1[] = { 0xff, 0xff };
177static unsigned char m1d2[] = { 0x00, 0x00 };
178static message m1[] = {
179 {0x1f30, 0, NULL},
180 {0xd000, 0, NULL},
181 {0xf000, 0, NULL},
182 {0x2000, 0, NULL},
183 {0x2f0f, 0, NULL},
184 {0x2650, 0, NULL},
185 {0xe107, 0, NULL},
186 {0x2502, sizeof(m1d1), m1d1},
187 {0x1f70, 0, NULL},
188 {0xd000, 0, NULL},
189 {0xd000, 0, NULL},
190 {0xd000, 0, NULL},
191 {0x9a01, sizeof(m1d2), m1d2},
192 {-1, -1, NULL}
193};
194
195/* method 2 */
196static unsigned char m2d1[] = { 0xff, 0xff };
197static message m2[] = {
198 {0x1f30, 0, NULL},
199 {0xf000, 0, NULL},
200 {0x2000, 0, NULL},
201 {0x2f0f, 0, NULL},
202 {0x2650, 0, NULL},
203 {0xe107, 0, NULL},
204 {0x2502, sizeof(m2d1), m2d1},
205 {0x1f70, 0, NULL},
206 {-1, -1, NULL}
207};
208
209/* init table */
210static message *init[3] = { m0, m1, m2 };
211
212
213/* JPEG static data in header (Huffman table, etc) */
214static unsigned char header1[] = {
215 0xFF, 0xD8,
216 /*
217 0xFF, 0xE0, 0x00, 0x10, 'J', 'F', 'I', 'F',
218 0x00, 0x01, 0x01, 0x00, 0x33, 0x8A, 0x00, 0x00, 0x33, 0x88,
219 */
220 0xFF, 0xDB, 0x00, 0x84
221};
222static unsigned char header2[] = {
223 0xFF, 0xC4, 0x00, 0x1F, 0x00, 0x00, 0x01, 0x05, 0x01, 0x01, 0x01,
224 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
225 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B,
226 0xFF, 0xC4, 0x00, 0xB5, 0x10, 0x00, 0x02, 0x01, 0x03, 0x03, 0x02,
227 0x04, 0x03, 0x05, 0x05, 0x04, 0x04, 0x00, 0x00, 0x01, 0x7D, 0x01,
228 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 0x21, 0x31, 0x41, 0x06,
229 0x13, 0x51, 0x61, 0x07, 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xA1,
230 0x08, 0x23, 0x42, 0xB1, 0xC1, 0x15, 0x52, 0xD1, 0xF0, 0x24, 0x33,
231 0x62, 0x72, 0x82, 0x09, 0x0A, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x25,
232 0x26, 0x27, 0x28, 0x29, 0x2A, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
233 0x3A, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x53, 0x54,
234 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x63, 0x64, 0x65, 0x66, 0x67,
235 0x68, 0x69, 0x6A, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A,
236 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x92, 0x93, 0x94,
237 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6,
238 0xA7, 0xA8, 0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8,
239 0xB9, 0xBA, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA,
240 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xE1, 0xE2,
241 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xF1, 0xF2, 0xF3,
242 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFF, 0xC4, 0x00, 0x1F,
243 0x01, 0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
244 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04,
245 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0xFF, 0xC4, 0x00, 0xB5,
246 0x11, 0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04, 0x07, 0x05,
247 0x04, 0x04, 0x00, 0x01, 0x02, 0x77, 0x00, 0x01, 0x02, 0x03, 0x11,
248 0x04, 0x05, 0x21, 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
249 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, 0xA1, 0xB1, 0xC1,
250 0x09, 0x23, 0x33, 0x52, 0xF0, 0x15, 0x62, 0x72, 0xD1, 0x0A, 0x16,
251 0x24, 0x34, 0xE1, 0x25, 0xF1, 0x17, 0x18, 0x19, 0x1A, 0x26, 0x27,
252 0x28, 0x29, 0x2A, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x43, 0x44,
253 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x53, 0x54, 0x55, 0x56, 0x57,
254 0x58, 0x59, 0x5A, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A,
255 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x82, 0x83, 0x84,
256 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x92, 0x93, 0x94, 0x95, 0x96,
257 0x97, 0x98, 0x99, 0x9A, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8,
258 0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA,
259 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xD2, 0xD3,
260 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xE2, 0xE3, 0xE4, 0xE5,
261 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
262 0xF8, 0xF9, 0xFA, 0xFF, 0xC0, 0x00, 0x11, 0x08, 0x00, 0xF0, 0x01,
263 0x40, 0x03, 0x01, 0x21, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01,
264 0xFF, 0xDA, 0x00, 0x0C, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11,
265 0x00, 0x3F, 0x00
266};
267static unsigned char header3;
268
269
270
271/********************/
272/* V4L2 integration */
273/********************/
274
275/* this function reads a full JPEG picture synchronously
276 * TODO: do it asynchronously... */
277static int read_frame(struct zr364xx_camera *cam, int framenum)
278{
279 int i, n, temp, head, size, actual_length;
280 unsigned char *ptr = NULL, *jpeg;
281
282 redo:
283 /* hardware brightness */
284 n = send_control_msg(cam->udev, 1, 0x2001, 0, NULL, 0);
285 temp = (0x60 << 8) + 127 - cam->brightness;
286 n = send_control_msg(cam->udev, 1, temp, 0, NULL, 0);
287
288 /* during the first loop we are going to insert JPEG header */
289 head = 0;
290 /* this is the place in memory where we are going to build
291 * the JPEG image */
292 jpeg = cam->framebuf + framenum * MAX_FRAME_SIZE;
293 /* read data... */
294 do {
295 n = usb_bulk_msg(cam->udev,
296 usb_rcvbulkpipe(cam->udev, 0x81),
297 cam->buffer, BUFFER_SIZE, &actual_length,
298 CTRL_TIMEOUT);
299 DBG("buffer : %d %d", cam->buffer[0], cam->buffer[1]);
300 DBG("bulk : n=%d size=%d", n, actual_length);
301 if (n < 0) {
302 info("error reading bulk msg");
303 return 0;
304 }
305 if (actual_length < 0 || actual_length > BUFFER_SIZE) {
306 info("wrong number of bytes");
307 return 0;
308 }
309
310 /* swap bytes if camera needs it */
311 if (cam->method == METHOD0) {
312 u16 *buf = (u16*)cam->buffer;
313 for (i = 0; i < BUFFER_SIZE/2; i++)
314 swab16s(buf + i);
315 }
316
317 /* write the JPEG header */
318 if (!head) {
319 DBG("jpeg header");
320 ptr = jpeg;
321 memcpy(ptr, header1, sizeof(header1));
322 ptr += sizeof(header1);
323 header3 = 0;
324 memcpy(ptr, &header3, 1);
325 ptr++;
326 memcpy(ptr, cam->buffer, 64);
327 ptr += 64;
328 header3 = 1;
329 memcpy(ptr, &header3, 1);
330 ptr++;
331 memcpy(ptr, cam->buffer + 64, 64);
332 ptr += 64;
333 memcpy(ptr, header2, sizeof(header2));
334 ptr += sizeof(header2);
335 memcpy(ptr, cam->buffer + 128,
336 actual_length - 128);
337 ptr += actual_length - 128;
338 head = 1;
339 DBG("header : %d %d %d %d %d %d %d %d %d",
340 cam->buffer[0], cam->buffer[1], cam->buffer[2],
341 cam->buffer[3], cam->buffer[4], cam->buffer[5],
342 cam->buffer[6], cam->buffer[7], cam->buffer[8]);
343 } else {
344 memcpy(ptr, cam->buffer, actual_length);
345 ptr += actual_length;
346 }
347 }
348 /* ... until there is no more */
349 while (actual_length == BUFFER_SIZE);
350
351 /* we skip the 2 first frames which are usually buggy */
352 if (cam->skip) {
353 cam->skip--;
354 goto redo;
355 }
356
357 /* go back to find the JPEG EOI marker */
358 size = ptr - jpeg;
359 ptr -= 2;
360 while (ptr > jpeg) {
361 if (*ptr == 0xFF && *(ptr + 1) == 0xD9
362 && *(ptr + 2) == 0xFF)
363 break;
364 ptr--;
365 }
366 if (ptr == jpeg)
367 DBG("No EOI marker");
368
369 /* Sometimes there is junk data in the middle of the picture,
370 * we want to skip this bogus frames */
371 while (ptr > jpeg) {
372 if (*ptr == 0xFF && *(ptr + 1) == 0xFF
373 && *(ptr + 2) == 0xFF)
374 break;
375 ptr--;
376 }
377 if (ptr != jpeg) {
378 DBG("Bogus frame ? %d", cam->nb);
379 goto redo;
380 }
381
382 DBG("jpeg : %d %d %d %d %d %d %d %d",
383 jpeg[0], jpeg[1], jpeg[2], jpeg[3],
384 jpeg[4], jpeg[5], jpeg[6], jpeg[7]);
385
386 return size;
387}
388
389
390static ssize_t zr364xx_read(struct file *file, char *buf, size_t cnt,
391 loff_t * ppos)
392{
393 unsigned long count = cnt;
394 struct video_device *vdev = video_devdata(file);
395 struct zr364xx_camera *cam;
396
397 DBG("zr364xx_read: read %d bytes.", (int) count);
398
399 if (vdev == NULL)
400 return -ENODEV;
401 cam = video_get_drvdata(vdev);
402
403 if (!buf)
404 return -EINVAL;
405
406 if (!count)
407 return -EINVAL;
408
409 /* NoMan Sux ! */
410 count = read_frame(cam, 0);
411
412 if (copy_to_user(buf, cam->framebuf, count))
413 return -EFAULT;
414
415 return count;
416}
417
418
419static int zr364xx_vidioc_querycap(struct file *file, void *priv,
420 struct v4l2_capability *cap)
421{
422 memset(cap, 0, sizeof(*cap));
423 strcpy(cap->driver, DRIVER_DESC);
424 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE;
425 return 0;
426}
427
428static int zr364xx_vidioc_enum_input(struct file *file, void *priv,
429 struct v4l2_input *i)
430{
431 if (i->index != 0)
432 return -EINVAL;
433 memset(i, 0, sizeof(*i));
434 i->index = 0;
435 strcpy(i->name, DRIVER_DESC " Camera");
436 i->type = V4L2_INPUT_TYPE_CAMERA;
437 return 0;
438}
439
440static int zr364xx_vidioc_g_input(struct file *file, void *priv,
441 unsigned int *i)
442{
443 *i = 0;
444 return 0;
445}
446
447static int zr364xx_vidioc_s_input(struct file *file, void *priv,
448 unsigned int i)
449{
450 if (i != 0)
451 return -EINVAL;
452 return 0;
453}
454
455static int zr364xx_vidioc_queryctrl(struct file *file, void *priv,
456 struct v4l2_queryctrl *c)
457{
458 struct video_device *vdev = video_devdata(file);
459 struct zr364xx_camera *cam;
460
461 if (vdev == NULL)
462 return -ENODEV;
463 cam = video_get_drvdata(vdev);
464
465 switch (c->id) {
466 case V4L2_CID_BRIGHTNESS:
467 c->type = V4L2_CTRL_TYPE_INTEGER;
468 strcpy(c->name, "Brightness");
469 c->minimum = 0;
470 c->maximum = 127;
471 c->step = 1;
472 c->default_value = cam->brightness;
473 c->flags = 0;
474 break;
475 default:
476 return -EINVAL;
477 }
478 return 0;
479}
480
481static int zr364xx_vidioc_s_ctrl(struct file *file, void *priv,
482 struct v4l2_control *c)
483{
484 struct video_device *vdev = video_devdata(file);
485 struct zr364xx_camera *cam;
486
487 if (vdev == NULL)
488 return -ENODEV;
489 cam = video_get_drvdata(vdev);
490
491 switch (c->id) {
492 case V4L2_CID_BRIGHTNESS:
493 cam->brightness = c->value;
494 break;
495 default:
496 return -EINVAL;
497 }
498 return 0;
499}
500
501static int zr364xx_vidioc_g_ctrl(struct file *file, void *priv,
502 struct v4l2_control *c)
503{
504 struct video_device *vdev = video_devdata(file);
505 struct zr364xx_camera *cam;
506
507 if (vdev == NULL)
508 return -ENODEV;
509 cam = video_get_drvdata(vdev);
510
511 switch (c->id) {
512 case V4L2_CID_BRIGHTNESS:
513 c->value = cam->brightness;
514 break;
515 default:
516 return -EINVAL;
517 }
518 return 0;
519}
520
521static int zr364xx_vidioc_enum_fmt_cap(struct file *file,
522 void *priv, struct v4l2_fmtdesc *f)
523{
524 if (f->index > 0)
525 return -EINVAL;
526 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
527 return -EINVAL;
528 memset(f, 0, sizeof(*f));
529 f->index = 0;
530 f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
531 f->flags = V4L2_FMT_FLAG_COMPRESSED;
532 strcpy(f->description, "JPEG");
533 f->pixelformat = V4L2_PIX_FMT_JPEG;
534 return 0;
535}
536
537static int zr364xx_vidioc_try_fmt_cap(struct file *file, void *priv,
538 struct v4l2_format *f)
539{
540 struct video_device *vdev = video_devdata(file);
541 struct zr364xx_camera *cam;
542
543 if (vdev == NULL)
544 return -ENODEV;
545 cam = video_get_drvdata(vdev);
546
547 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
548 return -EINVAL;
549 if (f->fmt.pix.pixelformat != V4L2_PIX_FMT_JPEG)
550 return -EINVAL;
551 if (f->fmt.pix.field != V4L2_FIELD_ANY &&
552 f->fmt.pix.field != V4L2_FIELD_NONE)
553 return -EINVAL;
554 f->fmt.pix.field = V4L2_FIELD_NONE;
555 f->fmt.pix.width = cam->width;
556 f->fmt.pix.height = cam->height;
557 f->fmt.pix.bytesperline = f->fmt.pix.width * 2;
558 f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
559 f->fmt.pix.colorspace = 0;
560 f->fmt.pix.priv = 0;
561 return 0;
562}
563
564static int zr364xx_vidioc_g_fmt_cap(struct file *file, void *priv,
565 struct v4l2_format *f)
566{
567 struct video_device *vdev = video_devdata(file);
568 struct zr364xx_camera *cam;
569
570 if (vdev == NULL)
571 return -ENODEV;
572 cam = video_get_drvdata(vdev);
573
574 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
575 return -EINVAL;
576 memset(&f->fmt.pix, 0, sizeof(struct v4l2_pix_format));
577 f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
578 f->fmt.pix.pixelformat = V4L2_PIX_FMT_JPEG;
579 f->fmt.pix.field = V4L2_FIELD_NONE;
580 f->fmt.pix.width = cam->width;
581 f->fmt.pix.height = cam->height;
582 f->fmt.pix.bytesperline = f->fmt.pix.width * 2;
583 f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
584 f->fmt.pix.colorspace = 0;
585 f->fmt.pix.priv = 0;
586 return 0;
587}
588
589static int zr364xx_vidioc_s_fmt_cap(struct file *file, void *priv,
590 struct v4l2_format *f)
591{
592 struct video_device *vdev = video_devdata(file);
593 struct zr364xx_camera *cam;
594
595 if (vdev == NULL)
596 return -ENODEV;
597 cam = video_get_drvdata(vdev);
598
599 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
600 return -EINVAL;
601 if (f->fmt.pix.pixelformat != V4L2_PIX_FMT_JPEG)
602 return -EINVAL;
603 if (f->fmt.pix.field != V4L2_FIELD_ANY &&
604 f->fmt.pix.field != V4L2_FIELD_NONE)
605 return -EINVAL;
606 f->fmt.pix.field = V4L2_FIELD_NONE;
607 f->fmt.pix.width = cam->width;
608 f->fmt.pix.height = cam->height;
609 f->fmt.pix.bytesperline = f->fmt.pix.width * 2;
610 f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
611 f->fmt.pix.colorspace = 0;
612 f->fmt.pix.priv = 0;
613 DBG("ok!");
614 return 0;
615}
616
617static int zr364xx_vidioc_streamon(struct file *file, void *priv,
618 enum v4l2_buf_type type)
619{
620 return 0;
621}
622
623static int zr364xx_vidioc_streamoff(struct file *file, void *priv,
624 enum v4l2_buf_type type)
625{
626 return 0;
627}
628
629
630/* open the camera */
631static int zr364xx_open(struct inode *inode, struct file *file)
632{
633 struct video_device *vdev = video_devdata(file);
634 struct zr364xx_camera *cam = video_get_drvdata(vdev);
635 struct usb_device *udev = cam->udev;
636 int i, err;
637
638 DBG("zr364xx_open");
639
640 cam->skip = 2;
641
642 err = video_exclusive_open(inode, file);
643 if (err < 0)
644 return err;
645
646 if (!cam->framebuf) {
647 cam->framebuf = vmalloc_32(MAX_FRAME_SIZE * FRAMES);
648 if (!cam->framebuf) {
649 info("vmalloc_32 failed!");
650 return -ENOMEM;
651 }
652 }
653
654 mutex_lock(&cam->lock);
655 for (i = 0; init[cam->method][i].size != -1; i++) {
656 err =
657 send_control_msg(udev, 1, init[cam->method][i].value,
658 0, init[cam->method][i].bytes,
659 init[cam->method][i].size);
660 if (err < 0) {
661 info("error during open sequence: %d", i);
662 mutex_unlock(&cam->lock);
663 return err;
664 }
665 }
666
667 file->private_data = vdev;
668
669 /* Added some delay here, since opening/closing the camera quickly,
670 * like Ekiga does during its startup, can crash the webcam
671 */
672 mdelay(100);
673
674 mutex_unlock(&cam->lock);
675 return 0;
676}
677
678
679/* release the camera */
680static int zr364xx_release(struct inode *inode, struct file *file)
681{
682 struct video_device *vdev = video_devdata(file);
683 struct zr364xx_camera *cam;
684 struct usb_device *udev;
685 int i, err;
686
687 DBG("zr364xx_release");
688
689 if (vdev == NULL)
690 return -ENODEV;
691 cam = video_get_drvdata(vdev);
692
693 udev = cam->udev;
694
695 mutex_lock(&cam->lock);
696 for (i = 0; i < 2; i++) {
697 err =
698 send_control_msg(udev, 1, init[cam->method][i].value,
699 0, init[i][cam->method].bytes,
700 init[cam->method][i].size);
701 if (err < 0) {
702 info("error during release sequence");
703 mutex_unlock(&cam->lock);
704 return err;
705 }
706 }
707
708 file->private_data = NULL;
709 video_exclusive_release(inode, file);
710
711 /* Added some delay here, since opening/closing the camera quickly,
712 * like Ekiga does during its startup, can crash the webcam
713 */
714 mdelay(100);
715
716 mutex_unlock(&cam->lock);
717 return 0;
718}
719
720
721static int zr364xx_mmap(struct file *file, struct vm_area_struct *vma)
722{
723 void *pos;
724 unsigned long start = vma->vm_start;
725 unsigned long size = vma->vm_end - vma->vm_start;
726 struct video_device *vdev = video_devdata(file);
727 struct zr364xx_camera *cam;
728
729 DBG("zr364xx_mmap: %ld\n", size);
730
731 if (vdev == NULL)
732 return -ENODEV;
733 cam = video_get_drvdata(vdev);
734
735 pos = cam->framebuf;
736 while (size > 0) {
737 if (vm_insert_page(vma, start, vmalloc_to_page(pos)))
738 return -EAGAIN;
739 start += PAGE_SIZE;
740 pos += PAGE_SIZE;
741 if (size > PAGE_SIZE)
742 size -= PAGE_SIZE;
743 else
744 size = 0;
745 }
746
747 return 0;
748}
749
750
751static struct file_operations zr364xx_fops = {
752 .owner = THIS_MODULE,
753 .open = zr364xx_open,
754 .release = zr364xx_release,
755 .read = zr364xx_read,
756 .mmap = zr364xx_mmap,
757 .ioctl = video_ioctl2,
758 .llseek = no_llseek,
759};
760
761static struct video_device zr364xx_template = {
762 .owner = THIS_MODULE,
763 .name = DRIVER_DESC,
764 .type = VID_TYPE_CAPTURE,
765 .fops = &zr364xx_fops,
766 .release = video_device_release,
767 .minor = -1,
768
769 .vidioc_querycap = zr364xx_vidioc_querycap,
770 .vidioc_enum_fmt_cap = zr364xx_vidioc_enum_fmt_cap,
771 .vidioc_try_fmt_cap = zr364xx_vidioc_try_fmt_cap,
772 .vidioc_s_fmt_cap = zr364xx_vidioc_s_fmt_cap,
773 .vidioc_g_fmt_cap = zr364xx_vidioc_g_fmt_cap,
774 .vidioc_enum_input = zr364xx_vidioc_enum_input,
775 .vidioc_g_input = zr364xx_vidioc_g_input,
776 .vidioc_s_input = zr364xx_vidioc_s_input,
777 .vidioc_streamon = zr364xx_vidioc_streamon,
778 .vidioc_streamoff = zr364xx_vidioc_streamoff,
779 .vidioc_queryctrl = zr364xx_vidioc_queryctrl,
780 .vidioc_g_ctrl = zr364xx_vidioc_g_ctrl,
781 .vidioc_s_ctrl = zr364xx_vidioc_s_ctrl,
782};
783
784
785
786/*******************/
787/* USB integration */
788/*******************/
789
790static int zr364xx_probe(struct usb_interface *intf,
791 const struct usb_device_id *id)
792{
793 struct usb_device *udev = interface_to_usbdev(intf);
794 struct zr364xx_camera *cam = NULL;
795
796 DBG("probing...");
797
798 info(DRIVER_DESC " compatible webcam plugged");
799 info("model %04x:%04x detected", udev->descriptor.idVendor,
800 udev->descriptor.idProduct);
801
802 if ((cam =
803 kmalloc(sizeof(struct zr364xx_camera), GFP_KERNEL)) == NULL) {
804 info("cam: out of memory !");
805 return -ENODEV;
806 }
807 memset(cam, 0x00, sizeof(struct zr364xx_camera));
808 /* save the init method used by this camera */
809 cam->method = id->driver_info;
810
811 cam->vdev = video_device_alloc();
812 if (cam->vdev == NULL) {
813 info("cam->vdev: out of memory !");
814 kfree(cam);
815 return -ENODEV;
816 }
817 memcpy(cam->vdev, &zr364xx_template, sizeof(zr364xx_template));
818 video_set_drvdata(cam->vdev, cam);
819 if (debug)
820 cam->vdev->debug = V4L2_DEBUG_IOCTL | V4L2_DEBUG_IOCTL_ARG;
821
822 cam->udev = udev;
823
824 if ((cam->buffer = kmalloc(BUFFER_SIZE, GFP_KERNEL)) == NULL) {
825 info("cam->buffer: out of memory !");
826 video_device_release(cam->vdev);
827 kfree(cam);
828 return -ENODEV;
829 }
830
831 switch (mode) {
832 case 1:
833 info("160x120 mode selected");
834 cam->width = 160;
835 cam->height = 120;
836 break;
837 case 2:
838 info("640x480 mode selected");
839 cam->width = 640;
840 cam->height = 480;
841 break;
842 default:
843 info("320x240 mode selected");
844 cam->width = 320;
845 cam->height = 240;
846 break;
847 }
848
849 m0d1[0] = mode;
850 m1[2].value = 0xf000 + mode;
851 m2[1].value = 0xf000 + mode;
852 header2[437] = cam->height / 256;
853 header2[438] = cam->height % 256;
854 header2[439] = cam->width / 256;
855 header2[440] = cam->width % 256;
856
857 cam->nb = 0;
858 cam->brightness = 64;
859 mutex_init(&cam->lock);
860
861 if (video_register_device(cam->vdev, VFL_TYPE_GRABBER, -1) == -1) {
862 info("video_register_device failed");
863 video_device_release(cam->vdev);
864 kfree(cam->buffer);
865 kfree(cam);
866 return -ENODEV;
867 }
868
869 usb_set_intfdata(intf, cam);
870
871 info(DRIVER_DESC " controlling video device %d", cam->vdev->minor);
872 return 0;
873}
874
875
876static void zr364xx_disconnect(struct usb_interface *intf)
877{
878 struct zr364xx_camera *cam = usb_get_intfdata(intf);
879 usb_set_intfdata(intf, NULL);
880 dev_set_drvdata(&intf->dev, NULL);
881 info(DRIVER_DESC " webcam unplugged");
882 if (cam->vdev)
883 video_unregister_device(cam->vdev);
884 cam->vdev = NULL;
885 kfree(cam->buffer);
886 if (cam->framebuf)
887 vfree(cam->framebuf);
888 kfree(cam);
889}
890
891
892
893/**********************/
894/* Module integration */
895/**********************/
896
897static struct usb_driver zr364xx_driver = {
898 .name = "zr364xx",
899 .probe = zr364xx_probe,
900 .disconnect = zr364xx_disconnect,
901 .id_table = device_table
902};
903
904
905static int __init zr364xx_init(void)
906{
907 int retval;
908 retval = usb_register(&zr364xx_driver) < 0;
909 if (retval)
910 info("usb_register failed!");
911 else
912 info(DRIVER_DESC " module loaded");
913 return retval;
914}
915
916
917static void __exit zr364xx_exit(void)
918{
919 info(DRIVER_DESC " module unloaded");
920 usb_deregister(&zr364xx_driver);
921}
922
923
924module_init(zr364xx_init);
925module_exit(zr364xx_exit);
926
927MODULE_AUTHOR(DRIVER_AUTHOR);
928MODULE_DESCRIPTION(DRIVER_DESC);
929MODULE_LICENSE("GPL");
diff --git a/include/linux/dvb/audio.h b/include/linux/dvb/audio.h
index 0874a67c6b92..89412e18f571 100644
--- a/include/linux/dvb/audio.h
+++ b/include/linux/dvb/audio.h
@@ -47,7 +47,9 @@ typedef enum {
47typedef enum { 47typedef enum {
48 AUDIO_STEREO, 48 AUDIO_STEREO,
49 AUDIO_MONO_LEFT, 49 AUDIO_MONO_LEFT,
50 AUDIO_MONO_RIGHT 50 AUDIO_MONO_RIGHT,
51 AUDIO_MONO,
52 AUDIO_STEREO_SWAPPED
51} audio_channel_select_t; 53} audio_channel_select_t;
52 54
53 55
@@ -133,5 +135,6 @@ typedef uint16_t audio_attributes_t;
133 * extracted by the PES parser. 135 * extracted by the PES parser.
134 */ 136 */
135#define AUDIO_GET_PTS _IOR('o', 19, __u64) 137#define AUDIO_GET_PTS _IOR('o', 19, __u64)
138#define AUDIO_BILINGUAL_CHANNEL_SELECT _IO('o', 20)
136 139
137#endif /* _DVBAUDIO_H_ */ 140#endif /* _DVBAUDIO_H_ */
diff --git a/include/linux/dvb/version.h b/include/linux/dvb/version.h
index 6183c9c4849e..126e0c26cb09 100644
--- a/include/linux/dvb/version.h
+++ b/include/linux/dvb/version.h
@@ -24,6 +24,6 @@
24#define _DVBVERSION_H_ 24#define _DVBVERSION_H_
25 25
26#define DVB_API_VERSION 3 26#define DVB_API_VERSION 3
27#define DVB_API_VERSION_MINOR 1 27#define DVB_API_VERSION_MINOR 2
28 28
29#endif /*_DVBVERSION_H_*/ 29#endif /*_DVBVERSION_H_*/
diff --git a/include/linux/dvb/video.h b/include/linux/dvb/video.h
index faebfda397ff..93e4c3a6d190 100644
--- a/include/linux/dvb/video.h
+++ b/include/linux/dvb/video.h
@@ -80,14 +80,70 @@ typedef enum {
80} video_play_state_t; 80} video_play_state_t;
81 81
82 82
83/* Decoder commands */
84#define VIDEO_CMD_PLAY (0)
85#define VIDEO_CMD_STOP (1)
86#define VIDEO_CMD_FREEZE (2)
87#define VIDEO_CMD_CONTINUE (3)
88
89/* Flags for VIDEO_CMD_FREEZE */
90#define VIDEO_CMD_FREEZE_TO_BLACK (1 << 0)
91
92/* Flags for VIDEO_CMD_STOP */
93#define VIDEO_CMD_STOP_TO_BLACK (1 << 0)
94#define VIDEO_CMD_STOP_IMMEDIATELY (1 << 1)
95
96/* Play input formats: */
97/* The decoder has no special format requirements */
98#define VIDEO_PLAY_FMT_NONE (0)
99/* The decoder requires full GOPs */
100#define VIDEO_PLAY_FMT_GOP (1)
101
102/* The structure must be zeroed before use by the application
103 This ensures it can be extended safely in the future. */
104struct video_command {
105 __u32 cmd;
106 __u32 flags;
107 union {
108 struct {
109 __u64 pts;
110 } stop;
111
112 struct {
113 /* 0 or 1000 specifies normal speed,
114 1 specifies forward single stepping,
115 -1 specifies backward single stepping,
116 >1: playback at speed/1000 of the normal speed,
117 <-1: reverse playback at (-speed/1000) of the normal speed. */
118 __s32 speed;
119 __u32 format;
120 } play;
121
122 struct {
123 __u32 data[16];
124 } raw;
125 };
126};
127
128/* FIELD_UNKNOWN can be used if the hardware does not know whether
129 the Vsync is for an odd, even or progressive (i.e. non-interlaced)
130 field. */
131#define VIDEO_VSYNC_FIELD_UNKNOWN (0)
132#define VIDEO_VSYNC_FIELD_ODD (1)
133#define VIDEO_VSYNC_FIELD_EVEN (2)
134#define VIDEO_VSYNC_FIELD_PROGRESSIVE (3)
135
83struct video_event { 136struct video_event {
84 int32_t type; 137 int32_t type;
85#define VIDEO_EVENT_SIZE_CHANGED 1 138#define VIDEO_EVENT_SIZE_CHANGED 1
86#define VIDEO_EVENT_FRAME_RATE_CHANGED 2 139#define VIDEO_EVENT_FRAME_RATE_CHANGED 2
140#define VIDEO_EVENT_DECODER_STOPPED 3
141#define VIDEO_EVENT_VSYNC 4
87 time_t timestamp; 142 time_t timestamp;
88 union { 143 union {
89 video_size_t size; 144 video_size_t size;
90 unsigned int frame_rate; /* in frames per 1000sec */ 145 unsigned int frame_rate; /* in frames per 1000sec */
146 unsigned char vsync_field; /* unknown/odd/even/progressive */
91 } u; 147 } u;
92}; 148};
93 149
@@ -213,4 +269,10 @@ typedef uint16_t video_attributes_t;
213 */ 269 */
214#define VIDEO_GET_PTS _IOR('o', 57, __u64) 270#define VIDEO_GET_PTS _IOR('o', 57, __u64)
215 271
272/* Read the number of displayed frames since the decoder was started */
273#define VIDEO_GET_FRAME_COUNT _IOR('o', 58, __u64)
274
275#define VIDEO_COMMAND _IOWR('o', 59, struct video_command)
276#define VIDEO_TRY_COMMAND _IOWR('o', 60, struct video_command)
277
216#endif /*_DVBVIDEO_H_*/ 278#endif /*_DVBVIDEO_H_*/
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
index 441b877bf150..a25c2afa67e1 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -96,44 +96,60 @@
96 * E N U M S 96 * E N U M S
97 */ 97 */
98enum v4l2_field { 98enum v4l2_field {
99 V4L2_FIELD_ANY = 0, /* driver can choose from none, 99 V4L2_FIELD_ANY = 0, /* driver can choose from none,
100 top, bottom, interlaced 100 top, bottom, interlaced
101 depending on whatever it thinks 101 depending on whatever it thinks
102 is approximate ... */ 102 is approximate ... */
103 V4L2_FIELD_NONE = 1, /* this device has no fields ... */ 103 V4L2_FIELD_NONE = 1, /* this device has no fields ... */
104 V4L2_FIELD_TOP = 2, /* top field only */ 104 V4L2_FIELD_TOP = 2, /* top field only */
105 V4L2_FIELD_BOTTOM = 3, /* bottom field only */ 105 V4L2_FIELD_BOTTOM = 3, /* bottom field only */
106 V4L2_FIELD_INTERLACED = 4, /* both fields interlaced */ 106 V4L2_FIELD_INTERLACED = 4, /* both fields interlaced */
107 V4L2_FIELD_SEQ_TB = 5, /* both fields sequential into one 107 V4L2_FIELD_SEQ_TB = 5, /* both fields sequential into one
108 buffer, top-bottom order */ 108 buffer, top-bottom order */
109 V4L2_FIELD_SEQ_BT = 6, /* same as above + bottom-top order */ 109 V4L2_FIELD_SEQ_BT = 6, /* same as above + bottom-top order */
110 V4L2_FIELD_ALTERNATE = 7, /* both fields alternating into 110 V4L2_FIELD_ALTERNATE = 7, /* both fields alternating into
111 separate buffers */ 111 separate buffers */
112 V4L2_FIELD_INTERLACED_TB = 8, /* both fields interlaced, top field
113 first and the top field is
114 transmitted first */
115 V4L2_FIELD_INTERLACED_BT = 9, /* both fields interlaced, top field
116 first and the bottom field is
117 transmitted first */
112}; 118};
113#define V4L2_FIELD_HAS_TOP(field) \ 119#define V4L2_FIELD_HAS_TOP(field) \
114 ((field) == V4L2_FIELD_TOP ||\ 120 ((field) == V4L2_FIELD_TOP ||\
115 (field) == V4L2_FIELD_INTERLACED ||\ 121 (field) == V4L2_FIELD_INTERLACED ||\
122 (field) == V4L2_FIELD_INTERLACED_TB ||\
123 (field) == V4L2_FIELD_INTERLACED_BT ||\
116 (field) == V4L2_FIELD_SEQ_TB ||\ 124 (field) == V4L2_FIELD_SEQ_TB ||\
117 (field) == V4L2_FIELD_SEQ_BT) 125 (field) == V4L2_FIELD_SEQ_BT)
118#define V4L2_FIELD_HAS_BOTTOM(field) \ 126#define V4L2_FIELD_HAS_BOTTOM(field) \
119 ((field) == V4L2_FIELD_BOTTOM ||\ 127 ((field) == V4L2_FIELD_BOTTOM ||\
120 (field) == V4L2_FIELD_INTERLACED ||\ 128 (field) == V4L2_FIELD_INTERLACED ||\
129 (field) == V4L2_FIELD_INTERLACED_TB ||\
130 (field) == V4L2_FIELD_INTERLACED_BT ||\
121 (field) == V4L2_FIELD_SEQ_TB ||\ 131 (field) == V4L2_FIELD_SEQ_TB ||\
122 (field) == V4L2_FIELD_SEQ_BT) 132 (field) == V4L2_FIELD_SEQ_BT)
123#define V4L2_FIELD_HAS_BOTH(field) \ 133#define V4L2_FIELD_HAS_BOTH(field) \
124 ((field) == V4L2_FIELD_INTERLACED ||\ 134 ((field) == V4L2_FIELD_INTERLACED ||\
125 (field) == V4L2_FIELD_SEQ_TB ||\ 135 (field) == V4L2_FIELD_INTERLACED_TB ||\
136 (field) == V4L2_FIELD_INTERLACED_BT ||\
137 (field) == V4L2_FIELD_SEQ_TB ||\
126 (field) == V4L2_FIELD_SEQ_BT) 138 (field) == V4L2_FIELD_SEQ_BT)
127 139
128enum v4l2_buf_type { 140enum v4l2_buf_type {
129 V4L2_BUF_TYPE_VIDEO_CAPTURE = 1, 141 V4L2_BUF_TYPE_VIDEO_CAPTURE = 1,
130 V4L2_BUF_TYPE_VIDEO_OUTPUT = 2, 142 V4L2_BUF_TYPE_VIDEO_OUTPUT = 2,
131 V4L2_BUF_TYPE_VIDEO_OVERLAY = 3, 143 V4L2_BUF_TYPE_VIDEO_OVERLAY = 3,
132 V4L2_BUF_TYPE_VBI_CAPTURE = 4, 144 V4L2_BUF_TYPE_VBI_CAPTURE = 4,
133 V4L2_BUF_TYPE_VBI_OUTPUT = 5, 145 V4L2_BUF_TYPE_VBI_OUTPUT = 5,
134 V4L2_BUF_TYPE_SLICED_VBI_CAPTURE = 6, 146 V4L2_BUF_TYPE_SLICED_VBI_CAPTURE = 6,
135 V4L2_BUF_TYPE_SLICED_VBI_OUTPUT = 7, 147 V4L2_BUF_TYPE_SLICED_VBI_OUTPUT = 7,
136 V4L2_BUF_TYPE_PRIVATE = 0x80, 148#if 1
149 /* Experimental */
150 V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY = 8,
151#endif
152 V4L2_BUF_TYPE_PRIVATE = 0x80,
137}; 153};
138 154
139enum v4l2_ctrl_type { 155enum v4l2_ctrl_type {
@@ -227,6 +243,8 @@ struct v4l2_capability
227#define V4L2_CAP_SLICED_VBI_CAPTURE 0x00000040 /* Is a sliced VBI capture device */ 243#define V4L2_CAP_SLICED_VBI_CAPTURE 0x00000040 /* Is a sliced VBI capture device */
228#define V4L2_CAP_SLICED_VBI_OUTPUT 0x00000080 /* Is a sliced VBI output device */ 244#define V4L2_CAP_SLICED_VBI_OUTPUT 0x00000080 /* Is a sliced VBI output device */
229#define V4L2_CAP_RDS_CAPTURE 0x00000100 /* RDS data capture */ 245#define V4L2_CAP_RDS_CAPTURE 0x00000100 /* RDS data capture */
246#define V4L2_CAP_VIDEO_OUTPUT_POS 0x00000200 /* Video output can have x,y coords */
247#define V4L2_CAP_VIDEO_OUTPUT_OVERLAY 0x00000400 /* Can do video output overlay */
230 248
231#define V4L2_CAP_TUNER 0x00010000 /* has a tuner */ 249#define V4L2_CAP_TUNER 0x00010000 /* has a tuner */
232#define V4L2_CAP_AUDIO 0x00020000 /* has audio support */ 250#define V4L2_CAP_AUDIO 0x00020000 /* has audio support */
@@ -249,6 +267,8 @@ struct v4l2_pix_format
249 __u32 sizeimage; 267 __u32 sizeimage;
250 enum v4l2_colorspace colorspace; 268 enum v4l2_colorspace colorspace;
251 __u32 priv; /* private data, depends on pixelformat */ 269 __u32 priv; /* private data, depends on pixelformat */
270 __u32 left; /* only valid if V4L2_CAP_VIDEO_OUTPUT_POS is set */
271 __u32 top; /* only valid if V4L2_CAP_VIDEO_OUTPUT_POS is set */
252}; 272};
253 273
254/* Pixel format FOURCC depth Description */ 274/* Pixel format FOURCC depth Description */
@@ -596,10 +616,14 @@ struct v4l2_framebuffer
596#define V4L2_FBUF_CAP_CHROMAKEY 0x0002 616#define V4L2_FBUF_CAP_CHROMAKEY 0x0002
597#define V4L2_FBUF_CAP_LIST_CLIPPING 0x0004 617#define V4L2_FBUF_CAP_LIST_CLIPPING 0x0004
598#define V4L2_FBUF_CAP_BITMAP_CLIPPING 0x0008 618#define V4L2_FBUF_CAP_BITMAP_CLIPPING 0x0008
619#define V4L2_FBUF_CAP_LOCAL_ALPHA 0x0010
620#define V4L2_FBUF_CAP_GLOBAL_ALPHA 0x0020
599/* Flags for the 'flags' field. */ 621/* Flags for the 'flags' field. */
600#define V4L2_FBUF_FLAG_PRIMARY 0x0001 622#define V4L2_FBUF_FLAG_PRIMARY 0x0001
601#define V4L2_FBUF_FLAG_OVERLAY 0x0002 623#define V4L2_FBUF_FLAG_OVERLAY 0x0002
602#define V4L2_FBUF_FLAG_CHROMAKEY 0x0004 624#define V4L2_FBUF_FLAG_CHROMAKEY 0x0004
625#define V4L2_FBUF_FLAG_LOCAL_ALPHA 0x0008
626#define V4L2_FBUF_FLAG_GLOBAL_ALPHA 0x0010
603 627
604struct v4l2_clip 628struct v4l2_clip
605{ 629{
@@ -615,6 +639,7 @@ struct v4l2_window
615 struct v4l2_clip __user *clips; 639 struct v4l2_clip __user *clips;
616 __u32 clipcount; 640 __u32 clipcount;
617 void __user *bitmap; 641 void __user *bitmap;
642 __u8 global_alpha;
618}; 643};
619 644
620/* 645/*
@@ -1037,6 +1062,7 @@ enum v4l2_mpeg_audio_crc {
1037 V4L2_MPEG_AUDIO_CRC_NONE = 0, 1062 V4L2_MPEG_AUDIO_CRC_NONE = 0,
1038 V4L2_MPEG_AUDIO_CRC_CRC16 = 1, 1063 V4L2_MPEG_AUDIO_CRC_CRC16 = 1,
1039}; 1064};
1065#define V4L2_CID_MPEG_AUDIO_MUTE (V4L2_CID_MPEG_BASE+109)
1040 1066
1041/* MPEG video */ 1067/* MPEG video */
1042#define V4L2_CID_MPEG_VIDEO_ENCODING (V4L2_CID_MPEG_BASE+200) 1068#define V4L2_CID_MPEG_VIDEO_ENCODING (V4L2_CID_MPEG_BASE+200)
@@ -1063,6 +1089,8 @@ enum v4l2_mpeg_video_bitrate_mode {
1063#define V4L2_CID_MPEG_VIDEO_BITRATE (V4L2_CID_MPEG_BASE+207) 1089#define V4L2_CID_MPEG_VIDEO_BITRATE (V4L2_CID_MPEG_BASE+207)
1064#define V4L2_CID_MPEG_VIDEO_BITRATE_PEAK (V4L2_CID_MPEG_BASE+208) 1090#define V4L2_CID_MPEG_VIDEO_BITRATE_PEAK (V4L2_CID_MPEG_BASE+208)
1065#define V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION (V4L2_CID_MPEG_BASE+209) 1091#define V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION (V4L2_CID_MPEG_BASE+209)
1092#define V4L2_CID_MPEG_VIDEO_MUTE (V4L2_CID_MPEG_BASE+210)
1093#define V4L2_CID_MPEG_VIDEO_MUTE_YUV (V4L2_CID_MPEG_BASE+211)
1066 1094
1067/* MPEG-class control IDs specific to the CX2584x driver as defined by V4L2 */ 1095/* MPEG-class control IDs specific to the CX2584x driver as defined by V4L2 */
1068#define V4L2_CID_MPEG_CX2341X_BASE (V4L2_CTRL_CLASS_MPEG | 0x1000) 1096#define V4L2_CID_MPEG_CX2341X_BASE (V4L2_CTRL_CLASS_MPEG | 0x1000)
@@ -1103,6 +1131,7 @@ enum v4l2_mpeg_cx2341x_video_median_filter_type {
1103#define V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP (V4L2_CID_MPEG_CX2341X_BASE+8) 1131#define V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP (V4L2_CID_MPEG_CX2341X_BASE+8)
1104#define V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM (V4L2_CID_MPEG_CX2341X_BASE+9) 1132#define V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM (V4L2_CID_MPEG_CX2341X_BASE+9)
1105#define V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP (V4L2_CID_MPEG_CX2341X_BASE+10) 1133#define V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP (V4L2_CID_MPEG_CX2341X_BASE+10)
1134#define V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS (V4L2_CID_MPEG_CX2341X_BASE+11)
1106 1135
1107/* 1136/*
1108 * T U N I N G 1137 * T U N I N G
@@ -1369,6 +1398,14 @@ struct v4l2_register {
1369 __u64 val; 1398 __u64 val;
1370}; 1399};
1371 1400
1401/* VIDIOC_G_CHIP_IDENT */
1402struct v4l2_chip_ident {
1403 __u32 match_type; /* Match type */
1404 __u32 match_chip; /* Match this chip, meaning determined by match_type */
1405 __u32 ident; /* chip identifier as specified in <media/v4l2-chip-ident.h> */
1406 __u32 revision; /* chip revision, chip specific */
1407};
1408
1372/* 1409/*
1373 * I O C T L C O D E S F O R V I D E O D E V I C E S 1410 * I O C T L C O D E S F O R V I D E O D E V I C E S
1374 * 1411 *
@@ -1442,6 +1479,8 @@ struct v4l2_register {
1442/* Experimental, only implemented if CONFIG_VIDEO_ADV_DEBUG is defined */ 1479/* Experimental, only implemented if CONFIG_VIDEO_ADV_DEBUG is defined */
1443#define VIDIOC_DBG_S_REGISTER _IOW ('V', 79, struct v4l2_register) 1480#define VIDIOC_DBG_S_REGISTER _IOW ('V', 79, struct v4l2_register)
1444#define VIDIOC_DBG_G_REGISTER _IOWR ('V', 80, struct v4l2_register) 1481#define VIDIOC_DBG_G_REGISTER _IOWR ('V', 80, struct v4l2_register)
1482
1483#define VIDIOC_G_CHIP_IDENT _IOWR ('V', 81, struct v4l2_chip_ident)
1445#endif 1484#endif
1446 1485
1447#ifdef __OLD_VIDIOC_ 1486#ifdef __OLD_VIDIOC_
diff --git a/include/media/cx2341x.h b/include/media/cx2341x.h
index d758a52cf556..38c12fed7535 100644
--- a/include/media/cx2341x.h
+++ b/include/media/cx2341x.h
@@ -40,6 +40,7 @@ struct cx2341x_mpeg_params {
40 /* stream */ 40 /* stream */
41 enum v4l2_mpeg_stream_type stream_type; 41 enum v4l2_mpeg_stream_type stream_type;
42 enum v4l2_mpeg_stream_vbi_fmt stream_vbi_fmt; 42 enum v4l2_mpeg_stream_vbi_fmt stream_vbi_fmt;
43 u16 stream_insert_nav_packets;
43 44
44 /* audio */ 45 /* audio */
45 enum v4l2_mpeg_audio_sampling_freq audio_sampling_freq; 46 enum v4l2_mpeg_audio_sampling_freq audio_sampling_freq;
@@ -50,6 +51,7 @@ struct cx2341x_mpeg_params {
50 enum v4l2_mpeg_audio_emphasis audio_emphasis; 51 enum v4l2_mpeg_audio_emphasis audio_emphasis;
51 enum v4l2_mpeg_audio_crc audio_crc; 52 enum v4l2_mpeg_audio_crc audio_crc;
52 u16 audio_properties; 53 u16 audio_properties;
54 u16 audio_mute;
53 55
54 /* video */ 56 /* video */
55 enum v4l2_mpeg_video_encoding video_encoding; 57 enum v4l2_mpeg_video_encoding video_encoding;
@@ -61,6 +63,8 @@ struct cx2341x_mpeg_params {
61 u32 video_bitrate; 63 u32 video_bitrate;
62 u32 video_bitrate_peak; 64 u32 video_bitrate_peak;
63 u16 video_temporal_decimation; 65 u16 video_temporal_decimation;
66 u16 video_mute;
67 u32 video_mute_yuv;
64 68
65 /* encoding filters */ 69 /* encoding filters */
66 enum v4l2_mpeg_cx2341x_video_spatial_filter_mode video_spatial_filter_mode; 70 enum v4l2_mpeg_cx2341x_video_spatial_filter_mode video_spatial_filter_mode;
@@ -162,7 +166,7 @@ void cx2341x_log_status(struct cx2341x_mpeg_params *p, const char *prefix);
162#define CX2341X_ENC_SET_PLACEHOLDER 0xd7 166#define CX2341X_ENC_SET_PLACEHOLDER 0xd7
163#define CX2341X_ENC_MUTE_VIDEO 0xd9 167#define CX2341X_ENC_MUTE_VIDEO 0xd9
164#define CX2341X_ENC_MUTE_AUDIO 0xda 168#define CX2341X_ENC_MUTE_AUDIO 0xda
165#define CX2341X_ENC_UNKNOWN 0xdb 169#define CX2341X_ENC_SET_VERT_CROP_LINE 0xdb
166#define CX2341X_ENC_MISC 0xdc 170#define CX2341X_ENC_MISC 0xdc
167 171
168/* OSD API, specific to the cx23415 */ 172/* OSD API, specific to the cx23415 */
diff --git a/include/media/ivtv.h b/include/media/ivtv.h
new file mode 100644
index 000000000000..412b48ea8eda
--- /dev/null
+++ b/include/media/ivtv.h
@@ -0,0 +1,65 @@
1/*
2 Public ivtv API header
3 Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
4 Copyright (C) 2004-2007 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#ifndef _LINUX_IVTV_H
22#define _LINUX_IVTV_H
23
24/* ivtv knows several distinct output modes: MPEG streaming,
25 YUV streaming, YUV updates through user DMA and the passthrough
26 mode.
27
28 In order to clearly tell the driver that we are in user DMA
29 YUV mode you need to call IVTV_IOC_DMA_FRAME with y_source == NULL
30 first (althrough if you don't then the first time
31 DMA_FRAME is called the mode switch is done automatically).
32
33 When you close the file handle the user DMA mode is exited again.
34
35 While in one mode, you cannot use another mode (EBUSY is returned).
36
37 All this means that if you want to change the YUV interlacing
38 for the user DMA YUV mode you first need to do call IVTV_IOC_DMA_FRAME
39 with y_source == NULL before you can set the correct format using
40 VIDIOC_S_FMT.
41
42 Eventually all this should be replaced with a proper V4L2 API,
43 but for now we have to do it this way. */
44
45struct ivtv_dma_frame {
46 enum v4l2_buf_type type; /* V4L2_BUF_TYPE_VIDEO_OUTPUT */
47 __u32 pixelformat; /* 0 == same as destination */
48 void __user *y_source; /* if NULL and type == V4L2_BUF_TYPE_VIDEO_OUTPUT,
49 then just switch to user DMA YUV output mode */
50 void __user *uv_source; /* Unused for RGB pixelformats */
51 struct v4l2_rect src;
52 struct v4l2_rect dst;
53 __u32 src_width;
54 __u32 src_height;
55};
56
57#define IVTV_IOC_DMA_FRAME _IOW ('V', BASE_VIDIOC_PRIVATE+0, struct ivtv_dma_frame)
58
59/* These are the VBI types as they appear in the embedded VBI private packets. */
60#define IVTV_SLICED_TYPE_TELETEXT_B (1)
61#define IVTV_SLICED_TYPE_CAPTION_525 (4)
62#define IVTV_SLICED_TYPE_WSS_625 (5)
63#define IVTV_SLICED_TYPE_VPS (7)
64
65#endif /* _LINUX_IVTV_H */
diff --git a/include/media/tuner.h b/include/media/tuner.h
index 99acf847365c..a41ac41113ac 100644
--- a/include/media/tuner.h
+++ b/include/media/tuner.h
@@ -177,6 +177,8 @@ struct tuner_setup {
177 unsigned short addr; /* I2C address */ 177 unsigned short addr; /* I2C address */
178 unsigned int type; /* Tuner type */ 178 unsigned int type; /* Tuner type */
179 unsigned int mode_mask; /* Allowed tuner modes */ 179 unsigned int mode_mask; /* Allowed tuner modes */
180 unsigned int config; /* configuraion for more complex tuners */
181 int (*tuner_callback) (void *dev, int command,int arg);
180}; 182};
181 183
182struct tuner { 184struct tuner {
@@ -211,6 +213,9 @@ struct tuner {
211 unsigned char tda827x_ver; 213 unsigned char tda827x_ver;
212 unsigned int sgIF; 214 unsigned int sgIF;
213 215
216 unsigned int config;
217 int (*tuner_callback) (void *dev, int command,int arg);
218
214 /* function ptrs */ 219 /* function ptrs */
215 void (*set_tv_freq)(struct i2c_client *c, unsigned int freq); 220 void (*set_tv_freq)(struct i2c_client *c, unsigned int freq);
216 void (*set_radio_freq)(struct i2c_client *c, unsigned int freq); 221 void (*set_radio_freq)(struct i2c_client *c, unsigned int freq);
diff --git a/include/media/v4l2-chip-ident.h b/include/media/v4l2-chip-ident.h
new file mode 100644
index 000000000000..09d16c4f00f7
--- /dev/null
+++ b/include/media/v4l2-chip-ident.h
@@ -0,0 +1,149 @@
1/*
2 v4l2 chip identifiers header
3
4 This header provides a list of chip identifiers that can be returned
5 through the VIDIOC_G_CHIP_IDENT ioctl.
6
7 Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 */
23
24#ifndef V4L2_CHIP_IDENT_H_
25#define V4L2_CHIP_IDENT_H_
26
27/* VIDIOC_G_CHIP_IDENT: identifies the actual chip installed on the board */
28enum {
29 /* general idents: reserved range 0-49 */
30 V4L2_IDENT_NONE = 0, /* No chip matched */
31 V4L2_IDENT_AMBIGUOUS = 1, /* Match too general, multiple chips matched */
32 V4L2_IDENT_UNKNOWN = 2, /* Chip found, but cannot identify */
33
34 /* module tvaudio: reserved range 50-99 */
35 V4L2_IDENT_TVAUDIO = 50, /* A tvaudio chip, unknown which it is exactly */
36
37 /* module saa7110: just ident 100 */
38 V4L2_IDENT_SAA7110 = 100,
39
40 /* module saa7111: just ident 101 */
41 V4L2_IDENT_SAA7111 = 101,
42
43 /* module saa7115: reserved range 102-149 */
44 V4L2_IDENT_SAA7113 = 103,
45 V4L2_IDENT_SAA7114 = 104,
46 V4L2_IDENT_SAA7115 = 105,
47 V4L2_IDENT_SAA7118 = 108,
48
49 /* module saa7127: reserved range 150-199 */
50 V4L2_IDENT_SAA7127 = 157,
51 V4L2_IDENT_SAA7129 = 159,
52
53 /* module cx25840: reserved range 200-249 */
54 V4L2_IDENT_CX25836 = 236,
55 V4L2_IDENT_CX25837 = 237,
56 V4L2_IDENT_CX25840 = 240,
57 V4L2_IDENT_CX25841 = 241,
58 V4L2_IDENT_CX25842 = 242,
59 V4L2_IDENT_CX25843 = 243,
60
61 /* OmniVision sensors: reserved range 250-299 */
62 V4L2_IDENT_OV7670 = 250,
63
64 /* Conexant MPEG encoder/decoders: reserved range 410-420 */
65 V4L2_IDENT_CX23415 = 415,
66 V4L2_IDENT_CX23416 = 416,
67
68 /* module wm8739: just ident 8739 */
69 V4L2_IDENT_WM8739 = 8739,
70
71 /* module wm8775: just ident 8775 */
72 V4L2_IDENT_WM8775 = 8775,
73
74 /* module cs53132a: just ident 53132 */
75 V4L2_IDENT_CS53l32A = 53132,
76
77 /* module upd64031a: just ident 64031 */
78 V4L2_IDENT_UPD64031A = 64031,
79
80 /* module upd64083: just ident 64083 */
81 V4L2_IDENT_UPD64083 = 64083,
82
83 /* module msp34xx: reserved range 34000-34999 */
84 V4L2_IDENT_MSP3400B = 34002,
85 V4L2_IDENT_MSP3410B = 34102,
86
87 V4L2_IDENT_MSP3400C = 34003,
88 V4L2_IDENT_MSP3410C = 34103,
89
90 V4L2_IDENT_MSP3400D = 34004,
91 V4L2_IDENT_MSP3410D = 34104,
92 V4L2_IDENT_MSP3405D = 34054,
93 V4L2_IDENT_MSP3415D = 34154,
94 V4L2_IDENT_MSP3407D = 34074,
95 V4L2_IDENT_MSP3417D = 34174,
96
97 V4L2_IDENT_MSP3400G = 34007,
98 V4L2_IDENT_MSP3410G = 34107,
99 V4L2_IDENT_MSP3420G = 34207,
100 V4L2_IDENT_MSP3430G = 34307,
101 V4L2_IDENT_MSP3440G = 34407,
102 V4L2_IDENT_MSP3450G = 34507,
103 V4L2_IDENT_MSP3460G = 34607,
104
105 V4L2_IDENT_MSP3401G = 34017,
106 V4L2_IDENT_MSP3411G = 34117,
107 V4L2_IDENT_MSP3421G = 34217,
108 V4L2_IDENT_MSP3431G = 34317,
109 V4L2_IDENT_MSP3441G = 34417,
110 V4L2_IDENT_MSP3451G = 34517,
111 V4L2_IDENT_MSP3461G = 34617,
112
113 V4L2_IDENT_MSP3402G = 34027,
114 V4L2_IDENT_MSP3412G = 34127,
115 V4L2_IDENT_MSP3422G = 34227,
116 V4L2_IDENT_MSP3442G = 34427,
117 V4L2_IDENT_MSP3452G = 34527,
118
119 V4L2_IDENT_MSP3405G = 34057,
120 V4L2_IDENT_MSP3415G = 34157,
121 V4L2_IDENT_MSP3425G = 34257,
122 V4L2_IDENT_MSP3435G = 34357,
123 V4L2_IDENT_MSP3445G = 34457,
124 V4L2_IDENT_MSP3455G = 34557,
125 V4L2_IDENT_MSP3465G = 34657,
126
127 V4L2_IDENT_MSP3407G = 34077,
128 V4L2_IDENT_MSP3417G = 34177,
129 V4L2_IDENT_MSP3427G = 34277,
130 V4L2_IDENT_MSP3437G = 34377,
131 V4L2_IDENT_MSP3447G = 34477,
132 V4L2_IDENT_MSP3457G = 34577,
133 V4L2_IDENT_MSP3467G = 34677,
134
135 /* module msp44xx: reserved range 44000-44999 */
136 V4L2_IDENT_MSP4400G = 44007,
137 V4L2_IDENT_MSP4410G = 44107,
138 V4L2_IDENT_MSP4420G = 44207,
139 V4L2_IDENT_MSP4440G = 44407,
140 V4L2_IDENT_MSP4450G = 44507,
141
142 V4L2_IDENT_MSP4408G = 44087,
143 V4L2_IDENT_MSP4418G = 44187,
144 V4L2_IDENT_MSP4428G = 44287,
145 V4L2_IDENT_MSP4448G = 44487,
146 V4L2_IDENT_MSP4458G = 44587,
147};
148
149#endif
diff --git a/include/media/v4l2-common.h b/include/media/v4l2-common.h
index 6eaeec98ed89..181a40c46a52 100644
--- a/include/media/v4l2-common.h
+++ b/include/media/v4l2-common.h
@@ -98,6 +98,8 @@ u32 v4l2_ctrl_next(const u32 * const *ctrl_classes, u32 id);
98 98
99struct i2c_client; /* forward reference */ 99struct i2c_client; /* forward reference */
100int v4l2_chip_match_i2c_client(struct i2c_client *c, u32 id_type, u32 chip_id); 100int v4l2_chip_match_i2c_client(struct i2c_client *c, u32 id_type, u32 chip_id);
101int v4l2_chip_ident_i2c_client(struct i2c_client *c, struct v4l2_chip_ident *chip,
102 u32 ident, u32 revision);
101int v4l2_chip_match_host(u32 id_type, u32 chip_id); 103int v4l2_chip_match_host(u32 id_type, u32 chip_id);
102 104
103/* ------------------------------------------------------------------------- */ 105/* ------------------------------------------------------------------------- */
@@ -114,39 +116,6 @@ struct v4l2_decode_vbi_line {
114 u32 type; /* VBI service type (V4L2_SLICED_*). 0 if no service found */ 116 u32 type; /* VBI service type (V4L2_SLICED_*). 0 if no service found */
115}; 117};
116 118
117/* VIDIOC_INT_G_CHIP_IDENT: identifies the actual chip installed on the board */
118enum v4l2_chip_ident {
119 /* general idents: reserved range 0-49 */
120 V4L2_IDENT_UNKNOWN = 0,
121
122 /* module saa7110: just ident= 100 */
123 V4L2_IDENT_SAA7110 = 100,
124
125 /* module saa7111: just ident= 101 */
126 V4L2_IDENT_SAA7111 = 101,
127
128 /* module saa7115: reserved range 102-149 */
129 V4L2_IDENT_SAA7113 = 103,
130 V4L2_IDENT_SAA7114 = 104,
131 V4L2_IDENT_SAA7115 = 105,
132 V4L2_IDENT_SAA7118 = 108,
133
134 /* module saa7127: reserved range 150-199 */
135 V4L2_IDENT_SAA7127 = 157,
136 V4L2_IDENT_SAA7129 = 159,
137
138 /* module cx25840: reserved range 200-249 */
139 V4L2_IDENT_CX25836 = 236,
140 V4L2_IDENT_CX25837 = 237,
141 V4L2_IDENT_CX25840 = 240,
142 V4L2_IDENT_CX25841 = 241,
143 V4L2_IDENT_CX25842 = 242,
144 V4L2_IDENT_CX25843 = 243,
145
146 /* OmniVision sensors - range 250-299 */
147 V4L2_IDENT_OV7670 = 250,
148};
149
150/* audio ioctls */ 119/* audio ioctls */
151 120
152/* v4l device was opened in Radio mode, to be replaced by VIDIOC_INT_S_TUNER_MODE */ 121/* v4l device was opened in Radio mode, to be replaced by VIDIOC_INT_S_TUNER_MODE */
@@ -208,10 +177,6 @@ enum v4l2_chip_ident {
208 whether CC data from the first or second field should be obtained). */ 177 whether CC data from the first or second field should be obtained). */
209#define VIDIOC_INT_G_VBI_DATA _IOWR('d', 106, struct v4l2_sliced_vbi_data) 178#define VIDIOC_INT_G_VBI_DATA _IOWR('d', 106, struct v4l2_sliced_vbi_data)
210 179
211/* Returns the chip identifier or V4L2_IDENT_UNKNOWN if no identification can
212 be made. */
213#define VIDIOC_INT_G_CHIP_IDENT _IOR ('d', 107, enum v4l2_chip_ident)
214
215/* Sets I2S speed in bps. This is used to provide a standard way to select I2S 180/* Sets I2S speed in bps. This is used to provide a standard way to select I2S
216 clock used by driving digital audio streams at some board designs. 181 clock used by driving digital audio streams at some board designs.
217 Usual values for the frequency are 1024000 and 2048000. 182 Usual values for the frequency are 1024000 and 2048000.
@@ -254,4 +219,12 @@ struct v4l2_crystal_freq {
254 default values. */ 219 default values. */
255#define VIDIOC_INT_INIT _IOW ('d', 114, u32) 220#define VIDIOC_INT_INIT _IOW ('d', 114, u32)
256 221
222/* Set v4l2_std_id for video OUTPUT devices. This is ignored by
223 video input devices. */
224#define VIDIOC_INT_S_STD_OUTPUT _IOW ('d', 115, v4l2_std_id)
225
226/* Get v4l2_std_id for video OUTPUT devices. This is ignored by
227 video input devices. */
228#define VIDIOC_INT_G_STD_OUTPUT _IOW ('d', 116, v4l2_std_id)
229
257#endif /* V4L2_COMMON_H_ */ 230#endif /* V4L2_COMMON_H_ */
diff --git a/include/media/v4l2-dev.h b/include/media/v4l2-dev.h
index 1dd3d3239ecf..d62847f846c2 100644
--- a/include/media/v4l2-dev.h
+++ b/include/media/v4l2-dev.h
@@ -127,6 +127,8 @@ struct video_device
127 struct v4l2_fmtdesc *f); 127 struct v4l2_fmtdesc *f);
128 int (*vidioc_enum_fmt_video_output)(struct file *file, void *fh, 128 int (*vidioc_enum_fmt_video_output)(struct file *file, void *fh,
129 struct v4l2_fmtdesc *f); 129 struct v4l2_fmtdesc *f);
130 int (*vidioc_enum_fmt_output_overlay) (struct file *file, void *fh,
131 struct v4l2_fmtdesc *f);
130 int (*vidioc_enum_fmt_vbi_output) (struct file *file, void *fh, 132 int (*vidioc_enum_fmt_vbi_output) (struct file *file, void *fh,
131 struct v4l2_fmtdesc *f); 133 struct v4l2_fmtdesc *f);
132 int (*vidioc_enum_fmt_type_private)(struct file *file, void *fh, 134 int (*vidioc_enum_fmt_type_private)(struct file *file, void *fh,
@@ -145,6 +147,8 @@ struct video_device
145 struct v4l2_format *f); 147 struct v4l2_format *f);
146 int (*vidioc_g_fmt_video_output)(struct file *file, void *fh, 148 int (*vidioc_g_fmt_video_output)(struct file *file, void *fh,
147 struct v4l2_format *f); 149 struct v4l2_format *f);
150 int (*vidioc_g_fmt_output_overlay) (struct file *file, void *fh,
151 struct v4l2_format *f);
148 int (*vidioc_g_fmt_type_private)(struct file *file, void *fh, 152 int (*vidioc_g_fmt_type_private)(struct file *file, void *fh,
149 struct v4l2_format *f); 153 struct v4l2_format *f);
150 154
@@ -162,6 +166,8 @@ struct video_device
162 struct v4l2_format *f); 166 struct v4l2_format *f);
163 int (*vidioc_s_fmt_video_output)(struct file *file, void *fh, 167 int (*vidioc_s_fmt_video_output)(struct file *file, void *fh,
164 struct v4l2_format *f); 168 struct v4l2_format *f);
169 int (*vidioc_s_fmt_output_overlay) (struct file *file, void *fh,
170 struct v4l2_format *f);
165 int (*vidioc_s_fmt_type_private)(struct file *file, void *fh, 171 int (*vidioc_s_fmt_type_private)(struct file *file, void *fh,
166 struct v4l2_format *f); 172 struct v4l2_format *f);
167 173
@@ -178,6 +184,8 @@ struct video_device
178 struct v4l2_format *f); 184 struct v4l2_format *f);
179 int (*vidioc_try_fmt_video_output)(struct file *file, void *fh, 185 int (*vidioc_try_fmt_video_output)(struct file *file, void *fh,
180 struct v4l2_format *f); 186 struct v4l2_format *f);
187 int (*vidioc_try_fmt_output_overlay)(struct file *file, void *fh,
188 struct v4l2_format *f);
181 int (*vidioc_try_fmt_type_private)(struct file *file, void *fh, 189 int (*vidioc_try_fmt_type_private)(struct file *file, void *fh,
182 struct v4l2_format *f); 190 struct v4l2_format *f);
183 191
@@ -309,6 +317,8 @@ struct video_device
309 int (*vidioc_s_register) (struct file *file, void *fh, 317 int (*vidioc_s_register) (struct file *file, void *fh,
310 struct v4l2_register *reg); 318 struct v4l2_register *reg);
311#endif 319#endif
320 int (*vidioc_g_chip_ident) (struct file *file, void *fh,
321 struct v4l2_chip_ident *chip);
312 322
313 323
314#ifdef OBSOLETE_OWNER /* to be removed soon */ 324#ifdef OBSOLETE_OWNER /* to be removed soon */