summaryrefslogtreecommitdiff
path: root/linux
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@infradead.org>2007-05-06 10:03:10 -0300
committerMauro Carvalho Chehab <mchehab@infradead.org>2007-05-06 10:03:10 -0300
commit76775b7f2ced0c0301ac3ae201aafc3d9b88e091 (patch)
treef0ad9167da8049f5b468fe5a58a1f438450665d6 /linux
parent8ab655cc3c286a78e3af8ac2a88a839ea073306a (diff)
parent46cf6abc45f699c5843872c7ef8e782e4d0e1a27 (diff)
downloadmediapointer-dvb-s2-76775b7f2ced0c0301ac3ae201aafc3d9b88e091.tar.gz
mediapointer-dvb-s2-76775b7f2ced0c0301ac3ae201aafc3d9b88e091.tar.bz2
merge: http://linuxtv.org/hg/~aapot/m920x
From: Mauro Carvalho Chehab <mchehab@infradead.org> Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'linux')
-rw-r--r--linux/Documentation/video4linux/CARDLIST.bttv2
-rw-r--r--linux/Documentation/video4linux/CARDLIST.saa71345
-rw-r--r--linux/Documentation/video4linux/CARDLIST.usbvision64
-rw-r--r--linux/Documentation/video4linux/sn9c102.txt80
-rw-r--r--linux/drivers/media/Kconfig9
-rw-r--r--linux/drivers/media/Makefile2
-rw-r--r--linux/drivers/media/common/ir-keymaps.c8
-rw-r--r--linux/drivers/media/common/saa7146_core.c54
-rw-r--r--linux/drivers/media/common/saa7146_fops.c1
-rw-r--r--linux/drivers/media/common/saa7146_video.c6
-rw-r--r--linux/drivers/media/dvb/Kconfig24
-rw-r--r--linux/drivers/media/dvb/b2c2/flexcop-pci.c9
-rw-r--r--linux/drivers/media/dvb/bt8xx/bt878.c4
-rw-r--r--linux/drivers/media/dvb/dvb-core/Kconfig14
-rw-r--r--linux/drivers/media/dvb/dvb-core/dmxdev.c56
-rw-r--r--linux/drivers/media/dvb/dvb-core/dmxdev.h2
-rw-r--r--linux/drivers/media/dvb/dvb-core/dvb_frontend.c20
-rw-r--r--linux/drivers/media/dvb/dvb-core/dvb_net.c32
-rw-r--r--linux/drivers/media/dvb/dvb-core/dvb_net.h1
-rw-r--r--linux/drivers/media/dvb/dvb-core/dvbdev.c1
-rw-r--r--linux/drivers/media/dvb/dvb-core/dvbdev.h1
-rw-r--r--linux/drivers/media/dvb/dvb-usb/Kconfig7
-rw-r--r--linux/drivers/media/dvb/dvb-usb/Makefile4
-rw-r--r--linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h3
-rw-r--r--linux/drivers/media/dvb/dvb-usb/dvb-usb-remote.c2
-rw-r--r--linux/drivers/media/dvb/dvb-usb/opera1.c595
-rw-r--r--linux/drivers/media/dvb/dvb-usb/opera1.h9
-rw-r--r--linux/drivers/media/dvb/dvb-usb/vp702x-fe.c14
-rw-r--r--linux/drivers/media/dvb/frontends/Kconfig7
-rw-r--r--linux/drivers/media/dvb/frontends/Makefile1
-rw-r--r--linux/drivers/media/dvb/frontends/dvb-pll.c301
-rw-r--r--linux/drivers/media/dvb/frontends/dvb-pll.h4
-rw-r--r--linux/drivers/media/dvb/frontends/isl6421.c1
-rw-r--r--linux/drivers/media/dvb/frontends/lgdt330x.c4
-rw-r--r--linux/drivers/media/dvb/frontends/nxt200x.c4
-rw-r--r--linux/drivers/media/dvb/frontends/tda10021.c45
-rw-r--r--linux/drivers/media/dvb/frontends/tda10023.c548
-rw-r--r--linux/drivers/media/dvb/frontends/tda1002x.h (renamed from linux/drivers/media/dvb/frontends/tda10021.h)33
-rw-r--r--linux/drivers/media/dvb/frontends/tda10086.c2
-rw-r--r--linux/drivers/media/dvb/frontends/tda827x.c85
-rw-r--r--linux/drivers/media/dvb/pluto2/pluto2.c30
-rw-r--r--linux/drivers/media/dvb/ttpci/Kconfig2
-rw-r--r--linux/drivers/media/dvb/ttpci/av7110.c9
-rw-r--r--linux/drivers/media/dvb/ttpci/budget-av.c147
-rw-r--r--linux/drivers/media/dvb/ttpci/budget-ci.c2
-rw-r--r--linux/drivers/media/dvb/ttpci/budget-core.c95
-rw-r--r--linux/drivers/media/dvb/ttpci/budget.h3
-rw-r--r--linux/drivers/media/radio/Kconfig11
-rw-r--r--linux/drivers/media/radio/radio-aimslab.c240
-rw-r--r--linux/drivers/media/radio/radio-gemtek-pci.c253
-rw-r--r--linux/drivers/media/radio/radio-gemtek.c260
-rw-r--r--linux/drivers/media/radio/radio-maestro.c277
-rw-r--r--linux/drivers/media/radio/radio-rtrack2.c255
-rw-r--r--linux/drivers/media/radio/radio-sf16fmi.c274
-rw-r--r--linux/drivers/media/radio/radio-sf16fmr2.c362
-rw-r--r--linux/drivers/media/radio/radio-terratec.c247
-rw-r--r--linux/drivers/media/radio/radio-trust.c258
-rw-r--r--linux/drivers/media/radio/radio-typhoon.c239
-rw-r--r--linux/drivers/media/radio/radio-zoltrix.c256
-rw-r--r--linux/drivers/media/video/Kconfig47
-rw-r--r--linux/drivers/media/video/bt8xx/bttv-cards.c53
-rw-r--r--linux/drivers/media/video/bt8xx/bttv-driver.c36
-rw-r--r--linux/drivers/media/video/bt8xx/bttv-i2c.c2
-rw-r--r--linux/drivers/media/video/bt8xx/bttv.h2
-rw-r--r--linux/drivers/media/video/bt8xx/bttvp.h3
-rw-r--r--linux/drivers/media/video/cafe_ccic.c71
-rw-r--r--linux/drivers/media/video/cpia_pp.c46
-rw-r--r--linux/drivers/media/video/cx25840/cx25840-core.c4
-rw-r--r--linux/drivers/media/video/cx88/cx88-alsa.c10
-rw-r--r--linux/drivers/media/video/cx88/cx88-cards.c25
-rw-r--r--linux/drivers/media/video/cx88/cx88-core.c8
-rw-r--r--linux/drivers/media/video/cx88/cx88-dvb.c20
-rw-r--r--linux/drivers/media/video/cx88/cx88-i2c.c3
-rw-r--r--linux/drivers/media/video/cx88/cx88-mpeg.c10
-rw-r--r--linux/drivers/media/video/cx88/cx88-video.c6
-rw-r--r--linux/drivers/media/video/cx88/cx88.h2
-rw-r--r--linux/drivers/media/video/em28xx/Kconfig2
-rw-r--r--linux/drivers/media/video/em28xx/em28xx-i2c.c2
-rw-r--r--linux/drivers/media/video/et61x251/Kconfig2
-rw-r--r--linux/drivers/media/video/ir-kbd-i2c.c2
-rw-r--r--linux/drivers/media/video/ivtv/ivtv-driver.c2
-rw-r--r--linux/drivers/media/video/ivtv/ivtv-fileops.c2
-rw-r--r--linux/drivers/media/video/ivtv/ivtv-ioctl.c6
-rw-r--r--linux/drivers/media/video/ov7670.c34
-rw-r--r--linux/drivers/media/video/planb.c6
-rw-r--r--linux/drivers/media/video/planb.h1
-rw-r--r--linux/drivers/media/video/pvrusb2/Kconfig2
-rw-r--r--linux/drivers/media/video/pvrusb2/pvrusb2-encoder.c13
-rw-r--r--linux/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h2
-rw-r--r--linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c28
-rw-r--r--linux/drivers/media/video/pvrusb2/pvrusb2-hdw.h3
-rw-r--r--linux/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c23
-rw-r--r--linux/drivers/media/video/pvrusb2/pvrusb2-sysfs.c42
-rw-r--r--linux/drivers/media/video/pvrusb2/pvrusb2-v4l2.c8
-rw-r--r--linux/drivers/media/video/pwc/Kconfig2
-rw-r--r--linux/drivers/media/video/pwc/pwc-ctrl.c61
-rw-r--r--linux/drivers/media/video/pwc/pwc-if.c16
-rw-r--r--linux/drivers/media/video/pwc/pwc-ioctl.h40
-rw-r--r--linux/drivers/media/video/pwc/pwc-kiara.c2
-rw-r--r--linux/drivers/media/video/pwc/pwc-kiara.h5
-rw-r--r--linux/drivers/media/video/pwc/pwc-timon.c4
-rw-r--r--linux/drivers/media/video/pwc/pwc-timon.h6
-rw-r--r--linux/drivers/media/video/pwc/pwc-v4l.c62
-rw-r--r--linux/drivers/media/video/pwc/pwc.h5
-rw-r--r--linux/drivers/media/video/saa7134/saa7134-cards.c127
-rw-r--r--linux/drivers/media/video/saa7134/saa7134-dvb.c19
-rw-r--r--linux/drivers/media/video/saa7134/saa7134-i2c.c2
-rw-r--r--linux/drivers/media/video/saa7134/saa7134-input.c1
-rw-r--r--linux/drivers/media/video/saa7134/saa7134.h3
-rw-r--r--linux/drivers/media/video/se401.c36
-rw-r--r--linux/drivers/media/video/sn9c102/Kconfig2
-rw-r--r--linux/drivers/media/video/sn9c102/Makefile17
-rw-r--r--linux/drivers/media/video/sn9c102/sn9c102.h21
-rw-r--r--linux/drivers/media/video/sn9c102/sn9c102_core.c327
-rw-r--r--linux/drivers/media/video/sn9c102/sn9c102_devtable.h18
-rw-r--r--linux/drivers/media/video/sn9c102/sn9c102_hv7131d.c31
-rw-r--r--linux/drivers/media/video/sn9c102/sn9c102_hv7131r.c362
-rw-r--r--linux/drivers/media/video/sn9c102/sn9c102_mi0343.c133
-rw-r--r--linux/drivers/media/video/sn9c102/sn9c102_mi0360.c452
-rw-r--r--linux/drivers/media/video/sn9c102/sn9c102_ov7630.c126
-rw-r--r--linux/drivers/media/video/sn9c102/sn9c102_ov7660.c297
-rw-r--r--linux/drivers/media/video/sn9c102/sn9c102_pas106b.c27
-rw-r--r--linux/drivers/media/video/sn9c102/sn9c102_pas202bcb.c77
-rw-r--r--linux/drivers/media/video/sn9c102/sn9c102_sensor.h35
-rw-r--r--linux/drivers/media/video/sn9c102/sn9c102_tas5110c1b.c20
-rw-r--r--linux/drivers/media/video/sn9c102/sn9c102_tas5110d.c118
-rw-r--r--linux/drivers/media/video/sn9c102/sn9c102_tas5130d1b.c21
-rw-r--r--linux/drivers/media/video/tda7432.c1
-rw-r--r--linux/drivers/media/video/tda8290.c8
-rw-r--r--linux/drivers/media/video/tda9875.c1
-rw-r--r--linux/drivers/media/video/tvaudio.c1
-rw-r--r--linux/drivers/media/video/usbvideo/Kconfig8
-rw-r--r--linux/drivers/media/video/usbvision/Kconfig2
-rw-r--r--linux/drivers/media/video/usbvision/usbvision-cards.c1183
-rw-r--r--linux/drivers/media/video/usbvision/usbvision-cards.h66
-rw-r--r--linux/drivers/media/video/usbvision/usbvision-core.c10
-rw-r--r--linux/drivers/media/video/usbvision/usbvision-i2c.c110
-rw-r--r--linux/drivers/media/video/usbvision/usbvision-video.c212
-rw-r--r--linux/drivers/media/video/usbvision/usbvision.h60
-rw-r--r--linux/drivers/media/video/v4l1-compat.c64
-rw-r--r--linux/drivers/media/video/video-buf.c4
-rw-r--r--linux/drivers/media/video/videocodec.c3
-rw-r--r--linux/drivers/media/video/videodev.c55
-rw-r--r--linux/drivers/media/video/zc0301/Kconfig2
-rw-r--r--linux/include/media/saa7146.h2
-rw-r--r--linux/include/media/saa7146_vv.h2
146 files changed, 7074 insertions, 3007 deletions
diff --git a/linux/Documentation/video4linux/CARDLIST.bttv b/linux/Documentation/video4linux/CARDLIST.bttv
index fc2fe9bc6..b60639130 100644
--- a/linux/Documentation/video4linux/CARDLIST.bttv
+++ b/linux/Documentation/video4linux/CARDLIST.bttv
@@ -143,3 +143,5 @@
142 -> Sabrent TV-FM (bttv version)
143 -> Hauppauge ImpactVCB (bt878) [0070:13eb]
144 -> MagicTV
+145 -> SSAI Security Video Interface [4149:5353]
+146 -> SSAI Ultrasound Video Interface [414a:5353]
diff --git a/linux/Documentation/video4linux/CARDLIST.saa7134 b/linux/Documentation/video4linux/CARDLIST.saa7134
index d7bb2e2e4..712e8c833 100644
--- a/linux/Documentation/video4linux/CARDLIST.saa7134
+++ b/linux/Documentation/video4linux/CARDLIST.saa7134
@@ -52,7 +52,7 @@
51 -> ProVideo PV952 [1540:9524]
52 -> AverMedia AverTV/305 [1461:2108]
53 -> ASUS TV-FM 7135 [1043:4845]
- 54 -> LifeView FlyTV Platinum FM / Gold [5168:0214,1489:0214,5168:0304]
+ 54 -> LifeView FlyTV Platinum FM / Gold [5168:0214,5168:5214,1489:0214,5168:0304]
55 -> LifeView FlyDVB-T DUO / MSI TV@nywhere Duo [5168:0306,4E42:0306]
56 -> Avermedia AVerTV 307 [1461:a70a]
57 -> Avermedia AVerTV GO 007 FM [1461:f31f]
@@ -111,3 +111,6 @@
110 -> Avermedia M102 [1461:f31e]
111 -> ASUS P7131 4871 [1043:4871]
112 -> ASUSTeK P7131 Hybrid [1043:4876]
+113 -> Elitegroup ECS TVP3XP FM1246 Tuner Card (PAL,FM) [1019:4cb6]
+114 -> KWorld DVB-T 210 [17de:7250]
+115 -> Sabrent PCMCIA TV-PCB05 [0919:2003]
diff --git a/linux/Documentation/video4linux/CARDLIST.usbvision b/linux/Documentation/video4linux/CARDLIST.usbvision
new file mode 100644
index 000000000..3d6850ef0
--- /dev/null
+++ b/linux/Documentation/video4linux/CARDLIST.usbvision
@@ -0,0 +1,64 @@
+ 0 -> Xanboo [0a6f:0400]
+ 1 -> Belkin USB VideoBus II Adapter [050d:0106]
+ 2 -> Belkin Components USB VideoBus [050d:0207]
+ 3 -> Belkin USB VideoBus II [050d:0208]
+ 4 -> echoFX InterView Lite [0571:0002]
+ 5 -> USBGear USBG-V1 resp. HAMA USB [0573:0003]
+ 6 -> D-Link V100 [0573:0400]
+ 7 -> X10 USB Camera [0573:2000]
+ 8 -> Hauppauge WinTV USB Live (PAL B/G) [0573:2d00]
+ 9 -> Hauppauge WinTV USB Live Pro (NTSC M/N) [0573:2d01]
+ 10 -> Zoran Co. PMD (Nogatech) AV-grabber Manhattan [0573:2101]
+ 11 -> Nogatech USB-TV (NTSC) FM [0573:4100]
+ 12 -> PNY USB-TV (NTSC) FM [0573:4110]
+ 13 -> PixelView PlayTv-USB PRO (PAL) FM [0573:4450]
+ 14 -> ZTV ZT-721 2.4GHz USB A/V Receiver [0573:4550]
+ 15 -> Hauppauge WinTV USB (NTSC M/N) [0573:4d00]
+ 16 -> Hauppauge WinTV USB (PAL B/G) [0573:4d01]
+ 17 -> Hauppauge WinTV USB (PAL I) [0573:4d02]
+ 18 -> Hauppauge WinTV USB (PAL/SECAM L) [0573:4d03]
+ 19 -> Hauppauge WinTV USB (PAL D/K) [0573:4d04]
+ 20 -> Hauppauge WinTV USB (NTSC FM) [0573:4d10]
+ 21 -> Hauppauge WinTV USB (PAL B/G FM) [0573:4d11]
+ 22 -> Hauppauge WinTV USB (PAL I FM) [0573:4d12]
+ 23 -> Hauppauge WinTV USB (PAL D/K FM) [0573:4d14]
+ 24 -> Hauppauge WinTV USB Pro (NTSC M/N) [0573:4d2a]
+ 25 -> Hauppauge WinTV USB Pro (NTSC M/N) V2 [0573:4d2b]
+ 26 -> Hauppauge WinTV USB Pro (PAL/SECAM B/G/I/D/K/L) [0573:4d2c]
+ 27 -> Hauppauge WinTV USB Pro (NTSC M/N) V3 [0573:4d20]
+ 28 -> Hauppauge WinTV USB Pro (PAL B/G) [0573:4d21]
+ 29 -> Hauppauge WinTV USB Pro (PAL I) [0573:4d22]
+ 30 -> Hauppauge WinTV USB Pro (PAL/SECAM L) [0573:4d23]
+ 31 -> Hauppauge WinTV USB Pro (PAL D/K) [0573:4d24]
+ 32 -> Hauppauge WinTV USB Pro (PAL/SECAM BGDK/I/L) [0573:4d25]
+ 33 -> Hauppauge WinTV USB Pro (PAL/SECAM BGDK/I/L) V2 [0573:4d26]
+ 34 -> Hauppauge WinTV USB Pro (PAL B/G) V2 [0573:4d27]
+ 35 -> Hauppauge WinTV USB Pro (PAL B/G,D/K) [0573:4d28]
+ 36 -> Hauppauge WinTV USB Pro (PAL I,D/K) [0573:4d29]
+ 37 -> Hauppauge WinTV USB Pro (NTSC M/N FM) [0573:4d30]
+ 38 -> Hauppauge WinTV USB Pro (PAL B/G FM) [0573:4d31]
+ 39 -> Hauppauge WinTV USB Pro (PAL I FM) [0573:4d32]
+ 40 -> Hauppauge WinTV USB Pro (PAL D/K FM) [0573:4d34]
+ 41 -> Hauppauge WinTV USB Pro (Temic PAL/SECAM B/G/I/D/K/L FM) [0573:4d35]
+ 42 -> Hauppauge WinTV USB Pro (Temic PAL B/G FM) [0573:4d36]
+ 43 -> Hauppauge WinTV USB Pro (PAL/SECAM B/G/I/D/K/L FM) [0573:4d37]
+ 44 -> Hauppauge WinTV USB Pro (NTSC M/N FM) V2 [0573:4d38]
+ 45 -> Camtel Technology USB TV Genie Pro FM Model TVB330 [0768:0006]
+ 46 -> Digital Video Creator I [07d0:0001]
+ 47 -> Global Village GV-007 (NTSC) [07d0:0002]
+ 48 -> Dazzle Fusion Model DVC-50 Rev 1 (NTSC) [07d0:0003]
+ 49 -> Dazzle Fusion Model DVC-80 Rev 1 (PAL) [07d0:0004]
+ 50 -> Dazzle Fusion Model DVC-90 Rev 1 (SECAM) [07d0:0005]
+ 51 -> Eskape Labs MyTV2Go [07f8:9104]
+ 52 -> Pinnacle Studio PCTV USB (PAL) [2304:010d]
+ 53 -> Pinnacle Studio PCTV USB (SECAM) [2304:0109]
+ 54 -> Pinnacle Studio PCTV USB (PAL) FM [2304:0110]
+ 55 -> Miro PCTV USB [2304:0111]
+ 56 -> Pinnacle Studio PCTV USB (NTSC) FM [2304:0112]
+ 57 -> Pinnacle Studio PCTV USB (PAL) FM V2 [2304:0210]
+ 58 -> Pinnacle Studio PCTV USB (NTSC) FM V2 [2304:0212]
+ 59 -> Pinnacle Studio PCTV USB (PAL) FM V3 [2304:0214]
+ 60 -> Pinnacle Studio Linx Video input cable (NTSC) [2304:0300]
+ 61 -> Pinnacle Studio Linx Video input cable (PAL) [2304:0301]
+ 62 -> Pinnacle PCTV Bungee USB (PAL) FM [2304:0419]
+ 63 -> Hauppauge WinTv-USB [2400:4200]
diff --git a/linux/Documentation/video4linux/sn9c102.txt b/linux/Documentation/video4linux/sn9c102.txt
index 2913da3d0..279717c96 100644
--- a/linux/Documentation/video4linux/sn9c102.txt
+++ b/linux/Documentation/video4linux/sn9c102.txt
@@ -25,7 +25,7 @@ Index
1. Copyright
============
-Copyright (C) 2004-2006 by Luca Risolia <luca.risolia@studio.unibo.it>
+Copyright (C) 2004-2007 by Luca Risolia <luca.risolia@studio.unibo.it>
2. Disclaimer
@@ -216,10 +216,10 @@ Description: Debugging information level, from 0 to 3:
1 = critical errors
2 = significant informations
3 = more verbose messages
- Level 3 is useful for testing only, when only one device
- is used. It also shows some more informations about the
- hardware being detected. This parameter can be changed at
- runtime thanks to the /sys filesystem interface.
+ Level 3 is useful for testing only. It also shows some more
+ informations about the hardware being detected.
+ This parameter can be changed at runtime thanks to the /sys
+ filesystem interface.
Default: 2
-------------------------------------------------------------------------------
@@ -235,7 +235,7 @@ created in the /sys/class/video4linux/videoX directory. You can set the green
channel's gain by writing the desired value to it. The value may range from 0
to 15 for the SN9C101 or SN9C102 bridges, from 0 to 127 for the SN9C103,
SN9C105 and SN9C120 bridges.
-Similarly, only for the SN9C103, SN9C105 and SN9120 controllers, blue and red
+Similarly, only for the SN9C103, SN9C105 and SN9C120 controllers, blue and red
gain control files are available in the same directory, for which accepted
values may range from 0 to 127.
@@ -355,6 +355,9 @@ devices assembling the SN9C1xx PC camera controllers:
Vendor ID Product ID
--------- ----------
+0x0458 0x7025
+0x045e 0x00f5
+0x045e 0x00f7
0x0471 0x0327
0x0471 0x0328
0x0c45 0x6001
@@ -402,38 +405,49 @@ Vendor ID Product ID
0x0c45 0x60bc
0x0c45 0x60be
0x0c45 0x60c0
+0x0c45 0x60c2
0x0c45 0x60c8
0x0c45 0x60cc
0x0c45 0x60ea
0x0c45 0x60ec
+0x0c45 0x60ef
0x0c45 0x60fa
0x0c45 0x60fb
0x0c45 0x60fc
0x0c45 0x60fe
+0x0c45 0x6102
+0x0c45 0x6108
+0x0c45 0x610f
0x0c45 0x6130
+0x0c45 0x6138
0x0c45 0x613a
0x0c45 0x613b
0x0c45 0x613c
0x0c45 0x613e
The list above does not imply that all those devices work with this driver: up
-until now only the ones that assemble the following image sensors are
-supported; kernel messages will always tell you whether this is the case (see
-"Module loading" paragraph):
-
-Model Manufacturer
------ ------------
-HV7131D Hynix Semiconductor, Inc.
-MI-0343 Micron Technology, Inc.
-OV7630 OmniVision Technologies, Inc.
-OV7660 OmniVision Technologies, Inc.
-PAS106B PixArt Imaging, Inc.
-PAS202BCA PixArt Imaging, Inc.
-PAS202BCB PixArt Imaging, Inc.
-TAS5110C1B Taiwan Advanced Sensor Corporation
-TAS5130D1B Taiwan Advanced Sensor Corporation
-
-Some of the available control settings of each image sensor are supported
+until now only the ones that assemble the following pairs of SN9C1xx bridges
+and image sensors are supported; kernel messages will always tell you whether
+this is the case (see "Module loading" paragraph):
+
+Image sensor / SN9C1xx bridge | SN9C10[12] SN9C103 SN9C105 SN9C120
+-------------------------------------------------------------------------------
+HV7131D Hynix Semiconductor | Yes No No No
+HV7131R Hynix Semiconductor | No Yes Yes Yes
+MI-0343 Micron Technology | Yes No No No
+MI-0360 Micron Technology | No Yes Yes Yes
+OV7630 OmniVision Technologies | Yes Yes No No
+OV7660 OmniVision Technologies | No No Yes Yes
+PAS106B PixArt Imaging | Yes No No No
+PAS202B PixArt Imaging | Yes Yes No No
+TAS5110C1B Taiwan Advanced Sensor | Yes No No No
+TAS5110D Taiwan Advanced Sensor | Yes No No No
+TAS5130D1B Taiwan Advanced Sensor | Yes No No No
+
+"Yes" means that the pair is supported by the driver, while "No" means that the
+pair does not exist or is not supported by the driver.
+
+Only some of the available control settings of each image sensor are supported
through the V4L2 interface.
Donations of new models for further testing and support would be much
@@ -467,13 +481,12 @@ scaling factor is restored to 1.
This driver supports two different video formats: the first one is the "8-bit
Sequential Bayer" format and can be used to obtain uncompressed video data
from the device through the current I/O method, while the second one provides
-"raw" compressed video data (without frame headers not related to the
-compressed data). The compression quality may vary from 0 to 1 and can be
-selected or queried thanks to the VIDIOC_S_JPEGCOMP and VIDIOC_G_JPEGCOMP V4L2
-ioctl's. For maximum flexibility, both the default active video format and the
-default compression quality depend on how the image sensor being used is
-initialized (as described in the documentation of the API for the image sensors
-supplied by this driver).
+either "raw" compressed video data (without frame headers not related to the
+compressed data) or standard JPEG (with frame headers). The compression quality
+may vary from 0 to 1 and can be selected or queried thanks to the
+VIDIOC_S_JPEGCOMP and VIDIOC_G_JPEGCOMP V4L2 ioctl's. For maximum flexibility,
+both the default active video format and the default compression quality
+depend on how the image sensor being used is initialized.
11. Video frame formats [1]
@@ -482,8 +495,8 @@ The SN9C1xx PC Camera Controllers can send images in two possible video
formats over the USB: either native "Sequential RGB Bayer" or compressed.
The compression is used to achieve high frame rates. With regard to the
SN9C101, SN9C102 and SN9C103, the compression is based on the Huffman encoding
-algorithm described below, while the SN9C105 and SN9C120 the compression is
-based on the JPEG standard.
+algorithm described below, while with regard to the SN9C105 and SN9C120 the
+compression is based on the JPEG standard.
The current video format may be selected or queried from the user application
by calling the VIDIOC_S_FMT or VIDIOC_G_FMT ioctl's, as described in the V4L2
API specifications.
@@ -573,4 +586,5 @@ order):
- Mizuno Takafumi for the donation of a webcam;
- an "anonymous" donator (who didn't want his name to be revealed) for the
donation of a webcam.
-- an anonymous donator for the donation of four webcams.
+- an anonymous donator for the donation of four webcams and two boards with ten
+ image sensors.
diff --git a/linux/drivers/media/Kconfig b/linux/drivers/media/Kconfig
index 91d25798a..a852799f7 100644
--- a/linux/drivers/media/Kconfig
+++ b/linux/drivers/media/Kconfig
@@ -86,6 +86,14 @@ config VIDEO_TVEEPROM
tristate
depends on I2C
+config DAB
+ boolean "DAB adapters"
+ default y
+ ---help---
+ Allow selecting support for for Digital Audio Broadcasting (DAB)
+ Receiver adapters.
+
+if DAB
config USB_DABUSB
tristate "DABUSB driver"
depends on USB
@@ -99,5 +107,6 @@ config USB_DABUSB
To compile this driver as a module, choose M here: the
module will be called dabusb.
+endif # DAB
endmenu
diff --git a/linux/drivers/media/Makefile b/linux/drivers/media/Makefile
index c578a529e..8fa19939c 100644
--- a/linux/drivers/media/Makefile
+++ b/linux/drivers/media/Makefile
@@ -5,4 +5,4 @@
obj-y := common/
obj-$(CONFIG_VIDEO_DEV) += video/
obj-$(CONFIG_VIDEO_DEV) += radio/
-obj-$(CONFIG_DVB) += dvb/
+obj-$(CONFIG_DVB_CORE) += dvb/
diff --git a/linux/drivers/media/common/ir-keymaps.c b/linux/drivers/media/common/ir-keymaps.c
index 430314831..0f4d805f3 100644
--- a/linux/drivers/media/common/ir-keymaps.c
+++ b/linux/drivers/media/common/ir-keymaps.c
@@ -1789,7 +1789,7 @@ IR_KEYTAB_TYPE ir_codes_encore_enltv[IR_KEYTAB_SIZE] = {
EXPORT_SYMBOL_GPL(ir_codes_encore_enltv);
-/* for the Technotrend 1500 bundled remote: */
+/* for the Technotrend 1500 bundled remotes (grey and black): */
IR_KEYTAB_TYPE ir_codes_tt_1500[IR_KEYTAB_SIZE] = {
[ 0x01 ] = KEY_POWER,
[ 0x02 ] = KEY_SHUFFLE, /* ? double-arrow key */
@@ -1824,6 +1824,12 @@ IR_KEYTAB_TYPE ir_codes_tt_1500[IR_KEYTAB_SIZE] = {
[ 0x25 ] = KEY_VOLUMEUP,
[ 0x26 ] = KEY_VOLUMEDOWN,
[ 0x27 ] = KEY_SETUP,
+ [ 0x3a ] = KEY_RECORD, /* these keys are only in the black remote */
+ [ 0x3b ] = KEY_PLAY,
+ [ 0x3c ] = KEY_STOP,
+ [ 0x3d ] = KEY_REWIND,
+ [ 0x3e ] = KEY_PAUSE,
+ [ 0x3f ] = KEY_FORWARD,
};
EXPORT_SYMBOL_GPL(ir_codes_tt_1500);
diff --git a/linux/drivers/media/common/saa7146_core.c b/linux/drivers/media/common/saa7146_core.c
index b13f2ade3..06edb5fc1 100644
--- a/linux/drivers/media/common/saa7146_core.c
+++ b/linux/drivers/media/common/saa7146_core.c
@@ -136,28 +136,45 @@ char *saa7146_vmalloc_build_pgtable(struct pci_dev *pci, long length, struct saa
char *mem = vmalloc_32(length);
int slen = 0;
- if (NULL == mem) {
- return NULL;
- }
+ if (NULL == mem)
+ goto err_null;
- if (!(pt->slist = vmalloc_to_sg(mem, pages))) {
- vfree(mem);
- return NULL;
- }
+ if (!(pt->slist = vmalloc_to_sg(mem, pages)))
+ goto err_free_mem;
- if (saa7146_pgtable_alloc(pci, pt)) {
- kfree(pt->slist);
- pt->slist = NULL;
- vfree(mem);
- return NULL;
- }
+ if (saa7146_pgtable_alloc(pci, pt))
+ goto err_free_slist;
- slen = pci_map_sg(pci,pt->slist,pages,PCI_DMA_FROMDEVICE);
- if (0 != saa7146_pgtable_build_single(pci, pt, pt->slist, slen)) {
- return NULL;
- }
+ pt->nents = pages;
+ slen = pci_map_sg(pci,pt->slist,pt->nents,PCI_DMA_FROMDEVICE);
+ if (0 == slen)
+ goto err_free_pgtable;
+
+ if (0 != saa7146_pgtable_build_single(pci, pt, pt->slist, slen))
+ goto err_unmap_sg;
return mem;
+
+err_unmap_sg:
+ pci_unmap_sg(pci, pt->slist, pt->nents, PCI_DMA_FROMDEVICE);
+err_free_pgtable:
+ saa7146_pgtable_free(pci, pt);
+err_free_slist:
+ kfree(pt->slist);
+ pt->slist = NULL;
+err_free_mem:
+ vfree(mem);
+err_null:
+ return NULL;
+}
+
+void saa7146_vfree_destroy_pgtable(struct pci_dev *pci, char *mem, struct saa7146_pgtable *pt)
+{
+ pci_unmap_sg(pci, pt->slist, pt->nents, PCI_DMA_FROMDEVICE);
+ saa7146_pgtable_free(pci, pt);
+ kfree(pt->slist);
+ pt->slist = NULL;
+ vfree(mem);
}
void saa7146_pgtable_free(struct pci_dev *pci, struct saa7146_pgtable *pt)
@@ -166,8 +183,6 @@ void saa7146_pgtable_free(struct pci_dev *pci, struct saa7146_pgtable *pt)
return;
pci_free_consistent(pci, pt->size, pt->cpu, pt->dma);
pt->cpu = NULL;
- kfree(pt->slist);
- pt->slist = NULL;
}
int saa7146_pgtable_alloc(struct pci_dev *pci, struct saa7146_pgtable *pt)
@@ -532,6 +547,7 @@ EXPORT_SYMBOL_GPL(saa7146_pgtable_alloc);
EXPORT_SYMBOL_GPL(saa7146_pgtable_free);
EXPORT_SYMBOL_GPL(saa7146_pgtable_build_single);
EXPORT_SYMBOL_GPL(saa7146_vmalloc_build_pgtable);
+EXPORT_SYMBOL_GPL(saa7146_vfree_destroy_pgtable);
EXPORT_SYMBOL_GPL(saa7146_wait_for_debi_done);
EXPORT_SYMBOL_GPL(saa7146_setgpio);
diff --git a/linux/drivers/media/common/saa7146_fops.c b/linux/drivers/media/common/saa7146_fops.c
index 67d4d1a51..33257be76 100644
--- a/linux/drivers/media/common/saa7146_fops.c
+++ b/linux/drivers/media/common/saa7146_fops.c
@@ -308,7 +308,6 @@ static int fops_release(struct inode *inode, struct file *file)
return 0;
}
-int saa7146_video_do_ioctl(struct inode *inode, struct file *file, unsigned int cmd, void *arg);
static int fops_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
{
/*
diff --git a/linux/drivers/media/common/saa7146_video.c b/linux/drivers/media/common/saa7146_video.c
index 35288c4bc..d3537ff4f 100644
--- a/linux/drivers/media/common/saa7146_video.c
+++ b/linux/drivers/media/common/saa7146_video.c
@@ -1429,6 +1429,7 @@ static void video_close(struct saa7146_dev *dev, struct file *file)
{
struct saa7146_fh *fh = (struct saa7146_fh *)file->private_data;
struct saa7146_vv *vv = dev->vv_data;
+ struct videobuf_queue *q = &fh->video_q;
int err;
if (IS_CAPTURE_ACTIVE(fh) != 0) {
@@ -1437,6 +1438,11 @@ static void video_close(struct saa7146_dev *dev, struct file *file)
err = saa7146_stop_preview(fh);
}
+ // release all capture buffers
+ mutex_lock(&q->lock);
+ videobuf_read_stop(q);
+ mutex_unlock(&q->lock);
+
/* hmm, why is this function declared void? */
/* return err */
}
diff --git a/linux/drivers/media/dvb/Kconfig b/linux/drivers/media/dvb/Kconfig
index a97c8f5e9..efd2b7468 100644
--- a/linux/drivers/media/dvb/Kconfig
+++ b/linux/drivers/media/dvb/Kconfig
@@ -2,24 +2,16 @@
# Multimedia device configuration
#
-menu "Digital Video Broadcasting Devices"
+source "drivers/media/dvb/dvb-core/Kconfig"
-config DVB
- bool "DVB For Linux"
- depends on NET && INET
+menuconfig DVB_CAPTURE_DRIVERS
+ bool "DVB/ATSC adapters"
+ depends on DVB_CORE
+ default y
---help---
- Support Digital Video Broadcasting hardware. Enable this if you
- own a DVB adapter and want to use it or if you compile Linux for
- a digital SetTopBox.
-
- API specs and user tools are available from <http://www.linuxtv.org/>.
+ Say Y to select Digital TV adapters
- Please report problems regarding this driver to the LinuxDVB
- mailing list.
-
- If unsure say N.
-
-source "drivers/media/dvb/dvb-core/Kconfig"
+if DVB_CAPTURE_DRIVERS
comment "Supported SAA7146 based PCI Adapters"
depends on DVB_CORE && PCI && I2C
@@ -48,4 +40,4 @@ comment "Supported DVB Frontends"
depends on DVB_CORE
source "drivers/media/dvb/frontends/Kconfig"
-endmenu
+endif # DVB_CAPTURE_DRIVERS
diff --git a/linux/drivers/media/dvb/b2c2/flexcop-pci.c b/linux/drivers/media/dvb/b2c2/flexcop-pci.c
index 648f319b2..4388a78a1 100644
--- a/linux/drivers/media/dvb/b2c2/flexcop-pci.c
+++ b/linux/drivers/media/dvb/b2c2/flexcop-pci.c
@@ -143,10 +143,11 @@ static irqreturn_t flexcop_pci_isr(int irq, void *dev_id)
{
struct flexcop_pci *fc_pci = dev_id;
struct flexcop_device *fc = fc_pci->fc_dev;
+ unsigned long flags;
flexcop_ibi_value v;
irqreturn_t ret = IRQ_HANDLED;
- spin_lock_irq(&fc_pci->irq_lock);
+ spin_lock_irqsave(&fc_pci->irq_lock,flags);
v = fc->read_ibi_reg(fc,irq_20c);
@@ -210,7 +211,7 @@ static irqreturn_t flexcop_pci_isr(int irq, void *dev_id)
ret = IRQ_NONE;
}
- spin_unlock_irq(&fc_pci->irq_lock);
+ spin_unlock_irqrestore(&fc_pci->irq_lock,flags);
return ret;
}
@@ -309,12 +310,12 @@ static int flexcop_pci_init(struct flexcop_pci *fc_pci)
}
pci_set_drvdata(fc_pci->pdev, fc_pci);
-
+ spin_lock_init(&fc_pci->irq_lock);
if ((ret = request_irq(fc_pci->pdev->irq, flexcop_pci_isr,
IRQF_SHARED, DRIVER_NAME, fc_pci)) != 0)
goto err_pci_iounmap;
- spin_lock_init(&fc_pci->irq_lock);
+
fc_pci->init_state |= FC_PCI_INIT;
return ret;
diff --git a/linux/drivers/media/dvb/bt8xx/bt878.c b/linux/drivers/media/dvb/bt8xx/bt878.c
index 3a99cc594..1a75690f2 100644
--- a/linux/drivers/media/dvb/bt8xx/bt878.c
+++ b/linux/drivers/media/dvb/bt8xx/bt878.c
@@ -397,9 +397,7 @@ static struct cards card_list[] __devinitdata = {
{ 0xdb1118ac, BTTV_BOARD_DVICO_DVBT_LITE, "Ultraview DVB-T Lite" },
{ 0xd50018ac, BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE, "DViCO FusionHDTV 5 Lite" },
{ 0x20007063, BTTV_BOARD_PC_HDTV, "pcHDTV HD-2000 TV" },
- { 0x00261822, BTTV_BOARD_TWINHAN_DST, "DNTV Live! Mini" },
-
- { 0, -1, NULL }
+ { 0x00261822, BTTV_BOARD_TWINHAN_DST, "DNTV Live! Mini" }
};
diff --git a/linux/drivers/media/dvb/dvb-core/Kconfig b/linux/drivers/media/dvb/dvb-core/Kconfig
index 1990eda10..e3e6839f8 100644
--- a/linux/drivers/media/dvb/dvb-core/Kconfig
+++ b/linux/drivers/media/dvb/dvb-core/Kconfig
@@ -1,12 +1,22 @@
config DVB_CORE
- tristate "DVB Core Support"
- depends on DVB
+ tristate "DVB for Linux"
+ depends on NET && INET
select CRC32
help
+ Support Digital Video Broadcasting hardware. Enable this if you
+ own a DVB adapter and want to use it or if you compile Linux for
+ a digital SetTopBox.
+
DVB core utility functions for device handling, software fallbacks etc.
Say Y when you have a DVB card and want to use it. Say Y if your want
to build your drivers outside the kernel, but need the DVB core. All
in-kernel drivers will select this automatically if needed.
+
+ API specs and user tools are available from <http://www.linuxtv.org/>.
+
+ Please report problems regarding this driver to the LinuxDVB
+ mailing list.
+
If unsure say N.
config DVB_CORE_ATTACH
diff --git a/linux/drivers/media/dvb/dvb-core/dmxdev.c b/linux/drivers/media/dvb/dvb-core/dmxdev.c
index a5c0e1a3e..275df65fd 100644
--- a/linux/drivers/media/dvb/dvb-core/dmxdev.c
+++ b/linux/drivers/media/dvb/dvb-core/dmxdev.c
@@ -132,6 +132,11 @@ static int dvb_dvr_open(struct inode *inode, struct file *file)
if (mutex_lock_interruptible(&dmxdev->mutex))
return -ERESTARTSYS;
+ if (dmxdev->exit) {
+ mutex_unlock(&dmxdev->mutex);
+ return -ENODEV;
+ }
+
if ((file->f_flags & O_ACCMODE) == O_RDWR) {
if (!(dmxdev->capabilities & DMXDEV_CAP_DUPLEX)) {
mutex_unlock(&dmxdev->mutex);
@@ -171,6 +176,7 @@ static int dvb_dvr_open(struct inode *inode, struct file *file)
dmxdev->demux->disconnect_frontend(dmxdev->demux);
dmxdev->demux->connect_frontend(dmxdev->demux, front);
}
+ dvbdev->users++;
mutex_unlock(&dmxdev->mutex);
return 0;
}
@@ -198,7 +204,16 @@ static int dvb_dvr_release(struct inode *inode, struct file *file)
vfree(mem);
}
}
- mutex_unlock(&dmxdev->mutex);
+ /* TODO */
+ dvbdev->users--;
+ if(dvbdev->users==-1 && dmxdev->exit==1) {
+ fops_put(file->f_op);
+ file->f_op = NULL;
+ mutex_unlock(&dmxdev->mutex);
+ wake_up(&dvbdev->wait_queue);
+ } else
+ mutex_unlock(&dmxdev->mutex);
+
return 0;
}
@@ -215,6 +230,11 @@ static ssize_t dvb_dvr_write(struct file *file, const char __user *buf,
return -EINVAL;
if (mutex_lock_interruptible(&dmxdev->mutex))
return -ERESTARTSYS;
+
+ if (dmxdev->exit) {
+ mutex_unlock(&dmxdev->mutex);
+ return -ENODEV;
+ }
ret = dmxdev->demux->write(dmxdev->demux, buf, count);
mutex_unlock(&dmxdev->mutex);
return ret;
@@ -227,6 +247,11 @@ static ssize_t dvb_dvr_read(struct file *file, char __user *buf, size_t count,
struct dmxdev *dmxdev = dvbdev->priv;
int ret;
+ if (dmxdev->exit) {
+ mutex_unlock(&dmxdev->mutex);
+ return -ENODEV;
+ }
+
//mutex_lock(&dmxdev->mutex);
ret = dvb_dmxdev_buffer_read(&dmxdev->dvr_buffer,
file->f_flags & O_NONBLOCK,
@@ -665,6 +690,8 @@ static int dvb_demux_open(struct inode *inode, struct file *file)
dmxdevfilter->feed.ts = NULL;
init_timer(&dmxdevfilter->timer);
+ dvbdev->users++;
+
mutex_unlock(&dmxdev->mutex);
return 0;
}
@@ -943,7 +970,21 @@ static int dvb_demux_release(struct inode *inode, struct file *file)
struct dmxdev_filter *dmxdevfilter = file->private_data;
struct dmxdev *dmxdev = dmxdevfilter->dev;
- return dvb_dmxdev_filter_free(dmxdev, dmxdevfilter);
+ int ret;
+
+ ret = dvb_dmxdev_filter_free(dmxdev, dmxdevfilter);
+
+ mutex_lock(&dmxdev->mutex);
+ dmxdev->dvbdev->users--;
+ if(dmxdev->dvbdev->users==1 && dmxdev->exit==1) {
+ fops_put(file->f_op);
+ file->f_op = NULL;
+ mutex_unlock(&dmxdev->mutex);
+ wake_up(&dmxdev->dvbdev->wait_queue);
+ } else
+ mutex_unlock(&dmxdev->mutex);
+
+ return ret;
}
static struct file_operations dvb_demux_fops = {
@@ -1027,6 +1068,7 @@ static struct file_operations dvb_dvr_fops = {
static struct dvb_device dvbdev_dvr = {
.priv = NULL,
.readers = 1,
+ .users = 1,
.fops = &dvb_dvr_fops
};
@@ -1064,6 +1106,16 @@ EXPORT_SYMBOL(dvb_dmxdev_init);
void dvb_dmxdev_release(struct dmxdev *dmxdev)
{
+ dmxdev->exit=1;
+ if (dmxdev->dvbdev->users > 1) {
+ wait_event(dmxdev->dvbdev->wait_queue,
+ dmxdev->dvbdev->users==1);
+ }
+ if (dmxdev->dvr_dvbdev->users > 1) {
+ wait_event(dmxdev->dvr_dvbdev->wait_queue,
+ dmxdev->dvr_dvbdev->users==1);
+ }
+
dvb_unregister_device(dmxdev->dvbdev);
dvb_unregister_device(dmxdev->dvr_dvbdev);
diff --git a/linux/drivers/media/dvb/dvb-core/dmxdev.h b/linux/drivers/media/dvb/dvb-core/dmxdev.h
index 080abd9a9..bb416e6c2 100644
--- a/linux/drivers/media/dvb/dvb-core/dmxdev.h
+++ b/linux/drivers/media/dvb/dvb-core/dmxdev.h
@@ -98,6 +98,8 @@ struct dmxdev {
int filternum;
int capabilities;
+
+ unsigned int exit:1;
#define DMXDEV_CAP_DUPLEX 1
struct dmx_frontend *dvr_orig_fe;
diff --git a/linux/drivers/media/dvb/dvb-core/dvb_frontend.c b/linux/drivers/media/dvb/dvb-core/dvb_frontend.c
index 60c8b0da2..2cad44fb2 100644
--- a/linux/drivers/media/dvb/dvb-core/dvb_frontend.c
+++ b/linux/drivers/media/dvb/dvb-core/dvb_frontend.c
@@ -611,6 +611,7 @@ static void dvb_frontend_stop(struct dvb_frontend *fe)
return;
kthread_stop(fepriv->thread);
+
init_MUTEX (&fepriv->sem);
fepriv->state = FESTATE_IDLE;
@@ -1028,6 +1029,7 @@ static int dvb_frontend_release(struct inode *inode, struct file *file)
struct dvb_device *dvbdev = file->private_data;
struct dvb_frontend *fe = dvbdev->priv;
struct dvb_frontend_private *fepriv = fe->frontend_priv;
+ int ret;
dprintk ("%s\n", __FUNCTION__);
@@ -1037,7 +1039,14 @@ static int dvb_frontend_release(struct inode *inode, struct file *file)
if (fe->ops.ts_bus_ctrl)
fe->ops.ts_bus_ctrl (fe, 0);
- return dvb_generic_release (inode, file);
+ ret = dvb_generic_release (inode, file);
+
+ if (dvbdev->users==-1 && fepriv->exit==1) {
+ fops_put(file->f_op);
+ file->f_op = NULL;
+ wake_up(&dvbdev->wait_queue);
+ }
+ return ret;
}
static struct file_operations dvb_frontend_fops = {
@@ -1097,8 +1106,15 @@ int dvb_unregister_frontend(struct dvb_frontend* fe)
dprintk ("%s\n", __FUNCTION__);
mutex_lock(&frontend_mutex);
- dvb_unregister_device (fepriv->dvbdev);
dvb_frontend_stop (fe);
+ mutex_unlock(&frontend_mutex);
+
+ if (fepriv->dvbdev->users < -1)
+ wait_event(fepriv->dvbdev->wait_queue,
+ fepriv->dvbdev->users==-1);
+
+ mutex_lock(&frontend_mutex);
+ dvb_unregister_device (fepriv->dvbdev);
/* fe is invalid now */
kfree(fepriv);
diff --git a/linux/drivers/media/dvb/dvb-core/dvb_net.c b/linux/drivers/media/dvb/dvb-core/dvb_net.c
index 3e94e6cf9..7089412e3 100644
--- a/linux/drivers/media/dvb/dvb-core/dvb_net.c
+++ b/linux/drivers/media/dvb/dvb-core/dvb_net.c
@@ -1476,11 +1476,36 @@ static int dvb_net_ioctl(struct inode *inode, struct file *file,
return dvb_usercopy(inode, file, cmd, arg, dvb_net_do_ioctl);
}
+static int dvb_net_close(struct inode *inode, struct file *file)
+{
+ struct dvb_device *dvbdev = file->private_data;
+ struct dvb_net *dvbnet = dvbdev->priv;
+
+ if (!dvbdev)
+ return -ENODEV;
+
+ if ((file->f_flags & O_ACCMODE) == O_RDONLY) {
+ dvbdev->readers++;
+ } else {
+ dvbdev->writers++;
+ }
+
+ dvbdev->users++;
+
+ if(dvbdev->users == 1 && dvbnet->exit==1) {
+ fops_put(file->f_op);
+ file->f_op = NULL;
+ wake_up(&dvbdev->wait_queue);
+ }
+ return 0;
+}
+
+
static struct file_operations dvb_net_fops = {
.owner = THIS_MODULE,
.ioctl = dvb_net_ioctl,
.open = dvb_generic_open,
- .release = dvb_generic_release,
+ .release = dvb_net_close,
};
static struct dvb_device dvbdev_net = {
@@ -1495,6 +1520,11 @@ void dvb_net_release (struct dvb_net *dvbnet)
{
int i;
+ dvbnet->exit = 1;
+ if (dvbnet->dvbdev->users < 1)
+ wait_event(dvbnet->dvbdev->wait_queue,
+ dvbnet->dvbdev->users==1);
+
dvb_unregister_device(dvbnet->dvbdev);
for (i=0; i<DVB_NET_DEVICES_MAX; i++) {
diff --git a/linux/drivers/media/dvb/dvb-core/dvb_net.h b/linux/drivers/media/dvb/dvb-core/dvb_net.h
index f14e4ca38..3a3126cae 100644
--- a/linux/drivers/media/dvb/dvb-core/dvb_net.h
+++ b/linux/drivers/media/dvb/dvb-core/dvb_net.h
@@ -36,6 +36,7 @@ struct dvb_net {
struct dvb_device *dvbdev;
struct net_device *device[DVB_NET_DEVICES_MAX];
int state[DVB_NET_DEVICES_MAX];
+ unsigned int exit:1;
struct dmx_demux *demux;
};
diff --git a/linux/drivers/media/dvb/dvb-core/dvbdev.c b/linux/drivers/media/dvb/dvb-core/dvbdev.c
index 9c8e9c3f4..17104fb4b 100644
--- a/linux/drivers/media/dvb/dvb-core/dvbdev.c
+++ b/linux/drivers/media/dvb/dvb-core/dvbdev.c
@@ -244,6 +244,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
dvbdev->adapter = adap;
dvbdev->priv = priv;
dvbdev->fops = dvbdevfops;
+ init_waitqueue_head (&dvbdev->wait_queue);
memcpy(dvbdev->fops, template->fops, sizeof(struct file_operations));
dvbdev->fops->owner = adap->module;
diff --git a/linux/drivers/media/dvb/dvb-core/dvbdev.h b/linux/drivers/media/dvb/dvb-core/dvbdev.h
index 26e4a9135..cb76869bd 100644
--- a/linux/drivers/media/dvb/dvb-core/dvbdev.h
+++ b/linux/drivers/media/dvb/dvb-core/dvbdev.h
@@ -70,6 +70,7 @@ struct dvb_device {
int writers;
int users;
+ wait_queue_head_t wait_queue;
/* don't really need those !? -- FIXME: use video_usercopy */
int (*kernel_ioctl)(struct inode *inode, struct file *file,
unsigned int cmd, void *arg);
diff --git a/linux/drivers/media/dvb/dvb-usb/Kconfig b/linux/drivers/media/dvb/dvb-usb/Kconfig
index 8aa12722c..54488737a 100644
--- a/linux/drivers/media/dvb/dvb-usb/Kconfig
+++ b/linux/drivers/media/dvb/dvb-usb/Kconfig
@@ -211,3 +211,10 @@ config DVB_USB_DTT200U
The receivers are also known as DTT200U (Yakumo) and UB300 (Yuan).
The WT-220U and its clones are pen-sized.
+
+config DVB_USB_OPERA1
+ tristate "Opera1 DVB-S USB2.0 receiver"
+ depends on DVB_USB
+ select DVB_STV0299 if !DVB_FE_CUSTOMISE
+ help
+ Say Y here to support the Opera DVB-S USB2.0 receiver.
diff --git a/linux/drivers/media/dvb/dvb-usb/Makefile b/linux/drivers/media/dvb/dvb-usb/Makefile
index 40f28f559..976f840cc 100644
--- a/linux/drivers/media/dvb/dvb-usb/Makefile
+++ b/linux/drivers/media/dvb/dvb-usb/Makefile
@@ -51,4 +51,8 @@ obj-$(CONFIG_DVB_USB_TTUSB2) += dvb-usb-ttusb2.o
dvb-usb-dib0700-objs = dib0700_core.o dib0700_devices.o
obj-$(CONFIG_DVB_USB_DIB0700) += dvb-usb-dib0700.o
+dvb-usb-opera-objs = opera1.o
+obj-$(CONFIG_DVB_USB_OPERA1) += dvb-usb-opera.o
+
+
EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/
diff --git a/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
index 9b762a7f2..403081689 100644
--- a/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
+++ b/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
@@ -33,6 +33,7 @@
#define USB_VID_LITEON 0x04ca
#define USB_VID_MEDION 0x1660
#define USB_VID_MSI 0x0db0
+#define USB_VID_OPERA1 0x695c
#define USB_VID_PINNACLE 0x2304
#define USB_VID_VISIONPLUS 0x13d3
#define USB_VID_TWINHAN 0x1822
@@ -145,6 +146,8 @@
#define USB_PID_GENPIX_8PSK_WARM 0x0201
#define USB_PID_SIGMATEK_DVB_110 0x6610
#define USB_PID_MSI_DIGI_VOX_MINI_II 0x1513
+#define USB_PID_OPERA1_COLD 0x2830
+#define USB_PID_OPERA1_WARM 0x3829
#define USB_PID_LIFEVIEW_TV_WALKER_TWIN_COLD 0x0514
#define USB_PID_LIFEVIEW_TV_WALKER_TWIN_WARM 0x0513
diff --git a/linux/drivers/media/dvb/dvb-usb/dvb-usb-remote.c b/linux/drivers/media/dvb/dvb-usb/dvb-usb-remote.c
index cccc2512a..9d5f1bc1e 100644
--- a/linux/drivers/media/dvb/dvb-usb/dvb-usb-remote.c
+++ b/linux/drivers/media/dvb/dvb-usb/dvb-usb-remote.c
@@ -121,8 +121,6 @@ int dvb_usb_remote_init(struct dvb_usb_device *d)
return -ENOMEM;
input_dev->evbit[0] = BIT(EV_KEY);
- input_dev->keycodesize = sizeof(unsigned char);
- input_dev->keycodemax = KEY_MAX;
input_dev->name = "IR-receiver inside an USB DVB receiver";
input_dev->phys = d->rc_phys;
usb_to_input_id(d->udev, &input_dev->id);
diff --git a/linux/drivers/media/dvb/dvb-usb/opera1.c b/linux/drivers/media/dvb/dvb-usb/opera1.c
new file mode 100644
index 000000000..dda7a44bf
--- /dev/null
+++ b/linux/drivers/media/dvb/dvb-usb/opera1.c
@@ -0,0 +1,595 @@
+/* DVB USB framework compliant Linux driver for the Opera1 DVB-S Card
+*
+* Copyright (C) 2006 Mario Hlawitschka (dh1pa@amsat.org)
+* Copyright (C) 2006 Marco Gittler (g.marco@freenet.de)
+*
+* This program is free software; you can redistribute it and/or modify it
+* under the terms of the GNU General Public License as published by the Free
+* Software Foundation, version 2.
+*
+* see Documentation/dvb/README.dvb-usb for more information
+*/
+
+#include "opera1.h"
+#include "stv0299.h"
+
+#define OPERA_READ_MSG 0
+#define OPERA_WRITE_MSG 1
+#define OPERA_I2C_TUNER 0xd1
+
+#define READ_FX2_REG_REQ 0xba
+#define READ_MAC_ADDR 0x08
+#define OPERA_WRITE_FX2 0xbb
+#define OPERA_TUNER_REQ 0xb1
+#define REG_1F_SYMBOLRATE_BYTE0 0x1f
+#define REG_20_SYMBOLRATE_BYTE1 0x20
+#define REG_21_SYMBOLRATE_BYTE2 0x21
+
+#define ADDR_B600_VOLTAGE_13V (0x02)
+#define ADDR_B601_VOLTAGE_18V (0x03)
+#define ADDR_B1A6_STREAM_CTRL (0x04)
+#define ADDR_B880_READ_REMOTE (0x05)
+
+struct opera1_state {
+ u32 last_key_pressed;
+};
+struct opera_rc_keys {
+ u32 keycode;
+ u32 event;
+};
+
+int dvb_usb_opera1_debug;
+module_param_named(debug, dvb_usb_opera1_debug, int, 0644);
+MODULE_PARM_DESC(debug,
+ "set debugging level (1=info,xfer=2,pll=4,ts=8,err=16,rc=32,fw=64 (or-able))."
+ DVB_USB_DEBUG_STATUS);
+#if 0
+struct mutex mymutex;
+#endif
+
+static int opera1_xilinx_rw(struct usb_device *dev, u8 request, u16 value,
+ u8 * data, u16 len, int flags)
+{
+ int ret;
+ u8 r;
+ u8 u8buf[len];
+
+ unsigned int pipe = (flags == OPERA_READ_MSG) ?
+ usb_rcvctrlpipe(dev,0) : usb_sndctrlpipe(dev, 0);
+ u8 request_type = (flags == OPERA_READ_MSG) ? USB_DIR_IN : USB_DIR_OUT;
+
+#if 0
+ if (mutex_lock_interruptible(&mymutex)) {
+ return -EAGAIN;
+ }
+#endif
+ if (flags == OPERA_WRITE_MSG)
+ memcpy(u8buf, data, len);
+ ret =
+ usb_control_msg(dev, pipe, request, request_type | USB_TYPE_VENDOR,
+ value, 0x0, u8buf, len, 2000);
+
+ if (request == OPERA_TUNER_REQ) {
+ if (usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
+ OPERA_TUNER_REQ, USB_DIR_IN | USB_TYPE_VENDOR,
+ 0x01, 0x0, &r, 1, 2000)<1 || r!=0x08)
+ return 0;
+ }
+ if (flags == OPERA_READ_MSG)
+ memcpy(data, u8buf, len);
+#if 0
+ mutex_unlock(&mymutex);
+#endif
+ return ret;
+}
+
+/* I2C */
+
+static int opera1_usb_i2c_msgxfer(struct dvb_usb_device *dev, u16 addr,
+ u8 * buf, u16 len)
+{
+ int ret = 0;
+ u8 request;
+ u16 value;
+
+ if (!dev) {
+ info("no usb_device");
+ return -EINVAL;
+ }
+ if (mutex_lock_interruptible(&dev->usb_mutex) < 0)
+ return -EAGAIN;
+
+ switch (addr>>1){
+ case ADDR_B600_VOLTAGE_13V:
+ request=0xb6;
+ value=0x00;
+ break;
+ case ADDR_B601_VOLTAGE_18V:
+ request=0xb6;
+ value=0x01;
+ break;
+ case ADDR_B1A6_STREAM_CTRL:
+ request=0xb1;
+ value=0xa6;
+ break;
+ case ADDR_B880_READ_REMOTE:
+ request=0xb8;
+ value=0x80;
+ break;
+ default:
+ request=0xb1;
+ value=addr;
+ }
+ ret = opera1_xilinx_rw(dev->udev, request,
+ value, buf, len,
+ addr&0x01?OPERA_READ_MSG:OPERA_WRITE_MSG);
+
+ mutex_unlock(&dev->usb_mutex);
+ return ret;
+}
+
+static int opera1_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
+ int num)
+{
+ struct dvb_usb_device *d = i2c_get_adapdata(adap);
+ int i = 0, tmp = 0;
+
+ if (!d)
+ return -ENODEV;
+ if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
+ return -EAGAIN;
+
+ for (i = 0; i < num; i++) {
+ if ((tmp = opera1_usb_i2c_msgxfer(d,
+ (msg[i].addr<<1)|(msg[i].flags&I2C_M_RD?0x01:0),
+ msg[i].buf,
+ msg[i].len
+ )!= msg[i].len)) {
+ break;
+ }
+ if (dvb_usb_opera1_debug & 0x10)
+ info("sending i2c mesage %d %d", tmp, msg[i].len);
+ }
+ mutex_unlock(&d->i2c_mutex);
+ return num;
+}
+
+static u32 opera1_i2c_func(struct i2c_adapter *adapter)
+{
+ return I2C_FUNC_I2C;
+}
+
+static struct i2c_algorithm opera1_i2c_algo = {
+ .master_xfer = opera1_i2c_xfer,
+ .functionality = opera1_i2c_func,
+};
+
+static int opera1_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
+{
+ static u8 command_13v[1]={0x00};
+ static u8 command_18v[1]={0x01};
+ struct i2c_msg msg[] = {
+ {.addr = ADDR_B600_VOLTAGE_13V,.flags = 0,.buf = command_13v,.len = 1},
+ };
+ struct dvb_usb_adapter *udev_adap =
+ (struct dvb_usb_adapter *)(fe->dvb->priv);
+ if (voltage == SEC_VOLTAGE_18) {
+ msg[0].addr = ADDR_B601_VOLTAGE_18V;
+ msg[0].buf = command_18v;
+ }
+ i2c_transfer(&udev_adap->dev->i2c_adap, msg, 1);
+ return 0;
+}
+
+static int opera1_stv0299_set_symbol_rate(struct dvb_frontend *fe, u32 srate,
+ u32 ratio)
+{
+ stv0299_writereg(fe, 0x13, 0x98);
+ stv0299_writereg(fe, 0x14, 0x95);
+ stv0299_writereg(fe, REG_1F_SYMBOLRATE_BYTE0, (ratio >> 16) & 0xff);
+ stv0299_writereg(fe, REG_20_SYMBOLRATE_BYTE1, (ratio >> 8) & 0xff);
+ stv0299_writereg(fe, REG_21_SYMBOLRATE_BYTE2, (ratio) & 0xf0);
+ return 0;
+
+}
+static u8 opera1_inittab[] = {
+ 0x00, 0xa1,
+ 0x01, 0x15,
+ 0x02, 0x00,
+ 0x03, 0x00,
+ 0x04, 0x7d,
+ 0x05, 0x05,
+ 0x06, 0x02,
+ 0x07, 0x00,
+ 0x0b, 0x00,
+ 0x0c, 0x01,
+ 0x0d, 0x81,
+ 0x0e, 0x44,
+ 0x0f, 0x19,
+ 0x10, 0x3f,
+ 0x11, 0x84,
+ 0x12, 0xda,
+ 0x13, 0x98,
+ 0x14, 0x95,
+ 0x15, 0xc9,
+ 0x16, 0xeb,
+ 0x17, 0x00,
+ 0x18, 0x19,
+ 0x19, 0x8b,
+ 0x1a, 0x00,
+ 0x1b, 0x82,
+ 0x1c, 0x7f,
+ 0x1d, 0x00,
+ 0x1e, 0x00,
+ REG_1F_SYMBOLRATE_BYTE0, 0x06,
+ REG_20_SYMBOLRATE_BYTE1, 0x50,
+ REG_21_SYMBOLRATE_BYTE2, 0x10,
+ 0x22, 0x00,
+ 0x23, 0x00,
+ 0x24, 0x37,
+ 0x25, 0xbc,
+ 0x26, 0x00,
+ 0x27, 0x00,
+ 0x28, 0x00,
+ 0x29, 0x1e,
+ 0x2a, 0x14,
+ 0x2b, 0x1f,
+ 0x2c, 0x09,
+ 0x2d, 0x0a,
+ 0x2e, 0x00,
+ 0x2f, 0x00,
+ 0x30, 0x00,
+ 0x31, 0x1f,
+ 0x32, 0x19,
+ 0x33, 0xfc,
+ 0x34, 0x13,
+ 0xff, 0xff,
+};
+
+static struct stv0299_config opera1_stv0299_config = {
+ .demod_address = 0xd0>>1,
+ .min_delay_ms = 100,
+ .mclk = 88000000UL,
+ .invert = 1,
+ .skip_reinit = 0,
+ .lock_output = STV0229_LOCKOUTPUT_0,
+ .volt13_op0_op1 = STV0299_VOLT13_OP0,
+ .inittab = opera1_inittab,
+ .set_symbol_rate = opera1_stv0299_set_symbol_rate,
+};
+
+static int opera1_frontend_attach(struct dvb_usb_adapter *d)
+{
+ if ((d->fe =
+ dvb_attach(stv0299_attach, &opera1_stv0299_config,
+ &d->dev->i2c_adap)) != NULL) {
+ d->fe->ops.set_voltage = opera1_set_voltage;
+ return 0;
+ }
+ info("not attached stv0299");
+ return -EIO;
+}
+
+static int opera1_tuner_attach(struct dvb_usb_adapter *adap)
+{
+ dvb_attach(
+ dvb_pll_attach, adap->fe, 0xc0>>1,
+ &adap->dev->i2c_adap, &dvb_pll_opera1
+ );
+ return 0;
+}
+
+static int opera1_power_ctrl(struct dvb_usb_device *d, int onoff)
+{
+ u8 val = onoff ? 0x01 : 0x00;
+
+ if (dvb_usb_opera1_debug)
+ info("power %s", onoff ? "on" : "off");
+ return opera1_xilinx_rw(d->udev, 0xb7, val,
+ &val, 1, OPERA_WRITE_MSG);
+}
+
+static int opera1_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
+{
+ static u8 buf_start[2] = { 0xff, 0x03 };
+ static u8 buf_stop[2] = { 0xff, 0x00 };
+ struct i2c_msg start_tuner[] = {
+ {.addr = ADDR_B1A6_STREAM_CTRL,.buf = onoff ? buf_start : buf_stop,.len = 2},
+ };
+ if (dvb_usb_opera1_debug)
+ info("streaming %s", onoff ? "on" : "off");
+ i2c_transfer(&adap->dev->i2c_adap, start_tuner, 1);
+ return 0;
+}
+
+static int opera1_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid,
+ int onoff)
+{
+ u8 b_pid[3];
+ struct i2c_msg msg[] = {
+ {.addr = ADDR_B1A6_STREAM_CTRL,.buf = b_pid,.len = 3},
+ };
+ if (dvb_usb_opera1_debug)
+ info("pidfilter index: %d pid: %d %s", index, pid,
+ onoff ? "on" : "off");
+ b_pid[0] = (2 * index) + 4;
+ b_pid[1] = onoff ? (pid & 0xff) : (0x00);
+ b_pid[2] = onoff ? ((pid >> 8) & 0xff) : (0x00);
+ i2c_transfer(&adap->dev->i2c_adap, msg, 1);
+ return 0;
+}
+
+static int opera1_pid_filter_control(struct dvb_usb_adapter *adap, int onoff)
+{
+ int u = 0x04;
+ u8 b_pid[3];
+ struct i2c_msg msg[] = {
+ {.addr = ADDR_B1A6_STREAM_CTRL,.buf = b_pid,.len = 3},
+ };
+ if (dvb_usb_opera1_debug)
+ info("%s hw-pidfilter", onoff ? "enable" : "disable");
+ for (; u < 0x7e; u += 2) {
+ b_pid[0] = u;
+ b_pid[1] = 0;
+ b_pid[2] = 0x80;
+ i2c_transfer(&adap->dev->i2c_adap, msg, 1);
+ }
+ return 0;
+}
+
+static struct dvb_usb_rc_key opera1_rc_keys[] = {
+ {0x5f, 0xa0, KEY_1},
+ {0x51, 0xaf, KEY_2},
+ {0x5d, 0xa2, KEY_3},
+ {0x41, 0xbe, KEY_4},
+ {0x0b, 0xf5, KEY_5},
+ {0x43, 0xbd, KEY_6},
+ {0x47, 0xb8, KEY_7},
+ {0x49, 0xb6, KEY_8},
+ {0x05, 0xfa, KEY_9},
+ {0x45, 0xba, KEY_0},
+ {0x09, 0xf6, KEY_UP}, /*chanup */
+ {0x1b, 0xe5, KEY_DOWN}, /*chandown */
+ {0x5d, 0xa3, KEY_LEFT}, /*voldown */
+ {0x5f, 0xa1, KEY_RIGHT}, /*volup */
+ {0x07, 0xf8, KEY_SPACE}, /*tab */
+ {0x1f, 0xe1, KEY_ENTER}, /*play ok */
+ {0x1b, 0xe4, KEY_Z}, /*zoom */
+ {0x59, 0xa6, KEY_M}, /*mute */
+ {0x5b, 0xa5, KEY_F}, /*tv/f */
+ {0x19, 0xe7, KEY_R}, /*rec */
+ {0x01, 0xfe, KEY_S}, /*Stop */
+ {0x03, 0xfd, KEY_P}, /*pause */
+ {0x03, 0xfc, KEY_W}, /*<- -> */
+ {0x07, 0xf9, KEY_C}, /*capture */
+ {0x47, 0xb9, KEY_Q}, /*exit */
+ {0x43, 0xbc, KEY_O}, /*power */
+
+};
+
+static int opera1_rc_query(struct dvb_usb_device *dev, u32 * event, int *state)
+{
+ struct opera1_state *opst = dev->priv;
+ u8 rcbuffer[32];
+ const u16 startmarker1 = 0x10ed;
+ const u16 startmarker2 = 0x11ec;
+ struct i2c_msg read_remote[] = {
+ {.addr = ADDR_B880_READ_REMOTE,.buf = rcbuffer,.flags = I2C_M_RD,.len = 32},
+ };
+ int i = 0;
+ u32 send_key = 0;
+
+ if (i2c_transfer(&dev->i2c_adap, read_remote, 1) == 1) {
+ for (i = 0; i < 32; i++) {
+ if (rcbuffer[i])
+ send_key |= 1;
+ if (i < 31)
+ send_key = send_key << 1;
+ }
+ if (send_key & 0x8000)
+ send_key = (send_key << 1) | (send_key >> 15 & 0x01);
+
+ if (send_key == 0xffff && opst->last_key_pressed != 0) {
+ *state = REMOTE_KEY_REPEAT;
+ *event = opst->last_key_pressed;
+ return 0;
+ }
+ for (; send_key != 0;) {
+ if (send_key >> 16 == startmarker2) {
+ break;
+ } else if (send_key >> 16 == startmarker1) {
+ send_key =
+ (send_key & 0xfffeffff) | (startmarker1 << 16);
+ break;
+ } else
+ send_key >>= 1;
+ }
+
+ if (send_key == 0)
+ return 0;
+
+ send_key = (send_key & 0xffff) | 0x0100;
+
+ for (i = 0; i < ARRAY_SIZE(opera1_rc_keys); i++) {
+ if ((opera1_rc_keys[i].custom * 256 +
+ opera1_rc_keys[i].data) == (send_key & 0xffff)) {
+ *state = REMOTE_KEY_PRESSED;
+ *event = opera1_rc_keys[i].event;
+ opst->last_key_pressed =
+ opera1_rc_keys[i].event;
+ break;
+ }
+ opst->last_key_pressed = 0;
+ }
+ } else
+ *state = REMOTE_NO_KEY_PRESSED;
+ return 0;
+}
+
+static struct usb_device_id opera1_table[] = {
+ {USB_DEVICE(USB_VID_CYPRESS, USB_PID_OPERA1_COLD)},
+ {USB_DEVICE(USB_VID_OPERA1, USB_PID_OPERA1_WARM)},
+ {}
+};
+
+MODULE_DEVICE_TABLE(usb, opera1_table);
+
+static int opera1_read_mac_address(struct dvb_usb_device *d, u8 mac[6])
+{
+ u8 command[] = { READ_MAC_ADDR };
+ opera1_xilinx_rw(d->udev, 0xb1, 0xa0, command, 1, OPERA_WRITE_MSG);
+ opera1_xilinx_rw(d->udev, 0xb1, 0xa1, mac, 6, OPERA_READ_MSG);
+ return 0;
+}
+static int opera1_xilinx_load_firmware(struct usb_device *dev,
+ const char *filename)
+{
+ const struct firmware *fw = NULL;
+ u8 *b, *p;
+ int ret = 0, i;
+ u8 testval;
+ info("start downloading fpga firmware");
+
+ if ((ret = request_firmware(&fw, filename, &dev->dev)) != 0) {
+ err("did not find the firmware file. (%s) "
+ "Please see linux/Documentation/dvb/ for more details on firmware-problems.",
+ filename);
+ return ret;
+ } else {
+ p = kmalloc(fw->size, GFP_KERNEL);
+ opera1_xilinx_rw(dev, 0xbc, 0x00, &testval, 1, OPERA_READ_MSG);
+ if (p != NULL && testval != 0x67) {
+
+ u8 reset = 0, fpga_command = 0;
+ memcpy(p, fw->data, fw->size);
+ /* clear fpga ? */
+ opera1_xilinx_rw(dev, 0xbc, 0xaa, &fpga_command, 1,
+ OPERA_WRITE_MSG);
+ for (i = 0; p[i] != 0 && i < fw->size;) {
+ b = (u8 *) p + i;
+ if (opera1_xilinx_rw
+ (dev, OPERA_WRITE_FX2, 0x0, b + 1, b[0],
+ OPERA_WRITE_MSG) != b[0]
+ ) {
+ err("error while transferring firmware");
+ ret = -EINVAL;
+ break;
+ }
+ i = i + 1 + b[0];
+ }
+ /* restart the CPU */
+ if (ret || opera1_xilinx_rw
+ (dev, 0xa0, 0xe600, &reset, 1,
+ OPERA_WRITE_MSG) != 1) {
+ err("could not restart the USB controller CPU.");
+ ret = -EINVAL;
+ }
+ kfree(p);
+ }
+ }
+ if (fw) {
+ release_firmware(fw);
+ }
+ return ret;
+}
+
+static struct dvb_usb_device_properties opera1_properties = {
+ .caps = DVB_USB_IS_AN_I2C_ADAPTER,
+ .usb_ctrl = CYPRESS_FX2,
+ .firmware = "dvb-usb-opera-01.fw",
+ .size_of_priv = sizeof(struct opera1_state),
+
+ .power_ctrl = opera1_power_ctrl,
+ .i2c_algo = &opera1_i2c_algo,
+
+ .rc_key_map = opera1_rc_keys,
+ .rc_key_map_size = ARRAY_SIZE(opera1_rc_keys),
+ .rc_interval = 200,
+ .rc_query = opera1_rc_query,
+ .read_mac_address = opera1_read_mac_address,
+ .generic_bulk_ctrl_endpoint = 0x00,
+ /* parameter for the MPEG2-data transfer */
+ .num_adapters = 1,
+ .adapter = {
+ {
+ .frontend_attach = opera1_frontend_attach,
+ .streaming_ctrl = opera1_streaming_ctrl,
+ .tuner_attach = opera1_tuner_attach,
+ .caps =
+ DVB_USB_ADAP_HAS_PID_FILTER |
+ DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+ .pid_filter = opera1_pid_filter,
+ .pid_filter_ctrl = opera1_pid_filter_control,
+ .pid_filter_count = 252,
+ .stream = {
+ .type = USB_BULK,
+ .count = 10,
+ .endpoint = 0x82,
+ .u = {
+ .bulk = {
+ .buffersize = 4096,
+ }
+ }
+ },
+ }
+ },
+ .num_device_descs = 1,
+ .devices = {
+ {"Opera1 DVB-S USB2.0",
+ {&opera1_table[0], NULL},
+ {&opera1_table[1], NULL},
+ },
+ }
+};
+
+static int opera1_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ struct dvb_usb_device *d;
+ struct usb_device *udev = interface_to_usbdev(intf);
+
+ if (udev->descriptor.idProduct == USB_PID_OPERA1_WARM &&
+ udev->descriptor.idVendor == USB_VID_OPERA1 &&
+ (d == NULL
+ || opera1_xilinx_load_firmware(udev, "dvb-usb-opera1-fpga.fw") != 0)
+ ) {
+ return -EINVAL;
+ }
+
+ if (dvb_usb_device_init(intf, &opera1_properties, THIS_MODULE, &d) != 0)
+ return -EINVAL;
+ return 0;
+}
+
+static struct usb_driver opera1_driver = {
+ .name = "opera1",
+ .probe = opera1_probe,
+ .disconnect = dvb_usb_device_exit,
+ .id_table = opera1_table,
+};
+
+static int __init opera1_module_init(void)
+{
+ int result = 0;
+#if 0
+ mutex_init(&mymutex);
+#endif
+ if ((result = usb_register(&opera1_driver))) {
+ err("usb_register failed. Error number %d", result);
+ }
+ return result;
+}
+
+static void __exit opera1_module_exit(void)
+{
+ usb_deregister(&opera1_driver);
+}
+
+module_init(opera1_module_init);
+module_exit(opera1_module_exit);
+
+MODULE_AUTHOR("Mario Hlawitschka (c) dh1pa@amsat.org");
+MODULE_AUTHOR("Marco Gittler (c) g.marco@freenet.de");
+MODULE_DESCRIPTION("Driver for Opera1 DVB-S device");
+MODULE_VERSION("0.1");
+MODULE_LICENSE("GPL");
diff --git a/linux/drivers/media/dvb/dvb-usb/opera1.h b/linux/drivers/media/dvb/dvb-usb/opera1.h
new file mode 100644
index 000000000..531744279
--- /dev/null
+++ b/linux/drivers/media/dvb/dvb-usb/opera1.h
@@ -0,0 +1,9 @@
+#ifndef _OPERA1_H_
+#define _OPERA1_H_
+
+#define DVB_USB_LOG_PREFIX "opera"
+#include "dvb-usb.h"
+
+extern int dvb_usb_opera1_debug;
+#define deb_xfer(args...) dprintk(dvb_usb_opera1_debug,0x02,args)
+#endif
diff --git a/linux/drivers/media/dvb/dvb-usb/vp702x-fe.c b/linux/drivers/media/dvb/dvb-usb/vp702x-fe.c
index 3ecb2e0ce..c3fdc7cd0 100644
--- a/linux/drivers/media/dvb/dvb-usb/vp702x-fe.c
+++ b/linux/drivers/media/dvb/dvb-usb/vp702x-fe.c
@@ -204,8 +204,8 @@ static int vp702x_fe_get_frontend(struct dvb_frontend* fe,
static int vp702x_fe_send_diseqc_msg (struct dvb_frontend* fe,
struct dvb_diseqc_master_cmd *m)
{
- //struct vp702x_fe_state *st = fe->demodulator_priv;
- u8 cmd[8];//,ibuf[10];
+ struct vp702x_fe_state *st = fe->demodulator_priv;
+ u8 cmd[8],ibuf[10];
memset(cmd,0,8);
deb_fe("%s\n",__FUNCTION__);
@@ -218,12 +218,12 @@ static int vp702x_fe_send_diseqc_msg (struct dvb_frontend* fe,
memcpy(&cmd[3], m->msg, m->msg_len);
cmd[7] = vp702x_chksum(cmd,0,7);
-// vp702x_usb_inout_op(st->d,cmd,8,ibuf,10,100);
+ vp702x_usb_inout_op(st->d,cmd,8,ibuf,10,100);
-// if (ibuf[2] == 0 && ibuf[3] == 0)
-// deb_fe("diseqc cmd failed.\n");
-// else
-// deb_fe("diseqc cmd succeeded.\n");
+ if (ibuf[2] == 0 && ibuf[3] == 0)
+ deb_fe("diseqc cmd failed.\n");
+ else
+ deb_fe("diseqc cmd succeeded.\n");
return 0;
}
diff --git a/linux/drivers/media/dvb/frontends/Kconfig b/linux/drivers/media/dvb/frontends/Kconfig
index 10c4e7bdd..ff448761d 100644
--- a/linux/drivers/media/dvb/frontends/Kconfig
+++ b/linux/drivers/media/dvb/frontends/Kconfig
@@ -205,6 +205,13 @@ config DVB_TDA10021
help
A DVB-C tuner module. Say Y when you want to support this frontend.
+config DVB_TDA10023
+ tristate "Philips TDA10023 based"
+ depends on DVB_CORE && I2C
+ default m if DVB_FE_CUSTOMISE
+ help
+ A DVB-C tuner module. Say Y when you want to support this frontend.
+
config DVB_STV0297
tristate "ST STV0297 based"
depends on DVB_CORE && I2C
diff --git a/linux/drivers/media/dvb/frontends/Makefile b/linux/drivers/media/dvb/frontends/Makefile
index 905fcfc87..27f386585 100644
--- a/linux/drivers/media/dvb/frontends/Makefile
+++ b/linux/drivers/media/dvb/frontends/Makefile
@@ -25,6 +25,7 @@ obj-$(CONFIG_DVB_MT352) += mt352.o
obj-$(CONFIG_DVB_ZL10353) += zl10353.o
obj-$(CONFIG_DVB_CX22702) += cx22702.o
obj-$(CONFIG_DVB_TDA10021) += tda10021.o
+obj-$(CONFIG_DVB_TDA10023) += tda10023.o
obj-$(CONFIG_DVB_STV0297) += stv0297.o
obj-$(CONFIG_DVB_NXT200X) += nxt200x.o
obj-$(CONFIG_DVB_OR51211) += or51211.o
diff --git a/linux/drivers/media/dvb/frontends/dvb-pll.c b/linux/drivers/media/dvb/frontends/dvb-pll.c
index abc08f0ae..5f96ffda9 100644
--- a/linux/drivers/media/dvb/frontends/dvb-pll.c
+++ b/linux/drivers/media/dvb/frontends/dvb-pll.c
@@ -42,13 +42,14 @@ struct dvb_pll_desc dvb_pll_thomson_dtt7579 = {
.name = "Thomson dtt7579",
.min = 177000000,
.max = 858000000,
- .count = 5,
+ .iffreq= 36166667,
+ .sleepdata = (u8[]){ 2, 0xb4, 0x03 },
+ .count = 4,
.entries = {
- { 0, 36166667, 166666, 0xb4, 0x03 }, /* go sleep */
- { 443250000, 36166667, 166666, 0xb4, 0x02 },
- { 542000000, 36166667, 166666, 0xb4, 0x08 },
- { 771000000, 36166667, 166666, 0xbc, 0x08 },
- { 999999999, 36166667, 166666, 0xf4, 0x08 },
+ { 443250000, 166667, 0xb4, 0x02 },
+ { 542000000, 166667, 0xb4, 0x08 },
+ { 771000000, 166667, 0xbc, 0x08 },
+ { 999999999, 166667, 0xf4, 0x08 },
},
};
EXPORT_SYMBOL(dvb_pll_thomson_dtt7579);
@@ -57,11 +58,12 @@ struct dvb_pll_desc dvb_pll_thomson_dtt7610 = {
.name = "Thomson dtt7610",
.min = 44000000,
.max = 958000000,
+ .iffreq= 44000000,
.count = 3,
.entries = {
- { 157250000, 44000000, 62500, 0x8e, 0x39 },
- { 454000000, 44000000, 62500, 0x8e, 0x3a },
- { 999999999, 44000000, 62500, 0x8e, 0x3c },
+ { 157250000, 62500, 0x8e, 0x39 },
+ { 454000000, 62500, 0x8e, 0x3a },
+ { 999999999, 62500, 0x8e, 0x3c },
},
};
EXPORT_SYMBOL(dvb_pll_thomson_dtt7610);
@@ -77,14 +79,15 @@ struct dvb_pll_desc dvb_pll_thomson_dtt759x = {
.min = 177000000,
.max = 896000000,
.setbw = thomson_dtt759x_bw,
- .count = 6,
+ .iffreq= 36166667,
+ .sleepdata = (u8[]){ 2, 0x84, 0x03 },
+ .count = 5,
.entries = {
- { 0, 36166667, 166666, 0x84, 0x03 },
- { 264000000, 36166667, 166666, 0xb4, 0x02 },
- { 470000000, 36166667, 166666, 0xbc, 0x02 },
- { 735000000, 36166667, 166666, 0xbc, 0x08 },
- { 835000000, 36166667, 166666, 0xf4, 0x08 },
- { 999999999, 36166667, 166666, 0xfc, 0x08 },
+ { 264000000, 166667, 0xb4, 0x02 },
+ { 470000000, 166667, 0xbc, 0x02 },
+ { 735000000, 166667, 0xbc, 0x08 },
+ { 835000000, 166667, 0xf4, 0x08 },
+ { 999999999, 166667, 0xfc, 0x08 },
},
};
EXPORT_SYMBOL(dvb_pll_thomson_dtt759x);
@@ -93,14 +96,15 @@ struct dvb_pll_desc dvb_pll_lg_z201 = {
.name = "LG z201",
.min = 174000000,
.max = 862000000,
- .count = 6,
+ .iffreq= 36166667,
+ .sleepdata = (u8[]){ 2, 0xbc, 0x03 },
+ .count = 5,
.entries = {
- { 0, 36166667, 166666, 0xbc, 0x03 },
- { 157500000, 36166667, 166666, 0xbc, 0x01 },
- { 443250000, 36166667, 166666, 0xbc, 0x02 },
- { 542000000, 36166667, 166666, 0xbc, 0x04 },
- { 830000000, 36166667, 166666, 0xf4, 0x04 },
- { 999999999, 36166667, 166666, 0xfc, 0x04 },
+ { 157500000, 166667, 0xbc, 0x01 },
+ { 443250000, 166667, 0xbc, 0x02 },
+ { 542000000, 166667, 0xbc, 0x04 },
+ { 830000000, 166667, 0xf4, 0x04 },
+ { 999999999, 166667, 0xfc, 0x04 },
},
};
EXPORT_SYMBOL(dvb_pll_lg_z201);
@@ -109,11 +113,12 @@ struct dvb_pll_desc dvb_pll_microtune_4042 = {
.name = "Microtune 4042 FI5",
.min = 57000000,
.max = 858000000,
+ .iffreq= 44000000,
.count = 3,
.entries = {
- { 162000000, 44000000, 62500, 0x8e, 0xa1 },
- { 457000000, 44000000, 62500, 0x8e, 0x91 },
- { 999999999, 44000000, 62500, 0x8e, 0x31 },
+ { 162000000, 62500, 0x8e, 0xa1 },
+ { 457000000, 62500, 0x8e, 0x91 },
+ { 999999999, 62500, 0x8e, 0x31 },
},
};
EXPORT_SYMBOL(dvb_pll_microtune_4042);
@@ -123,12 +128,13 @@ struct dvb_pll_desc dvb_pll_thomson_dtt761x = {
.name = "Thomson dtt761x",
.min = 57000000,
.max = 863000000,
+ .iffreq= 44000000,
.count = 3,
.initdata = tua603x_agc103,
.entries = {
- { 147000000, 44000000, 62500, 0x8e, 0x39 },
- { 417000000, 44000000, 62500, 0x8e, 0x3a },
- { 999999999, 44000000, 62500, 0x8e, 0x3c },
+ { 147000000, 62500, 0x8e, 0x39 },
+ { 417000000, 62500, 0x8e, 0x3a },
+ { 999999999, 62500, 0x8e, 0x3c },
},
};
EXPORT_SYMBOL(dvb_pll_thomson_dtt761x);
@@ -137,17 +143,18 @@ struct dvb_pll_desc dvb_pll_unknown_1 = {
.name = "unknown 1", /* used by dntv live dvb-t */
.min = 174000000,
.max = 862000000,
+ .iffreq= 36166667,
.count = 9,
.entries = {
- { 150000000, 36166667, 166666, 0xb4, 0x01 },
- { 173000000, 36166667, 166666, 0xbc, 0x01 },
- { 250000000, 36166667, 166666, 0xb4, 0x02 },
- { 400000000, 36166667, 166666, 0xbc, 0x02 },
- { 420000000, 36166667, 166666, 0xf4, 0x02 },
- { 470000000, 36166667, 166666, 0xfc, 0x02 },
- { 600000000, 36166667, 166666, 0xbc, 0x08 },
- { 730000000, 36166667, 166666, 0xf4, 0x08 },
- { 999999999, 36166667, 166666, 0xfc, 0x08 },
+ { 150000000, 166667, 0xb4, 0x01 },
+ { 173000000, 166667, 0xbc, 0x01 },
+ { 250000000, 166667, 0xb4, 0x02 },
+ { 400000000, 166667, 0xbc, 0x02 },
+ { 420000000, 166667, 0xf4, 0x02 },
+ { 470000000, 166667, 0xfc, 0x02 },
+ { 600000000, 166667, 0xbc, 0x08 },
+ { 730000000, 166667, 0xf4, 0x08 },
+ { 999999999, 166667, 0xfc, 0x08 },
},
};
EXPORT_SYMBOL(dvb_pll_unknown_1);
@@ -159,11 +166,12 @@ struct dvb_pll_desc dvb_pll_tua6010xs = {
.name = "Infineon TUA6010XS",
.min = 44250000,
.max = 858000000,
+ .iffreq= 36125000,
.count = 3,
.entries = {
- { 115750000, 36125000, 62500, 0x8e, 0x03 },
- { 403250000, 36125000, 62500, 0x8e, 0x06 },
- { 999999999, 36125000, 62500, 0x8e, 0x85 },
+ { 115750000, 62500, 0x8e, 0x03 },
+ { 403250000, 62500, 0x8e, 0x06 },
+ { 999999999, 62500, 0x8e, 0x85 },
},
};
EXPORT_SYMBOL(dvb_pll_tua6010xs);
@@ -173,12 +181,13 @@ struct dvb_pll_desc dvb_pll_env57h1xd5 = {
.name = "Panasonic ENV57H1XD5",
.min = 44250000,
.max = 858000000,
+ .iffreq= 36125000,
.count = 4,
.entries = {
- { 153000000, 36291666, 166666, 0xc2, 0x41 },
- { 470000000, 36291666, 166666, 0xc2, 0x42 },
- { 526000000, 36291666, 166666, 0xc2, 0x84 },
- { 999999999, 36291666, 166666, 0xc2, 0xa4 },
+ { 153000000, 166667, 0xc2, 0x41 },
+ { 470000000, 166667, 0xc2, 0x42 },
+ { 526000000, 166667, 0xc2, 0x84 },
+ { 999999999, 166667, 0xc2, 0xa4 },
},
};
EXPORT_SYMBOL(dvb_pll_env57h1xd5);
@@ -197,20 +206,21 @@ struct dvb_pll_desc dvb_pll_tda665x = {
.min = 44250000,
.max = 858000000,
.setbw = tda665x_bw,
+ .iffreq= 36166667,
.count = 12,
.entries = {
- { 93834000, 36249333, 166667, 0xca, 0x61 /* 011 0 0 0 01 */ },
- { 123834000, 36249333, 166667, 0xca, 0xa1 /* 101 0 0 0 01 */ },
- { 161000000, 36249333, 166667, 0xca, 0xa1 /* 101 0 0 0 01 */ },
- { 163834000, 36249333, 166667, 0xca, 0xc2 /* 110 0 0 0 10 */ },
- { 253834000, 36249333, 166667, 0xca, 0x62 /* 011 0 0 0 10 */ },
- { 383834000, 36249333, 166667, 0xca, 0xa2 /* 101 0 0 0 10 */ },
- { 443834000, 36249333, 166667, 0xca, 0xc2 /* 110 0 0 0 10 */ },
- { 444000000, 36249333, 166667, 0xca, 0xc4 /* 110 0 0 1 00 */ },
- { 583834000, 36249333, 166667, 0xca, 0x64 /* 011 0 0 1 00 */ },
- { 793834000, 36249333, 166667, 0xca, 0xa4 /* 101 0 0 1 00 */ },
- { 444834000, 36249333, 166667, 0xca, 0xc4 /* 110 0 0 1 00 */ },
- { 861000000, 36249333, 166667, 0xca, 0xe4 /* 111 0 0 1 00 */ },
+ { 93834000, 166667, 0xca, 0x61 /* 011 0 0 0 01 */ },
+ { 123834000, 166667, 0xca, 0xa1 /* 101 0 0 0 01 */ },
+ { 161000000, 166667, 0xca, 0xa1 /* 101 0 0 0 01 */ },
+ { 163834000, 166667, 0xca, 0xc2 /* 110 0 0 0 10 */ },
+ { 253834000, 166667, 0xca, 0x62 /* 011 0 0 0 10 */ },
+ { 383834000, 166667, 0xca, 0xa2 /* 101 0 0 0 10 */ },
+ { 443834000, 166667, 0xca, 0xc2 /* 110 0 0 0 10 */ },
+ { 444000000, 166667, 0xca, 0xc4 /* 110 0 0 1 00 */ },
+ { 583834000, 166667, 0xca, 0x64 /* 011 0 0 1 00 */ },
+ { 793834000, 166667, 0xca, 0xa4 /* 101 0 0 1 00 */ },
+ { 444834000, 166667, 0xca, 0xc4 /* 110 0 0 1 00 */ },
+ { 861000000, 166667, 0xca, 0xe4 /* 111 0 0 1 00 */ },
}
};
EXPORT_SYMBOL(dvb_pll_tda665x);
@@ -228,12 +238,13 @@ struct dvb_pll_desc dvb_pll_tua6034 = {
.name = "Infineon TUA6034",
.min = 44250000,
.max = 858000000,
+ .iffreq= 36166667,
.count = 3,
.setbw = tua6034_bw,
.entries = {
- { 174500000, 36166667, 62500, 0xce, 0x01 },
- { 230000000, 36166667, 62500, 0xce, 0x02 },
- { 999999999, 36166667, 62500, 0xce, 0x04 },
+ { 174500000, 62500, 0xce, 0x01 },
+ { 230000000, 62500, 0xce, 0x02 },
+ { 999999999, 62500, 0xce, 0x04 },
},
};
EXPORT_SYMBOL(dvb_pll_tua6034);
@@ -245,12 +256,13 @@ struct dvb_pll_desc dvb_pll_lg_tdvs_h06xf = {
.name = "LG TDVS-H06xF",
.min = 54000000,
.max = 863000000,
+ .iffreq= 44000000,
.initdata = tua603x_agc103,
.count = 3,
.entries = {
- { 165000000, 44000000, 62500, 0xce, 0x01 },
- { 450000000, 44000000, 62500, 0xce, 0x02 },
- { 999999999, 44000000, 62500, 0xce, 0x04 },
+ { 165000000, 62500, 0xce, 0x01 },
+ { 450000000, 62500, 0xce, 0x02 },
+ { 999999999, 62500, 0xce, 0x04 },
},
};
EXPORT_SYMBOL(dvb_pll_lg_tdvs_h06xf);
@@ -268,16 +280,17 @@ struct dvb_pll_desc dvb_pll_fmd1216me = {
.name = "Philips FMD1216ME",
.min = 50870000,
.max = 858000000,
+ .iffreq= 36125000,
.setbw = fmd1216me_bw,
.count = 7,
.entries = {
- { 143870000, 36213333, 166667, 0xbc, 0x41 },
- { 158870000, 36213333, 166667, 0xf4, 0x41 },
- { 329870000, 36213333, 166667, 0xbc, 0x42 },
- { 441870000, 36213333, 166667, 0xf4, 0x42 },
- { 625870000, 36213333, 166667, 0xbc, 0x44 },
- { 803870000, 36213333, 166667, 0xf4, 0x44 },
- { 999999999, 36213333, 166667, 0xfc, 0x44 },
+ { 143870000, 166667, 0xbc, 0x41 },
+ { 158870000, 166667, 0xf4, 0x41 },
+ { 329870000, 166667, 0xbc, 0x42 },
+ { 441870000, 166667, 0xf4, 0x42 },
+ { 625870000, 166667, 0xbc, 0x44 },
+ { 803870000, 166667, 0xf4, 0x44 },
+ { 999999999, 166667, 0xfc, 0x44 },
}
};
EXPORT_SYMBOL(dvb_pll_fmd1216me);
@@ -295,13 +308,14 @@ struct dvb_pll_desc dvb_pll_tded4 = {
.name = "ALPS TDED4",
.min = 47000000,
.max = 863000000,
+ .iffreq= 36166667,
.setbw = tded4_bw,
.count = 4,
.entries = {
- { 153000000, 36166667, 166667, 0x85, 0x01 },
- { 470000000, 36166667, 166667, 0x85, 0x02 },
- { 823000000, 36166667, 166667, 0x85, 0x08 },
- { 999999999, 36166667, 166667, 0x85, 0x88 },
+ { 153000000, 166667, 0x85, 0x01 },
+ { 470000000, 166667, 0x85, 0x02 },
+ { 823000000, 166667, 0x85, 0x08 },
+ { 999999999, 166667, 0x85, 0x88 },
}
};
EXPORT_SYMBOL(dvb_pll_tded4);
@@ -313,12 +327,13 @@ struct dvb_pll_desc dvb_pll_tdhu2 = {
.name = "ALPS TDHU2",
.min = 54000000,
.max = 864000000,
+ .iffreq= 44000000,
.count = 4,
.entries = {
- { 162000000, 44000000, 62500, 0x85, 0x01 },
- { 426000000, 44000000, 62500, 0x85, 0x02 },
- { 782000000, 44000000, 62500, 0x85, 0x08 },
- { 999999999, 44000000, 62500, 0x85, 0x88 },
+ { 162000000, 62500, 0x85, 0x01 },
+ { 426000000, 62500, 0x85, 0x02 },
+ { 782000000, 62500, 0x85, 0x08 },
+ { 999999999, 62500, 0x85, 0x88 },
}
};
EXPORT_SYMBOL(dvb_pll_tdhu2);
@@ -330,11 +345,12 @@ struct dvb_pll_desc dvb_pll_tuv1236d = {
.name = "Philips TUV1236D",
.min = 54000000,
.max = 864000000,
+ .iffreq= 44000000,
.count = 3,
.entries = {
- { 157250000, 44000000, 62500, 0xc6, 0x41 },
- { 454000000, 44000000, 62500, 0xc6, 0x42 },
- { 999999999, 44000000, 62500, 0xc6, 0x44 },
+ { 157250000, 62500, 0xc6, 0x41 },
+ { 454000000, 62500, 0xc6, 0x42 },
+ { 999999999, 62500, 0xc6, 0x44 },
},
};
EXPORT_SYMBOL(dvb_pll_tuv1236d);
@@ -346,14 +362,15 @@ struct dvb_pll_desc dvb_pll_samsung_tbmv = {
.name = "Samsung TBMV30111IN / TBMV30712IN1",
.min = 54000000,
.max = 860000000,
+ .iffreq= 44000000,
.count = 6,
.entries = {
- { 172000000, 44000000, 166666, 0xb4, 0x01 },
- { 214000000, 44000000, 166666, 0xb4, 0x02 },
- { 467000000, 44000000, 166666, 0xbc, 0x02 },
- { 721000000, 44000000, 166666, 0xbc, 0x08 },
- { 841000000, 44000000, 166666, 0xf4, 0x08 },
- { 999999999, 44000000, 166666, 0xfc, 0x02 },
+ { 172000000, 166667, 0xb4, 0x01 },
+ { 214000000, 166667, 0xb4, 0x02 },
+ { 467000000, 166667, 0xbc, 0x02 },
+ { 721000000, 166667, 0xbc, 0x08 },
+ { 841000000, 166667, 0xf4, 0x08 },
+ { 999999999, 166667, 0xfc, 0x02 },
}
};
EXPORT_SYMBOL(dvb_pll_samsung_tbmv);
@@ -365,12 +382,13 @@ struct dvb_pll_desc dvb_pll_philips_sd1878_tda8261 = {
.name = "Philips SD1878",
.min = 950000,
.max = 2150000,
+ .iffreq= 249, /* zero-IF, offset 249 is to round up */
.count = 4,
.entries = {
- { 1250000, 499, 500, 0xc4, 0x00},
- { 1550000, 499, 500, 0xc4, 0x40},
- { 2050000, 499, 500, 0xc4, 0x80},
- { 2150000, 499, 500, 0xc4, 0xc0},
+ { 1250000, 500, 0xc4, 0x00},
+ { 1550000, 500, 0xc4, 0x40},
+ { 2050000, 500, 0xc4, 0x80},
+ { 2150000, 500, 0xc4, 0xc0},
},
};
EXPORT_SYMBOL(dvb_pll_philips_sd1878_tda8261);
@@ -401,18 +419,19 @@ struct dvb_pll_desc dvb_pll_philips_td1316 = {
.name = "Philips TD1316",
.min = 87000000,
.max = 895000000,
+ .iffreq= 36166667,
.setbw = td1316_bw,
.count = 9,
.entries = {
- { 93834000, 36166000, 166666, 0xca, 0x60},
- { 123834000, 36166000, 166666, 0xca, 0xa0},
- { 163834000, 36166000, 166666, 0xca, 0xc0},
- { 253834000, 36166000, 166666, 0xca, 0x60},
- { 383834000, 36166000, 166666, 0xca, 0xa0},
- { 443834000, 36166000, 166666, 0xca, 0xc0},
- { 583834000, 36166000, 166666, 0xca, 0x60},
- { 793834000, 36166000, 166666, 0xca, 0xa0},
- { 858834000, 36166000, 166666, 0xca, 0xe0},
+ { 93834000, 166667, 0xca, 0x60},
+ { 123834000, 166667, 0xca, 0xa0},
+ { 163834000, 166667, 0xca, 0xc0},
+ { 253834000, 166667, 0xca, 0x60},
+ { 383834000, 166667, 0xca, 0xa0},
+ { 443834000, 166667, 0xca, 0xc0},
+ { 583834000, 166667, 0xca, 0x60},
+ { 793834000, 166667, 0xca, 0xa0},
+ { 858834000, 166667, 0xca, 0xe0},
},
};
EXPORT_SYMBOL(dvb_pll_philips_td1316);
@@ -422,15 +441,41 @@ struct dvb_pll_desc dvb_pll_thomson_fe6600 = {
.name = "Thomson FE6600",
.min = 44250000,
.max = 858000000,
+ .iffreq= 36125000,
.count = 4,
.entries = {
- { 250000000, 36213333, 166667, 0xb4, 0x12 },
- { 455000000, 36213333, 166667, 0xfe, 0x11 },
- { 775500000, 36213333, 166667, 0xbc, 0x18 },
- { 999999999, 36213333, 166667, 0xf4, 0x18 },
+ { 250000000, 166667, 0xb4, 0x12 },
+ { 455000000, 166667, 0xfe, 0x11 },
+ { 775500000, 166667, 0xbc, 0x18 },
+ { 999999999, 166667, 0xf4, 0x18 },
}
};
EXPORT_SYMBOL(dvb_pll_thomson_fe6600);
+static void opera1_bw(u8 *buf, u32 freq, int bandwidth)
+{
+ if (bandwidth == BANDWIDTH_8_MHZ)
+ buf[2] |= 0x08;
+}
+
+struct dvb_pll_desc dvb_pll_opera1 = {
+ .name = "Opera Tuner",
+ .min = 900000,
+ .max = 2250000,
+ .iffreq= 0,
+ .setbw = opera1_bw,
+ .count = 8,
+ .entries = {
+ { 1064000, 500, 0xe5, 0xc6 },
+ { 1169000, 500, 0xe5, 0xe6 },
+ { 1299000, 500, 0xe5, 0x24 },
+ { 1444000, 500, 0xe5, 0x44 },
+ { 1606000, 500, 0xe5, 0x64 },
+ { 1777000, 500, 0xe5, 0x84 },
+ { 1941000, 500, 0xe5, 0xa4 },
+ { 2250000, 500, 0xe5, 0xc4 },
+ }
+};
+EXPORT_SYMBOL(dvb_pll_opera1);
struct dvb_pll_priv {
/* i2c details */
@@ -472,7 +517,8 @@ int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf,
if (i == desc->count)
return -EINVAL;
- div = (freq + desc->entries[i].offset) / desc->entries[i].stepsize;
+ div = (freq + desc->iffreq + desc->entries[i].stepsize/2) /
+ desc->entries[i].stepsize;
buf[0] = div >> 8;
buf[1] = div & 0xff;
buf[2] = desc->entries[i].config;
@@ -486,7 +532,7 @@ int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf,
desc->name, div, buf[0], buf[1], buf[2], buf[3]);
// calculate the frequency we set it to
- return (div * desc->entries[i].stepsize) - desc->entries[i].offset;
+ return (div * desc->entries[i].stepsize) - desc->iffreq;
}
EXPORT_SYMBOL(dvb_pll_configure);
@@ -500,35 +546,27 @@ static int dvb_pll_release(struct dvb_frontend *fe)
static int dvb_pll_sleep(struct dvb_frontend *fe)
{
struct dvb_pll_priv *priv = fe->tuner_priv;
- u8 buf[4];
- struct i2c_msg msg =
- { .addr = priv->pll_i2c_address, .flags = 0,
- .buf = buf, .len = sizeof(buf) };
- int i;
- int result;
if (priv->i2c == NULL)
return -EINVAL;
- for (i = 0; i < priv->pll_desc->count; i++) {
- if (priv->pll_desc->entries[i].limit == 0)
- break;
- }
- if (i == priv->pll_desc->count)
- return 0;
+ if (priv->pll_desc->sleepdata) {
+ struct i2c_msg msg = { .flags = 0,
+ .addr = priv->pll_i2c_address,
+ .buf = priv->pll_desc->sleepdata + 1,
+ .len = priv->pll_desc->sleepdata[0] };
- buf[0] = 0;
- buf[1] = 0;
- buf[2] = priv->pll_desc->entries[i].config;
- buf[3] = priv->pll_desc->entries[i].cb;
+ int result;
- if (fe->ops.i2c_gate_ctrl)
- fe->ops.i2c_gate_ctrl(fe, 1);
- if ((result = i2c_transfer(priv->i2c, &msg, 1)) != 1) {
- return result;
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 1);
+ if ((result = i2c_transfer(priv->i2c, &msg, 1)) != 1) {
+ return result;
+ }
+ return 0;
}
-
- return 0;
+ /* Shouldn't be called when initdata is NULL, maybe BUG()? */
+ return -EINVAL;
}
static int dvb_pll_set_params(struct dvb_frontend *fe,
@@ -640,6 +678,7 @@ static int dvb_pll_init(struct dvb_frontend *fe)
static struct dvb_tuner_ops dvb_pll_tuner_ops = {
.release = dvb_pll_release,
.sleep = dvb_pll_sleep,
+ .init = dvb_pll_init,
.set_params = dvb_pll_set_params,
.calc_regs = dvb_pll_calc_regs,
.get_frequency = dvb_pll_get_frequency,
@@ -682,8 +721,10 @@ struct dvb_frontend *dvb_pll_attach(struct dvb_frontend *fe, int pll_addr,
sizeof(fe->ops.tuner_ops.info.name));
fe->ops.tuner_ops.info.frequency_min = desc->min;
fe->ops.tuner_ops.info.frequency_min = desc->max;
- if (desc->initdata)
- fe->ops.tuner_ops.init = dvb_pll_init;
+ if (!desc->initdata)
+ fe->ops.tuner_ops.init = NULL;
+ if (!desc->sleepdata)
+ fe->ops.tuner_ops.sleep = NULL;
fe->tuner_priv = priv;
return fe;
diff --git a/linux/drivers/media/dvb/frontends/dvb-pll.h b/linux/drivers/media/dvb/frontends/dvb-pll.h
index bb79a7815..5209f46f0 100644
--- a/linux/drivers/media/dvb/frontends/dvb-pll.h
+++ b/linux/drivers/media/dvb/frontends/dvb-pll.h
@@ -12,12 +12,13 @@ struct dvb_pll_desc {
char *name;
u32 min;
u32 max;
+ u32 iffreq;
void (*setbw)(u8 *buf, u32 freq, int bandwidth);
u8 *initdata;
+ u8 *sleepdata;
int count;
struct {
u32 limit;
- u32 offset;
u32 stepsize;
u8 config;
u8 cb;
@@ -47,6 +48,7 @@ extern struct dvb_pll_desc dvb_pll_philips_sd1878_tda8261;
extern struct dvb_pll_desc dvb_pll_philips_td1316;
extern struct dvb_pll_desc dvb_pll_thomson_fe6600;
+extern struct dvb_pll_desc dvb_pll_opera1;
extern int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf,
u32 freq, int bandwidth);
diff --git a/linux/drivers/media/dvb/frontends/isl6421.c b/linux/drivers/media/dvb/frontends/isl6421.c
index ef319369e..c967148a5 100644
--- a/linux/drivers/media/dvb/frontends/isl6421.c
+++ b/linux/drivers/media/dvb/frontends/isl6421.c
@@ -122,6 +122,7 @@ struct dvb_frontend *isl6421_attach(struct dvb_frontend *fe, struct i2c_adapter
/* detect if it is present or not */
if (isl6421_set_voltage(fe, SEC_VOLTAGE_OFF)) {
kfree(isl6421);
+ fe->sec_priv = NULL;
return NULL;
}
diff --git a/linux/drivers/media/dvb/frontends/lgdt330x.c b/linux/drivers/media/dvb/frontends/lgdt330x.c
index 48ad12c49..706f78b4f 100644
--- a/linux/drivers/media/dvb/frontends/lgdt330x.c
+++ b/linux/drivers/media/dvb/frontends/lgdt330x.c
@@ -481,7 +481,7 @@ static int lgdt3302_read_status(struct dvb_frontend* fe, fe_status_t* status)
*status |= FE_HAS_CARRIER;
break;
default:
- printk("KERN_WARNING lgdt330x: %s: Modulation set to unsupported value\n", __FUNCTION__);
+ printk(KERN_WARNING "lgdt330x: %s: Modulation set to unsupported value\n", __FUNCTION__);
}
return 0;
@@ -540,7 +540,7 @@ static int lgdt3303_read_status(struct dvb_frontend* fe, fe_status_t* status)
}
break;
default:
- printk("KERN_WARNING lgdt330x: %s: Modulation set to unsupported value\n", __FUNCTION__);
+ printk(KERN_WARNING "lgdt330x: %s: Modulation set to unsupported value\n", __FUNCTION__);
}
return 0;
}
diff --git a/linux/drivers/media/dvb/frontends/nxt200x.c b/linux/drivers/media/dvb/frontends/nxt200x.c
index 87c286ee6..b809f83d9 100644
--- a/linux/drivers/media/dvb/frontends/nxt200x.c
+++ b/linux/drivers/media/dvb/frontends/nxt200x.c
@@ -562,7 +562,7 @@ static int nxt200x_setup_frontend_parameters (struct dvb_frontend* fe,
/* set input */
if (state->config->set_pll_input)
- state->config->set_pll_input(buf, 1);
+ state->config->set_pll_input(buf+1, 1);
break;
case VSB_8:
/* Set non-punctured clock for VSB */
@@ -571,7 +571,7 @@ static int nxt200x_setup_frontend_parameters (struct dvb_frontend* fe,
/* set input */
if (state->config->set_pll_input)
- state->config->set_pll_input(buf, 0);
+ state->config->set_pll_input(buf+1, 0);
break;
default:
return -EINVAL;
diff --git a/linux/drivers/media/dvb/frontends/tda10021.c b/linux/drivers/media/dvb/frontends/tda10021.c
index f34f82fa9..3bc71c601 100644
--- a/linux/drivers/media/dvb/frontends/tda10021.c
+++ b/linux/drivers/media/dvb/frontends/tda10021.c
@@ -30,13 +30,13 @@
#include <linux/slab.h>
#include "dvb_frontend.h"
-#include "tda10021.h"
+#include "tda1002x.h"
struct tda10021_state {
struct i2c_adapter* i2c;
/* configuration settings */
- const struct tda10021_config* config;
+ const struct tda1002x_config* config;
struct dvb_frontend frontend;
u8 pwm;
@@ -53,9 +53,6 @@ struct tda10021_state {
static int verbose;
#define XIN 57840000UL
-#define DISABLE_INVERSION(reg0) do { reg0 |= 0x20; } while (0)
-#define ENABLE_INVERSION(reg0) do { reg0 &= ~0x20; } while (0)
-#define HAS_INVERSION(reg0) (!(reg0 & 0x20))
#define FIN (XIN >> 4)
@@ -64,7 +61,7 @@ static u8 tda10021_inittab[0x40]=
{
0x73, 0x6a, 0x23, 0x0a, 0x02, 0x37, 0x77, 0x1a,
0x37, 0x6a, 0x17, 0x8a, 0x1e, 0x86, 0x43, 0x40,
- 0xb8, 0x3f, 0xa0, 0x00, 0xcd, 0x01, 0x00, 0xff,
+ 0xb8, 0x3f, 0xa1, 0x00, 0xcd, 0x01, 0x00, 0xff,
0x11, 0x00, 0x7c, 0x31, 0x30, 0x20, 0x00, 0x00,
0x02, 0x00, 0x00, 0x7d, 0x00, 0x00, 0x00, 0x00,
0x07, 0x00, 0x33, 0x11, 0x0d, 0x95, 0x08, 0x58,
@@ -97,7 +94,8 @@ static u8 tda10021_readreg (struct tda10021_state* state, u8 reg)
int ret;
ret = i2c_transfer (state->i2c, msg, 2);
- if (ret != 2)
+ // Don't print an error message if the id is read.
+ if (ret != 2 && reg != 0x1a)
printk("DVB: TDA10021: %s: readreg error (ret == %i)\n",
__FUNCTION__, ret);
return b1[0];
@@ -136,10 +134,10 @@ static int tda10021_setup_reg0 (struct tda10021_state* state, u8 reg0,
{
reg0 |= state->reg0 & 0x63;
- if (INVERSION_ON == inversion)
- ENABLE_INVERSION(reg0);
- else if (INVERSION_OFF == inversion)
- DISABLE_INVERSION(reg0);
+ if ((INVERSION_ON == inversion) ^ (state->config->invert == 0))
+ reg0 &= ~0x20;
+ else
+ reg0 |= 0x20;
_tda10021_writereg (state, 0x00, reg0 & 0xfe);
_tda10021_writereg (state, 0x00, reg0 | 0x01);
@@ -201,16 +199,6 @@ static int tda10021_set_symbolrate (struct tda10021_state* state, u32 symbolrate
return 0;
}
-static int tda10021_write(struct dvb_frontend* fe, u8 *buf, int len)
-{
- struct tda10021_state* state = fe->demodulator_priv;
-
- if (len != 2)
- return -EINVAL;
-
- return _tda10021_writereg(state, buf[0], buf[1]);
-}
-
static int tda10021_init (struct dvb_frontend *fe)
{
struct tda10021_state* state = fe->demodulator_priv;
@@ -258,6 +246,9 @@ static int tda10021_set_parameters (struct dvb_frontend *fe,
if (qam < 0 || qam > 5)
return -EINVAL;
+ if (p->inversion != INVERSION_ON && p->inversion != INVERSION_OFF)
+ return -EINVAL;
+
//printk("tda10021: set frequency to %d qam=%d symrate=%d\n", p->frequency,qam,p->u.qam.symbol_rate);
if (fe->ops.tuner_ops.set_params) {
@@ -366,7 +357,7 @@ static int tda10021_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_pa
-((s32)p->u.qam.symbol_rate * afc) >> 10);
}
- p->inversion = HAS_INVERSION(state->reg0) ? INVERSION_ON : INVERSION_OFF;
+ p->inversion = ((state->reg0 & 0x20) == 0x20) ^ (state->config->invert != 0) ? INVERSION_ON : INVERSION_OFF;
p->u.qam.modulation = ((state->reg0 >> 2) & 7) + QAM_16;
p->u.qam.fec_inner = FEC_NONE;
@@ -408,11 +399,12 @@ static void tda10021_release(struct dvb_frontend* fe)
static struct dvb_frontend_ops tda10021_ops;
-struct dvb_frontend* tda10021_attach(const struct tda10021_config* config,
+struct dvb_frontend* tda10021_attach(const struct tda1002x_config* config,
struct i2c_adapter* i2c,
u8 pwm)
{
struct tda10021_state* state = NULL;
+ u8 id;
/* allocate memory for the internal state */
state = kmalloc(sizeof(struct tda10021_state), GFP_KERNEL);
@@ -425,7 +417,11 @@ struct dvb_frontend* tda10021_attach(const struct tda10021_config* config,
state->reg0 = tda10021_inittab[0];
/* check if the demod is there */
- if ((tda10021_readreg(state, 0x1a) & 0xf0) != 0x70) goto error;
+ id = tda10021_readreg(state, 0x1a);
+ if ((id & 0xf0) != 0x70) goto error;
+
+ printk("TDA10021: i2c-addr = 0x%02x, id = 0x%02x\n",
+ state->config->demod_address, id);
/* create dvb_frontend */
memcpy(&state->frontend.ops, &tda10021_ops, sizeof(struct dvb_frontend_ops));
@@ -461,7 +457,6 @@ static struct dvb_frontend_ops tda10021_ops = {
.init = tda10021_init,
.sleep = tda10021_sleep,
- .write = tda10021_write,
.i2c_gate_ctrl = tda10021_i2c_gate_ctrl,
.set_frontend = tda10021_set_parameters,
diff --git a/linux/drivers/media/dvb/frontends/tda10023.c b/linux/drivers/media/dvb/frontends/tda10023.c
new file mode 100644
index 000000000..5452526ff
--- /dev/null
+++ b/linux/drivers/media/dvb/frontends/tda10023.c
@@ -0,0 +1,548 @@
+/*
+ TDA10023 - DVB-C decoder
+ (as used in Philips CU1216-3 NIM and the Reelbox DVB-C tuner card)
+
+ Copyright (C) 2005 Georg Acher, BayCom GmbH (acher at baycom dot de)
+ Copyright (c) 2006 Hartmut Birr (e9hack at gmail dot com)
+
+ Remotely based on tda10021.c
+ Copyright (C) 1999 Convergence Integrated Media GmbH <ralph@convergence.de>
+ Copyright (C) 2004 Markus Schulz <msc@antzsystem.de>
+ Support for TDA10021
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+
+#include <asm/div64.h>
+
+#include "dvb_frontend.h"
+#include "tda1002x.h"
+
+
+struct tda10023_state {
+ struct i2c_adapter* i2c;
+ /* configuration settings */
+ const struct tda1002x_config* config;
+ struct dvb_frontend frontend;
+
+ u8 pwm;
+ u8 reg0;
+};
+
+
+#if 0
+#define dprintk(x...) printk(x)
+#else
+#define dprintk(x...)
+#endif
+
+static int verbose;
+
+#define XTAL 28920000UL
+#define PLL_M 8UL
+#define PLL_P 4UL
+#define PLL_N 1UL
+#define SYSCLK (XTAL*PLL_M/(PLL_N*PLL_P)) // -> 57840000
+
+static u8 tda10023_inittab[]={
+ // reg mask val
+ 0x2a,0xff,0x02, // PLL3, Bypass, Power Down
+ 0xff,0x64,0x00, // Sleep 100ms
+ 0x2a,0xff,0x03, // PLL3, Bypass, Power Down
+ 0xff,0x64,0x00, // Sleep 100ms
+ 0x28,0xff,PLL_M-1, // PLL1 M=8
+ 0x29,0xff,((PLL_P-1)<<6)|(PLL_N-1), // PLL2
+ 0x00,0xff,0x23, // GPR FSAMPLING=1
+ 0x2a,0xff,0x08, // PLL3 PSACLK=1
+ 0xff,0x64,0x00, // Sleep 100ms
+ 0x1f,0xff,0x00, // RESET
+ 0xff,0x64,0x00, // Sleep 100ms
+ 0xe6,0x0c,0x04, // RSCFG_IND
+ 0x10,0xc0,0x80, // DECDVBCFG1 PBER=1
+
+ 0x0e,0xff,0x82, // GAIN1
+ 0x03,0x08,0x08, // CLKCONF DYN=1
+ 0x2e,0xbf,0x30, // AGCCONF2 TRIAGC=0,POSAGC=ENAGCIF=1 PPWMTUN=0 PPWMIF=0
+ 0x01,0xff,0x30, // AGCREF
+ 0x1e,0x84,0x84, // CONTROL SACLK_ON=1
+ 0x1b,0xff,0xc8, // ADC TWOS=1
+ 0x3b,0xff,0xff, // IFMAX
+ 0x3c,0xff,0x00, // IFMIN
+ 0x34,0xff,0x00, // PWMREF
+ 0x35,0xff,0xff, // TUNMAX
+ 0x36,0xff,0x00, // TUNMIN
+ 0x06,0xff,0x7f, // EQCONF1 POSI=7 ENADAPT=ENEQUAL=DFE=1 // 0x77
+ 0x1c,0x30,0x30, // EQCONF2 STEPALGO=SGNALGO=1
+ 0x37,0xff,0xf6, // DELTAF_LSB
+ 0x38,0xff,0xff, // DELTAF_MSB
+ 0x02,0xff,0x93, // AGCCONF1 IFS=1 KAGCIF=2 KAGCTUN=3
+ 0x2d,0xff,0xf6, // SWEEP SWPOS=1 SWDYN=7 SWSTEP=1 SWLEN=2
+ 0x04,0x10,0x00, // SWRAMP=1
+ 0x12,0xff,0xa1, // INTP1 POCLKP=1 FEL=1 MFS=0
+ 0x2b,0x01,0xa1, // INTS1
+ 0x20,0xff,0x04, // INTP2 SWAPP=? MSBFIRSTP=? INTPSEL=?
+ 0x2c,0xff,0x0d, // INTP/S TRIP=0 TRIS=0
+ 0xc4,0xff,0x00,
+ 0xc3,0x30,0x00,
+ 0xb5,0xff,0x19, // ERAGC_THD
+ 0x00,0x03,0x01, // GPR, CLBS soft reset
+ 0x00,0x03,0x03, // GPR, CLBS soft reset
+ 0xff,0x64,0x00, // Sleep 100ms
+ 0xff,0xff,0xff
+};
+
+static u8 tda10023_readreg (struct tda10023_state* state, u8 reg)
+{
+ u8 b0 [] = { reg };
+ u8 b1 [] = { 0 };
+ struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 1 },
+ { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } };
+ int ret;
+
+ ret = i2c_transfer (state->i2c, msg, 2);
+ if (ret != 2)
+ printk("DVB: TDA10023: %s: readreg error (ret == %i)\n",
+ __FUNCTION__, ret);
+ return b1[0];
+}
+
+static int tda10023_writereg (struct tda10023_state* state, u8 reg, u8 data)
+{
+ u8 buf[] = { reg, data };
+ struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 };
+ int ret;
+
+ ret = i2c_transfer (state->i2c, &msg, 1);
+ if (ret != 1)
+ printk("DVB: TDA10023(%d): %s, writereg error "
+ "(reg == 0x%02x, val == 0x%02x, ret == %i)\n",
+ state->frontend.dvb->num, __FUNCTION__, reg, data, ret);
+
+ return (ret != 1) ? -EREMOTEIO : 0;
+}
+
+
+static int tda10023_writebit (struct tda10023_state* state, u8 reg, u8 mask,u8 data)
+{
+ if (mask==0xff)
+ return tda10023_writereg(state, reg, data);
+ else {
+ u8 val;
+ val=tda10023_readreg(state,reg);
+ val&=~mask;
+ val|=(data&mask);
+ return tda10023_writereg(state, reg, val);
+ }
+}
+
+static void tda10023_writetab(struct tda10023_state* state, u8* tab)
+{
+ u8 r,m,v;
+ while (1) {
+ r=*tab++;
+ m=*tab++;
+ v=*tab++;
+ if (r==0xff) {
+ if (m==0xff)
+ break;
+ else
+ msleep(m);
+ }
+ else
+ tda10023_writebit(state,r,m,v);
+ }
+}
+
+//get access to tuner
+static int lock_tuner(struct tda10023_state* state)
+{
+ u8 buf[2] = { 0x0f, 0xc0 };
+ struct i2c_msg msg = {.addr=state->config->demod_address, .flags=0, .buf=buf, .len=2};
+
+ if(i2c_transfer(state->i2c, &msg, 1) != 1)
+ {
+ printk("tda10023: lock tuner fails\n");
+ return -EREMOTEIO;
+ }
+ return 0;
+}
+
+//release access from tuner
+static int unlock_tuner(struct tda10023_state* state)
+{
+ u8 buf[2] = { 0x0f, 0x40 };
+ struct i2c_msg msg_post={.addr=state->config->demod_address, .flags=0, .buf=buf, .len=2};
+
+ if(i2c_transfer(state->i2c, &msg_post, 1) != 1)
+ {
+ printk("tda10023: unlock tuner fails\n");
+ return -EREMOTEIO;
+ }
+ return 0;
+}
+
+static int tda10023_setup_reg0 (struct tda10023_state* state, u8 reg0)
+{
+ reg0 |= state->reg0 & 0x63;
+
+ tda10023_writereg (state, 0x00, reg0 & 0xfe);
+ tda10023_writereg (state, 0x00, reg0 | 0x01);
+
+ state->reg0 = reg0;
+ return 0;
+}
+
+static int tda10023_set_symbolrate (struct tda10023_state* state, u32 sr)
+{
+ s32 BDR;
+ s32 BDRI;
+ s16 SFIL=0;
+ u16 NDEC = 0;
+
+ if (sr > (SYSCLK/(2*4)))
+ sr=SYSCLK/(2*4);
+
+ if (sr<870000)
+ sr=870000;
+
+ if (sr < (u32)(SYSCLK/98.40)) {
+ NDEC=3;
+ SFIL=1;
+ } else if (sr<(u32)(SYSCLK/64.0)) {
+ NDEC=3;
+ SFIL=0;
+ } else if (sr<(u32)(SYSCLK/49.2)) {
+ NDEC=2;
+ SFIL=1;
+ } else if (sr<(u32)(SYSCLK/32.0)) {
+ NDEC=2;
+ SFIL=0;
+ } else if (sr<(u32)(SYSCLK/24.6)) {
+ NDEC=1;
+ SFIL=1;
+ } else if (sr<(u32)(SYSCLK/16.0)) {
+ NDEC=1;
+ SFIL=0;
+ } else if (sr<(u32)(SYSCLK/12.3)) {
+ NDEC=0;
+ SFIL=1;
+ }
+
+ BDRI=SYSCLK*16;
+ BDRI>>=NDEC;
+ BDRI +=sr/2;
+ BDRI /=sr;
+
+ if (BDRI>255)
+ BDRI=255;
+
+ {
+ u64 BDRX;
+
+ BDRX=1<<(24+NDEC);
+ BDRX*=sr;
+ do_div(BDRX,SYSCLK); // BDRX/=SYSCLK;
+
+ BDR=(s32)BDRX;
+ }
+// printk("Symbolrate %i, BDR %i BDRI %i, NDEC %i\n",sr,BDR,BDRI,NDEC);
+ tda10023_writebit (state, 0x03, 0xc0, NDEC<<6);
+ tda10023_writereg (state, 0x0a, BDR&255);
+ tda10023_writereg (state, 0x0b, (BDR>>8)&255);
+ tda10023_writereg (state, 0x0c, (BDR>>16)&31);
+ tda10023_writereg (state, 0x0d, BDRI);
+ tda10023_writereg (state, 0x3d, (SFIL<<7));
+ return 0;
+}
+
+static int tda10023_init (struct dvb_frontend *fe)
+{
+ struct tda10023_state* state = fe->demodulator_priv;
+
+ dprintk("DVB: TDA10023(%d): init chip\n", fe->adapter->num);
+
+ tda10023_writetab(state, tda10023_inittab);
+
+ return 0;
+}
+
+static int tda10023_set_parameters (struct dvb_frontend *fe,
+ struct dvb_frontend_parameters *p)
+{
+ struct tda10023_state* state = fe->demodulator_priv;
+
+ static int qamvals[6][6] = {
+ // QAM LOCKTHR MSETH AREF AGCREFNYQ ERAGCNYQ_THD
+ { (5<<2), 0x78, 0x8c, 0x96, 0x78, 0x4c }, // 4 QAM
+ { (0<<2), 0x87, 0xa2, 0x91, 0x8c, 0x57 }, // 16 QAM
+ { (1<<2), 0x64, 0x74, 0x96, 0x8c, 0x57 }, // 32 QAM
+ { (2<<2), 0x46, 0x43, 0x6a, 0x6a, 0x44 }, // 64 QAM
+ { (3<<2), 0x36, 0x34, 0x7e, 0x78, 0x4c }, // 128 QAM
+ { (4<<2), 0x26, 0x23, 0x6c, 0x5c, 0x3c }, // 256 QAM
+ };
+
+ int qam = p->u.qam.modulation;
+
+ if (qam < 0 || qam > 5)
+ return -EINVAL;
+
+ if (fe->ops.tuner_ops.set_params) {
+ fe->ops.tuner_ops.set_params(fe, p);
+ if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
+ }
+
+ tda10023_set_symbolrate (state, p->u.qam.symbol_rate);
+ tda10023_writereg (state, 0x05, qamvals[qam][1]);
+ tda10023_writereg (state, 0x08, qamvals[qam][2]);
+ tda10023_writereg (state, 0x09, qamvals[qam][3]);
+ tda10023_writereg (state, 0xb4, qamvals[qam][4]);
+ tda10023_writereg (state, 0xb6, qamvals[qam][5]);
+
+// tda10023_writereg (state, 0x04, (p->inversion?0x12:0x32));
+// tda10023_writebit (state, 0x04, 0x60, (p->inversion?0:0x20));
+ tda10023_writebit (state, 0x04, 0x40, 0x40);
+ tda10023_setup_reg0 (state, qamvals[qam][0]);
+
+ return 0;
+}
+
+static int tda10023_read_status(struct dvb_frontend* fe, fe_status_t* status)
+{
+ struct tda10023_state* state = fe->demodulator_priv;
+ int sync;
+
+ *status = 0;
+
+ //0x11[1] == CARLOCK -> Carrier locked
+ //0x11[2] == FSYNC -> Frame synchronisation
+ //0x11[3] == FEL -> Front End locked
+ //0x11[6] == NODVB -> DVB Mode Information
+ sync = tda10023_readreg (state, 0x11);
+
+ if (sync & 2)
+ *status |= FE_HAS_SIGNAL|FE_HAS_CARRIER;
+
+ if (sync & 4)
+ *status |= FE_HAS_SYNC|FE_HAS_VITERBI;
+
+ if (sync & 8)
+ *status |= FE_HAS_LOCK;
+
+ return 0;
+}
+
+static int tda10023_read_ber(struct dvb_frontend* fe, u32* ber)
+{
+ struct tda10023_state* state = fe->demodulator_priv;
+ u8 a,b,c;
+ a=tda10023_readreg(state, 0x14);
+ b=tda10023_readreg(state, 0x15);
+ c=tda10023_readreg(state, 0x16)&0xf;
+ tda10023_writebit (state, 0x10, 0xc0, 0x00);
+
+ *ber = a | (b<<8)| (c<<16);
+ return 0;
+}
+
+static int tda10023_read_signal_strength(struct dvb_frontend* fe, u16* strength)
+{
+ struct tda10023_state* state = fe->demodulator_priv;
+ u8 ifgain=tda10023_readreg(state, 0x2f);
+
+ u16 gain = ((255-tda10023_readreg(state, 0x17))) + (255-ifgain)/16;
+ // Max raw value is about 0xb0 -> Normalize to >0xf0 after 0x90
+ if (gain>0x90)
+ gain=gain+2*(gain-0x90);
+ if (gain>255)
+ gain=255;
+
+ *strength = (gain<<8)|gain;
+ return 0;
+}
+
+static int tda10023_read_snr(struct dvb_frontend* fe, u16* snr)
+{
+ struct tda10023_state* state = fe->demodulator_priv;
+
+ u8 quality = ~tda10023_readreg(state, 0x18);
+ *snr = (quality << 8) | quality;
+ return 0;
+}
+
+static int tda10023_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
+{
+ struct tda10023_state* state = fe->demodulator_priv;
+ u8 a,b,c,d;
+ a= tda10023_readreg (state, 0x74);
+ b= tda10023_readreg (state, 0x75);
+ c= tda10023_readreg (state, 0x76);
+ d= tda10023_readreg (state, 0x77);
+ *ucblocks = a | (b<<8)|(c<<16)|(d<<24);
+
+ tda10023_writebit (state, 0x10, 0x20,0x00);
+ tda10023_writebit (state, 0x10, 0x20,0x20);
+ tda10023_writebit (state, 0x13, 0x01, 0x00);
+
+ return 0;
+}
+
+static int tda10023_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
+{
+ struct tda10023_state* state = fe->demodulator_priv;
+ int sync,inv;
+ s8 afc = 0;
+
+ sync = tda10023_readreg(state, 0x11);
+ afc = tda10023_readreg(state, 0x19);
+ inv = tda10023_readreg(state, 0x04);
+
+ if (verbose) {
+ /* AFC only valid when carrier has been recovered */
+ printk(sync & 2 ? "DVB: TDA10023(%d): AFC (%d) %dHz\n" :
+ "DVB: TDA10023(%d): [AFC (%d) %dHz]\n",
+ state->frontend.dvb->num, afc,
+ -((s32)p->u.qam.symbol_rate * afc) >> 10);
+ }
+
+ p->inversion = (inv&0x20?0:1);
+ p->u.qam.modulation = ((state->reg0 >> 2) & 7) + QAM_16;
+
+ p->u.qam.fec_inner = FEC_NONE;
+ p->frequency = ((p->frequency + 31250) / 62500) * 62500;
+
+ if (sync & 2)
+ p->frequency -= ((s32)p->u.qam.symbol_rate * afc) >> 10;
+
+ return 0;
+}
+
+static int tda10023_sleep(struct dvb_frontend* fe)
+{
+ struct tda10023_state* state = fe->demodulator_priv;
+
+ tda10023_writereg (state, 0x1b, 0x02); /* pdown ADC */
+ tda10023_writereg (state, 0x00, 0x80); /* standby */
+
+ return 0;
+}
+
+static int tda10023_i2c_gate_ctrl(struct dvb_frontend* fe, int enable)
+{
+ struct tda10023_state* state = fe->demodulator_priv;
+
+ if (enable) {
+ lock_tuner(state);
+ } else {
+ unlock_tuner(state);
+ }
+ return 0;
+}
+
+static void tda10023_release(struct dvb_frontend* fe)
+{
+ struct tda10023_state* state = fe->demodulator_priv;
+ kfree(state);
+}
+
+static struct dvb_frontend_ops tda10023_ops;
+
+struct dvb_frontend* tda10023_attach(const struct tda1002x_config* config,
+ struct i2c_adapter* i2c,
+ u8 pwm)
+{
+ struct tda10023_state* state = NULL;
+ int i;
+
+ /* allocate memory for the internal state */
+ state = kmalloc(sizeof(struct tda10023_state), GFP_KERNEL);
+ if (state == NULL) goto error;
+
+ /* setup the state */
+ state->config = config;
+ state->i2c = i2c;
+ memcpy(&state->frontend.ops, &tda10023_ops, sizeof(struct dvb_frontend_ops));
+ state->pwm = pwm;
+ for (i=0; i < sizeof(tda10023_inittab)/sizeof(*tda10023_inittab);i+=3) {
+ if (tda10023_inittab[i] == 0x00) {
+ state->reg0 = tda10023_inittab[i+2];
+ break;
+ }
+ }
+
+ // Wakeup if in standby
+ tda10023_writereg (state, 0x00, 0x33);
+ /* check if the demod is there */
+ if ((tda10023_readreg(state, 0x1a) & 0xf0) != 0x70) goto error;
+
+ /* create dvb_frontend */
+ memcpy(&state->frontend.ops, &tda10023_ops, sizeof(struct dvb_frontend_ops));
+ state->frontend.demodulator_priv = state;
+ return &state->frontend;
+
+error:
+ kfree(state);
+ return NULL;
+}
+
+static struct dvb_frontend_ops tda10023_ops = {
+
+ .info = {
+ .name = "Philips TDA10023 DVB-C",
+ .type = FE_QAM,
+ .frequency_stepsize = 62500,
+ .frequency_min = 51000000,
+ .frequency_max = 858000000,
+ .symbol_rate_min = (SYSCLK/2)/64, /* SACLK/64 == (SYSCLK/2)/64 */
+ .symbol_rate_max = (SYSCLK/2)/4, /* SACLK/4 */
+ #if 0
+ .frequency_tolerance = ???,
+ .symbol_rate_tolerance = ???, /* ppm */ /* == 8% (spec p. 5) */
+ #endif
+ .caps = 0x400 | //FE_CAN_QAM_4
+ FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 |
+ FE_CAN_QAM_128 | FE_CAN_QAM_256 |
+ FE_CAN_FEC_AUTO
+ },
+
+ .release = tda10023_release,
+
+ .init = tda10023_init,
+ .sleep = tda10023_sleep,
+ .i2c_gate_ctrl = tda10023_i2c_gate_ctrl,
+
+ .set_frontend = tda10023_set_parameters,
+ .get_frontend = tda10023_get_frontend,
+
+ .read_status = tda10023_read_status,
+ .read_ber = tda10023_read_ber,
+ .read_signal_strength = tda10023_read_signal_strength,
+ .read_snr = tda10023_read_snr,
+ .read_ucblocks = tda10023_read_ucblocks,
+};
+
+
+MODULE_DESCRIPTION("Philips TDA10023 DVB-C demodulator driver");
+MODULE_AUTHOR("Georg Acher, Hartmut Birr");
+MODULE_LICENSE("GPL");
+
+EXPORT_SYMBOL(tda10023_attach);
diff --git a/linux/drivers/media/dvb/frontends/tda10021.h b/linux/drivers/media/dvb/frontends/tda1002x.h
index e3da78010..e9094d812 100644
--- a/linux/drivers/media/dvb/frontends/tda10021.h
+++ b/linux/drivers/media/dvb/frontends/tda1002x.h
@@ -1,6 +1,6 @@
/*
- TDA10021 - Single Chip Cable Channel Receiver driver module
- used on the the Siemens DVB-C cards
+ TDA10021/TDA10023 - Single Chip Cable Channel Receiver driver module
+ used on the the Siemens DVB-C cards
Copyright (C) 1999 Convergence Integrated Media GmbH <ralph@convergence.de>
Copyright (C) 2004 Markus Schulz <msc@antzsystem.de>
@@ -21,22 +21,23 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#ifndef TDA10021_H
-#define TDA10021_H
+#ifndef TDA1002x_H
+#define TDA1002x_H
#include <linux/dvb/frontend.h>
-struct tda10021_config
+struct tda1002x_config
{
/* the demodulator's i2c address */
u8 demod_address;
+ u8 invert;
};
#if defined(CONFIG_DVB_TDA10021) || (defined(CONFIG_DVB_TDA10021_MODULE) && defined(MODULE))
-extern struct dvb_frontend* tda10021_attach(const struct tda10021_config* config,
+extern struct dvb_frontend* tda10021_attach(const struct tda1002x_config* config,
struct i2c_adapter* i2c, u8 pwm);
#else
-static inline struct dvb_frontend* tda10021_attach(const struct tda10021_config* config,
+static inline struct dvb_frontend* tda10021_attach(const struct tda1002x_config* config,
struct i2c_adapter* i2c, u8 pwm)
{
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*
}
#endif // CONFIG_DVB_TDA10021
-static inline int tda10021_writereg(struct dvb_frontend *fe, u8 reg, u8 val) {
- int r = 0;
- u8 buf[] = {reg, val};
- if (fe->ops.write)
- r = fe->ops.write(fe, buf, 2);
- return r;
+#if defined(CONFIG_DVB_TDA10023) || (defined(CONFIG_DVB_TDA10023_MODULE) && defined(MODULE))
+extern struct dvb_frontend* tda10023_attach(const struct tda1002x_config* config,
+ struct i2c_adapter* i2c, u8 pwm);
+#else
+static inline struct dvb_frontend* tda10023_attach(const struct tda1002x_config* config,
+ struct i2c_adapter* i2c, u8 pwm)
+{
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
+ return NULL;
}
+#endif // CONFIG_DVB_TDA10023
-#endif // TDA10021_H
+#endif // TDA1002x_H
diff --git a/linux/drivers/media/dvb/frontends/tda10086.c b/linux/drivers/media/dvb/frontends/tda10086.c
index 4c27a2d90..ccc429cbb 100644
--- a/linux/drivers/media/dvb/frontends/tda10086.c
+++ b/linux/drivers/media/dvb/frontends/tda10086.c
@@ -212,7 +212,7 @@ static int tda10086_send_master_cmd (struct dvb_frontend* fe,
for(i=0; i< cmd->msg_len; i++) {
tda10086_write_byte(state, 0x48+i, cmd->msg[i]);
}
- tda10086_write_byte(state, 0x36, 0x08 | ((cmd->msg_len + 1) << 4));
+ tda10086_write_byte(state, 0x36, 0x08 | ((cmd->msg_len - 1) << 4));
tda10086_diseqc_wait(state);
diff --git a/linux/drivers/media/dvb/frontends/tda827x.c b/linux/drivers/media/dvb/frontends/tda827x.c
index 8176a9b58..256fc4bf5 100644
--- a/linux/drivers/media/dvb/frontends/tda827x.c
+++ b/linux/drivers/media/dvb/frontends/tda827x.c
@@ -91,6 +91,7 @@ static int tda827xo_set_params(struct dvb_frontend *fe,
int i, tuner_freq, if_freq;
u32 N;
+ dprintk("%s:\n", __FUNCTION__);
switch (params->u.ofdm.bandwidth) {
case BANDWIDTH_6_MHZ:
if_freq = 4000000;
@@ -159,6 +160,7 @@ static int tda827xo_sleep(struct dvb_frontend *fe)
struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0,
.buf = buf, .len = sizeof(buf) };
+ dprintk("%s:\n", __FUNCTION__);
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 1);
i2c_transfer(priv->i2c_adap, &msg, 1);
@@ -222,6 +224,7 @@ static int tda827xa_set_params(struct dvb_frontend *fe,
int i, tuner_freq, if_freq;
u32 N;
+ dprintk("%s:\n", __FUNCTION__);
if (priv->cfg && priv->cfg->lna_gain)
priv->cfg->lna_gain(fe, 1);
msleep(20);
@@ -350,6 +353,7 @@ static int tda827xa_sleep(struct dvb_frontend *fe)
struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0,
.buf = buf, .len = sizeof(buf) };
+ dprintk("%s:\n", __FUNCTION__);
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 1);
@@ -388,13 +392,32 @@ static int tda827x_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
static int tda827x_init(struct dvb_frontend *fe)
{
struct tda827x_priv *priv = fe->tuner_priv;
-
+ dprintk("%s:\n", __FUNCTION__);
if (priv->cfg && priv->cfg->init)
priv->cfg->init(fe);
return 0;
}
+static int tda827x_probe_version(struct dvb_frontend *fe);
+
+static int tda827x_initial_init(struct dvb_frontend *fe)
+{
+ int ret;
+ ret = tda827x_probe_version(fe);
+ if (ret)
+ return ret;
+ return fe->ops.tuner_ops.init(fe);
+}
+
+static int tda827x_initial_sleep(struct dvb_frontend *fe)
+{
+ int ret;
+ ret = tda827x_probe_version(fe);
+ if (ret)
+ return ret;
+ return fe->ops.tuner_ops.sleep(fe);
+}
static struct dvb_tuner_ops tda827xo_tuner_ops = {
.info = {
@@ -404,8 +427,8 @@ static struct dvb_tuner_ops tda827xo_tuner_ops = {
.frequency_step = 250000
},
.release = tda827x_release,
- .init = tda827x_init,
- .sleep = tda827xo_sleep,
+ .init = tda827x_initial_init,
+ .sleep = tda827x_initial_sleep,
.set_params = tda827xo_set_params,
.get_frequency = tda827x_get_frequency,
.get_bandwidth = tda827x_get_bandwidth,
@@ -426,26 +449,36 @@ static struct dvb_tuner_ops tda827xa_tuner_ops = {
.get_bandwidth = tda827x_get_bandwidth,
};
-struct dvb_frontend *tda827x_attach(struct dvb_frontend *fe, int addr,
- struct i2c_adapter *i2c,
- struct tda827x_config *cfg)
-{
- struct tda827x_priv *priv = NULL;
- u8 data;
- u8 sb_msg[] = { 0x30, 0xd0 };
- struct i2c_msg msg = { .addr = addr, .flags = I2C_M_RD,
+static int tda827x_probe_version(struct dvb_frontend *fe)
+{ u8 data;
+ struct tda827x_priv *priv = fe->tuner_priv;
+ struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = I2C_M_RD,
.buf = &data, .len = 1 };
- dprintk("%s:\n", __FUNCTION__);
-
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 1);
-
- if (i2c_transfer(i2c, &msg, 1) != 1) {
+ if (i2c_transfer(priv->i2c_adap, &msg, 1) != 1) {
printk("%s: could not read from tuner at addr: 0x%02x\n",
- __FUNCTION__, addr << 1);
- return NULL;
+ __FUNCTION__, msg.addr << 1);
+ return -EIO;
+ }
+ if ((data & 0x3c) == 0) {
+ dprintk("tda827x tuner found\n");
+ fe->ops.tuner_ops.init = tda827x_init;
+ fe->ops.tuner_ops.sleep = tda827xo_sleep;
+ } else {
+ dprintk("tda827xa tuner found\n");
+ memcpy(&fe->ops.tuner_ops, &tda827xa_tuner_ops, sizeof(struct dvb_tuner_ops));
}
+ return 0;
+}
+
+struct dvb_frontend *tda827x_attach(struct dvb_frontend *fe, int addr,
+ struct i2c_adapter *i2c,
+ struct tda827x_config *cfg)
+{
+ struct tda827x_priv *priv = NULL;
+ dprintk("%s:\n", __FUNCTION__);
priv = kzalloc(sizeof(struct tda827x_priv), GFP_KERNEL);
if (priv == NULL)
return NULL;
@@ -453,25 +486,13 @@ struct dvb_frontend *tda827x_attach(struct dvb_frontend *fe, int addr,
priv->i2c_addr = addr;
priv->i2c_adap = i2c;
priv->cfg = cfg;
+ memcpy(&fe->ops.tuner_ops, &tda827xo_tuner_ops, sizeof(struct dvb_tuner_ops));
- msg.flags = 0;
- msg.buf = sb_msg;
- msg.len = sizeof(sb_msg);
-
- if ((data & 0x3c) == 0) {
- dprintk("tda827x tuner found\n");
- memcpy(&fe->ops.tuner_ops, &tda827xo_tuner_ops, sizeof(struct dvb_tuner_ops));
- } else {
- dprintk("tda827xa tuner found\n");
- memcpy(&fe->ops.tuner_ops, &tda827xa_tuner_ops, sizeof(struct dvb_tuner_ops));
- sb_msg[1] = 0x90;
- }
fe->tuner_priv = priv;
- if (fe->ops.i2c_gate_ctrl)
- fe->ops.i2c_gate_ctrl(fe, 1);
- i2c_transfer(i2c, &msg, 1);
+
return fe;
}
+
EXPORT_SYMBOL(tda827x_attach);
module_param(debug, int, 0644);
diff --git a/linux/drivers/media/dvb/pluto2/pluto2.c b/linux/drivers/media/dvb/pluto2/pluto2.c
index cb049d1a8..b104e63eb 100644
--- a/linux/drivers/media/dvb/pluto2/pluto2.c
+++ b/linux/drivers/media/dvb/pluto2/pluto2.c
@@ -149,6 +149,15 @@ static inline void pluto_rw(struct pluto *pluto, u32 reg, u32 mask, u32 bits)
writel(val, &pluto->io_mem[reg]);
}
+static void pluto_write_tscr(struct pluto *pluto, u32 val)
+{
+ /* set the number of packets */
+ val &= ~TSCR_ADEF;
+ val |= TS_DMA_PACKETS / 2;
+
+ pluto_writereg(pluto, REG_TSCR, val);
+}
+
static void pluto_setsda(void *data, int state)
{
struct pluto *pluto = data;
@@ -213,11 +222,11 @@ static void pluto_reset_ts(struct pluto *pluto, int reenable)
if (val & TSCR_RSTN) {
val &= ~TSCR_RSTN;
- pluto_writereg(pluto, REG_TSCR, val);
+ pluto_write_tscr(pluto, val);
}
if (reenable) {
val |= TSCR_RSTN;
- pluto_writereg(pluto, REG_TSCR, val);
+ pluto_write_tscr(pluto, val);
}
}
@@ -284,12 +293,20 @@ static void pluto_dma_end(struct pluto *pluto, unsigned int nbpackets)
* but no packets have been transfered.
* [2] Sometimes (actually very often) NBPACKETS stays at zero
* although one packet has been transfered.
+ * [3] Sometimes (actually rarely), the card gets into an erroneous
+ * mode where it continuously generates interrupts, claiming it
+ * has recieved nbpackets>TS_DMA_PACKETS packets, but no packet
+ * has been transfered. Only a reset seems to solve this
*/
if ((nbpackets == 0) || (nbpackets > TS_DMA_PACKETS)) {
unsigned int i = 0;
while (pluto->dma_buf[i] == 0x47)
i += 188;
nbpackets = i / 188;
+ if (i == 0) {
+ pluto_reset_ts(pluto, 1);
+ dev_printk(KERN_DEBUG, &pluto->pdev->dev, "resetting TS because of invalid packet counter\n");
+ }
}
dvb_dmx_swfilter_packets(&pluto->demux, pluto->dma_buf, nbpackets);
@@ -343,7 +360,7 @@ static irqreturn_t pluto_irq(int irq, void *dev_id)
}
/* ACK the interrupt */
- pluto_writereg(pluto, REG_TSCR, tscr | TSCR_IACK);
+ pluto_write_tscr(pluto, tscr | TSCR_IACK);
return IRQ_HANDLED;
}
@@ -352,9 +369,6 @@ static void __devinit pluto_enable_irqs(struct pluto *pluto)
{
u32 val = pluto_readreg(pluto, REG_TSCR);
- /* set the number of packets */
- val &= ~TSCR_ADEF;
- val |= TS_DMA_PACKETS / 2;
/* disable AFUL and LOCK interrupts */
val |= (TSCR_MSKA | TSCR_MSKL);
/* enable DMA and OVERFLOW interrupts */
@@ -362,7 +376,7 @@ static void __devinit pluto_enable_irqs(struct pluto *pluto)
/* clear pending interrupts */
val |= TSCR_IACK;
- pluto_writereg(pluto, REG_TSCR, val);
+ pluto_write_tscr(pluto, val);
}
static void pluto_disable_irqs(struct pluto *pluto)
@@ -374,7 +388,7 @@ static void pluto_disable_irqs(struct pluto *pluto)
/* clear pending interrupts */
val |= TSCR_IACK;
- pluto_writereg(pluto, REG_TSCR, val);
+ pluto_write_tscr(pluto, val);
}
static int __devinit pluto_hw_init(struct pluto *pluto)
diff --git a/linux/drivers/media/dvb/ttpci/Kconfig b/linux/drivers/media/dvb/ttpci/Kconfig
index 3cd319ff0..7751628e1 100644
--- a/linux/drivers/media/dvb/ttpci/Kconfig
+++ b/linux/drivers/media/dvb/ttpci/Kconfig
@@ -67,6 +67,7 @@ config DVB_BUDGET
select DVB_L64781 if !DVB_FE_CUSTOMISE
select DVB_TDA8083 if !DVB_FE_CUSTOMISE
select DVB_TDA10021 if !DVB_FE_CUSTOMISE
+ select DVB_TDA10023 if !DVB_FE_CUSTOMISE
select DVB_S5H1420 if !DVB_FE_CUSTOMISE
select DVB_TDA10086 if !DVB_FE_CUSTOMISE
select DVB_TDA826X if !DVB_FE_CUSTOMISE
@@ -111,6 +112,7 @@ config DVB_BUDGET_AV
select DVB_STV0299 if !DVB_FE_CUSTOMISE
select DVB_TDA1004X if !DVB_FE_CUSTOMISE
select DVB_TDA10021 if !DVB_FE_CUSTOMISE
+ select DVB_TDA10023 if !DVB_FE_CUSTOMISE
select DVB_TUA6100 if !DVB_FE_CUSTOMISE
select FW_LOADER
help
diff --git a/linux/drivers/media/dvb/ttpci/av7110.c b/linux/drivers/media/dvb/ttpci/av7110.c
index 77ccd99ad..3b31c294d 100644
--- a/linux/drivers/media/dvb/ttpci/av7110.c
+++ b/linux/drivers/media/dvb/ttpci/av7110.c
@@ -1246,6 +1246,9 @@ static void vpeirq(unsigned long data)
if (!budget->feeding1 || (newdma == olddma))
return;
+ /* Ensure streamed PCI data is synced to CPU */
+ pci_dma_sync_sg_for_cpu(budget->dev->pci, budget->pt.slist, budget->pt.nents, PCI_DMA_FROMDEVICE);
+
#if 0 /* keep */
/* track rps1 activity */
printk("vpeirq: %02x Event Counter 1 0x%04x\n",
@@ -2679,8 +2682,8 @@ err_iobuf_vfree_6:
err_pci_free_5:
pci_free_consistent(pdev, 8192, av7110->debi_virt, av7110->debi_bus);
err_saa71466_vfree_4:
- if (!av7110->grabbing)
- saa7146_pgtable_free(pdev, &av7110->pt);
+ if (av7110->grabbing)
+ saa7146_vfree_destroy_pgtable(pdev, av7110->grabbing, &av7110->pt);
err_i2c_del_3:
i2c_del_adapter(&av7110->i2c_adap);
err_dvb_unregister_adapter_2:
@@ -2710,7 +2713,7 @@ static int __devexit av7110_detach(struct saa7146_dev* saa)
SAA7146_ISR_CLEAR(saa, MASK_10);
msleep(50);
tasklet_kill(&av7110->vpe_tasklet);
- saa7146_pgtable_free(saa->pci, &av7110->pt);
+ saa7146_vfree_destroy_pgtable(saa->pci, av7110->grabbing, &av7110->pt);
}
av7110_exit_v4l(av7110);
diff --git a/linux/drivers/media/dvb/ttpci/budget-av.c b/linux/drivers/media/dvb/ttpci/budget-av.c
index 3035b224c..0e817d6f1 100644
--- a/linux/drivers/media/dvb/ttpci/budget-av.c
+++ b/linux/drivers/media/dvb/ttpci/budget-av.c
@@ -35,7 +35,7 @@
#include "budget.h"
#include "stv0299.h"
-#include "tda10021.h"
+#include "tda1002x.h"
#include "tda1004x.h"
#include "tua6100.h"
#include "dvb-pll.h"
@@ -66,9 +66,6 @@ struct budget_av {
int slot_status;
struct dvb_ca_en50221 ca;
u8 reinitialise_demod:1;
- u8 tda10021_poclkp:1;
- u8 tda10021_ts_enabled;
- int (*tda10021_set_frontend)(struct dvb_frontend *fe, struct dvb_frontend_parameters *p);
};
static 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)
if (budget_av->reinitialise_demod)
dvb_frontend_reinitialise(budget_av->budget.dvb_frontend);
- /* set tda10021 back to original clock configuration on reset */
- if (budget_av->tda10021_poclkp) {
- tda10021_writereg(budget_av->budget.dvb_frontend, 0x12, 0xa0);
- budget_av->tda10021_ts_enabled = 0;
- }
-
return 0;
}
@@ -256,11 +247,6 @@ static int ciintf_slot_shutdown(struct dvb_ca_en50221 *ca, int slot)
ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTB);
budget_av->slot_status = SLOTSTATUS_NONE;
- /* set tda10021 back to original clock configuration when cam removed */
- if (budget_av->tda10021_poclkp) {
- tda10021_writereg(budget_av->budget.dvb_frontend, 0x12, 0xa0);
- budget_av->tda10021_ts_enabled = 0;
- }
return 0;
}
@@ -276,12 +262,6 @@ static int ciintf_slot_ts_enable(struct dvb_ca_en50221 *ca, int slot)
ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTA);
- /* tda10021 seems to need a different TS clock config when data is routed to the CAM */
- if (budget_av->tda10021_poclkp) {
- tda10021_writereg(budget_av->budget.dvb_frontend, 0x12, 0xa1);
- budget_av->tda10021_ts_enabled = 1;
- }
-
return 0;
}
@@ -631,37 +611,62 @@ static struct stv0299_config cinergy_1200s_1894_0010_config = {
static int philips_cu1216_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
{
struct budget *budget = (struct budget *) fe->dvb->priv;
- u8 buf[4];
+ u8 buf[6];
struct i2c_msg msg = {.addr = 0x60,.flags = 0,.buf = buf,.len = sizeof(buf) };
+ int i;
+#define CU1216_IF 36125000
#define TUNER_MUL 62500
- u32 div = (params->frequency + 36125000 + TUNER_MUL / 2) / TUNER_MUL;
+ u32 div = (params->frequency + CU1216_IF + TUNER_MUL / 2) / TUNER_MUL;
buf[0] = (div >> 8) & 0x7f;
buf[1] = div & 0xff;
- buf[2] = 0x86;
+ buf[2] = 0xce;
buf[3] = (params->frequency < 150000000 ? 0x01 :
params->frequency < 445000000 ? 0x02 : 0x04);
+ buf[4] = 0xde;
+ buf[5] = 0x20;
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 1);
+ if (i2c_transfer(&budget->i2c_adap, &msg, 1) != 1)
+ return -EIO;
+ /* wait for the pll lock */
+ msg.flags = I2C_M_RD;
+ msg.len = 1;
+ for (i = 0; i < 20; i++) {
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 1);
+ if (i2c_transfer(&budget->i2c_adap, &msg, 1) == 1 && (buf[0] & 0x40))
+ break;
+ msleep(10);
+ }
+
+ /* switch the charge pump to the lower current */
+ msg.flags = 0;
+ msg.len = 2;
+ msg.buf = &buf[2];
+ buf[2] &= ~0x40;
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 1);
if (i2c_transfer(&budget->i2c_adap, &msg, 1) != 1)
return -EIO;
+
return 0;
}
-static struct tda10021_config philips_cu1216_config = {
+static struct tda1002x_config philips_cu1216_config = {
.demod_address = 0x0c,
+ .invert = 1,
};
-static struct tda10021_config philips_cu1216_config_altaddress = {
+static struct tda1002x_config philips_cu1216_config_altaddress = {
.demod_address = 0x0d,
+ .invert = 0,
};
-
-
-
static int philips_tu1216_tuner_init(struct dvb_frontend *fe)
{
struct budget *budget = (struct budget *) fe->dvb->priv;
@@ -908,41 +913,28 @@ static u8 read_pwm(struct budget_av *budget_av)
return pwm;
}
-#define SUBID_DVBS_KNC1 0x0010
-#define SUBID_DVBS_KNC1_PLUS 0x0011
-#define SUBID_DVBS_TYPHOON 0x4f56
-#define SUBID_DVBS_CINERGY1200 0x1154
-#define SUBID_DVBS_CYNERGY1200N 0x1155
-
-#define SUBID_DVBS_TV_STAR 0x0014
-#define SUBID_DVBS_TV_STAR_CI 0x0016
-#define SUBID_DVBS_EASYWATCH_1 0x001a
-#define SUBID_DVBS_EASYWATCH 0x001e
-#define SUBID_DVBC_EASYWATCH 0x002a
-#define SUBID_DVBC_KNC1 0x0020
-#define SUBID_DVBC_KNC1_PLUS 0x0021
-#define SUBID_DVBC_CINERGY1200 0x1156
-
-#define SUBID_DVBT_KNC1_PLUS 0x0031
-#define SUBID_DVBT_KNC1 0x0030
-#define SUBID_DVBT_CINERGY1200 0x1157
-
-
-static int tda10021_set_frontend(struct dvb_frontend *fe,
- struct dvb_frontend_parameters *p)
-{
- struct budget_av* budget_av = fe->dvb->priv;
- int result;
-
- result = budget_av->tda10021_set_frontend(fe, p);
- if (budget_av->tda10021_ts_enabled) {
- tda10021_writereg(budget_av->budget.dvb_frontend, 0x12, 0xa1);
- } else {
- tda10021_writereg(budget_av->budget.dvb_frontend, 0x12, 0xa0);
- }
-
- return result;
-}
+#define SUBID_DVBS_KNC1 0x0010
+#define SUBID_DVBS_KNC1_PLUS 0x0011
+#define SUBID_DVBS_TYPHOON 0x4f56
+#define SUBID_DVBS_CINERGY1200 0x1154
+#define SUBID_DVBS_CYNERGY1200N 0x1155
+#define SUBID_DVBS_TV_STAR 0x0014
+#define SUBID_DVBS_TV_STAR_CI 0x0016
+#define SUBID_DVBS_EASYWATCH_1 0x001a
+#define SUBID_DVBS_EASYWATCH 0x001e
+
+#define SUBID_DVBC_EASYWATCH 0x002a
+#define SUBID_DVBC_EASYWATCH_MK3 0x002c
+#define SUBID_DVBC_KNC1 0x0020
+#define SUBID_DVBC_KNC1_PLUS 0x0021
+#define SUBID_DVBC_KNC1_MK3 0x0022
+#define SUBID_DVBC_KNC1_PLUS_MK3 0x0023
+#define SUBID_DVBC_CINERGY1200 0x1156
+#define SUBID_DVBC_CINERGY1200_MK3 0x1176
+
+#define SUBID_DVBT_KNC1_PLUS 0x0031
+#define SUBID_DVBT_KNC1 0x0030
+#define SUBID_DVBT_CINERGY1200 0x1157
static void frontend_init(struct budget_av *budget_av)
{
@@ -961,6 +953,7 @@ static void frontend_init(struct budget_av *budget_av)
case SUBID_DVBC_KNC1_PLUS:
case SUBID_DVBT_KNC1_PLUS:
case SUBID_DVBC_EASYWATCH:
+ case SUBID_DVBC_KNC1_PLUS_MK3:
saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTHI);
break;
}
@@ -1017,6 +1010,7 @@ static void frontend_init(struct budget_av *budget_av)
case SUBID_DVBC_CINERGY1200:
case SUBID_DVBC_EASYWATCH:
budget_av->reinitialise_demod = 1;
+ budget_av->budget.dev->i2c_bitrate = SAA7146_I2C_BUS_BIT_RATE_240;
fe = dvb_attach(tda10021_attach, &philips_cu1216_config,
&budget_av->budget.i2c_adap,
read_pwm(budget_av));
@@ -1025,9 +1019,20 @@ static void frontend_init(struct budget_av *budget_av)
&budget_av->budget.i2c_adap,
read_pwm(budget_av));
if (fe) {
- budget_av->tda10021_poclkp = 1;
- budget_av->tda10021_set_frontend = fe->ops.set_frontend;
- fe->ops.set_frontend = tda10021_set_frontend;
+ fe->ops.tuner_ops.set_params = philips_cu1216_tuner_set_params;
+ }
+ break;
+
+ case SUBID_DVBC_EASYWATCH_MK3:
+ case SUBID_DVBC_CINERGY1200_MK3:
+ case SUBID_DVBC_KNC1_MK3:
+ case SUBID_DVBC_KNC1_PLUS_MK3:
+ budget_av->reinitialise_demod = 1;
+ budget_av->budget.dev->i2c_bitrate = SAA7146_I2C_BUS_BIT_RATE_240;
+ fe = dvb_attach(tda10023_attach, &philips_cu1216_config,
+ &budget_av->budget.i2c_adap,
+ read_pwm(budget_av));
+ if (fe) {
fe->ops.tuner_ops.set_params = philips_cu1216_tuner_set_params;
}
break;
@@ -1260,12 +1265,16 @@ MAKE_BUDGET_INFO(kncxs, "KNC TV STAR DVB-S", BUDGET_TVSTAR);
MAKE_BUDGET_INFO(satewpls, "Satelco EasyWatch DVB-S light", BUDGET_TVSTAR);
MAKE_BUDGET_INFO(satewpls1, "Satelco EasyWatch DVB-S light", BUDGET_KNC1S);
MAKE_BUDGET_INFO(satewplc, "Satelco EasyWatch DVB-C", BUDGET_KNC1CP);
+MAKE_BUDGET_INFO(satewcmk3, "Satelco EasyWatch DVB-C MK3", BUDGET_KNC1C_MK3);
MAKE_BUDGET_INFO(knc1sp, "KNC1 DVB-S Plus", BUDGET_KNC1SP);
MAKE_BUDGET_INFO(knc1cp, "KNC1 DVB-C Plus", BUDGET_KNC1CP);
+MAKE_BUDGET_INFO(knc1cmk3, "KNC1 DVB-C MK3", BUDGET_KNC1C_MK3);
+MAKE_BUDGET_INFO(knc1cpmk3, "KNC1 DVB-C Plus MK3", BUDGET_KNC1CP_MK3);
MAKE_BUDGET_INFO(knc1tp, "KNC1 DVB-T Plus", BUDGET_KNC1TP);
MAKE_BUDGET_INFO(cin1200s, "TerraTec Cinergy 1200 DVB-S", BUDGET_CIN1200S);
MAKE_BUDGET_INFO(cin1200sn, "TerraTec Cinergy 1200 DVB-S", BUDGET_CIN1200S);
MAKE_BUDGET_INFO(cin1200c, "Terratec Cinergy 1200 DVB-C", BUDGET_CIN1200C);
+MAKE_BUDGET_INFO(cin1200cmk3, "Terratec Cinergy 1200 DVB-C MK3", BUDGET_CIN1200C_MK3);
MAKE_BUDGET_INFO(cin1200t, "Terratec Cinergy 1200 DVB-T", BUDGET_CIN1200T);
static struct pci_device_id pci_tbl[] = {
@@ -1279,13 +1288,17 @@ static struct pci_device_id pci_tbl[] = {
MAKE_EXTENSION_PCI(satewpls, 0x1894, 0x001e),
MAKE_EXTENSION_PCI(satewpls1, 0x1894, 0x001a),
MAKE_EXTENSION_PCI(satewplc, 0x1894, 0x002a),
+ MAKE_EXTENSION_PCI(satewcmk3, 0x1894, 0x002c),
MAKE_EXTENSION_PCI(knc1c, 0x1894, 0x0020),
MAKE_EXTENSION_PCI(knc1cp, 0x1894, 0x0021),
+ MAKE_EXTENSION_PCI(knc1cmk3, 0x1894, 0x0022),
+ MAKE_EXTENSION_PCI(knc1cpmk3, 0x1894, 0x0023),
MAKE_EXTENSION_PCI(knc1t, 0x1894, 0x0030),
MAKE_EXTENSION_PCI(knc1tp, 0x1894, 0x0031),
MAKE_EXTENSION_PCI(cin1200s, 0x153b, 0x1154),
MAKE_EXTENSION_PCI(cin1200sn, 0x153b, 0x1155),
MAKE_EXTENSION_PCI(cin1200c, 0x153b, 0x1156),
+ MAKE_EXTENSION_PCI(cin1200cmk3, 0x153b, 0x1176),
MAKE_EXTENSION_PCI(cin1200t, 0x153b, 0x1157),
{
.vendor = 0,
diff --git a/linux/drivers/media/dvb/ttpci/budget-ci.c b/linux/drivers/media/dvb/ttpci/budget-ci.c
index 0152eff90..302c5a786 100644
--- a/linux/drivers/media/dvb/ttpci/budget-ci.c
+++ b/linux/drivers/media/dvb/ttpci/budget-ci.c
@@ -910,7 +910,7 @@ static int dvbc_philips_tdm1316l_tuner_set_params(struct dvb_frontend *fe, struc
band = 1;
} else if (tuner_frequency < 200000000) {
cp = 6;
- band = 2;
+ band = 1;
} else if (tuner_frequency < 290000000) {
cp = 3;
band = 2;
diff --git a/linux/drivers/media/dvb/ttpci/budget-core.c b/linux/drivers/media/dvb/ttpci/budget-core.c
index e15562f81..2557ac962 100644
--- a/linux/drivers/media/dvb/ttpci/budget-core.c
+++ b/linux/drivers/media/dvb/ttpci/budget-core.c
@@ -41,11 +41,14 @@
#define TS_WIDTH (2 * TS_SIZE)
#define TS_WIDTH_ACTIVY TS_SIZE
+#define TS_WIDTH_DVBC TS_SIZE
#define TS_HEIGHT_MASK 0xf00
#define TS_HEIGHT_MASK_ACTIVY 0xc00
+#define TS_HEIGHT_MASK_DVBC 0xe00
#define TS_MIN_BUFSIZE_K 188
#define TS_MAX_BUFSIZE_K 1410
#define TS_MAX_BUFSIZE_K_ACTIVY 564
+#define TS_MAX_BUFSIZE_K_DVBC 1316
#define BUFFER_WARNING_WAIT (30*HZ)
int budget_debug;
@@ -106,6 +109,19 @@ static int start_ts_capture(struct budget *budget)
saa7146_write(dev, MC2, (MASK_10 | MASK_26));
saa7146_write(dev, BRS_CTRL, 0x60000000);
break;
+ case BUDGET_CIN1200C_MK3:
+ case BUDGET_KNC1C_MK3:
+ case BUDGET_KNC1CP_MK3:
+ if (budget->video_port == BUDGET_VIDEO_PORTA) {
+ saa7146_write(dev, DD1_INIT, 0x06000200);
+ saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26));
+ saa7146_write(dev, BRS_CTRL, 0x00000000);
+ } else {
+ saa7146_write(dev, DD1_INIT, 0x00000600);
+ saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26));
+ saa7146_write(dev, BRS_CTRL, 0x60000000);
+ }
+ break;
default:
if (budget->video_port == BUDGET_VIDEO_PORTA) {
saa7146_write(dev, DD1_INIT, 0x06000200);
@@ -122,7 +138,13 @@ static int start_ts_capture(struct budget *budget)
mdelay(10);
saa7146_write(dev, BASE_ODD3, 0);
- saa7146_write(dev, BASE_EVEN3, 0);
+ if (budget->buffer_size > budget->buffer_height * budget->buffer_width) {
+ // using odd/even buffers
+ saa7146_write(dev, BASE_EVEN3, budget->buffer_height * budget->buffer_width);
+ } else {
+ // using a single buffer
+ saa7146_write(dev, BASE_EVEN3, 0);
+ }
saa7146_write(dev, PROT_ADDR3, budget->buffer_size);
saa7146_write(dev, BASE_PAGE3, budget->pt.dma | ME1 | 0x90);
@@ -173,6 +195,9 @@ static void vpeirq(unsigned long data)
u32 newdma = saa7146_read(budget->dev, PCI_VDP3);
u32 count;
+ /* Ensure streamed PCI data is synced to CPU */
+ pci_dma_sync_sg_for_cpu(budget->dev->pci, budget->pt.slist, budget->pt.nents, PCI_DMA_FROMDEVICE);
+
/* nearest lower position divisible by 188 */
newdma -= newdma % 188;
@@ -399,11 +424,25 @@ int ttpci_budget_init(struct budget *budget, struct saa7146_dev *dev,
budget->card = bi;
budget->dev = (struct saa7146_dev *) dev;
- if (budget->card->type == BUDGET_FS_ACTIVY) {
+ switch(budget->card->type) {
+ case BUDGET_FS_ACTIVY:
budget->buffer_width = TS_WIDTH_ACTIVY;
max_bufsize = TS_MAX_BUFSIZE_K_ACTIVY;
height_mask = TS_HEIGHT_MASK_ACTIVY;
- } else {
+ break;
+
+ case BUDGET_KNC1C:
+ case BUDGET_KNC1CP:
+ case BUDGET_CIN1200C:
+ case BUDGET_KNC1C_MK3:
+ case BUDGET_KNC1CP_MK3:
+ case BUDGET_CIN1200C_MK3:
+ budget->buffer_width = TS_WIDTH_DVBC;
+ max_bufsize = TS_MAX_BUFSIZE_K_DVBC;
+ height_mask = TS_HEIGHT_MASK_DVBC;
+ break;
+
+ default:
budget->buffer_width = TS_WIDTH;
max_bufsize = TS_MAX_BUFSIZE_K;
height_mask = TS_HEIGHT_MASK;
@@ -415,14 +454,22 @@ int ttpci_budget_init(struct budget *budget, struct saa7146_dev *dev,
dma_buffer_size = max_bufsize;
budget->buffer_height = dma_buffer_size * 1024 / budget->buffer_width;
- budget->buffer_height &= height_mask;
- budget->buffer_size = budget->buffer_height * budget->buffer_width;
+ if (budget->buffer_height > 0xfff) {
+ budget->buffer_height /= 2;
+ budget->buffer_height &= height_mask;
+ budget->buffer_size = 2 * budget->buffer_height * budget->buffer_width;
+ } else {
+ budget->buffer_height &= height_mask;
+ budget->buffer_size = budget->buffer_height * budget->buffer_width;
+ }
budget->buffer_warning_threshold = budget->buffer_size * 80/100;
budget->buffer_warnings = 0;
budget->buffer_warning_time = jiffies;
- dprintk(2, "%s: width = %d, height = %d\n",
- budget->dev->name, budget->buffer_width, budget->buffer_height);
+ dprintk(2, "%s: buffer type = %s, width = %d, height = %d\n",
+ budget->dev->name,
+ budget->buffer_size > budget->buffer_width * budget->buffer_height ? "odd/even" : "single",
+ budget->buffer_width, budget->buffer_height);
printk("%s: dma buffer size %u\n", budget->dev->name, budget->buffer_size);
if ((ret = dvb_register_adapter(&budget->dvb_adapter, budget->card->name, owner, &budget->dev->pci->dev)) < 0) {
@@ -460,16 +507,16 @@ int ttpci_budget_init(struct budget *budget, struct saa7146_dev *dev,
strcpy(budget->i2c_adap.name, budget->card->name);
if (i2c_add_adapter(&budget->i2c_adap) < 0) {
- dvb_unregister_adapter(&budget->dvb_adapter);
- return -ENOMEM;
+ ret = -ENOMEM;
+ goto err_dvb_unregister;
}
ttpci_eeprom_parse_mac(&budget->i2c_adap, budget->dvb_adapter.proposed_mac);
- if (NULL ==
- (budget->grabbing = saa7146_vmalloc_build_pgtable(dev->pci, budget->buffer_size, &budget->pt))) {
+ budget->grabbing = saa7146_vmalloc_build_pgtable(dev->pci, budget->buffer_size, &budget->pt);
+ if (NULL == budget->grabbing) {
ret = -ENOMEM;
- goto err;
+ goto err_del_i2c;
}
saa7146_write(dev, PCI_BT_V1, 0x001c0000);
@@ -482,14 +529,16 @@ int ttpci_budget_init(struct budget *budget, struct saa7146_dev *dev,
if (bi->type != BUDGET_FS_ACTIVY)
saa7146_setgpio(dev, 2, SAA7146_GPIO_OUTHI);
- if (budget_register(budget) == 0) {
- return 0;
- }
-err:
- i2c_del_adapter(&budget->i2c_adap);
+ if (budget_register(budget) == 0)
+ return 0; /* Everything OK */
- vfree(budget->grabbing);
+ /* An error occurred, cleanup resources */
+ saa7146_vfree_destroy_pgtable(dev->pci, budget->grabbing, &budget->pt);
+err_del_i2c:
+ i2c_del_adapter(&budget->i2c_adap);
+
+err_dvb_unregister:
dvb_unregister_adapter(&budget->dvb_adapter);
return ret;
@@ -511,15 +560,13 @@ int ttpci_budget_deinit(struct budget *budget)
budget_unregister(budget);
- i2c_del_adapter(&budget->i2c_adap);
-
- dvb_unregister_adapter(&budget->dvb_adapter);
-
tasklet_kill(&budget->vpe_tasklet);
- saa7146_pgtable_free(dev->pci, &budget->pt);
+ saa7146_vfree_destroy_pgtable(dev->pci, budget->grabbing, &budget->pt);
+
+ i2c_del_adapter(&budget->i2c_adap);
- vfree(budget->grabbing);
+ dvb_unregister_adapter(&budget->dvb_adapter);
return 0;
}
diff --git a/linux/drivers/media/dvb/ttpci/budget.h b/linux/drivers/media/dvb/ttpci/budget.h
index 8a20d59b7..94922db7a 100644
--- a/linux/drivers/media/dvb/ttpci/budget.h
+++ b/linux/drivers/media/dvb/ttpci/budget.h
@@ -107,6 +107,9 @@ static struct saa7146_pci_extension_data x_var = { \
#define BUDGET_KNC1CP 12
#define BUDGET_KNC1TP 13
#define BUDGET_TVSTAR 14
+#define BUDGET_CIN1200C_MK3 15
+#define BUDGET_KNC1C_MK3 16
+#define BUDGET_KNC1CP_MK3 17
#define BUDGET_VIDEO_PORTA 0
#define BUDGET_VIDEO_PORTB 1
diff --git a/linux/drivers/media/radio/Kconfig b/linux/drivers/media/radio/Kconfig
index 4ab38a851..fe881407f 100644
--- a/linux/drivers/media/radio/Kconfig
+++ b/linux/drivers/media/radio/Kconfig
@@ -2,8 +2,14 @@
# Multimedia Video device configuration
#
-menu "Radio Adapters"
+menuconfig RADIO_ADAPTERS
+ bool "Radio Adapters"
depends on VIDEO_DEV
+ default y
+ ---help---
+ Say Y here to enable selecting AM/FM radio adapters.
+
+if RADIO_ADAPTERS
config RADIO_CADET
tristate "ADS Cadet AM/FM Tuner"
@@ -360,4 +366,5 @@ config USB_DSBR
To compile this driver as a module, choose M here: the
module will be called dsbr100.
-endmenu
+
+endif # RADIO_ADAPTERS
diff --git a/linux/drivers/media/radio/radio-aimslab.c b/linux/drivers/media/radio/radio-aimslab.c
index 2ec2b1401..920f097fb 100644
--- a/linux/drivers/media/radio/radio-aimslab.c
+++ b/linux/drivers/media/radio/radio-aimslab.c
@@ -236,129 +236,149 @@ static struct v4l2_queryctrl radio_qctrl[] = {
}
};
-static int rt_do_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, void *arg)
+static int vidioc_querycap(struct file *file, void *priv,
+ struct v4l2_capability *v)
+{
+ strlcpy(v->driver, "radio-aimslab", sizeof(v->driver));
+ strlcpy(v->card, "RadioTrack", sizeof(v->card));
+ sprintf(v->bus_info, "ISA");
+ v->version = RADIO_VERSION;
+ v->capabilities = V4L2_CAP_TUNER;
+ return 0;
+}
+
+static int vidioc_g_tuner(struct file *file, void *priv,
+ struct v4l2_tuner *v)
{
struct video_device *dev = video_devdata(file);
- struct rt_device *rt=dev->priv;
+ struct rt_device *rt = dev->priv;
- switch(cmd)
- {
- case VIDIOC_QUERYCAP:
- {
- struct v4l2_capability *v = arg;
- memset(v,0,sizeof(*v));
- strlcpy(v->driver, "radio-aimslab", sizeof (v->driver));
- strlcpy(v->card, "RadioTrack", sizeof (v->card));
- sprintf(v->bus_info,"ISA");
- v->version = RADIO_VERSION;
- v->capabilities = V4L2_CAP_TUNER;
+ if (v->index > 0)
+ return -EINVAL;
- return 0;
- }
- case VIDIOC_G_TUNER:
- {
- struct v4l2_tuner *v = arg;
+ strcpy(v->name, "FM");
+ v->type = V4L2_TUNER_RADIO;
+ v->rangelow = (87*16000);
+ v->rangehigh = (108*16000);
+ v->rxsubchans = V4L2_TUNER_SUB_MONO;
+ v->capability = V4L2_TUNER_CAP_LOW;
+ v->audmode = V4L2_TUNER_MODE_MONO;
+ v->signal = 0xffff*rt_getsigstr(rt);
+ return 0;
+}
+
+static int vidioc_s_tuner(struct file *file, void *priv,
+ struct v4l2_tuner *v)
+{
+ if (v->index > 0)
+ return -EINVAL;
+ return 0;
+}
- if (v->index > 0)
- return -EINVAL;
+static int vidioc_s_frequency(struct file *file, void *priv,
+ struct v4l2_frequency *f)
+{
+ struct video_device *dev = video_devdata(file);
+ struct rt_device *rt = dev->priv;
- memset(v,0,sizeof(*v));
- strcpy(v->name, "FM");
- v->type = V4L2_TUNER_RADIO;
+ rt->curfreq = f->frequency;
+ rt_setfreq(rt, rt->curfreq);
+ return 0;
+}
- v->rangelow=(87*16000);
- v->rangehigh=(108*16000);
- v->rxsubchans =V4L2_TUNER_SUB_MONO;
- v->capability=V4L2_TUNER_CAP_LOW;
- v->audmode = V4L2_TUNER_MODE_MONO;
- v->signal=0xFFFF*rt_getsigstr(rt);
+static int vidioc_g_frequency(struct file *file, void *priv,
+ struct v4l2_frequency *f)
+{
+ struct video_device *dev = video_devdata(file);
+ struct rt_device *rt = dev->priv;
- return 0;
- }
- case VIDIOC_S_TUNER:
- {
- struct v4l2_tuner *v = arg;
+ f->type = V4L2_TUNER_RADIO;
+ f->frequency = rt->curfreq;
+ return 0;
+}
- if (v->index > 0)
- return -EINVAL;
+static int vidioc_queryctrl(struct file *file, void *priv,
+ struct v4l2_queryctrl *qc)
+{
+ int i;
+ for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
+ if (qc->id && qc->id == radio_qctrl[i].id) {
+ memcpy(qc, &(radio_qctrl[i]),
+ sizeof(*qc));
return 0;
}
- case VIDIOC_S_FREQUENCY:
- {
- struct v4l2_frequency *f = arg;
+ }
+ return -EINVAL;
+}
- rt->curfreq = f->frequency;
- rt_setfreq(rt, rt->curfreq);
- return 0;
- }
- case VIDIOC_G_FREQUENCY:
- {
- struct v4l2_frequency *f = arg;
+static int vidioc_g_ctrl(struct file *file, void *priv,
+ struct v4l2_control *ctrl)
+{
+ struct video_device *dev = video_devdata(file);
+ struct rt_device *rt = dev->priv;
- f->type = V4L2_TUNER_RADIO;
- f->frequency = rt->curfreq;
+ switch (ctrl->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ ctrl->value = rt->muted;
+ return 0;
+ case V4L2_CID_AUDIO_VOLUME:
+ ctrl->value = rt->curvol * 6554;
+ return 0;
+ }
+ return -EINVAL;
+}
- return 0;
- }
- case VIDIOC_QUERYCTRL:
- {
- struct v4l2_queryctrl *qc = arg;
- int i;
-
- for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
- if (qc->id && qc->id == radio_qctrl[i].id) {
- memcpy(qc, &(radio_qctrl[i]),
- sizeof(*qc));
- return (0);
- }
- }
- return -EINVAL;
- }
- case VIDIOC_G_CTRL:
- {
- struct v4l2_control *ctrl= arg;
-
- switch (ctrl->id) {
- case V4L2_CID_AUDIO_MUTE:
- ctrl->value=rt->muted;
- return (0);
- case V4L2_CID_AUDIO_VOLUME:
- ctrl->value=rt->curvol * 6554;
- return (0);
- }
- return -EINVAL;
- }
- case VIDIOC_S_CTRL:
- {
- struct v4l2_control *ctrl= arg;
-
- switch (ctrl->id) {
- case V4L2_CID_AUDIO_MUTE:
- if (ctrl->value) {
- rt_mute(rt);
- } else {
- rt_setvol(rt,rt->curvol);
- }
- return (0);
- case V4L2_CID_AUDIO_VOLUME:
- rt_setvol(rt,ctrl->value);
- return (0);
- }
- return -EINVAL;
- }
+static int vidioc_s_ctrl(struct file *file, void *priv,
+ struct v4l2_control *ctrl)
+{
+ struct video_device *dev = video_devdata(file);
+ struct rt_device *rt = dev->priv;
- default:
- return v4l_compat_translate_ioctl(inode,file,cmd,arg,
- rt_do_ioctl);
+ switch (ctrl->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ if (ctrl->value)
+ rt_mute(rt);
+ else
+ rt_setvol(rt,rt->curvol);
+ return 0;
+ case V4L2_CID_AUDIO_VOLUME:
+ rt_setvol(rt,ctrl->value);
+ return 0;
}
+ return -EINVAL;
+}
+
+static int vidioc_g_audio (struct file *file, void *priv,
+ struct v4l2_audio *a)
+{
+ if (a->index > 1)
+ return -EINVAL;
+
+ strcpy(a->name, "Radio");
+ a->capability = V4L2_AUDCAP_STEREO;
+ return 0;
+}
+
+static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
+{
+ *i = 0;
+ return 0;
+}
+
+static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
+{
+ if (i != 0)
+ return -EINVAL;
+ return 0;
}
-static int rt_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg)
+static int vidioc_s_audio(struct file *file, void *priv,
+ struct v4l2_audio *a)
{
- return video_usercopy(inode, file, cmd, arg, rt_do_ioctl);
+ if (a->index != 0)
+ return -EINVAL;
+ return 0;
}
static struct rt_device rtrack_unit;
@@ -367,7 +387,7 @@ static const struct file_operations rtrack_fops = {
.owner = THIS_MODULE,
.open = video_exclusive_open,
.release = video_exclusive_release,
- .ioctl = rt_ioctl,
+ .ioctl = video_ioctl2,
.compat_ioctl = v4l_compat_ioctl32,
.llseek = no_llseek,
};
@@ -379,6 +399,18 @@ static struct video_device rtrack_radio=
.type = VID_TYPE_TUNER,
.hardware = 0,
.fops = &rtrack_fops,
+ .vidioc_querycap = vidioc_querycap,
+ .vidioc_g_tuner = vidioc_g_tuner,
+ .vidioc_s_tuner = vidioc_s_tuner,
+ .vidioc_g_audio = vidioc_g_audio,
+ .vidioc_s_audio = vidioc_s_audio,
+ .vidioc_g_input = vidioc_g_input,
+ .vidioc_s_input = vidioc_s_input,
+ .vidioc_g_frequency = vidioc_g_frequency,
+ .vidioc_s_frequency = vidioc_s_frequency,
+ .vidioc_queryctrl = vidioc_queryctrl,
+ .vidioc_g_ctrl = vidioc_g_ctrl,
+ .vidioc_s_ctrl = vidioc_s_ctrl,
};
static int __init rtrack_init(void)
diff --git a/linux/drivers/media/radio/radio-gemtek-pci.c b/linux/drivers/media/radio/radio-gemtek-pci.c
index 98c0da421..09cb193e0 100644
--- a/linux/drivers/media/radio/radio-gemtek-pci.c
+++ b/linux/drivers/media/radio/radio-gemtek-pci.c
@@ -193,131 +193,158 @@ static inline unsigned int gemtek_pci_getsignal( struct gemtek_pci_card *card )
return ( inb( card->iobase ) & 0x08 ) ? 0 : 1;
}
-static int gemtek_pci_do_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, void *arg)
+static int vidioc_querycap(struct file *file, void *priv,
+ struct v4l2_capability *v)
+{
+ strlcpy(v->driver, "radio-gemtek-pci", sizeof(v->driver));
+ strlcpy(v->card, "GemTek PCI Radio", sizeof(v->card));
+ sprintf(v->bus_info, "ISA");
+ v->version = RADIO_VERSION;
+ v->capabilities = V4L2_CAP_TUNER;
+ return 0;
+}
+
+static int vidioc_g_tuner(struct file *file, void *priv,
+ struct v4l2_tuner *v)
{
struct video_device *dev = video_devdata(file);
struct gemtek_pci_card *card = dev->priv;
- switch ( cmd ) {
- case VIDIOC_QUERYCAP:
- {
- struct v4l2_capability *v = arg;
- memset(v,0,sizeof(*v));
- strlcpy(v->driver, "radio-gemtek-pci", sizeof (v->driver));
- strlcpy(v->card, "GemTek PCI Radio", sizeof (v->card));
- sprintf(v->bus_info,"ISA");
- v->version = RADIO_VERSION;
- v->capabilities = V4L2_CAP_TUNER;
-
- return 0;
- }
- case VIDIOC_G_TUNER:
- {
- struct v4l2_tuner *v = arg;
+ if (v->index > 0)
+ return -EINVAL;
+
+ strcpy(v->name, "FM");
+ v->type = V4L2_TUNER_RADIO;
+ v->rangelow = GEMTEK_PCI_RANGE_LOW;
+ v->rangehigh = GEMTEK_PCI_RANGE_HIGH;
+ v->rxsubchans = V4L2_TUNER_SUB_MONO;
+ v->capability = V4L2_TUNER_CAP_LOW;
+ v->audmode = V4L2_TUNER_MODE_MONO;
+ v->signal = 0xffff * gemtek_pci_getsignal(card);
+ return 0;
+}
- if (v->index > 0)
- return -EINVAL;
+static int vidioc_s_tuner(struct file *file, void *priv,
+ struct v4l2_tuner *v)
+{
+ if (v->index > 0)
+ return -EINVAL;
+ return 0;
+}
- memset(v,0,sizeof(*v));
- strcpy(v->name, "FM");
- v->type = V4L2_TUNER_RADIO;
+static int vidioc_s_frequency(struct file *file, void *priv,
+ struct v4l2_frequency *f)
+{
+ struct video_device *dev = video_devdata(file);
+ struct gemtek_pci_card *card = dev->priv;
- v->rangelow = GEMTEK_PCI_RANGE_LOW;
- v->rangehigh = GEMTEK_PCI_RANGE_HIGH;
- v->rxsubchans =V4L2_TUNER_SUB_MONO;
- v->capability=V4L2_TUNER_CAP_LOW;
- v->audmode = V4L2_TUNER_MODE_MONO;
- v->signal=0xFFFF*gemtek_pci_getsignal( card );
+ if ( (f->frequency < GEMTEK_PCI_RANGE_LOW) ||
+ (f->frequency > GEMTEK_PCI_RANGE_HIGH) )
+ return -EINVAL;
+ gemtek_pci_setfrequency(card, f->frequency);
+ card->current_frequency = f->frequency;
+ card->mute = false;
+ return 0;
+}
- return 0;
- }
- case VIDIOC_S_TUNER:
- {
- struct v4l2_tuner *v = arg;
+static int vidioc_g_frequency(struct file *file, void *priv,
+ struct v4l2_frequency *f)
+{
+ struct video_device *dev = video_devdata(file);
+ struct gemtek_pci_card *card = dev->priv;
- if (v->index > 0)
- return -EINVAL;
+ f->type = V4L2_TUNER_RADIO;
+ f->frequency = card->current_frequency;
+ return 0;
+}
+static int vidioc_queryctrl(struct file *file, void *priv,
+ struct v4l2_queryctrl *qc)
+{
+ int i;
+ for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
+ if (qc->id && qc->id == radio_qctrl[i].id) {
+ memcpy(qc, &(radio_qctrl[i]),
+ sizeof(*qc));
return 0;
}
- case VIDIOC_S_FREQUENCY:
- {
- struct v4l2_frequency *f = arg;
+ }
+ return -EINVAL;
+}
- if ( (f->frequency < GEMTEK_PCI_RANGE_LOW) ||
- (f->frequency > GEMTEK_PCI_RANGE_HIGH) )
- return -EINVAL;
+static int vidioc_g_ctrl(struct file *file, void *priv,
+ struct v4l2_control *ctrl)
+{
+ struct video_device *dev = video_devdata(file);
+ struct gemtek_pci_card *card = dev->priv;
+ switch (ctrl->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ ctrl->value = card->mute;
+ return 0;
+ case V4L2_CID_AUDIO_VOLUME:
+ if (card->mute)
+ ctrl->value = 0;
+ else
+ ctrl->value = 65535;
+ return 0;
+ }
+ return -EINVAL;
+}
- gemtek_pci_setfrequency( card, f->frequency );
- card->current_frequency = f->frequency;
- card->mute = false;
- return 0;
- }
- case VIDIOC_QUERYCTRL:
- {
- struct v4l2_queryctrl *qc = arg;
- int i;
-
- for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
- if (qc->id && qc->id == radio_qctrl[i].id) {
- memcpy(qc, &(radio_qctrl[i]),
- sizeof(*qc));
- return (0);
- }
- }
- return -EINVAL;
- }
- case VIDIOC_G_CTRL:
- {
- struct v4l2_control *ctrl= arg;
-
- switch (ctrl->id) {
- case V4L2_CID_AUDIO_MUTE:
- ctrl->value=card->mute;
- return (0);
- case V4L2_CID_AUDIO_VOLUME:
- if (card->mute)
- ctrl->value=0;
- else
- ctrl->value=65535;
- return (0);
- }
- return -EINVAL;
- }
- case VIDIOC_S_CTRL:
- {
- struct v4l2_control *ctrl= arg;
-
- switch (ctrl->id) {
- case V4L2_CID_AUDIO_MUTE:
- if (ctrl->value) {
- gemtek_pci_mute(card);
- } else {
- gemtek_pci_unmute(card);
- }
- return (0);
- case V4L2_CID_AUDIO_VOLUME:
- if (ctrl->value) {
- gemtek_pci_unmute(card);
- } else {
- gemtek_pci_mute(card);
- }
- return (0);
- }
- return -EINVAL;
- }
- default:
- return v4l_compat_translate_ioctl(inode,file,cmd,arg,
- gemtek_pci_do_ioctl);
+static int vidioc_s_ctrl(struct file *file, void *priv,
+ struct v4l2_control *ctrl)
+{
+ struct video_device *dev = video_devdata(file);
+ struct gemtek_pci_card *card = dev->priv;
+
+ switch (ctrl->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ if (ctrl->value)
+ gemtek_pci_mute(card);
+ else
+ gemtek_pci_unmute(card);
+ return 0;
+ case V4L2_CID_AUDIO_VOLUME:
+ if (ctrl->value)
+ gemtek_pci_unmute(card);
+ else
+ gemtek_pci_mute(card);
+ return 0;
}
+ return -EINVAL;
}
-static int gemtek_pci_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg)
+static int vidioc_g_audio(struct file *file, void *priv,
+ struct v4l2_audio *a)
{
- return video_usercopy(inode, file, cmd, arg, gemtek_pci_do_ioctl);
+ if (a->index > 1)
+ return -EINVAL;
+
+ strcpy(a->name, "Radio");
+ a->capability = V4L2_AUDCAP_STEREO;
+ return 0;
+}
+
+static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
+{
+ *i = 0;
+ return 0;
+}
+
+static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
+{
+ if (i != 0)
+ return -EINVAL;
+ return 0;
+}
+
+static int vidioc_s_audio(struct file *file, void *priv,
+ struct v4l2_audio *a)
+{
+ if (a->index != 0)
+ return -EINVAL;
+ return 0;
}
enum {
@@ -343,7 +370,7 @@ static const struct file_operations gemtek_pci_fops = {
.owner = THIS_MODULE,
.open = video_exclusive_open,
.release = video_exclusive_release,
- .ioctl = gemtek_pci_ioctl,
+ .ioctl = video_ioctl2,
.compat_ioctl = v4l_compat_ioctl32,
.llseek = no_llseek,
};
@@ -354,6 +381,18 @@ static struct video_device vdev_template = {
.type = VID_TYPE_TUNER,
.hardware = 0,
.fops = &gemtek_pci_fops,
+ .vidioc_querycap = vidioc_querycap,
+ .vidioc_g_tuner = vidioc_g_tuner,
+ .vidioc_s_tuner = vidioc_s_tuner,
+ .vidioc_g_audio = vidioc_g_audio,
+ .vidioc_s_audio = vidioc_s_audio,
+ .vidioc_g_input = vidioc_g_input,
+ .vidioc_s_input = vidioc_s_input,
+ .vidioc_g_frequency = vidioc_g_frequency,
+ .vidioc_s_frequency = vidioc_s_frequency,
+ .vidioc_queryctrl = vidioc_queryctrl,
+ .vidioc_g_ctrl = vidioc_g_ctrl,
+ .vidioc_s_ctrl = vidioc_s_ctrl,
};
static int __devinit gemtek_pci_probe( struct pci_dev *pci_dev, const struct pci_device_id *pci_id )
diff --git a/linux/drivers/media/radio/radio-gemtek.c b/linux/drivers/media/radio/radio-gemtek.c
index 7b09b4f2a..f44a213a9 100644
--- a/linux/drivers/media/radio/radio-gemtek.c
+++ b/linux/drivers/media/radio/radio-gemtek.c
@@ -162,137 +162,157 @@ static int gemtek_getsigstr(struct gemtek_device *dev)
return 1; /* signal present */
}
-static int gemtek_do_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, void *arg)
+static int vidioc_querycap(struct file *file, void *priv,
+ struct v4l2_capability *v)
+{
+ strlcpy(v->driver, "radio-gemtek", sizeof(v->driver));
+ strlcpy(v->card, "GemTek", sizeof(v->card));
+ sprintf(v->bus_info, "ISA");
+ v->version = RADIO_VERSION;
+ v->capabilities = V4L2_CAP_TUNER;
+ return 0;
+}
+
+static int vidioc_g_tuner(struct file *file, void *priv,
+ struct v4l2_tuner *v)
{
struct video_device *dev = video_devdata(file);
- struct gemtek_device *rt=dev->priv;
+ struct gemtek_device *rt = dev->priv;
- switch(cmd)
- {
- case VIDIOC_QUERYCAP:
- {
- struct v4l2_capability *v = arg;
- memset(v,0,sizeof(*v));
- strlcpy(v->driver, "radio-gemtek", sizeof (v->driver));
- strlcpy(v->card, "GemTek", sizeof (v->card));
- sprintf(v->bus_info,"ISA");
- v->version = RADIO_VERSION;
- v->capabilities = V4L2_CAP_TUNER;
+ if (v->index > 0)
+ return -EINVAL;
- return 0;
- }
- case VIDIOC_G_TUNER:
- {
- struct v4l2_tuner *v = arg;
+ strcpy(v->name, "FM");
+ v->type = V4L2_TUNER_RADIO;
+ v->rangelow = (87*16000);
+ v->rangehigh = (108*16000);
+ v->rxsubchans = V4L2_TUNER_SUB_MONO;
+ v->capability = V4L2_TUNER_CAP_LOW;
+ v->audmode = V4L2_TUNER_MODE_MONO;
+ v->signal = 0xffff*gemtek_getsigstr(rt);
+ return 0;
+}
+
+static int vidioc_s_tuner(struct file *file, void *priv,
+ struct v4l2_tuner *v)
+{
+ if (v->index > 0)
+ return -EINVAL;
+ return 0;
+}
- if (v->index > 0)
- return -EINVAL;
+static int vidioc_s_frequency(struct file *file, void *priv,
+ struct v4l2_frequency *f)
+{
+ struct video_device *dev = video_devdata(file);
+ struct gemtek_device *rt = dev->priv;
- memset(v,0,sizeof(*v));
- strcpy(v->name, "FM");
- v->type = V4L2_TUNER_RADIO;
+ rt->curfreq = f->frequency;
+ /* needs to be called twice in order for getsigstr to work */
+ gemtek_setfreq(rt, rt->curfreq);
+ gemtek_setfreq(rt, rt->curfreq);
+ return 0;
+}
- v->rangelow=(87*16000);
- v->rangehigh=(108*16000);
- v->rxsubchans =V4L2_TUNER_SUB_MONO;
- v->capability=V4L2_TUNER_CAP_LOW;
- v->audmode = V4L2_TUNER_MODE_MONO;
- v->signal=0xFFFF*gemtek_getsigstr(rt);
+static int vidioc_g_frequency(struct file *file, void *priv,
+ struct v4l2_frequency *f)
+{
+ struct video_device *dev = video_devdata(file);
+ struct gemtek_device *rt = dev->priv;
- return 0;
- }
- case VIDIOC_S_TUNER:
- {
- struct v4l2_tuner *v = arg;
+ f->type = V4L2_TUNER_RADIO;
+ f->frequency = rt->curfreq;
+ return 0;
+}
- if (v->index > 0)
- return -EINVAL;
+static int vidioc_queryctrl(struct file *file, void *priv,
+ struct v4l2_queryctrl *qc)
+{
+ int i;
+ for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
+ if (qc->id && qc->id == radio_qctrl[i].id) {
+ memcpy(qc, &(radio_qctrl[i]),
+ sizeof(*qc));
return 0;
}
- case VIDIOC_S_FREQUENCY:
- {
- struct v4l2_frequency *f = arg;
-
- rt->curfreq = f->frequency;
- /* needs to be called twice in order for getsigstr to work */
- gemtek_setfreq(rt, rt->curfreq);
- gemtek_setfreq(rt, rt->curfreq);
- return 0;
- }
- case VIDIOC_G_FREQUENCY:
- {
- struct v4l2_frequency *f = arg;
+ }
+ return -EINVAL;
+}
- f->type = V4L2_TUNER_RADIO;
- f->frequency = rt->curfreq;
+static int vidioc_g_ctrl(struct file *file, void *priv,
+ struct v4l2_control *ctrl)
+{
+ struct video_device *dev = video_devdata(file);
+ struct gemtek_device *rt = dev->priv;
- return 0;
- }
- case VIDIOC_QUERYCTRL:
- {
- struct v4l2_queryctrl *qc = arg;
- int i;
-
- for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
- if (qc->id && qc->id == radio_qctrl[i].id) {
- memcpy(qc, &(radio_qctrl[i]),
- sizeof(*qc));
- return (0);
- }
- }
- return -EINVAL;
- }
- case VIDIOC_G_CTRL:
- {
- struct v4l2_control *ctrl= arg;
-
- switch (ctrl->id) {
- case V4L2_CID_AUDIO_MUTE:
- ctrl->value=rt->muted;
- return (0);
- case V4L2_CID_AUDIO_VOLUME:
- if (rt->muted)
- ctrl->value=0;
- else
- ctrl->value=65535;
- return (0);
- }
- return -EINVAL;
- }
- case VIDIOC_S_CTRL:
- {
- struct v4l2_control *ctrl= arg;
-
- switch (ctrl->id) {
- case V4L2_CID_AUDIO_MUTE:
- if (ctrl->value) {
- gemtek_mute(rt);
- } else {
- gemtek_unmute(rt);
- }
- return (0);
- case V4L2_CID_AUDIO_VOLUME:
- if (ctrl->value) {
- gemtek_unmute(rt);
- } else {
- gemtek_mute(rt);
- }
- return (0);
- }
- return -EINVAL;
- }
- default:
- return v4l_compat_translate_ioctl(inode,file,cmd,arg,
- gemtek_do_ioctl);
+ switch (ctrl->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ ctrl->value = rt->muted;
+ return 0;
+ case V4L2_CID_AUDIO_VOLUME:
+ if (rt->muted)
+ ctrl->value = 0;
+ else
+ ctrl->value = 65535;
+ return 0;
+ }
+ return -EINVAL;
+}
+
+static int vidioc_s_ctrl(struct file *file, void *priv,
+ struct v4l2_control *ctrl)
+{
+ struct video_device *dev = video_devdata(file);
+ struct gemtek_device *rt = dev->priv;
+
+ switch (ctrl->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ if (ctrl->value)
+ gemtek_mute(rt);
+ else
+ gemtek_unmute(rt);
+ return 0;
+ case V4L2_CID_AUDIO_VOLUME:
+ if (ctrl->value)
+ gemtek_unmute(rt);
+ else
+ gemtek_mute(rt);
+ return 0;
}
+ return -EINVAL;
}
-static int gemtek_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg)
+static int vidioc_g_audio (struct file *file, void *priv,
+ struct v4l2_audio *a)
{
- return video_usercopy(inode, file, cmd, arg, gemtek_do_ioctl);
+ if (a->index > 1)
+ return -EINVAL;
+
+ strcpy(a->name, "Radio");
+ a->capability = V4L2_AUDCAP_STEREO;
+ return 0;
+}
+
+static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
+{
+ *i = 0;
+ return 0;
+}
+
+static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
+{
+ if (i != 0)
+ return -EINVAL;
+ return 0;
+}
+
+static int vidioc_s_audio(struct file *file, void *priv,
+ struct v4l2_audio *a)
+{
+ if (a->index != 0)
+ return -EINVAL;
+ return 0;
}
static struct gemtek_device gemtek_unit;
@@ -301,7 +321,7 @@ static const struct file_operations gemtek_fops = {
.owner = THIS_MODULE,
.open = video_exclusive_open,
.release = video_exclusive_release,
- .ioctl = gemtek_ioctl,
+ .ioctl = video_ioctl2,
.compat_ioctl = v4l_compat_ioctl32,
.llseek = no_llseek,
};
@@ -313,6 +333,18 @@ static struct video_device gemtek_radio=
.type = VID_TYPE_TUNER,
.hardware = 0,
.fops = &gemtek_fops,
+ .vidioc_querycap = vidioc_querycap,
+ .vidioc_g_tuner = vidioc_g_tuner,
+ .vidioc_s_tuner = vidioc_s_tuner,
+ .vidioc_g_audio = vidioc_g_audio,
+ .vidioc_s_audio = vidioc_s_audio,
+ .vidioc_g_input = vidioc_g_input,
+ .vidioc_s_input = vidioc_s_input,
+ .vidioc_g_frequency = vidioc_g_frequency,
+ .vidioc_s_frequency = vidioc_s_frequency,
+ .vidioc_queryctrl = vidioc_queryctrl,
+ .vidioc_g_ctrl = vidioc_g_ctrl,
+ .vidioc_s_ctrl = vidioc_s_ctrl,
};
static int __init gemtek_init(void)
diff --git a/linux/drivers/media/radio/radio-maestro.c b/linux/drivers/media/radio/radio-maestro.c
index ffecdcdea..792116a91 100644
--- a/linux/drivers/media/radio/radio-maestro.c
+++ b/linux/drivers/media/radio/radio-maestro.c
@@ -78,8 +78,6 @@ static struct v4l2_queryctrl radio_qctrl[] = {
static int radio_nr = -1;
module_param(radio_nr, int, 0);
-static int radio_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg);
static int maestro_probe(struct pci_dev *pdev, const struct pci_device_id *ent);
static void maestro_remove(struct pci_dev *pdev);
@@ -105,18 +103,11 @@ static const struct file_operations maestro_fops = {
.owner = THIS_MODULE,
.open = video_exclusive_open,
.release = video_exclusive_release,
- .ioctl = radio_ioctl,
+ .ioctl = video_ioctl2,
.compat_ioctl = v4l_compat_ioctl32,
.llseek = no_llseek,
};
-static struct video_device maestro_radio = {
- .name = "Maestro radio",
- .type = VID_TYPE_TUNER,
- .hardware = 0,
- .fops = &maestro_fops,
-};
-
struct radio_device {
u16 io, /* base of Maestro card radio io (GPIO_DATA)*/
muted, /* VIDEO_AUDIO_MUTE */
@@ -197,153 +188,153 @@ static void radio_bits_set(struct radio_device *dev, u32 data)
msleep(125);
}
-static inline int radio_function(struct inode *inode, struct file *file,
- unsigned int cmd, void *arg)
+static int vidioc_querycap(struct file *file, void *priv,
+ struct v4l2_capability *v)
+{
+ strlcpy(v->driver, "radio-maestro", sizeof(v->driver));
+ strlcpy(v->card, "Maestro Radio", sizeof(v->card));
+ sprintf(v->bus_info, "PCI");
+ v->version = RADIO_VERSION;
+ v->capabilities = V4L2_CAP_TUNER;
+ return 0;
+}
+
+static int vidioc_g_tuner(struct file *file, void *priv,
+ struct v4l2_tuner *v)
{
struct video_device *dev = video_devdata(file);
struct radio_device *card = video_get_drvdata(dev);
- switch (cmd) {
- case VIDIOC_QUERYCAP:
- {
- struct v4l2_capability *v = arg;
- memset(v,0,sizeof(*v));
- strlcpy(v->driver, "radio-maestro", sizeof (v->driver));
- strlcpy(v->card, "Maestro Radio", sizeof (v->card));
- sprintf(v->bus_info,"PCI");
- v->version = RADIO_VERSION;
- v->capabilities = V4L2_CAP_TUNER;
-
- return 0;
- }
- case VIDIOC_G_TUNER:
- {
- struct v4l2_tuner *v = arg;
-
- if (v->index > 0)
- return -EINVAL;
-
- (void)radio_bits_get(card);
+ if (v->index > 0)
+ return -EINVAL;
+
+ (void)radio_bits_get(card);
+
+ strcpy(v->name, "FM");
+ v->type = V4L2_TUNER_RADIO;
+ v->rangelow = FREQ_LO;
+ v->rangehigh = FREQ_HI;
+ v->rxsubchans = V4L2_TUNER_SUB_MONO|V4L2_TUNER_SUB_STEREO;
+ v->capability = V4L2_TUNER_CAP_LOW;
+ if(card->stereo)
+ v->audmode = V4L2_TUNER_MODE_STEREO;
+ else
+ v->audmode = V4L2_TUNER_MODE_MONO;
+ v->signal = card->tuned;
+ return 0;
+}
- memset(v,0,sizeof(*v));
- strcpy(v->name, "FM");
- v->type = V4L2_TUNER_RADIO;
+static int vidioc_s_tuner(struct file *file, void *priv,
+ struct v4l2_tuner *v)
+{
+ if (v->index > 0)
+ return -EINVAL;
+ return 0;
+}
- v->rangelow = FREQ_LO;
- v->rangehigh = FREQ_HI;
- v->rxsubchans =V4L2_TUNER_SUB_MONO|V4L2_TUNER_SUB_STEREO;
- v->capability=V4L2_TUNER_CAP_LOW;
- if(card->stereo)
- v->audmode = V4L2_TUNER_MODE_STEREO;
- else
- v->audmode = V4L2_TUNER_MODE_MONO;
- v->signal=card->tuned;
+static int vidioc_s_frequency(struct file *file, void *priv,
+ struct v4l2_frequency *f)
+{
+ struct video_device *dev = video_devdata(file);
+ struct radio_device *card = video_get_drvdata(dev);
- return 0;
- }
- case VIDIOC_S_TUNER:
- {
- struct v4l2_tuner *v = arg;
+ if (f->frequency < FREQ_LO || f->frequency > FREQ_HI)
+ return -EINVAL;
+ radio_bits_set(card, FREQ2BITS(f->frequency));
+ return 0;
+}
- if (v->index > 0)
- return -EINVAL;
+static int vidioc_g_frequency(struct file *file, void *priv,
+ struct v4l2_frequency *f)
+{
+ struct video_device *dev = video_devdata(file);
+ struct radio_device *card = video_get_drvdata(dev);
- return 0;
- }
- case VIDIOC_S_FREQUENCY:
- {
- struct v4l2_frequency *f = arg;
+ f->type = V4L2_TUNER_RADIO;
+ f->frequency = BITS2FREQ(radio_bits_get(card));
+ return 0;
+}
- if (f->frequency < FREQ_LO || f->frequency > FREQ_HI)
- return -EINVAL;
- radio_bits_set(card, FREQ2BITS(f->frequency));
+static int vidioc_queryctrl(struct file *file, void *priv,
+ struct v4l2_queryctrl *qc)
+{
+ int i;
+ for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
+ if (qc->id && qc->id == radio_qctrl[i].id) {
+ memcpy(qc, &(radio_qctrl[i]),
+ sizeof(*qc));
return 0;
}
- case VIDIOC_G_FREQUENCY:
- {
- struct v4l2_frequency *f = arg;
+ }
+ return -EINVAL;
+}
- f->type = V4L2_TUNER_RADIO;
- f->frequency = BITS2FREQ(radio_bits_get(card));
+static int vidioc_g_ctrl(struct file *file, void *priv,
+ struct v4l2_control *ctrl)
+{
+ struct video_device *dev = video_devdata(file);
+ struct radio_device *card = video_get_drvdata(dev);
- return 0;
- }
- case VIDIOC_QUERYCTRL:
- {
- struct v4l2_queryctrl *qc = arg;
- int i;
-
- for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
- if (qc->id && qc->id == radio_qctrl[i].id) {
- memcpy(qc, &(radio_qctrl[i]),
- sizeof(*qc));
- return (0);
- }
- }
- return -EINVAL;
- }
- case VIDIOC_G_CTRL:
- {
- struct v4l2_control *ctrl= arg;
-
- switch (ctrl->id) {
- case V4L2_CID_AUDIO_MUTE:
- ctrl->value=card->muted;
- return (0);
- }
- return -EINVAL;
- }
- case VIDIOC_S_CTRL:
- {
- struct v4l2_control *ctrl= arg;
-
- switch (ctrl->id) {
- case V4L2_CID_AUDIO_MUTE:
- {
- register u16 io = card->io;
- register u16 omask = inw(io + IO_MASK);
- outw(~STR_WREN, io + IO_MASK);
- outw((card->muted = ctrl->value ) ?
- STR_WREN : 0, io);
- udelay(4);
- outw(omask, io + IO_MASK);
- msleep(125);
-
- return (0);
- }
- }
- return -EINVAL;
- }
-#if 0 /* Probably, this is useless */
- case VIDIOCGUNIT: {
- struct video_unit *v = arg;
- v->video = VIDEO_NO_UNIT;
- v->vbi = VIDEO_NO_UNIT;
- v->radio = dev->minor;
- v->audio = 0;
- v->teletext = VIDEO_NO_UNIT;
- return 0;
- }
-#endif
- default:
- return v4l_compat_translate_ioctl(inode,file,cmd,arg,
- radio_function);
+ switch (ctrl->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ ctrl->value = card->muted;
+ return 0;
}
+ return -EINVAL;
}
-static int radio_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg)
+static int vidioc_s_ctrl(struct file *file, void *priv,
+ struct v4l2_control *ctrl)
{
struct video_device *dev = video_devdata(file);
struct radio_device *card = video_get_drvdata(dev);
- int ret;
+ register u16 io = card->io;
+ register u16 omask = inw(io + IO_MASK);
+
+ switch (ctrl->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ outw(~STR_WREN, io + IO_MASK);
+ outw((card->muted = ctrl->value ) ?
+ STR_WREN : 0, io);
+ udelay(4);
+ outw(omask, io + IO_MASK);
+ msleep(125);
+ return 0;
+ }
+ return -EINVAL;
+}
+
+static int vidioc_g_audio(struct file *file, void *priv,
+ struct v4l2_audio *a)
+{
+ if (a->index > 1)
+ return -EINVAL;
+
+ strcpy(a->name, "Radio");
+ a->capability = V4L2_AUDCAP_STEREO;
+ return 0;
+}
+
+static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
+{
+ *i = 0;
+ return 0;
+}
- mutex_lock(&card->lock);
- ret = video_usercopy(inode, file, cmd, arg, radio_function);
- mutex_unlock(&card->lock);
+static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
+{
+ if (i != 0)
+ return -EINVAL;
+ return 0;
+}
- return ret;
+static int vidioc_s_audio(struct file *file, void *priv,
+ struct v4l2_audio *a)
+{
+ if (a->index != 0)
+ return -EINVAL;
+ return 0;
}
static u16 __devinit radio_power_on(struct radio_device *dev)
@@ -370,6 +361,24 @@ static u16 __devinit radio_power_on(struct radio_device *dev)
return (ofreq == radio_bits_get(dev));
}
+static struct video_device maestro_radio = {
+ .name = "Maestro radio",
+ .type = VID_TYPE_TUNER,
+ .fops = &maestro_fops,
+ .vidioc_querycap = vidioc_querycap,
+ .vidioc_g_tuner = vidioc_g_tuner,
+ .vidioc_s_tuner = vidioc_s_tuner,
+ .vidioc_g_audio = vidioc_g_audio,
+ .vidioc_s_audio = vidioc_s_audio,
+ .vidioc_g_input = vidioc_g_input,
+ .vidioc_s_input = vidioc_s_input,
+ .vidioc_g_frequency = vidioc_g_frequency,
+ .vidioc_s_frequency = vidioc_s_frequency,
+ .vidioc_queryctrl = vidioc_queryctrl,
+ .vidioc_g_ctrl = vidioc_g_ctrl,
+ .vidioc_s_ctrl = vidioc_s_ctrl,
+};
+
static int __devinit maestro_probe(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
diff --git a/linux/drivers/media/radio/radio-rtrack2.c b/linux/drivers/media/radio/radio-rtrack2.c
index 80fcbde1f..e8ab31ab6 100644
--- a/linux/drivers/media/radio/radio-rtrack2.c
+++ b/linux/drivers/media/radio/radio-rtrack2.c
@@ -123,6 +123,26 @@ static int rt_setfreq(struct rt_device *dev, unsigned long freq)
return 0;
}
+static int vidioc_querycap(struct file *file, void *priv,
+ struct v4l2_capability *v)
+{
+ strlcpy(v->driver, "radio-rtrack2", sizeof(v->driver));
+ strlcpy(v->card, "RadioTrack II", sizeof(v->card));
+ sprintf(v->bus_info, "ISA");
+ v->version = RADIO_VERSION;
+ v->capabilities = V4L2_CAP_TUNER;
+ return 0;
+}
+
+static int vidioc_s_tuner(struct file *file, void *priv,
+ struct v4l2_tuner *v)
+{
+ if (v->index > 0)
+ return -EINVAL;
+
+ return 0;
+}
+
static int rt_getsigstr(struct rt_device *dev)
{
if (inb(io) & 2) /* bit set = no signal present */
@@ -130,135 +150,136 @@ static int rt_getsigstr(struct rt_device *dev)
return 1; /* signal present */
}
-static int rt_do_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, void *arg)
+static int vidioc_g_tuner(struct file *file, void *priv,
+ struct v4l2_tuner *v)
{
struct video_device *dev = video_devdata(file);
- struct rt_device *rt=dev->priv;
+ struct rt_device *rt = dev->priv;
- switch(cmd)
- {
- case VIDIOC_QUERYCAP:
- {
- struct v4l2_capability *v = arg;
- memset(v,0,sizeof(*v));
- strlcpy(v->driver, "radio-rtrack2", sizeof (v->driver));
- strlcpy(v->card, "RadioTrack II", sizeof (v->card));
- sprintf(v->bus_info,"ISA");
- v->version = RADIO_VERSION;
- v->capabilities = V4L2_CAP_TUNER;
+ if (v->index > 0)
+ return -EINVAL;
- return 0;
- }
- case VIDIOC_G_TUNER:
- {
- struct v4l2_tuner *v = arg;
+ strcpy(v->name, "FM");
+ v->type = V4L2_TUNER_RADIO;
+ v->rangelow = (88*16000);
+ v->rangehigh = (108*16000);
+ v->rxsubchans = V4L2_TUNER_SUB_MONO;
+ v->capability = V4L2_TUNER_CAP_LOW;
+ v->audmode = V4L2_TUNER_MODE_MONO;
+ v->signal = 0xFFFF*rt_getsigstr(rt);
+ return 0;
+}
- if (v->index > 0)
- return -EINVAL;
+static int vidioc_s_frequency(struct file *file, void *priv,
+ struct v4l2_frequency *f)
+{
+ struct video_device *dev = video_devdata(file);
+ struct rt_device *rt = dev->priv;
- memset(v,0,sizeof(*v));
- strcpy(v->name, "FM");
- v->type = V4L2_TUNER_RADIO;
+ rt->curfreq = f->frequency;
+ rt_setfreq(rt, rt->curfreq);
+ return 0;
+}
- v->rangelow=(88*16000);
- v->rangehigh=(108*16000);
- v->rxsubchans =V4L2_TUNER_SUB_MONO;
- v->capability=V4L2_TUNER_CAP_LOW;
- v->audmode = V4L2_TUNER_MODE_MONO;
- v->signal=0xFFFF*rt_getsigstr(rt);
+static int vidioc_g_frequency(struct file *file, void *priv,
+ struct v4l2_frequency *f)
+{
+ struct video_device *dev = video_devdata(file);
+ struct rt_device *rt = dev->priv;
- return 0;
- }
- case VIDIOC_S_TUNER:
- {
- struct v4l2_tuner *v = arg;
+ f->type = V4L2_TUNER_RADIO;
+ f->frequency = rt->curfreq;
+ return 0;
+}
- if (v->index > 0)
- return -EINVAL;
+static int vidioc_queryctrl(struct file *file, void *priv,
+ struct v4l2_queryctrl *qc)
+{
+ int i;
+ for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
+ if (qc->id && qc->id == radio_qctrl[i].id) {
+ memcpy(qc, &(radio_qctrl[i]),
+ sizeof(*qc));
return 0;
}
- case VIDIOC_S_FREQUENCY:
- {
- struct v4l2_frequency *f = arg;
+ }
+ return -EINVAL;
+}
- rt->curfreq = f->frequency;
- rt_setfreq(rt, rt->curfreq);
- return 0;
- }
- case VIDIOC_G_FREQUENCY:
- {
- struct v4l2_frequency *f = arg;
+static int vidioc_g_ctrl(struct file *file, void *priv,
+ struct v4l2_control *ctrl)
+{
+ struct video_device *dev = video_devdata(file);
+ struct rt_device *rt = dev->priv;
- f->type = V4L2_TUNER_RADIO;
- f->frequency = rt->curfreq;
+ switch (ctrl->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ ctrl->value = rt->muted;
+ return 0;
+ case V4L2_CID_AUDIO_VOLUME:
+ if (rt->muted)
+ ctrl->value = 0;
+ else
+ ctrl->value = 65535;
+ return 0;
+ }
+ return -EINVAL;
+}
- return 0;
- }
- case VIDIOC_QUERYCTRL:
- {
- struct v4l2_queryctrl *qc = arg;
- int i;
-
- for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
- if (qc->id && qc->id == radio_qctrl[i].id) {
- memcpy(qc, &(radio_qctrl[i]),
- sizeof(*qc));
- return (0);
- }
- }
- return -EINVAL;
- }
- case VIDIOC_G_CTRL:
- {
- struct v4l2_control *ctrl= arg;
-
- switch (ctrl->id) {
- case V4L2_CID_AUDIO_MUTE:
- ctrl->value=rt->muted;
- return (0);
- case V4L2_CID_AUDIO_VOLUME:
- if (rt->muted)
- ctrl->value=0;
- else
- ctrl->value=65535;
- return (0);
- }
- return -EINVAL;
- }
- case VIDIOC_S_CTRL:
- {
- struct v4l2_control *ctrl= arg;
-
- switch (ctrl->id) {
- case V4L2_CID_AUDIO_MUTE:
- if (ctrl->value) {
- rt_mute(rt);
- } else {
- rt_unmute(rt);
- }
- return (0);
- case V4L2_CID_AUDIO_VOLUME:
- if (ctrl->value) {
- rt_unmute(rt);
- } else {
- rt_mute(rt);
- }
- return (0);
- }
- return -EINVAL;
- }
- default:
- return v4l_compat_translate_ioctl(inode,file,cmd,arg,
- rt_do_ioctl);
+static int vidioc_s_ctrl(struct file *file, void *priv,
+ struct v4l2_control *ctrl)
+{
+ struct video_device *dev = video_devdata(file);
+ struct rt_device *rt = dev->priv;
+
+ switch (ctrl->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ if (ctrl->value)
+ rt_mute(rt);
+ else
+ rt_unmute(rt);
+ return 0;
+ case V4L2_CID_AUDIO_VOLUME:
+ if (ctrl->value)
+ rt_unmute(rt);
+ else
+ rt_mute(rt);
+ return 0;
}
+ return -EINVAL;
}
-static int rt_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg)
+static int vidioc_g_audio(struct file *file, void *priv,
+ struct v4l2_audio *a)
{
- return video_usercopy(inode, file, cmd, arg, rt_do_ioctl);
+ if (a->index > 1)
+ return -EINVAL;
+
+ strcpy(a->name, "Radio");
+ a->capability = V4L2_AUDCAP_STEREO;
+ return 0;
+}
+
+static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
+{
+ *i = 0;
+ return 0;
+}
+
+static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
+{
+ if (i != 0)
+ return -EINVAL;
+ return 0;
+}
+
+static int vidioc_s_audio(struct file *file, void *priv,
+ struct v4l2_audio *a)
+{
+ if (a->index != 0)
+ return -EINVAL;
+ return 0;
}
static struct rt_device rtrack2_unit;
@@ -267,7 +288,7 @@ static const struct file_operations rtrack2_fops = {
.owner = THIS_MODULE,
.open = video_exclusive_open,
.release = video_exclusive_release,
- .ioctl = rt_ioctl,
+ .ioctl = video_ioctl2,
.compat_ioctl = v4l_compat_ioctl32,
.llseek = no_llseek,
};
@@ -279,6 +300,18 @@ static struct video_device rtrack2_radio=
.type = VID_TYPE_TUNER,
.hardware = 0,
.fops = &rtrack2_fops,
+ .vidioc_querycap = vidioc_querycap,
+ .vidioc_g_tuner = vidioc_g_tuner,
+ .vidioc_s_tuner = vidioc_s_tuner,
+ .vidioc_g_frequency = vidioc_g_frequency,
+ .vidioc_s_frequency = vidioc_s_frequency,
+ .vidioc_queryctrl = vidioc_queryctrl,
+ .vidioc_g_ctrl = vidioc_g_ctrl,
+ .vidioc_s_ctrl = vidioc_s_ctrl,
+ .vidioc_g_audio = vidioc_g_audio,
+ .vidioc_s_audio = vidioc_s_audio,
+ .vidioc_g_input = vidioc_g_input,
+ .vidioc_s_input = vidioc_s_input,
};
static int __init rtrack2_init(void)
diff --git a/linux/drivers/media/radio/radio-sf16fmi.c b/linux/drivers/media/radio/radio-sf16fmi.c
index 00f9c12e7..925fe9205 100644
--- a/linux/drivers/media/radio/radio-sf16fmi.c
+++ b/linux/drivers/media/radio/radio-sf16fmi.c
@@ -137,149 +137,155 @@ static inline int fmi_getsigstr(struct fmi_device *dev)
return (res & 2) ? 0 : 0xFFFF;
}
-static int fmi_do_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, void *arg)
+static int vidioc_querycap(struct file *file, void *priv,
+ struct v4l2_capability *v)
{
+ strlcpy(v->driver, "radio-sf16fmi", sizeof(v->driver));
+ strlcpy(v->card, "SF16-FMx radio", sizeof(v->card));
+ sprintf(v->bus_info, "ISA");
+ v->version = RADIO_VERSION;
+ v->capabilities = V4L2_CAP_TUNER;
+ return 0;
+}
+
+static int vidioc_g_tuner(struct file *file, void *priv,
+ struct v4l2_tuner *v)
+{
+ int mult;
struct video_device *dev = video_devdata(file);
- struct fmi_device *fmi=dev->priv;
+ struct fmi_device *fmi = dev->priv;
- switch(cmd)
- {
- case VIDIOC_QUERYCAP:
- {
- struct v4l2_capability *v = arg;
- memset(v,0,sizeof(*v));
- strlcpy(v->driver, "radio-sf16fmi", sizeof (v->driver));
- strlcpy(v->card, "SF16-FMx radio", sizeof (v->card));
- sprintf(v->bus_info,"ISA");
- v->version = RADIO_VERSION;
- v->capabilities = V4L2_CAP_TUNER;
+ if (v->index > 0)
+ return -EINVAL;
- return 0;
- }
- case VIDIOC_G_TUNER:
- {
- struct v4l2_tuner *v = arg;
- int mult;
-
- if (v->index > 0)
- return -EINVAL;
-
- memset(v,0,sizeof(*v));
- strcpy(v->name, "FM");
- v->type = V4L2_TUNER_RADIO;
-
- mult = (fmi->flags & V4L2_TUNER_CAP_LOW) ? 1 : 1000;
- v->rangelow = RSF16_MINFREQ/mult;
- v->rangehigh = RSF16_MAXFREQ/mult;
- v->rxsubchans =V4L2_TUNER_SUB_MONO | V4L2_TUNER_MODE_STEREO;
- v->capability=fmi->flags&V4L2_TUNER_CAP_LOW;
- v->audmode = V4L2_TUNER_MODE_STEREO;
- v->signal = fmi_getsigstr(fmi);
+ strcpy(v->name, "FM");
+ v->type = V4L2_TUNER_RADIO;
+ mult = (fmi->flags & V4L2_TUNER_CAP_LOW) ? 1 : 1000;
+ v->rangelow = RSF16_MINFREQ/mult;
+ v->rangehigh = RSF16_MAXFREQ/mult;
+ v->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_MODE_STEREO;
+ v->capability = fmi->flags&V4L2_TUNER_CAP_LOW;
+ v->audmode = V4L2_TUNER_MODE_STEREO;
+ v->signal = fmi_getsigstr(fmi);
+ return 0;
+}
- return 0;
- }
- case VIDIOC_S_TUNER:
- {
- struct v4l2_tuner *v = arg;
+static int vidioc_s_tuner(struct file *file, void *priv,
+ struct v4l2_tuner *v)
+{
+ if (v->index > 0)
+ return -EINVAL;
+ return 0;
+}
- if (v->index > 0)
- return -EINVAL;
+static int vidioc_s_frequency(struct file *file, void *priv,
+ struct v4l2_frequency *f)
+{
+ struct video_device *dev = video_devdata(file);
+ struct fmi_device *fmi = dev->priv;
- return 0;
- }
- case VIDIOC_S_FREQUENCY:
- {
- struct v4l2_frequency *f = arg;
-
- if (!(fmi->flags & V4L2_TUNER_CAP_LOW))
- f->frequency *= 1000;
- if (f->frequency < RSF16_MINFREQ ||
- f->frequency > RSF16_MAXFREQ )
- return -EINVAL;
- /*rounding in steps of 800 to match th freq
- that will be used */
- fmi->curfreq = (f->frequency/800)*800;
- fmi_setfreq(fmi);
+ if (!(fmi->flags & V4L2_TUNER_CAP_LOW))
+ f->frequency *= 1000;
+ if (f->frequency < RSF16_MINFREQ ||
+ f->frequency > RSF16_MAXFREQ )
+ return -EINVAL;
+ /*rounding in steps of 800 to match th freq
+ that will be used */
+ fmi->curfreq = (f->frequency/800)*800;
+ fmi_setfreq(fmi);
+ return 0;
+}
- return 0;
- }
- case VIDIOC_G_FREQUENCY:
- {
- struct v4l2_frequency *f = arg;
+static int vidioc_g_frequency(struct file *file, void *priv,
+ struct v4l2_frequency *f)
+{
+ struct video_device *dev = video_devdata(file);
+ struct fmi_device *fmi = dev->priv;
- f->type = V4L2_TUNER_RADIO;
- f->frequency = fmi->curfreq;
- if (!(fmi->flags & V4L2_TUNER_CAP_LOW))
- f->frequency /= 1000;
+ f->type = V4L2_TUNER_RADIO;
+ f->frequency = fmi->curfreq;
+ if (!(fmi->flags & V4L2_TUNER_CAP_LOW))
+ f->frequency /= 1000;
+ return 0;
+}
+static int vidioc_queryctrl(struct file *file, void *priv,
+ struct v4l2_queryctrl *qc)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
+ if (qc->id && qc->id == radio_qctrl[i].id) {
+ memcpy(qc, &(radio_qctrl[i]),
+ sizeof(*qc));
return 0;
}
- case VIDIOC_QUERYCTRL:
- {
- struct v4l2_queryctrl *qc = arg;
- int i;
-
- for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
- if (qc->id && qc->id == radio_qctrl[i].id) {
- memcpy(qc, &(radio_qctrl[i]),
- sizeof(*qc));
- return (0);
- }
- }
- return -EINVAL;
- }
- case VIDIOC_G_CTRL:
- {
- struct v4l2_control *ctrl= arg;
-
- switch (ctrl->id) {
- case V4L2_CID_AUDIO_MUTE:
- ctrl->value=fmi->curvol;
- return (0);
- }
- return -EINVAL;
- }
- case VIDIOC_S_CTRL:
- {
- struct v4l2_control *ctrl= arg;
-
- switch (ctrl->id) {
- case V4L2_CID_AUDIO_MUTE:
- {
- if (ctrl->value)
- fmi_mute(fmi->port);
- else
- fmi_unmute(fmi->port);
-
- fmi->curvol=ctrl->value;
- return (0);
- }
- }
- return -EINVAL;
- }
-#if 0 /* Probably, this is useless */
- case VIDIOCGUNIT:
- {
- struct video_unit *v = arg;
- v->video=VIDEO_NO_UNIT;
- v->vbi=VIDEO_NO_UNIT;
- v->radio=dev->minor;
- v->audio=0; /* How do we find out this??? */
- v->teletext=VIDEO_NO_UNIT;
- return 0;
- }
-#endif
- default:
- return v4l_compat_translate_ioctl(inode,file,cmd,arg,
- fmi_do_ioctl);
}
+ return -EINVAL;
+}
+
+static int vidioc_g_ctrl(struct file *file, void *priv,
+ struct v4l2_control *ctrl)
+{
+ struct video_device *dev = video_devdata(file);
+ struct fmi_device *fmi = dev->priv;
+
+ switch (ctrl->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ ctrl->value = fmi->curvol;
+ return 0;
+ }
+ return -EINVAL;
+}
+
+static int vidioc_s_ctrl(struct file *file, void *priv,
+ struct v4l2_control *ctrl)
+{
+ struct video_device *dev = video_devdata(file);
+ struct fmi_device *fmi = dev->priv;
+
+ switch (ctrl->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ if (ctrl->value)
+ fmi_mute(fmi->port);
+ else
+ fmi_unmute(fmi->port);
+ fmi->curvol = ctrl->value;
+ return 0;
+ }
+ return -EINVAL;
+}
+
+static int vidioc_g_audio(struct file *file, void *priv,
+ struct v4l2_audio *a)
+{
+ if (a->index > 1)
+ return -EINVAL;
+
+ strcpy(a->name, "Radio");
+ a->capability = V4L2_AUDCAP_STEREO;
+ return 0;
+}
+
+static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
+{
+ *i = 0;
+ return 0;
+}
+
+static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
+{
+ if (i != 0)
+ return -EINVAL;
+ return 0;
}
-static int fmi_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg)
+static int vidioc_s_audio(struct file *file, void *priv,
+ struct v4l2_audio *a)
{
- return video_usercopy(inode, file, cmd, arg, fmi_do_ioctl);
+ if (a->index != 0)
+ return -EINVAL;
+ return 0;
}
static struct fmi_device fmi_unit;
@@ -288,7 +294,7 @@ static const struct file_operations fmi_fops = {
.owner = THIS_MODULE,
.open = video_exclusive_open,
.release = video_exclusive_release,
- .ioctl = fmi_ioctl,
+ .ioctl = video_ioctl2,
.compat_ioctl = v4l_compat_ioctl32,
.llseek = no_llseek,
};
@@ -300,6 +306,18 @@ static struct video_device fmi_radio=
.type = VID_TYPE_TUNER,
.hardware = 0,
.fops = &fmi_fops,
+ .vidioc_querycap = vidioc_querycap,
+ .vidioc_g_tuner = vidioc_g_tuner,
+ .vidioc_s_tuner = vidioc_s_tuner,
+ .vidioc_g_audio = vidioc_g_audio,
+ .vidioc_s_audio = vidioc_s_audio,
+ .vidioc_g_input = vidioc_g_input,
+ .vidioc_s_input = vidioc_s_input,
+ .vidioc_g_frequency = vidioc_g_frequency,
+ .vidioc_s_frequency = vidioc_s_frequency,
+ .vidioc_queryctrl = vidioc_queryctrl,
+ .vidioc_g_ctrl = vidioc_g_ctrl,
+ .vidioc_s_ctrl = vidioc_s_ctrl,
};
/* ladis: this is my card. does any other types exist? */
diff --git a/linux/drivers/media/radio/radio-sf16fmr2.c b/linux/drivers/media/radio/radio-sf16fmr2.c
index 267c3d8d4..e2b037fad 100644
--- a/linux/drivers/media/radio/radio-sf16fmr2.c
+++ b/linux/drivers/media/radio/radio-sf16fmr2.c
@@ -231,198 +231,204 @@ static int fmr2_setvolume(struct fmr2_device *dev)
return 0;
}
-static int fmr2_do_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, void *arg)
+static int vidioc_querycap(struct file *file, void *priv,
+ struct v4l2_capability *v)
{
+ strlcpy(v->driver, "radio-sf16fmr2", sizeof(v->driver));
+ strlcpy(v->card, "SF16-FMR2 radio", sizeof(v->card));
+ sprintf(v->bus_info, "ISA");
+ v->version = RADIO_VERSION;
+ v->capabilities = V4L2_CAP_TUNER;
+ return 0;
+}
+
+static int vidioc_g_tuner(struct file *file, void *priv,
+ struct v4l2_tuner *v)
+{
+ int mult;
struct video_device *dev = video_devdata(file);
struct fmr2_device *fmr2 = dev->priv;
- debug_print((KERN_DEBUG "freq %ld flags %d vol %d mute %d "
- "stereo %d type %d\n",
- fmr2->curfreq, fmr2->flags, fmr2->curvol, fmr2->mute,
- fmr2->stereo, fmr2->card_type));
- switch(cmd)
- {
- case VIDIOC_QUERYCAP:
- {
- struct v4l2_capability *v = arg;
- memset(v,0,sizeof(*v));
- strlcpy(v->driver, "radio-sf16fmr2", sizeof (v->driver));
- strlcpy(v->card, "SF16-FMR2 radio", sizeof (v->card));
- sprintf(v->bus_info,"ISA");
- v->version = RADIO_VERSION;
- v->capabilities = V4L2_CAP_TUNER;
+ if (v->index > 0)
+ return -EINVAL;
- return 0;
- }
- case VIDIOC_G_TUNER:
- {
- struct v4l2_tuner *v = arg;
- int mult;
-
- if (v->index > 0)
- return -EINVAL;
-
- memset(v,0,sizeof(*v));
- strcpy(v->name, "FM");
- v->type = V4L2_TUNER_RADIO;
-
- mult = (fmr2->flags & V4L2_TUNER_CAP_LOW) ? 1 : 1000;
- v->rangelow = RSF16_MINFREQ/mult;
- v->rangehigh = RSF16_MAXFREQ/mult;
- v->rxsubchans =V4L2_TUNER_SUB_MONO | V4L2_TUNER_MODE_STEREO;
- v->capability=fmr2->flags&V4L2_TUNER_CAP_LOW;
-
- v->audmode = fmr2->stereo ? V4L2_TUNER_MODE_STEREO:
- V4L2_TUNER_MODE_MONO;
- mutex_lock(&lock);
- v->signal = fmr2_getsigstr(fmr2);
- mutex_unlock(&lock);
+ strcpy(v->name, "FM");
+ v->type = V4L2_TUNER_RADIO;
- return 0;
- }
- case VIDIOC_S_TUNER:
- {
- struct v4l2_tuner *v = arg;
+ mult = (fmr2->flags & V4L2_TUNER_CAP_LOW) ? 1 : 1000;
+ v->rangelow = RSF16_MINFREQ/mult;
+ v->rangehigh = RSF16_MAXFREQ/mult;
+ v->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_MODE_STEREO;
+ v->capability = fmr2->flags&V4L2_TUNER_CAP_LOW;
+ v->audmode = fmr2->stereo ? V4L2_TUNER_MODE_STEREO:
+ V4L2_TUNER_MODE_MONO;
+ mutex_lock(&lock);
+ v->signal = fmr2_getsigstr(fmr2);
+ mutex_unlock(&lock);
+ return 0;
+}
- if (v->index > 0)
- return -EINVAL;
+static int vidioc_s_tuner(struct file *file, void *priv,
+ struct v4l2_tuner *v)
+{
+ if (v->index > 0)
+ return -EINVAL;
+ return 0;
+}
- return 0;
- }
- case VIDIOC_S_FREQUENCY:
- {
- struct v4l2_frequency *f = arg;
-
- if (!(fmr2->flags & V4L2_TUNER_CAP_LOW))
- f->frequency *= 1000;
- if (f->frequency < RSF16_MINFREQ ||
- f->frequency > RSF16_MAXFREQ )
- return -EINVAL;
- /*rounding in steps of 200 to match th freq
- that will be used */
- fmr2->curfreq = (f->frequency/200)*200;
-
- /* set card freq (if not muted) */
- if (fmr2->curvol && !fmr2->mute)
- {
- mutex_lock(&lock);
- fmr2_setfreq(fmr2);
- mutex_unlock(&lock);
- }
+static int vidioc_s_frequency(struct file *file, void *priv,
+ struct v4l2_frequency *f)
+{
+ struct video_device *dev = video_devdata(file);
+ struct fmr2_device *fmr2 = dev->priv;
- return 0;
- }
- case VIDIOC_G_FREQUENCY:
- {
- struct v4l2_frequency *f = arg;
+ if (!(fmr2->flags & V4L2_TUNER_CAP_LOW))
+ f->frequency *= 1000;
+ if (f->frequency < RSF16_MINFREQ ||
+ f->frequency > RSF16_MAXFREQ )
+ return -EINVAL;
+ /*rounding in steps of 200 to match th freq
+ that will be used */
+ fmr2->curfreq = (f->frequency/200)*200;
+
+ /* set card freq (if not muted) */
+ if (fmr2->curvol && !fmr2->mute) {
+ mutex_lock(&lock);
+ fmr2_setfreq(fmr2);
+ mutex_unlock(&lock);
+ }
+ return 0;
+}
+
+static int vidioc_g_frequency(struct file *file, void *priv,
+ struct v4l2_frequency *f)
+{
+ struct video_device *dev = video_devdata(file);
+ struct fmr2_device *fmr2 = dev->priv;
- f->type = V4L2_TUNER_RADIO;
- f->frequency = fmr2->curfreq;
- if (!(fmr2->flags & V4L2_TUNER_CAP_LOW))
- f->frequency /= 1000;
+ f->type = V4L2_TUNER_RADIO;
+ f->frequency = fmr2->curfreq;
+ if (!(fmr2->flags & V4L2_TUNER_CAP_LOW))
+ f->frequency /= 1000;
+ return 0;
+}
+
+static int vidioc_queryctrl(struct file *file, void *priv,
+ struct v4l2_queryctrl *qc)
+{
+ int i;
+ struct video_device *dev = video_devdata(file);
+ struct fmr2_device *fmr2 = dev->priv;
+ for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
+ if ((fmr2->card_type != 11)
+ && V4L2_CID_AUDIO_VOLUME)
+ radio_qctrl[i].step = 65535;
+ if (qc->id && qc->id == radio_qctrl[i].id) {
+ memcpy(qc, &(radio_qctrl[i]),
+ sizeof(*qc));
return 0;
}
- case VIDIOC_QUERYCTRL:
- {
- struct v4l2_queryctrl *qc = arg;
- int i;
-
- for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
- if ((fmr2->card_type != 11)
- && V4L2_CID_AUDIO_VOLUME)
- radio_qctrl[i].step=65535;
- if (qc->id && qc->id == radio_qctrl[i].id) {
- memcpy(qc, &(radio_qctrl[i]),
- sizeof(*qc));
- return (0);
- }
- }
- return -EINVAL;
+ }
+ return -EINVAL;
+}
+
+static int vidioc_g_ctrl(struct file *file, void *priv,
+ struct v4l2_control *ctrl)
+{
+ struct video_device *dev = video_devdata(file);
+ struct fmr2_device *fmr2 = dev->priv;
+
+ switch (ctrl->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ ctrl->value = fmr2->mute;
+ return 0;
+ case V4L2_CID_AUDIO_VOLUME:
+ ctrl->value = fmr2->curvol;
+ return 0;
+ }
+ return -EINVAL;
+}
+
+static int vidioc_s_ctrl(struct file *file, void *priv,
+ struct v4l2_control *ctrl)
+{
+ struct video_device *dev = video_devdata(file);
+ struct fmr2_device *fmr2 = dev->priv;
+
+ switch (ctrl->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ fmr2->mute = ctrl->value;
+ if (fmr2->card_type != 11) {
+ if (!fmr2->mute)
+ fmr2->curvol = 65535;
+ else
+ fmr2->curvol = 0;
}
- case VIDIOC_G_CTRL:
- {
- struct v4l2_control *ctrl= arg;
-
- switch (ctrl->id) {
- case V4L2_CID_AUDIO_MUTE:
- ctrl->value=fmr2->mute;
- return (0);
- case V4L2_CID_AUDIO_VOLUME:
- ctrl->value=fmr2->curvol;
- return (0);
+ break;
+ case V4L2_CID_AUDIO_VOLUME:
+ fmr2->curvol = ctrl->value;
+ if (fmr2->card_type != 11) {
+ if (fmr2->curvol) {
+ fmr2->curvol = 65535;
+ fmr2->mute = 0;
+ } else {
+ fmr2->curvol = 0;
+ fmr2->mute = 1;
}
- return -EINVAL;
}
- case VIDIOC_S_CTRL:
- {
- struct v4l2_control *ctrl= arg;
-
- switch (ctrl->id) {
- case V4L2_CID_AUDIO_MUTE:
- fmr2->mute=ctrl->value;
- if (fmr2->card_type != 11) {
- if (!fmr2->mute) {
- fmr2->curvol = 65535;
- } else {
- fmr2->curvol = 0;
- }
- }
- break;
- case V4L2_CID_AUDIO_VOLUME:
- fmr2->curvol = ctrl->value;
- if (fmr2->card_type != 11) {
- if (fmr2->curvol) {
- fmr2->curvol = 65535;
- fmr2->mute = 0;
- } else {
- fmr2->curvol = 0;
- fmr2->mute = 1;
- }
- }
- break;
- default:
- return -EINVAL;
- }
+ break;
+ default:
+ return -EINVAL;
+ }
+
#ifdef DEBUG
- if (fmr2->curvol && !fmr2->mute)
- printk(KERN_DEBUG "unmute\n");
- else
- printk(KERN_DEBUG "mute\n");
-#endif
- mutex_lock(&lock);
- if (fmr2->curvol && !fmr2->mute) {
- fmr2_setvolume(fmr2);
- fmr2_setfreq(fmr2);
- } else
- fmr2_mute(fmr2->port);
- mutex_unlock(&lock);
- return (0);
- }
-#if 0
- case VIDIOCGUNIT:
- {
- struct video_unit *v = arg;
- v->video=VIDEO_NO_UNIT;
- v->vbi=VIDEO_NO_UNIT;
- v->radio=dev->minor;
- v->audio=0; /* How do we find out this??? */
- v->teletext=VIDEO_NO_UNIT;
- return 0;
- }
+ if (fmr2->curvol && !fmr2->mute)
+ printk(KERN_DEBUG "unmute\n");
+ else
+ printk(KERN_DEBUG "mute\n");
#endif
- default:
- return v4l_compat_translate_ioctl(inode,file,cmd,arg,
- fmr2_do_ioctl);
- }
+ mutex_lock(&lock);
+ if (fmr2->curvol && !fmr2->mute) {
+ fmr2_setvolume(fmr2);
+ fmr2_setfreq(fmr2);
+ } else
+ fmr2_mute(fmr2->port);
+ mutex_unlock(&lock);
+ return 0;
+}
+
+static int vidioc_g_audio(struct file *file, void *priv,
+ struct v4l2_audio *a)
+{
+ if (a->index > 1)
+ return -EINVAL;
+
+ strcpy(a->name, "Radio");
+ a->capability = V4L2_AUDCAP_STEREO;
+ return 0;
+}
+
+static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
+{
+ *i = 0;
+ return 0;
}
-static int fmr2_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg)
- {
- return video_usercopy(inode, file, cmd, arg, fmr2_do_ioctl);
+static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
+{
+ if (i != 0)
+ return -EINVAL;
+ return 0;
+}
+
+static int vidioc_s_audio(struct file *file, void *priv,
+ struct v4l2_audio *a)
+{
+ if (a->index != 0)
+ return -EINVAL;
+ return 0;
}
static struct fmr2_device fmr2_unit;
@@ -431,7 +437,7 @@ static const struct file_operations fmr2_fops = {
.owner = THIS_MODULE,
.open = video_exclusive_open,
.release = video_exclusive_release,
- .ioctl = fmr2_ioctl,
+ .ioctl = video_ioctl2,
.compat_ioctl = v4l_compat_ioctl32,
.llseek = no_llseek,
};
@@ -443,6 +449,18 @@ static struct video_device fmr2_radio=
. type = VID_TYPE_TUNER,
.hardware = 0,
.fops = &fmr2_fops,
+ .vidioc_querycap = vidioc_querycap,
+ .vidioc_g_tuner = vidioc_g_tuner,
+ .vidioc_s_tuner = vidioc_s_tuner,
+ .vidioc_g_audio = vidioc_g_audio,
+ .vidioc_s_audio = vidioc_s_audio,
+ .vidioc_g_input = vidioc_g_input,
+ .vidioc_s_input = vidioc_s_input,
+ .vidioc_g_frequency = vidioc_g_frequency,
+ .vidioc_s_frequency = vidioc_s_frequency,
+ .vidioc_queryctrl = vidioc_queryctrl,
+ .vidioc_g_ctrl = vidioc_g_ctrl,
+ .vidioc_s_ctrl = vidioc_s_ctrl,
};
static int __init fmr2_init(void)
diff --git a/linux/drivers/media/radio/radio-terratec.c b/linux/drivers/media/radio/radio-terratec.c
index ffe1ffd31..d8a48bf85 100644
--- a/linux/drivers/media/radio/radio-terratec.c
+++ b/linux/drivers/media/radio/radio-terratec.c
@@ -206,135 +206,152 @@ static int tt_getsigstr(struct tt_device *dev) /* TODO */
return 1; /* signal present */
}
+static int vidioc_querycap(struct file *file, void *priv,
+ struct v4l2_capability *v)
+{
+ strlcpy(v->driver, "radio-terratec", sizeof(v->driver));
+ strlcpy(v->card, "ActiveRadio", sizeof(v->card));
+ sprintf(v->bus_info, "ISA");
+ v->version = RADIO_VERSION;
+ v->capabilities = V4L2_CAP_TUNER;
+ return 0;
+}
-/* implement the video4linux api */
-
-static int tt_do_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, void *arg)
+static int vidioc_g_tuner(struct file *file, void *priv,
+ struct v4l2_tuner *v)
{
struct video_device *dev = video_devdata(file);
- struct tt_device *tt=dev->priv;
+ struct tt_device *tt = dev->priv;
- switch(cmd)
- {
- case VIDIOC_QUERYCAP:
- {
- struct v4l2_capability *v = arg;
- memset(v,0,sizeof(*v));
- strlcpy(v->driver, "radio-terratec", sizeof (v->driver));
- strlcpy(v->card, "ActiveRadio", sizeof (v->card));
- sprintf(v->bus_info,"ISA");
- v->version = RADIO_VERSION;
- v->capabilities = V4L2_CAP_TUNER;
+ if (v->index > 0)
+ return -EINVAL;
- return 0;
- }
- case VIDIOC_G_TUNER:
- {
- struct v4l2_tuner *v = arg;
+ strcpy(v->name, "FM");
+ v->type = V4L2_TUNER_RADIO;
+ v->rangelow = (87*16000);
+ v->rangehigh = (108*16000);
+ v->rxsubchans = V4L2_TUNER_SUB_MONO;
+ v->capability = V4L2_TUNER_CAP_LOW;
+ v->audmode = V4L2_TUNER_MODE_MONO;
+ v->signal = 0xFFFF*tt_getsigstr(tt);
+ return 0;
+}
- if (v->index > 0)
- return -EINVAL;
+static int vidioc_s_tuner(struct file *file, void *priv,
+ struct v4l2_tuner *v)
+{
+ if (v->index > 0)
+ return -EINVAL;
+ return 0;
+}
- memset(v,0,sizeof(*v));
- strcpy(v->name, "FM");
- v->type = V4L2_TUNER_RADIO;
+static int vidioc_s_frequency(struct file *file, void *priv,
+ struct v4l2_frequency *f)
+{
+ struct video_device *dev = video_devdata(file);
+ struct tt_device *tt = dev->priv;
- v->rangelow=(87*16000);
- v->rangehigh=(108*16000);
- v->rxsubchans =V4L2_TUNER_SUB_MONO;
- v->capability=V4L2_TUNER_CAP_LOW;
- v->audmode = V4L2_TUNER_MODE_MONO;
- v->signal=0xFFFF*tt_getsigstr(tt);
+ tt->curfreq = f->frequency;
+ tt_setfreq(tt, tt->curfreq);
+ return 0;
+}
- return 0;
- }
- case VIDIOC_S_TUNER:
- {
- struct v4l2_tuner *v = arg;
+static int vidioc_g_frequency(struct file *file, void *priv,
+ struct v4l2_frequency *f)
+{
+ struct video_device *dev = video_devdata(file);
+ struct tt_device *tt = dev->priv;
- if (v->index > 0)
- return -EINVAL;
+ f->type = V4L2_TUNER_RADIO;
+ f->frequency = tt->curfreq;
+ return 0;
+}
- return 0;
- }
- case VIDIOC_S_FREQUENCY:
- {
- struct v4l2_frequency *f = arg;
+static int vidioc_queryctrl(struct file *file, void *priv,
+ struct v4l2_queryctrl *qc)
+{
+ int i;
- tt->curfreq = f->frequency;
- tt_setfreq(tt, tt->curfreq);
+ for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
+ if (qc->id && qc->id == radio_qctrl[i].id) {
+ memcpy(qc, &(radio_qctrl[i]),
+ sizeof(*qc));
return 0;
}
- case VIDIOC_G_FREQUENCY:
- {
- struct v4l2_frequency *f = arg;
+ }
+ return -EINVAL;
+}
- f->type = V4L2_TUNER_RADIO;
- f->frequency = tt->curfreq;
+static int vidioc_g_ctrl(struct file *file, void *priv,
+ struct v4l2_control *ctrl)
+{
+ struct video_device *dev = video_devdata(file);
+ struct tt_device *tt = dev->priv;
- return 0;
- }
- case VIDIOC_QUERYCTRL:
- {
- struct v4l2_queryctrl *qc = arg;
- int i;
-
- for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
- if (qc->id && qc->id == radio_qctrl[i].id) {
- memcpy(qc, &(radio_qctrl[i]),
- sizeof(*qc));
- return (0);
- }
- }
- return -EINVAL;
- }
- case VIDIOC_G_CTRL:
- {
- struct v4l2_control *ctrl= arg;
-
- switch (ctrl->id) {
- case V4L2_CID_AUDIO_MUTE:
- if (tt->muted)
- ctrl->value=1;
- else
- ctrl->value=0;
- return (0);
- case V4L2_CID_AUDIO_VOLUME:
- ctrl->value=tt->curvol * 6554;
- return (0);
- }
- return -EINVAL;
- }
- case VIDIOC_S_CTRL:
- {
- struct v4l2_control *ctrl= arg;
-
- switch (ctrl->id) {
- case V4L2_CID_AUDIO_MUTE:
- if (ctrl->value) {
- tt_mute(tt);
- } else {
- tt_setvol(tt,tt->curvol);
- }
- return (0);
- case V4L2_CID_AUDIO_VOLUME:
- tt_setvol(tt,ctrl->value);
- return (0);
- }
- return -EINVAL;
- }
+ switch (ctrl->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ if (tt->muted)
+ ctrl->value = 1;
+ else
+ ctrl->value = 0;
+ return 0;
+ case V4L2_CID_AUDIO_VOLUME:
+ ctrl->value = tt->curvol * 6554;
+ return 0;
+ }
+ return -EINVAL;
+}
- default:
- return v4l_compat_translate_ioctl(inode,file,cmd,arg,
- tt_do_ioctl);
+static int vidioc_s_ctrl(struct file *file, void *priv,
+ struct v4l2_control *ctrl)
+{
+ struct video_device *dev = video_devdata(file);
+ struct tt_device *tt = dev->priv;
+
+ switch (ctrl->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ if (ctrl->value)
+ tt_mute(tt);
+ else
+ tt_setvol(tt,tt->curvol);
+ return 0;
+ case V4L2_CID_AUDIO_VOLUME:
+ tt_setvol(tt,ctrl->value);
+ return 0;
}
+ return -EINVAL;
+}
+
+static int vidioc_g_audio(struct file *file, void *priv,
+ struct v4l2_audio *a)
+{
+ if (a->index > 1)
+ return -EINVAL;
+
+ strcpy(a->name, "Radio");
+ a->capability = V4L2_AUDCAP_STEREO;
+ return 0;
+}
+
+static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
+{
+ *i = 0;
+ return 0;
}
-static int tt_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg)
+static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
{
- return video_usercopy(inode, file, cmd, arg, tt_do_ioctl);
+ if (i != 0)
+ return -EINVAL;
+ return 0;
+}
+
+static int vidioc_s_audio(struct file *file, void *priv,
+ struct v4l2_audio *a)
+{
+ if (a->index != 0)
+ return -EINVAL;
+ return 0;
}
static struct tt_device terratec_unit;
@@ -343,7 +360,7 @@ static const struct file_operations terratec_fops = {
.owner = THIS_MODULE,
.open = video_exclusive_open,
.release = video_exclusive_release,
- .ioctl = tt_ioctl,
+ .ioctl = video_ioctl2,
.compat_ioctl = v4l_compat_ioctl32,
.llseek = no_llseek,
};
@@ -355,6 +372,18 @@ static struct video_device terratec_radio=
.type = VID_TYPE_TUNER,
.hardware = 0,
.fops = &terratec_fops,
+ .vidioc_querycap = vidioc_querycap,
+ .vidioc_g_tuner = vidioc_g_tuner,
+ .vidioc_s_tuner = vidioc_s_tuner,
+ .vidioc_g_frequency = vidioc_g_frequency,
+ .vidioc_s_frequency = vidioc_s_frequency,
+ .vidioc_queryctrl = vidioc_queryctrl,
+ .vidioc_g_ctrl = vidioc_g_ctrl,
+ .vidioc_s_ctrl = vidioc_s_ctrl,
+ .vidioc_g_audio = vidioc_g_audio,
+ .vidioc_s_audio = vidioc_s_audio,
+ .vidioc_g_input = vidioc_g_input,
+ .vidioc_s_input = vidioc_s_input,
};
static int __init terratec_init(void)
diff --git a/linux/drivers/media/radio/radio-trust.c b/linux/drivers/media/radio/radio-trust.c
index ee903a52b..f2196933a 100644
--- a/linux/drivers/media/radio/radio-trust.c
+++ b/linux/drivers/media/radio/radio-trust.c
@@ -193,147 +193,157 @@ static void tr_setfreq(unsigned long f)
write_i2c(5, TSA6060T_ADDR, (f << 1) | 1, f >> 7, 0x60 | ((f >> 15) & 1), 0);
}
-static int tr_do_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, void *arg)
+static int vidioc_querycap(struct file *file, void *priv,
+ struct v4l2_capability *v)
{
- switch(cmd)
- {
- case VIDIOC_QUERYCAP:
- {
- struct v4l2_capability *v = arg;
- memset(v,0,sizeof(*v));
- strlcpy(v->driver, "radio-trust", sizeof (v->driver));
- strlcpy(v->card, "Trust FM Radio", sizeof (v->card));
- sprintf(v->bus_info,"ISA");
- v->version = RADIO_VERSION;
- v->capabilities = V4L2_CAP_TUNER;
+ strlcpy(v->driver, "radio-trust", sizeof(v->driver));
+ strlcpy(v->card, "Trust FM Radio", sizeof(v->card));
+ sprintf(v->bus_info, "ISA");
+ v->version = RADIO_VERSION;
+ v->capabilities = V4L2_CAP_TUNER;
+ return 0;
+}
- return 0;
- }
- case VIDIOC_G_TUNER:
- {
- struct v4l2_tuner *v = arg;
-
- if (v->index > 0)
- return -EINVAL;
-
- memset(v,0,sizeof(*v));
- strcpy(v->name, "FM");
- v->type = V4L2_TUNER_RADIO;
-
- v->rangelow=(87.5*16000);
- v->rangehigh=(108*16000);
- v->rxsubchans =V4L2_TUNER_SUB_MONO|V4L2_TUNER_SUB_STEREO;
- v->capability=V4L2_TUNER_CAP_LOW;
- if(tr_getstereo())
- v->audmode = V4L2_TUNER_MODE_STEREO;
- else
- v->audmode = V4L2_TUNER_MODE_MONO;
- v->signal=tr_getsigstr();
+static int vidioc_g_tuner(struct file *file, void *priv,
+ struct v4l2_tuner *v)
+{
+ if (v->index > 0)
+ return -EINVAL;
- return 0;
- }
- case VIDIOC_S_TUNER:
- {
- struct v4l2_tuner *v = arg;
+ strcpy(v->name, "FM");
+ v->type = V4L2_TUNER_RADIO;
+ v->rangelow = (87.5*16000);
+ v->rangehigh = (108*16000);
+ v->rxsubchans = V4L2_TUNER_SUB_MONO|V4L2_TUNER_SUB_STEREO;
+ v->capability = V4L2_TUNER_CAP_LOW;
+ if (tr_getstereo())
+ v->audmode = V4L2_TUNER_MODE_STEREO;
+ else
+ v->audmode = V4L2_TUNER_MODE_MONO;
+ v->signal = tr_getsigstr();
+ return 0;
+}
- if (v->index > 0)
- return -EINVAL;
+static int vidioc_s_tuner(struct file *file, void *priv,
+ struct v4l2_tuner *v)
+{
+ if (v->index > 0)
+ return -EINVAL;
- return 0;
- }
- case VIDIOC_S_FREQUENCY:
- {
- struct v4l2_frequency *f = arg;
+ return 0;
+}
- curfreq = f->frequency;
- tr_setfreq(curfreq);
- return 0;
- }
- case VIDIOC_G_FREQUENCY:
- {
- struct v4l2_frequency *f = arg;
+static int vidioc_s_frequency(struct file *file, void *priv,
+ struct v4l2_frequency *f)
+{
+ curfreq = f->frequency;
+ tr_setfreq(curfreq);
+ return 0;
+}
- f->type = V4L2_TUNER_RADIO;
- f->frequency = curfreq;
+static int vidioc_g_frequency(struct file *file, void *priv,
+ struct v4l2_frequency *f)
+{
+ f->type = V4L2_TUNER_RADIO;
+ f->frequency = curfreq;
+ return 0;
+}
+static int vidioc_queryctrl(struct file *file, void *priv,
+ struct v4l2_queryctrl *qc)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
+ if (qc->id && qc->id == radio_qctrl[i].id) {
+ memcpy(qc, &(radio_qctrl[i]),
+ sizeof(*qc));
return 0;
}
- case VIDIOC_QUERYCTRL:
- {
- struct v4l2_queryctrl *qc = arg;
- int i;
-
- for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
- if (qc->id && qc->id == radio_qctrl[i].id) {
- memcpy(qc, &(radio_qctrl[i]),
- sizeof(*qc));
- return (0);
- }
- }
- return -EINVAL;
- }
- case VIDIOC_G_CTRL:
- {
- struct v4l2_control *ctrl= arg;
-
- switch (ctrl->id) {
- case V4L2_CID_AUDIO_MUTE:
- ctrl->value=curmute;
- return (0);
- case V4L2_CID_AUDIO_VOLUME:
- ctrl->value= curvol * 2048;
- return (0);
- case V4L2_CID_AUDIO_BASS:
- ctrl->value= curbass * 4370;
- return (0);
- case V4L2_CID_AUDIO_TREBLE:
- ctrl->value= curtreble * 4370;
- return (0);
- }
- return -EINVAL;
- }
- case VIDIOC_S_CTRL:
- {
- struct v4l2_control *ctrl= arg;
-
- switch (ctrl->id) {
- case V4L2_CID_AUDIO_MUTE:
- tr_setmute(ctrl->value);
- return 0;
- case V4L2_CID_AUDIO_VOLUME:
- tr_setvol(ctrl->value);
- return 0;
- case V4L2_CID_AUDIO_BASS:
- tr_setbass(ctrl->value);
- return 0;
- case V4L2_CID_AUDIO_TREBLE:
- tr_settreble(ctrl->value);
- return (0);
- }
+ }
+ return -EINVAL;
+}
+
+static int vidioc_g_ctrl(struct file *file, void *priv,
+ struct v4l2_control *ctrl)
+{
+ switch (ctrl->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ ctrl->value = curmute;
+ return 0;
+ case V4L2_CID_AUDIO_VOLUME:
+ ctrl->value = curvol * 2048;
+ return 0;
+ case V4L2_CID_AUDIO_BASS:
+ ctrl->value = curbass * 4370;
+ return 0;
+ case V4L2_CID_AUDIO_TREBLE:
+ ctrl->value = curtreble * 4370;
+ return 0;
+ }
+ return -EINVAL;
+}
+
+static int vidioc_s_ctrl(struct file *file, void *priv,
+ struct v4l2_control *ctrl)
+{
+ switch (ctrl->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ tr_setmute(ctrl->value);
+ return 0;
+ case V4L2_CID_AUDIO_VOLUME:
+ tr_setvol(ctrl->value);
+ return 0;
+ case V4L2_CID_AUDIO_BASS:
+ tr_setbass(ctrl->value);
+ return 0;
+ case V4L2_CID_AUDIO_TREBLE:
+ tr_settreble(ctrl->value);
+ return 0;
+ }
#if 0 /* Should implement mono/stereo on V4L2 */
tr_setstereo(v->mode & VIDEO_SOUND_STEREO);
#endif
- return -EINVAL;
- }
+ return -EINVAL;
+}
- default:
- return v4l_compat_translate_ioctl(inode,file,cmd,arg,
- tr_do_ioctl);
- }
+static int vidioc_g_audio(struct file *file, void *priv,
+ struct v4l2_audio *a)
+{
+ if (a->index > 1)
+ return -EINVAL;
+
+ strcpy(a->name, "Radio");
+ a->capability = V4L2_AUDCAP_STEREO;
+ return 0;
+}
+
+static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
+{
+ *i = 0;
+ return 0;
}
-static int tr_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg)
+static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
{
- return video_usercopy(inode, file, cmd, arg, tr_do_ioctl);
+ if (i != 0)
+ return -EINVAL;
+ return 0;
+}
+
+static int vidioc_s_audio(struct file *file, void *priv,
+ struct v4l2_audio *a)
+{
+ if (a->index != 0)
+ return -EINVAL;
+ return 0;
}
static const struct file_operations trust_fops = {
.owner = THIS_MODULE,
.open = video_exclusive_open,
.release = video_exclusive_release,
- .ioctl = tr_ioctl,
+ .ioctl = video_ioctl2,
.compat_ioctl = v4l_compat_ioctl32,
.llseek = no_llseek,
};
@@ -345,6 +355,18 @@ static struct video_device trust_radio=
.type = VID_TYPE_TUNER,
.hardware = 0,
.fops = &trust_fops,
+ .vidioc_querycap = vidioc_querycap,
+ .vidioc_g_tuner = vidioc_g_tuner,
+ .vidioc_s_tuner = vidioc_s_tuner,
+ .vidioc_g_frequency = vidioc_g_frequency,
+ .vidioc_s_frequency = vidioc_s_frequency,
+ .vidioc_queryctrl = vidioc_queryctrl,
+ .vidioc_g_ctrl = vidioc_g_ctrl,
+ .vidioc_s_ctrl = vidioc_s_ctrl,
+ .vidioc_g_audio = vidioc_g_audio,
+ .vidioc_s_audio = vidioc_s_audio,
+ .vidioc_g_input = vidioc_g_input,
+ .vidioc_s_input = vidioc_s_input,
};
static int __init trust_init(void)
diff --git a/linux/drivers/media/radio/radio-typhoon.c b/linux/drivers/media/radio/radio-typhoon.c
index 66b21f2cd..ca326b666 100644
--- a/linux/drivers/media/radio/radio-typhoon.c
+++ b/linux/drivers/media/radio/radio-typhoon.c
@@ -98,8 +98,6 @@ static int typhoon_setfreq(struct typhoon_device *dev, unsigned long frequency);
static void typhoon_mute(struct typhoon_device *dev);
static void typhoon_unmute(struct typhoon_device *dev);
static int typhoon_setvol(struct typhoon_device *dev, int vol);
-static int typhoon_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg);
#ifdef CONFIG_RADIO_TYPHOON_PROC_FS
static int typhoon_get_info(char *buf, char **start, off_t offset, int len);
#endif
@@ -191,129 +189,148 @@ static int typhoon_setvol(struct typhoon_device *dev, int vol)
return 0;
}
+static int vidioc_querycap(struct file *file, void *priv,
+ struct v4l2_capability *v)
+{
+ strlcpy(v->driver, "radio-typhoon", sizeof(v->driver));
+ strlcpy(v->card, "Typhoon Radio", sizeof(v->card));
+ sprintf(v->bus_info, "ISA");
+ v->version = RADIO_VERSION;
+ v->capabilities = V4L2_CAP_TUNER;
+ return 0;
+}
+
+static int vidioc_g_tuner(struct file *file, void *priv,
+ struct v4l2_tuner *v)
+{
+ if (v->index > 0)
+ return -EINVAL;
+
+ strcpy(v->name, "FM");
+ v->type = V4L2_TUNER_RADIO;
+ v->rangelow = (87.5*16000);
+ v->rangehigh = (108*16000);
+ v->rxsubchans = V4L2_TUNER_SUB_MONO;
+ v->capability = V4L2_TUNER_CAP_LOW;
+ v->audmode = V4L2_TUNER_MODE_MONO;
+ v->signal = 0xFFFF; /* We can't get the signal strength */
+ return 0;
+}
-static int typhoon_do_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, void *arg)
+static int vidioc_s_tuner(struct file *file, void *priv,
+ struct v4l2_tuner *v)
+{
+ if (v->index > 0)
+ return -EINVAL;
+
+ return 0;
+}
+
+static int vidioc_s_frequency(struct file *file, void *priv,
+ struct v4l2_frequency *f)
{
struct video_device *dev = video_devdata(file);
struct typhoon_device *typhoon = dev->priv;
- switch (cmd) {
- case VIDIOC_QUERYCAP:
- {
- struct v4l2_capability *v = arg;
- memset(v,0,sizeof(*v));
- strlcpy(v->driver, "radio-typhoon", sizeof (v->driver));
- strlcpy(v->card, "Typhoon Radio", sizeof (v->card));
- sprintf(v->bus_info,"ISA");
- v->version = RADIO_VERSION;
- v->capabilities = V4L2_CAP_TUNER;
+ typhoon->curfreq = f->frequency;
+ typhoon_setfreq(typhoon, typhoon->curfreq);
+ return 0;
+}
- return 0;
- }
- case VIDIOC_G_TUNER:
- {
- struct v4l2_tuner *v = arg;
+static int vidioc_g_frequency(struct file *file, void *priv,
+ struct v4l2_frequency *f)
+{
+ struct video_device *dev = video_devdata(file);
+ struct typhoon_device *typhoon = dev->priv;
- if (v->index > 0)
- return -EINVAL;
+ f->type = V4L2_TUNER_RADIO;
+ f->frequency = typhoon->curfreq;
- memset(v,0,sizeof(*v));
- strcpy(v->name, "FM");
- v->type = V4L2_TUNER_RADIO;
+ return 0;
+}
- v->rangelow=(87.5*16000);
- v->rangehigh=(108*16000);
- v->rxsubchans =V4L2_TUNER_SUB_MONO;
- v->capability=V4L2_TUNER_CAP_LOW;
- v->audmode = V4L2_TUNER_MODE_MONO;
- v->signal = 0xFFFF; /* We can't get the signal strength */
+static int vidioc_queryctrl(struct file *file, void *priv,
+ struct v4l2_queryctrl *qc)
+{
+ int i;
+ for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
+ if (qc->id && qc->id == radio_qctrl[i].id) {
+ memcpy(qc, &(radio_qctrl[i]),
+ sizeof(*qc));
return 0;
}
- case VIDIOC_S_TUNER:
- {
- struct v4l2_tuner *v = arg;
+ }
+ return -EINVAL;
+}
- if (v->index > 0)
- return -EINVAL;
+static int vidioc_g_ctrl(struct file *file, void *priv,
+ struct v4l2_control *ctrl)
+{
+ struct video_device *dev = video_devdata(file);
+ struct typhoon_device *typhoon = dev->priv;
- return 0;
- }
- case VIDIOC_S_FREQUENCY:
- {
- struct v4l2_frequency *f = arg;
+ switch (ctrl->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ ctrl->value = typhoon->muted;
+ return 0;
+ case V4L2_CID_AUDIO_VOLUME:
+ ctrl->value = typhoon->curvol;
+ return 0;
+ }
+ return -EINVAL;
+}
- typhoon->curfreq = f->frequency;
- typhoon_setfreq(typhoon, typhoon->curfreq);
- return 0;
- }
- case VIDIOC_G_FREQUENCY:
- {
- struct v4l2_frequency *f = arg;
+static int vidioc_s_ctrl (struct file *file, void *priv,
+ struct v4l2_control *ctrl)
+{
+ struct video_device *dev = video_devdata(file);
+ struct typhoon_device *typhoon = dev->priv;
- f->type = V4L2_TUNER_RADIO;
- f->frequency = typhoon->curfreq;
+ switch (ctrl->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ if (ctrl->value)
+ typhoon_mute(typhoon);
+ else
+ typhoon_unmute(typhoon);
+ return 0;
+ case V4L2_CID_AUDIO_VOLUME:
+ typhoon_setvol(typhoon, ctrl->value);
+ return 0;
+ }
+ return -EINVAL;
+}
- return 0;
- }
- case VIDIOC_QUERYCTRL:
- {
- struct v4l2_queryctrl *qc = arg;
- int i;
-
- for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
- if (qc->id && qc->id == radio_qctrl[i].id) {
- memcpy(qc, &(radio_qctrl[i]),
- sizeof(*qc));
- return (0);
- }
- }
- return -EINVAL;
- }
- case VIDIOC_G_CTRL:
- {
- struct v4l2_control *ctrl= arg;
-
- switch (ctrl->id) {
- case V4L2_CID_AUDIO_MUTE:
- ctrl->value=typhoon->muted;
- return (0);
- case V4L2_CID_AUDIO_VOLUME:
- ctrl->value=typhoon->curvol;
- return (0);
- }
- return -EINVAL;
- }
- case VIDIOC_S_CTRL:
- {
- struct v4l2_control *ctrl= arg;
-
- switch (ctrl->id) {
- case V4L2_CID_AUDIO_MUTE:
- if (ctrl->value) {
- typhoon_mute(typhoon);
- } else {
- typhoon_unmute(typhoon);
- }
- return (0);
- case V4L2_CID_AUDIO_VOLUME:
- typhoon_setvol(typhoon, ctrl->value);
- return (0);
- }
- return -EINVAL;
- }
+static int vidioc_g_audio(struct file *file, void *priv,
+ struct v4l2_audio *a)
+{
+ if (a->index > 1)
+ return -EINVAL;
- default:
- return v4l_compat_translate_ioctl(inode,file,cmd,arg,
- typhoon_do_ioctl);
- }
+ strcpy(a->name, "Radio");
+ a->capability = V4L2_AUDCAP_STEREO;
+ return 0;
+}
+
+static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
+{
+ *i = 0;
+ return 0;
+}
+
+static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
+{
+ if (i != 0)
+ return -EINVAL;
+ return 0;
}
-static int typhoon_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg)
+static int vidioc_s_audio(struct file *file, void *priv,
+ struct v4l2_audio *a)
{
- return video_usercopy(inode, file, cmd, arg, typhoon_do_ioctl);
+ if (a->index != 0)
+ return -EINVAL;
+ return 0;
}
static struct typhoon_device typhoon_unit =
@@ -327,7 +344,7 @@ static const struct file_operations typhoon_fops = {
.owner = THIS_MODULE,
.open = video_exclusive_open,
.release = video_exclusive_release,
- .ioctl = typhoon_ioctl,
+ .ioctl = video_ioctl2,
.compat_ioctl = v4l_compat_ioctl32,
.llseek = no_llseek,
};
@@ -339,6 +356,18 @@ static struct video_device typhoon_radio =
.type = VID_TYPE_TUNER,
.hardware = 0,
.fops = &typhoon_fops,
+ .vidioc_querycap = vidioc_querycap,
+ .vidioc_g_tuner = vidioc_g_tuner,
+ .vidioc_s_tuner = vidioc_s_tuner,
+ .vidioc_g_audio = vidioc_g_audio,
+ .vidioc_s_audio = vidioc_s_audio,
+ .vidioc_g_input = vidioc_g_input,
+ .vidioc_s_input = vidioc_s_input,
+ .vidioc_g_frequency = vidioc_g_frequency,
+ .vidioc_s_frequency = vidioc_s_frequency,
+ .vidioc_queryctrl = vidioc_queryctrl,
+ .vidioc_g_ctrl = vidioc_g_ctrl,
+ .vidioc_s_ctrl = vidioc_s_ctrl,
};
#ifdef CONFIG_RADIO_TYPHOON_PROC_FS
diff --git a/linux/drivers/media/radio/radio-zoltrix.c b/linux/drivers/media/radio/radio-zoltrix.c
index d1473bf04..2175bc2d8 100644
--- a/linux/drivers/media/radio/radio-zoltrix.c
+++ b/linux/drivers/media/radio/radio-zoltrix.c
@@ -235,121 +235,123 @@ static int zol_is_stereo (struct zol_device *dev)
return 0;
}
-static int zol_do_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, void *arg)
+static int vidioc_querycap(struct file *file, void *priv,
+ struct v4l2_capability *v)
+{
+ strlcpy(v->driver, "radio-zoltrix", sizeof(v->driver));
+ strlcpy(v->card, "Zoltrix Radio", sizeof(v->card));
+ sprintf(v->bus_info, "ISA");
+ v->version = RADIO_VERSION;
+ v->capabilities = V4L2_CAP_TUNER;
+ return 0;
+}
+
+static int vidioc_g_tuner(struct file *file, void *priv,
+ struct v4l2_tuner *v)
{
struct video_device *dev = video_devdata(file);
struct zol_device *zol = dev->priv;
- switch (cmd) {
- case VIDIOC_QUERYCAP:
- {
- struct v4l2_capability *v = arg;
- memset(v,0,sizeof(*v));
- strlcpy(v->driver, "radio-zoltrix", sizeof (v->driver));
- strlcpy(v->card, "Zoltrix Radio", sizeof (v->card));
- sprintf(v->bus_info,"ISA");
- v->version = RADIO_VERSION;
- v->capabilities = V4L2_CAP_TUNER;
+ if (v->index > 0)
+ return -EINVAL;
- return 0;
- }
- case VIDIOC_G_TUNER:
- {
- struct v4l2_tuner *v = arg;
-
- if (v->index > 0)
- return -EINVAL;
-
- memset(v,0,sizeof(*v));
- strcpy(v->name, "FM");
- v->type = V4L2_TUNER_RADIO;
-
- v->rangelow=(88*16000);
- v->rangehigh=(108*16000);
- v->rxsubchans =V4L2_TUNER_SUB_MONO|V4L2_TUNER_SUB_STEREO;
- v->capability=V4L2_TUNER_CAP_LOW;
- if(zol_is_stereo(zol))
- v->audmode = V4L2_TUNER_MODE_STEREO;
- else
- v->audmode = V4L2_TUNER_MODE_MONO;
- v->signal=0xFFFF*zol_getsigstr(zol);
+ strcpy(v->name, "FM");
+ v->type = V4L2_TUNER_RADIO;
+ v->rangelow = (88*16000);
+ v->rangehigh = (108*16000);
+ v->rxsubchans = V4L2_TUNER_SUB_MONO|V4L2_TUNER_SUB_STEREO;
+ v->capability = V4L2_TUNER_CAP_LOW;
+ if (zol_is_stereo(zol))
+ v->audmode = V4L2_TUNER_MODE_STEREO;
+ else
+ v->audmode = V4L2_TUNER_MODE_MONO;
+ v->signal = 0xFFFF*zol_getsigstr(zol);
+ return 0;
+}
- return 0;
- }
- case VIDIOC_S_TUNER:
- {
- struct v4l2_tuner *v = arg;
+static int vidioc_s_tuner(struct file *file, void *priv,
+ struct v4l2_tuner *v)
+{
+ if (v->index > 0)
+ return -EINVAL;
+ return 0;
+}
- if (v->index > 0)
- return -EINVAL;
+static int vidioc_s_frequency(struct file *file, void *priv,
+ struct v4l2_frequency *f)
+{
+ struct video_device *dev = video_devdata(file);
+ struct zol_device *zol = dev->priv;
- return 0;
- }
- case VIDIOC_S_FREQUENCY:
- {
- struct v4l2_frequency *f = arg;
+ zol->curfreq = f->frequency;
+ zol_setfreq(zol, zol->curfreq);
+ return 0;
+}
- zol->curfreq = f->frequency;
- zol_setfreq(zol, zol->curfreq);
- return 0;
- }
- case VIDIOC_G_FREQUENCY:
- {
- struct v4l2_frequency *f = arg;
+static int vidioc_g_frequency(struct file *file, void *priv,
+ struct v4l2_frequency *f)
+{
+ struct video_device *dev = video_devdata(file);
+ struct zol_device *zol = dev->priv;
+
+ f->type = V4L2_TUNER_RADIO;
+ f->frequency = zol->curfreq;
+ return 0;
+}
- f->type = V4L2_TUNER_RADIO;
- f->frequency = zol->curfreq;
+static int vidioc_queryctrl(struct file *file, void *priv,
+ struct v4l2_queryctrl *qc)
+{
+ int i;
+ for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
+ if (qc->id && qc->id == radio_qctrl[i].id) {
+ memcpy(qc, &(radio_qctrl[i]),
+ sizeof(*qc));
return 0;
}
- case VIDIOC_QUERYCTRL:
- {
- struct v4l2_queryctrl *qc = arg;
- int i;
-
- for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
- if (qc->id && qc->id == radio_qctrl[i].id) {
- memcpy(qc, &(radio_qctrl[i]),
- sizeof(*qc));
- return (0);
- }
- }
- return -EINVAL;
- }
- case VIDIOC_G_CTRL:
- {
- struct v4l2_control *ctrl= arg;
-
- switch (ctrl->id) {
- case V4L2_CID_AUDIO_MUTE:
- ctrl->value=zol->muted;
- return (0);
- case V4L2_CID_AUDIO_VOLUME:
- ctrl->value=zol->curvol * 4096;
- return (0);
- }
- return -EINVAL;
+ }
+ return -EINVAL;
+}
+
+static int vidioc_g_ctrl(struct file *file, void *priv,
+ struct v4l2_control *ctrl)
+{
+ struct video_device *dev = video_devdata(file);
+ struct zol_device *zol = dev->priv;
+
+ switch (ctrl->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ ctrl->value = zol->muted;
+ return 0;
+ case V4L2_CID_AUDIO_VOLUME:
+ ctrl->value = zol->curvol * 4096;
+ return 0;
+ }
+ return -EINVAL;
+}
+
+static int vidioc_s_ctrl(struct file *file, void *priv,
+ struct v4l2_control *ctrl)
+{
+ struct video_device *dev = video_devdata(file);
+ struct zol_device *zol = dev->priv;
+
+ switch (ctrl->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ if (ctrl->value)
+ zol_mute(zol);
+ else {
+ zol_unmute(zol);
+ zol_setvol(zol,zol->curvol);
}
- case VIDIOC_S_CTRL:
- {
- struct v4l2_control *ctrl= arg;
-
- switch (ctrl->id) {
- case V4L2_CID_AUDIO_MUTE:
- if (ctrl->value) {
- zol_mute(zol);
- } else {
- zol_unmute(zol);
- zol_setvol(zol,zol->curvol);
- }
- return (0);
- case V4L2_CID_AUDIO_VOLUME:
- zol_setvol(zol,ctrl->value/4096);
- return (0);
- }
- zol->stereo = 1;
- zol_setfreq(zol, zol->curfreq);
+ return 0;
+ case V4L2_CID_AUDIO_VOLUME:
+ zol_setvol(zol,ctrl->value/4096);
+ return 0;
+ }
+ zol->stereo = 1;
+ zol_setfreq(zol, zol->curfreq);
#if 0 /*keep*/
/* FIXME: Implement stereo/mono switch on V4L2 */
if (v->mode & VIDEO_SOUND_STEREO) {
@@ -361,19 +363,39 @@ static int zol_do_ioctl(struct inode *inode, struct file *file,
zol_setfreq(zol, zol->curfreq);
}
#endif
- return -EINVAL;
- }
+ return -EINVAL;
+}
- default:
- return v4l_compat_translate_ioctl(inode,file,cmd,arg,
- zol_do_ioctl);
- }
+static int vidioc_g_audio(struct file *file, void *priv,
+ struct v4l2_audio *a)
+{
+ if (a->index > 1)
+ return -EINVAL;
+
+ strcpy(a->name, "Radio");
+ a->capability = V4L2_AUDCAP_STEREO;
+ return 0;
+}
+
+static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
+{
+ *i = 0;
+ return 0;
}
-static int zol_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg)
+static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
{
- return video_usercopy(inode, file, cmd, arg, zol_do_ioctl);
+ if (i != 0)
+ return -EINVAL;
+ return 0;
+}
+
+static int vidioc_s_audio(struct file *file, void *priv,
+ struct v4l2_audio *a)
+{
+ if (a->index != 0)
+ return -EINVAL;
+ return 0;
}
static struct zol_device zoltrix_unit;
@@ -383,7 +405,7 @@ static const struct file_operations zoltrix_fops =
.owner = THIS_MODULE,
.open = video_exclusive_open,
.release = video_exclusive_release,
- .ioctl = zol_ioctl,
+ .ioctl = video_ioctl2,
.compat_ioctl = v4l_compat_ioctl32,
.llseek = no_llseek,
};
@@ -395,6 +417,18 @@ static struct video_device zoltrix_radio =
.type = VID_TYPE_TUNER,
.hardware = 0,
.fops = &zoltrix_fops,
+ .vidioc_querycap = vidioc_querycap,
+ .vidioc_g_tuner = vidioc_g_tuner,
+ .vidioc_s_tuner = vidioc_s_tuner,
+ .vidioc_g_audio = vidioc_g_audio,
+ .vidioc_s_audio = vidioc_s_audio,
+ .vidioc_g_input = vidioc_g_input,
+ .vidioc_s_input = vidioc_s_input,
+ .vidioc_g_frequency = vidioc_g_frequency,
+ .vidioc_s_frequency = vidioc_s_frequency,
+ .vidioc_queryctrl = vidioc_queryctrl,
+ .vidioc_g_ctrl = vidioc_g_ctrl,
+ .vidioc_s_ctrl = vidioc_s_ctrl,
};
static int __init zoltrix_init(void)
diff --git a/linux/drivers/media/video/Kconfig b/linux/drivers/media/video/Kconfig
index ac65aaf20..41e36bc3f 100644
--- a/linux/drivers/media/video/Kconfig
+++ b/linux/drivers/media/video/Kconfig
@@ -2,14 +2,19 @@
# Multimedia Video device configuration
#
-menu "Video Capture Adapters"
+menuconfig VIDEO_CAPTURE_DRIVERS
+ bool "Video capture adapters"
depends on VIDEO_DEV
+ default y
+ ---help---
+ Say Y here to enable selecting the video adapters for
+ webcams, analog TV, and hybrid analog/digital TV.
+ Some of those devices also supports FM radio.
-comment "Video Capture Adapters"
+if VIDEO_CAPTURE_DRIVERS
config VIDEO_ADV_DEBUG
bool "Enable advanced debug functionality"
- depends on VIDEO_DEV
default n
---help---
Say Y here to enable advanced debugging functionality on some
@@ -34,7 +39,7 @@ config VIDEO_HELPER_CHIPS_AUTO
#
menu "Encoders/decoders and other helper chips"
- depends on VIDEO_DEV && !VIDEO_HELPER_CHIPS_AUTO
+ depends on !VIDEO_HELPER_CHIPS_AUTO
comment "Audio decoders"
@@ -61,7 +66,7 @@ config VIDEO_TDA7432
config VIDEO_TDA9840
tristate "Philips TDA9840 audio processor"
- depends on VIDEO_DEV && I2C
+ depends on I2C
---help---
Support for tda9840 audio decoder chip found on some Zoran boards.
@@ -79,7 +84,7 @@ config VIDEO_TDA9875
config VIDEO_TEA6415C
tristate "Philips TEA6415C audio processor"
- depends on VIDEO_DEV && I2C
+ depends on I2C
---help---
Support for tea6415c audio decoder chip found on some bt8xx boards.
@@ -88,7 +93,7 @@ config VIDEO_TEA6415C
config VIDEO_TEA6420
tristate "Philips TEA6420 audio processor"
- depends on VIDEO_DEV && I2C
+ depends on I2C
---help---
Support for tea6420 audio decoder chip found on some bt8xx boards.
@@ -469,7 +474,7 @@ config VIDEO_SAA5246A
config VIDEO_SAA5249
tristate "SAA5249 Teletext processor"
- depends on VIDEO_DEV && I2C && VIDEO_V4L2
+ depends on I2C && VIDEO_V4L2
help
Support for I2C bus based teletext using the SAA5249 chip. At the
moment this is only useful on some European WinTV cards.
@@ -479,14 +484,14 @@ config VIDEO_SAA5249
config TUNER_3036
tristate "SAB3036 tuner"
- depends on VIDEO_DEV && I2C && VIDEO_V4L1
+ depends on I2C && VIDEO_V4L1
help
Say Y here to include support for Philips SAB3036 compatible tuners.
If in doubt, say N.
config TUNER_TEA5761
tristate "TEA 5761 radio tuner (EXPERIMENTAL)"
- depends on VIDEO_DEV && I2C
+ depends on I2C
select VIDEO_TUNER
help
Say Y here to include support for Philips TEA5761 radio tuner.
@@ -689,8 +694,12 @@ config VIDEO_CAFE_CCIC
# USB Multimedia device configuration
#
-menu "V4L USB devices"
- depends on USB && VIDEO_DEV
+menuconfig V4L_USB_DRIVERS
+ bool "V4L USB devices"
+ depends on USB
+ default y
+
+if V4L_USB_DRIVERS
source "drivers/media/video/pvrusb2/Kconfig"
@@ -715,7 +724,7 @@ config VIDEO_OVCAMCHIP
config USB_W9968CF
tristate "USB W996[87]CF JPEG Dual Mode Camera support"
- depends on USB && VIDEO_V4L1 && I2C
+ depends on VIDEO_V4L1 && I2C
select VIDEO_OVCAMCHIP
---help---
Say Y here if you want support for cameras based on OV681 or
@@ -733,7 +742,7 @@ config USB_W9968CF
config USB_OV511
tristate "USB OV511 Camera support"
- depends on USB && VIDEO_V4L1
+ depends on VIDEO_V4L1
---help---
Say Y here if you want to connect this type of camera to your
computer's USB port. See <file:Documentation/video4linux/ov511.txt>
@@ -744,7 +753,7 @@ config USB_OV511
config USB_SE401
tristate "USB SE401 Camera support"
- depends on USB && VIDEO_V4L1
+ depends on VIDEO_V4L1
---help---
Say Y here if you want to connect this type of camera to your
computer's USB port. See <file:Documentation/video4linux/se401.txt>
@@ -757,7 +766,7 @@ source "drivers/media/video/sn9c102/Kconfig"
config USB_STV680
tristate "USB STV680 (Pencam) Camera support"
- depends on USB && VIDEO_V4L1
+ depends on VIDEO_V4L1
---help---
Say Y here if you want to connect this type of camera to your
computer's USB port. This includes the Pencam line of cameras.
@@ -773,7 +782,7 @@ source "drivers/media/video/pwc/Kconfig"
config USB_ZR364XX
tristate "USB ZR364XX Camera support"
- depends on USB && VIDEO_V4L2
+ depends on VIDEO_V4L2
---help---
Say Y here if you want to connect this type of camera to your
computer's USB port.
@@ -783,6 +792,6 @@ config USB_ZR364XX
To compile this driver as a module, choose M here: the
module will be called zr364xx.
-endmenu # V4L USB devices
+endif # V4L_USB_DRIVERS
-endmenu
+endif # VIDEO_CAPTURE_DRIVERS
diff --git a/linux/drivers/media/video/bt8xx/bttv-cards.c b/linux/drivers/media/video/bt8xx/bttv-cards.c
index b0e6c3e9c..c704efb05 100644
--- a/linux/drivers/media/video/bt8xx/bttv-cards.c
+++ b/linux/drivers/media/video/bt8xx/bttv-cards.c
@@ -314,6 +314,9 @@ static struct CARD {
{ 0x15409511, BTTV_BOARD_ACORP_Y878F, "Acorp Y878F" },
+ { 0x53534149, BTTV_BOARD_SSAI_SECURITY, "SSAI Security Video Interface" },
+ { 0x5353414a, BTTV_BOARD_SSAI_ULTRASOUND, "SSAI Ultrasound Video Interface" },
+
/* likely broken, vendor id doesn't match the other magic views ...
* { 0xa0fca04f, BTTV_BOARD_MAGICTVIEW063, "Guillemot Maxi TV Video 3" }, */
@@ -2952,6 +2955,28 @@ struct tvcard bttv_tvcards[] = {
.has_radio = 1,
.has_remote = 1,
},
+ [BTTV_BOARD_SSAI_SECURITY] = {
+ .name = "SSAI Security Video Interface",
+ .video_inputs = 4,
+ .audio_inputs = 0,
+ .tuner = -1,
+ .svhs = -1,
+ .muxsel = { 0, 1, 2, 3 },
+ .tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ },
+ [BTTV_BOARD_SSAI_ULTRASOUND] = {
+ .name = "SSAI Ultrasound Video Interface",
+ .video_inputs = 2,
+ .audio_inputs = 0,
+ .tuner = -1,
+ .svhs = 1,
+ .muxsel = { 2, 0, 1, 3 },
+ .tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ },
};
static const unsigned int bttv_num_tvcards = ARRAY_SIZE(bttv_tvcards);
@@ -3015,20 +3040,20 @@ void __devinit bttv_idcard(struct bttv *btv)
if (UNSET != audiomux[0]) {
gpiobits = 0;
- for (i = 0; i < 4; i++) {
+ for (i = 0; i < ARRAY_SIZE(bttv_tvcards->gpiomux); i++) {
bttv_tvcards[btv->c.type].gpiomux[i] = audiomux[i];
gpiobits |= audiomux[i];
}
} else {
gpiobits = audioall;
- for (i = 0; i < 4; i++) {
+ for (i = 0; i < ARRAY_SIZE(bttv_tvcards->gpiomux); i++) {
bttv_tvcards[btv->c.type].gpiomux[i] = audioall;
}
}
bttv_tvcards[btv->c.type].gpiomask = (UNSET != gpiomask) ? gpiomask : gpiobits;
printk(KERN_INFO "bttv%d: gpio config override: mask=0x%x, mux=",
btv->c.nr,bttv_tvcards[btv->c.type].gpiomask);
- for (i = 0; i < 5; i++) {
+ for (i = 0; i < ARRAY_SIZE(bttv_tvcards->gpiomux); i++) {
printk("%s0x%x", i ? "," : "", bttv_tvcards[btv->c.type].gpiomux[i]);
}
printk("\n");
@@ -3692,7 +3717,7 @@ static int __devinit pvr_altera_load(struct bttv *btv, u8 *micro, u32 microlen)
for (n = 0; n < microlen; n++) {
bits = micro[n];
- for ( i = 0 ; i < 8 ; i++ ) {
+ for (i = 0 ; i < 8 ; i++) {
gpio_bits(BTTV_ALT_DCLK,0);
if (bits & 0x01)
gpio_bits(BTTV_ALT_DATA,BTTV_ALT_DATA);
@@ -3749,7 +3774,7 @@ static void __devinit osprey_eeprom(struct bttv *btv)
/* this might be an antique... check for MMAC label in eeprom */
if ((ee[0]=='M') && (ee[1]=='M') && (ee[2]=='A') && (ee[3]=='C')) {
unsigned char checksum = 0;
- for (i =0; i<21; i++)
+ for (i = 0; i < 21; i++)
checksum += ee[i];
if (checksum != ee[21])
return;
@@ -3761,12 +3786,13 @@ static void __devinit osprey_eeprom(struct bttv *btv)
unsigned short type;
int offset = 4*16;
- for(; offset < 8*16; offset += 16) {
+ for (; offset < 8*16; offset += 16) {
unsigned short checksum = 0;
/* verify the checksum */
- for(i = 0; i<14; i++) checksum += ee[i+offset];
- checksum = ~checksum; /* no idea why */
- if ((((checksum>>8)&0x0FF) == ee[offset+14]) &&
+ for (i = 0; i < 14; i++)
+ checksum += ee[i+offset];
+ checksum = ~checksum; /* no idea why */
+ if ((((checksum>>8)&0x0FF) == ee[offset+14]) &&
((checksum & 0x0FF) == ee[offset+15])) {
break;
}
@@ -3779,7 +3805,6 @@ static void __devinit osprey_eeprom(struct bttv *btv)
type = (ee[offset+4]<<8) | (ee[offset+5]);
switch(type) {
-
/* 848 based */
case 0x0004:
btv->c.type = BTTV_BOARD_OSPREY1x0_848;
@@ -4245,8 +4270,7 @@ static int tea5757_read(struct bttv *btv)
}
dprintk("bttv%d: tea5757:",btv->c.nr);
- for(i = 0; i < 24; i++)
- {
+ for (i = 0; i < 24; i++) {
udelay(5);
bus_high(btv,btv->mbox_clk);
udelay(5);
@@ -4278,8 +4302,7 @@ static int tea5757_write(struct bttv *btv, int value)
dprintk("bttv%d: tea5757: write 0x%X\n", btv->c.nr, value);
bus_low(btv,btv->mbox_clk);
bus_high(btv,btv->mbox_we);
- for(i = 0; i < 25; i++)
- {
+ for (i = 0; i < 25; i++) {
if (reg & 0x1000000)
bus_high(btv,btv->mbox_data);
else
@@ -4871,7 +4894,7 @@ static void kodicom4400r_init(struct bttv *btv)
gpio_write(1 << 9); /* reset MUX */
gpio_write(0);
/* Preset camera 0 to the 4 controllers */
- for (ix=0; ix<4; ix++) {
+ for (ix = 0; ix < 4; ix++) {
sw_status[ix] = ix;
kodicom4400r_write(btv, ix, ix, 1);
}
diff --git a/linux/drivers/media/video/bt8xx/bttv-driver.c b/linux/drivers/media/video/bt8xx/bttv-driver.c
index 25a61e379..2aad57b5a 100644
--- a/linux/drivers/media/video/bt8xx/bttv-driver.c
+++ b/linux/drivers/media/video/bt8xx/bttv-driver.c
@@ -177,6 +177,36 @@ static CLASS_DEVICE_ATTR(card, S_IRUGO, show_card, NULL);
#endif
/* ----------------------------------------------------------------------- */
+/* dvb auto-load setup */
+#if defined(CONFIG_MODULES) && defined(MODULE)
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
+static void request_module_async(void *ptr)
+#else
+static void request_module_async(struct work_struct *work)
+#endif
+{
+ request_module("dvb-bt8xx");
+}
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+#define request_modules(dev)
+#else
+static void request_modules(struct bttv *dev)
+{
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
+ INIT_WORK(&dev->request_module_wk, request_module_async, (void*)dev);
+#else
+ INIT_WORK(&dev->request_module_wk, request_module_async);
+#endif
+ schedule_work(&dev->request_module_wk);
+}
+#endif
+#else
+#define request_modules(dev)
+#endif /* CONFIG_MODULES */
+
+
+/* ----------------------------------------------------------------------- */
/* static data */
/* special timing tables from conexant... */
@@ -4811,9 +4841,11 @@ static int __devinit bttv_probe(struct pci_dev *dev,
}
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
- /* add subdevices */
- if (bttv_tvcards[btv->c.type].has_dvb)
+ /* add subdevices and autoload dvb-bt8xx if needed */
+ if (bttv_tvcards[btv->c.type].has_dvb) {
bttv_sub_add_device(&btv->c, "dvb");
+ request_modules(btv);
+ }
#endif
bttv_input_init(btv);
diff --git a/linux/drivers/media/video/bt8xx/bttv-i2c.c b/linux/drivers/media/video/bt8xx/bttv-i2c.c
index 68522754a..3f545c610 100644
--- a/linux/drivers/media/video/bt8xx/bttv-i2c.c
+++ b/linux/drivers/media/video/bt8xx/bttv-i2c.c
@@ -426,7 +426,7 @@ static void do_i2c_scan(char *name, struct i2c_client *c)
unsigned char buf;
int i,rc;
- for (i = 0; i < 128; i++) {
+ for (i = 0; i < ARRAY_SIZE(i2c_devs); i++) {
c->addr = i;
rc = i2c_master_recv(c,&buf,0);
if (rc < 0)
diff --git a/linux/drivers/media/video/bt8xx/bttv.h b/linux/drivers/media/video/bt8xx/bttv.h
index ed565fb8b..f9681147d 100644
--- a/linux/drivers/media/video/bt8xx/bttv.h
+++ b/linux/drivers/media/video/bt8xx/bttv.h
@@ -169,6 +169,8 @@
#define BTTV_BOARD_SABRENT_TVFM 0x8e
#define BTTV_BOARD_HAUPPAUGE_IMPACTVCB 0x8f
#define BTTV_BOARD_MACHTV_MAGICTV 0x90
+#define BTTV_BOARD_SSAI_SECURITY 0x91
+#define BTTV_BOARD_SSAI_ULTRASOUND 0x92
/* more card-specific defines */
#define PT2254_L_CHANNEL 0x10
diff --git a/linux/drivers/media/video/bt8xx/bttvp.h b/linux/drivers/media/video/bt8xx/bttvp.h
index a273c424b..eee6f5ae3 100644
--- a/linux/drivers/media/video/bt8xx/bttvp.h
+++ b/linux/drivers/media/video/bt8xx/bttvp.h
@@ -452,6 +452,9 @@ struct bttv {
unsigned int users;
struct bttv_fh init;
+ /* used to make dvb-bt8xx autoloadable */
+ struct work_struct request_module_wk;
+
/* Default (0) and current (1) video capturing and overlay
cropping parameters in bttv_tvnorm.cropcap units. Protected
by bttv.lock. */
diff --git a/linux/drivers/media/video/cafe_ccic.c b/linux/drivers/media/video/cafe_ccic.c
index b96d45654..0615ec50c 100644
--- a/linux/drivers/media/video/cafe_ccic.c
+++ b/linux/drivers/media/video/cafe_ccic.c
@@ -4,6 +4,7 @@
* sensor.
*
* Copyright 2006 One Laptop Per Child Association, Inc.
+ * Copyright 2006-7 Jonathan Corbet <corbet@lwn.net>
*
* Written by Jonathan Corbet, corbet@lwn.net.
*
@@ -38,7 +39,7 @@
#include "cafe_ccic-regs.h"
-#define CAFE_VERSION 0x000001
+#define CAFE_VERSION 0x000002
/*
@@ -712,7 +713,13 @@ static void cafe_ctlr_init(struct cafe_camera *cam)
cafe_reg_write(cam, REG_GL_CSR, GCSR_SRS|GCSR_MRS); /* Needed? */
cafe_reg_write(cam, REG_GL_CSR, GCSR_SRC|GCSR_MRC);
cafe_reg_write(cam, REG_GL_CSR, GCSR_SRC|GCSR_MRS);
+ /*
+ * Here we must wait a bit for the controller to come around.
+ */
+ spin_unlock_irqrestore(&cam->dev_lock, flags);
mdelay(5); /* FIXME revisit this */
+ spin_lock_irqsave(&cam->dev_lock, flags);
+
cafe_reg_write(cam, REG_GL_CSR, GCSR_CCIC_EN|GCSR_SRC|GCSR_MRC);
cafe_reg_set_bit(cam, REG_GL_IMASK, GIMSK_CCIC_EN);
/*
@@ -780,9 +787,9 @@ static void cafe_ctlr_power_up(struct cafe_camera *cam)
* Control 1 is power down, set to 0 to operate.
*/
cafe_reg_write(cam, REG_GPR, GPR_C1EN|GPR_C0EN); /* pwr up, reset */
- mdelay(1); /* Marvell says 1ms will do it */
+// mdelay(1); /* Marvell says 1ms will do it */
cafe_reg_write(cam, REG_GPR, GPR_C1EN|GPR_C0EN|GPR_C0);
- mdelay(1); /* Enough? */
+// mdelay(1); /* Enough? */
spin_unlock_irqrestore(&cam->dev_lock, flags);
}
@@ -1803,18 +1810,19 @@ static void cafe_frame_tasklet(unsigned long data)
if (list_empty(&cam->sb_avail))
break; /* Leave it valid, hope for better later */
clear_bit(bufno, &cam->flags);
- /*
- * We could perhaps drop the spinlock during this
- * big copy. Something to consider.
- */
sbuf = list_entry(cam->sb_avail.next,
struct cafe_sio_buffer, list);
+ /*
+ * Drop the lock during the big copy. This *should* be safe...
+ */
+ spin_unlock_irqrestore(&cam->dev_lock, flags);
memcpy(sbuf->buffer, cam->dma_bufs[bufno],
cam->pix_format.sizeimage);
sbuf->v4lbuf.bytesused = cam->pix_format.sizeimage;
sbuf->v4lbuf.sequence = cam->buf_seq[bufno];
sbuf->v4lbuf.flags &= ~V4L2_BUF_FLAG_QUEUED;
sbuf->v4lbuf.flags |= V4L2_BUF_FLAG_DONE;
+ spin_lock_irqsave(&cam->dev_lock, flags);
list_move_tail(&sbuf->list, &cam->sb_full);
}
if (! list_empty(&cam->sb_full))
@@ -2118,6 +2126,7 @@ static int cafe_pci_probe(struct pci_dev *pdev,
cam->v4ldev = cafe_v4l_template;
cam->v4ldev.debug = 0;
// cam->v4ldev.debug = V4L2_DEBUG_IOCTL_ARG;
+ cam->v4ldev.dev = &pdev->dev;
ret = video_register_device(&cam->v4ldev, VFL_TYPE_GRABBER, -1);
if (ret)
goto out_smbus;
@@ -2187,10 +2196,52 @@ static void cafe_pci_remove(struct pci_dev *pdev)
}
+#ifdef CONFIG_PM
+/*
+ * Basic power management.
+ */
+static int cafe_pci_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+ struct cafe_camera *cam = cafe_find_by_pdev(pdev);
+ int ret;
+
+ ret = pci_save_state(pdev);
+ if (ret)
+ return ret;
+ cafe_ctlr_stop_dma(cam);
+ cafe_ctlr_power_down(cam);
+ pci_disable_device(pdev);
+ return 0;
+}
+
+
+static int cafe_pci_resume(struct pci_dev *pdev)
+{
+ struct cafe_camera *cam = cafe_find_by_pdev(pdev);
+ int ret = 0;
+
+ ret = pci_restore_state(pdev);
+ if (ret)
+ return ret;
+ ret = pci_enable_device(pdev);
+ if (ret) {
+ cam_warn(cam, "Unable to re-enable device on resume!\n");
+ return ret;
+ }
+ cafe_ctlr_init(cam);
+ cafe_ctlr_power_up(cam);
+ set_bit(CF_CONFIG_NEEDED, &cam->flags);
+ if (cam->state == S_SPECREAD)
+ cam->state = S_IDLE; /* Don't bother restarting */
+ else if (cam->state == S_SINGLEREAD || cam->state == S_STREAMING)
+ ret = cafe_read_setup(cam, cam->state);
+ return ret;
+}
+
+#endif /* CONFIG_PM */
static struct pci_device_id cafe_ids[] = {
- { PCI_DEVICE(0x1148, 0x4340) }, /* Temporary ID on devel board */
{ PCI_DEVICE(0x11ab, 0x4100) }, /* Eventual real ID */
{ PCI_DEVICE(0x11ab, 0x4102) }, /* Really eventual real ID */
{ 0, }
@@ -2203,6 +2254,10 @@ static struct pci_driver cafe_pci_driver = {
.id_table = cafe_ids,
.probe = cafe_pci_probe,
.remove = cafe_pci_remove,
+#ifdef CONFIG_PM
+ .suspend = cafe_pci_suspend,
+ .resume = cafe_pci_resume,
+#endif
};
diff --git a/linux/drivers/media/video/cpia_pp.c b/linux/drivers/media/video/cpia_pp.c
index 337675e96..d2c34c156 100644
--- a/linux/drivers/media/video/cpia_pp.c
+++ b/linux/drivers/media/video/cpia_pp.c
@@ -62,7 +62,6 @@ static int cpia_pp_close(void *privdata);
#define PPCPIA_PARPORT_OFF -2
#define PPCPIA_PARPORT_NONE -1
-#ifdef MODULE
static int parport_nr[PARPORT_MAX] = {[0 ... PARPORT_MAX - 1] = PPCPIA_PARPORT_UNSPEC};
static char *parport[PARPORT_MAX] = {NULL,};
@@ -72,11 +71,6 @@ MODULE_LICENSE("GPL");
module_param_array(parport, charp, NULL, 0);
MODULE_PARM_DESC(parport, "'auto' or a list of parallel port numbers. Just like lp.");
-#else
-static int parport_nr[PARPORT_MAX] __initdata =
- {[0 ... PARPORT_MAX - 1] = PPCPIA_PARPORT_UNSPEC};
-static int parport_ptr = 0;
-#endif
struct pp_cam_entry {
struct pardevice *pdev;
@@ -827,7 +821,7 @@ static struct parport_driver cpia_pp_driver = {
.detach = cpia_pp_detach,
};
-static int cpia_pp_init(void)
+static int __init cpia_pp_init(void)
{
printk(KERN_INFO "%s v%d.%d.%d\n",ABOUT,
CPIA_PP_MAJ_VER,CPIA_PP_MIN_VER,CPIA_PP_PATCH_VER);
@@ -846,8 +840,7 @@ static int cpia_pp_init(void)
return 0;
}
-#ifdef MODULE
-int init_module(void)
+static int __init cpia_init(void)
{
if (parport[0]) {
/* The user gave some parameters. Let's see what they were. */
@@ -874,38 +867,11 @@ int init_module(void)
return cpia_pp_init();
}
-void cleanup_module(void)
+static void __exit cpia_cleanup(void)
{
- parport_unregister_driver (&cpia_pp_driver);
+ parport_unregister_driver(&cpia_pp_driver);
return;
}
-#else /* !MODULE */
-
-static int __init cpia_pp_setup(char *str)
-{
- int err;
-
- if (!strncmp(str, "parport", 7)) {
- int n = simple_strtoul(str + 7, NULL, 10);
- if (parport_ptr < PARPORT_MAX) {
- parport_nr[parport_ptr++] = n;
- } else {
- LOG("too many ports, %s ignored.\n", str);
- }
- } else if (!strcmp(str, "auto")) {
- parport_nr[0] = PPCPIA_PARPORT_AUTO;
- } else if (!strcmp(str, "none")) {
- parport_nr[parport_ptr++] = PPCPIA_PARPORT_NONE;
- }
-
- err=cpia_pp_init();
- if (err)
- return err;
-
- return 1;
-}
-
-__setup("cpia_pp=", cpia_pp_setup);
-
-#endif /* !MODULE */
+module_init(cpia_init);
+module_exit(cpia_cleanup);
diff --git a/linux/drivers/media/video/cx25840/cx25840-core.c b/linux/drivers/media/video/cx25840/cx25840-core.c
index c401c1ee7..9d40a2b95 100644
--- a/linux/drivers/media/video/cx25840/cx25840-core.c
+++ b/linux/drivers/media/video/cx25840/cx25840-core.c
@@ -566,7 +566,7 @@ static int set_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt)
{
struct v4l2_pix_format *pix;
int HSC, VSC, Vsrc, Hsrc, filter, Vlines;
- int is_pal = !(cx25840_get_v4lstd(client) & V4L2_STD_NTSC);
+ int is_50Hz = !(cx25840_get_v4lstd(client) & V4L2_STD_525_60);
switch (fmt->type) {
case V4L2_BUF_TYPE_VIDEO_CAPTURE:
@@ -578,7 +578,7 @@ static int set_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt)
Hsrc = (cx25840_read(client, 0x472) & 0x3f) << 4;
Hsrc |= (cx25840_read(client, 0x471) & 0xf0) >> 4;
- Vlines = pix->height + (is_pal ? 4 : 7);
+ Vlines = pix->height + (is_50Hz ? 4 : 7);
if ((pix->width * 16 < Hsrc) || (Hsrc < pix->width) ||
(Vlines * 8 < Vsrc) || (Vsrc < Vlines)) {
diff --git a/linux/drivers/media/video/cx88/cx88-alsa.c b/linux/drivers/media/video/cx88/cx88-alsa.c
index bf67ec27d..7131e05a3 100644
--- a/linux/drivers/media/video/cx88/cx88-alsa.c
+++ b/linux/drivers/media/video/cx88/cx88-alsa.c
@@ -27,6 +27,7 @@
#include <linux/init.h>
#include <linux/device.h>
#include <linux/interrupt.h>
+#include <linux/dma-mapping.h>
#include <asm/delay.h>
#include <sound/driver.h>
#include <sound/core.h>
@@ -257,7 +258,8 @@ static void cx8801_aud_irq(snd_cx88_card_t *chip)
cx_write(MO_AUD_INTSTAT, status);
if (debug > 1 || (status & mask & ~0xff))
cx88_print_irqbits(core->name, "irq aud",
- cx88_aud_irqs, status, mask);
+ cx88_aud_irqs, ARRAY_SIZE(cx88_aud_irqs),
+ status, mask);
/* risc op code error */
if (status & (1 << 16)) {
printk(KERN_WARNING "%s/0: audio risc op code error\n",core->name);
@@ -467,11 +469,9 @@ static int snd_cx88_hw_params(struct snd_pcm_substream * substream,
dprintk(1,"Setting buffer\n");
- buf = kmalloc(sizeof(*buf),GFP_KERNEL);
+ buf = kzalloc(sizeof(*buf),GFP_KERNEL);
if (NULL == buf)
return -ENOMEM;
- memset(buf,0,sizeof(*buf));
-
buf->vb.memory = V4L2_MEMORY_MMAP;
buf->vb.width = chip->period_size;
@@ -789,7 +789,7 @@ static int __devinit snd_cx88_create(struct snd_card *card,
return err;
}
- if (!pci_dma_supported(pci,0xffffffff)) {
+ if (!pci_dma_supported(pci,DMA_32BIT_MASK)) {
dprintk(0, "%s/1: Oops: no 32bit PCI DMA ???\n",core->name);
err = -EIO;
cx88_core_put(core,pci);
diff --git a/linux/drivers/media/video/cx88/cx88-cards.c b/linux/drivers/media/video/cx88/cx88-cards.c
index 774bcfed9..6be16512a 100644
--- a/linux/drivers/media/video/cx88/cx88-cards.c
+++ b/linux/drivers/media/video/cx88/cx88-cards.c
@@ -886,6 +886,12 @@ struct cx88_board cx88_boards[] = {
.input = {{
.type = CX88_VMUX_DVB,
.vmux = 0,
+ },{
+ .type = CX88_VMUX_COMPOSITE1,
+ .vmux = 1,
+ },{
+ .type = CX88_VMUX_SVIDEO,
+ .vmux = 2,
}},
.mpeg = CX88_MPEG_DVB,
},
@@ -1823,7 +1829,7 @@ static void dvico_fusionhdtv_hybrid_init(struct cx88_core *core)
{ 0x03, 0x0C },
};
- for (i = 0; i < 13; i++) {
+ for (i = 0; i < ARRAY_SIZE(init_bufs); i++) {
msg.buf = init_bufs[i];
msg.len = (i != 12 ? 5 : 2);
err = i2c_transfer(&core->i2c_adap, &msg, 1);
@@ -1950,12 +1956,21 @@ void cx88_card_setup(struct cx88_core *core)
if (0 == core->i2c_rc) {
/* enable tuner */
int i;
- static const u8 buffer [] = { 0x10,0x12,0x13,0x04,0x16,0x00,0x14,0x04,0x017,0x00 };
+ static const u8 buffer [][2] = {
+ {0x10,0x12},
+ {0x13,0x04},
+ {0x16,0x00},
+ {0x14,0x04},
+ {0x17,0x00}
+ };
core->i2c_client.addr = 0x0a;
- for (i = 0; i < 5; i++)
- if (2 != i2c_master_send(&core->i2c_client,&buffer[i*2],2))
- printk(KERN_WARNING "%s: Unable to enable tuner(%i).\n",
+ for (i = 0; i < ARRAY_SIZE(buffer); i++)
+ if (2 != i2c_master_send(&core->i2c_client,
+ buffer[i],2))
+ printk(KERN_WARNING
+ "%s: Unable to enable "
+ "tuner(%i).\n",
core->name, i);
}
break;
diff --git a/linux/drivers/media/video/cx88/cx88-core.c b/linux/drivers/media/video/cx88/cx88-core.c
index 367dc3c7b..ba132d065 100644
--- a/linux/drivers/media/video/cx88/cx88-core.c
+++ b/linux/drivers/media/video/cx88/cx88-core.c
@@ -524,12 +524,12 @@ static char *cx88_pci_irqs[32] = {
};
void cx88_print_irqbits(char *name, char *tag, char **strings,
- u32 bits, u32 mask)
+ int len, u32 bits, u32 mask)
{
unsigned int i;
printk(KERN_DEBUG "%s: %s [0x%x]", name, tag, bits);
- for (i = 0; i < 32; i++) {
+ for (i = 0; i < len; i++) {
if (!(bits & (1 << i)))
continue;
if (strings[i])
@@ -555,8 +555,8 @@ int cx88_core_irq(struct cx88_core *core, u32 status)
}
if (!handled)
cx88_print_irqbits(core->name, "irq pci",
- cx88_pci_irqs, status,
- core->pci_irqmask);
+ cx88_pci_irqs, ARRAY_SIZE(cx88_pci_irqs),
+ status, core->pci_irqmask);
return handled;
}
diff --git a/linux/drivers/media/video/cx88/cx88-dvb.c b/linux/drivers/media/video/cx88/cx88-dvb.c
index 2b24c27a6..2327b32fd 100644
--- a/linux/drivers/media/video/cx88/cx88-dvb.c
+++ b/linux/drivers/media/video/cx88/cx88-dvb.c
@@ -476,6 +476,8 @@ static int dvb_register(struct cx8802_dev *dev)
case CX88_BOARD_WINFAST_DTV2000H:
case CX88_BOARD_HAUPPAUGE_HVR1100:
case CX88_BOARD_HAUPPAUGE_HVR1100LP:
+ case CX88_BOARD_HAUPPAUGE_HVR1300:
+ case CX88_BOARD_HAUPPAUGE_HVR3000:
dev->dvb.frontend = dvb_attach(cx22702_attach,
&hauppauge_hvr_config,
&dev->core->i2c_adap);
@@ -694,24 +696,6 @@ static int dvb_register(struct cx8802_dev *dev)
dev->dvb.frontend->ops.set_voltage = geniatech_dvbs_set_voltage;
}
break;
- case CX88_BOARD_HAUPPAUGE_HVR1300:
- dev->dvb.frontend = dvb_attach(cx22702_attach,
- &hauppauge_hvr_config,
- &dev->core->i2c_adap);
- if (dev->dvb.frontend != NULL) {
- dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61,
- &dev->core->i2c_adap, &dvb_pll_fmd1216me);
- }
- break;
- case CX88_BOARD_HAUPPAUGE_HVR3000:
- dev->dvb.frontend = dvb_attach(cx22702_attach,
- &hauppauge_hvr_config,
- &dev->core->i2c_adap);
- if (dev->dvb.frontend != NULL) {
- dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61,
- &dev->core->i2c_adap, &dvb_pll_fmd1216me);
- }
- break;
default:
printk("%s: The frontend of your DVB/ATSC card isn't supported yet\n",
dev->core->name);
diff --git a/linux/drivers/media/video/cx88/cx88-i2c.c b/linux/drivers/media/video/cx88/cx88-i2c.c
index 2f60c957b..30fd0776a 100644
--- a/linux/drivers/media/video/cx88/cx88-i2c.c
+++ b/linux/drivers/media/video/cx88/cx88-i2c.c
@@ -1,3 +1,4 @@
+
/*
cx88-i2c.c -- all the i2c code is here
@@ -206,7 +207,7 @@ static void do_i2c_scan(char *name, struct i2c_client *c)
unsigned char buf;
int i,rc;
- for (i = 0; i < 128; i++) {
+ for (i = 0; i < ARRAY_SIZE(i2c_devs); i++) {
c->addr = i;
rc = i2c_master_recv(c,&buf,0);
if (rc < 0)
diff --git a/linux/drivers/media/video/cx88/cx88-mpeg.c b/linux/drivers/media/video/cx88/cx88-mpeg.c
index cb642ca03..861ac813e 100644
--- a/linux/drivers/media/video/cx88/cx88-mpeg.c
+++ b/linux/drivers/media/video/cx88/cx88-mpeg.c
@@ -30,6 +30,7 @@
#include <linux/device.h>
#endif
#include <linux/interrupt.h>
+#include <linux/dma-mapping.h>
#include <asm/delay.h>
#include "cx88.h"
@@ -405,7 +406,8 @@ static void cx8802_mpeg_irq(struct cx8802_dev *dev)
if (debug || (status & mask & ~0xff))
cx88_print_irqbits(core->name, "irq mpeg ",
- cx88_mpeg_irqs, status, mask);
+ cx88_mpeg_irqs, ARRAY_SIZE(cx88_mpeg_irqs),
+ status, mask);
/* risc op code error */
if (status & (1 << 16)) {
@@ -491,7 +493,7 @@ int cx8802_init_common(struct cx8802_dev *dev)
if (pci_enable_device(dev->pci))
return -EIO;
pci_set_master(dev->pci);
- if (!pci_dma_supported(dev->pci,0xffffffff)) {
+ if (!pci_dma_supported(dev->pci,DMA_32BIT_MASK)) {
printk("%s/2: Oops: no 32bit PCI DMA ???\n",dev->core->name);
return -EIO;
}
@@ -669,7 +671,7 @@ struct cx8802_driver * cx8802_get_driver(struct cx8802_dev *dev, enum cx88_board
}
/* Driver asked for hardware access. */
-int cx8802_request_acquire(struct cx8802_driver *drv)
+static int cx8802_request_acquire(struct cx8802_driver *drv)
{
struct cx88_core *core = drv->core;
@@ -689,7 +691,7 @@ int cx8802_request_acquire(struct cx8802_driver *drv)
}
/* Driver asked to release hardware. */
-int cx8802_request_release(struct cx8802_driver *drv)
+static int cx8802_request_release(struct cx8802_driver *drv)
{
struct cx88_core *core = drv->core;
diff --git a/linux/drivers/media/video/cx88/cx88-video.c b/linux/drivers/media/video/cx88/cx88-video.c
index 2e6259ceb..9b8edf555 100644
--- a/linux/drivers/media/video/cx88/cx88-video.c
+++ b/linux/drivers/media/video/cx88/cx88-video.c
@@ -39,6 +39,7 @@
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
#include <linux/kthread.h>
#endif
+#include <linux/dma-mapping.h>
#include <asm/div64.h>
#include "cx88.h"
@@ -1836,7 +1837,8 @@ static void cx8800_vid_irq(struct cx8800_dev *dev)
cx_write(MO_VID_INTSTAT, status);
if (irq_debug || (status & mask & ~0xff))
cx88_print_irqbits(core->name, "irq vid",
- cx88_vid_irqs, status, mask);
+ cx88_vid_irqs, ARRAY_SIZE(cx88_vid_irqs),
+ status, mask);
/* risc op code error */
if (status & (1 << 16)) {
@@ -2067,7 +2069,7 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev,
dev->pci_lat,(unsigned long long)pci_resource_start(pci_dev,0));
pci_set_master(pci_dev);
- if (!pci_dma_supported(pci_dev,0xffffffff)) {
+ if (!pci_dma_supported(pci_dev,DMA_32BIT_MASK)) {
printk("%s/0: Oops: no 32bit PCI DMA ???\n",core->name);
err = -EIO;
goto fail_core;
diff --git a/linux/drivers/media/video/cx88/cx88.h b/linux/drivers/media/video/cx88/cx88.h
index 4719046e1..a35b46cab 100644
--- a/linux/drivers/media/video/cx88/cx88.h
+++ b/linux/drivers/media/video/cx88/cx88.h
@@ -545,7 +545,7 @@ struct cx8802_dev {
/* cx88-core.c */
extern void cx88_print_irqbits(char *name, char *tag, char **strings,
- u32 bits, u32 mask);
+ int len, u32 bits, u32 mask);
extern int cx88_core_irq(struct cx88_core *core, u32 status);
extern void cx88_wakeup(struct cx88_core *core,
diff --git a/linux/drivers/media/video/em28xx/Kconfig b/linux/drivers/media/video/em28xx/Kconfig
index 9285a58e4..3823b62da 100644
--- a/linux/drivers/media/video/em28xx/Kconfig
+++ b/linux/drivers/media/video/em28xx/Kconfig
@@ -1,6 +1,6 @@
config VIDEO_EM28XX
tristate "Empia EM2800/2820/2840 USB video capture support"
- depends on VIDEO_V4L1 && USB && I2C
+ depends on VIDEO_V4L1 && I2C
select VIDEO_BUF
select VIDEO_TUNER
select VIDEO_TVEEPROM
diff --git a/linux/drivers/media/video/em28xx/em28xx-i2c.c b/linux/drivers/media/video/em28xx/em28xx-i2c.c
index 4ee4cea10..ceb71f67c 100644
--- a/linux/drivers/media/video/em28xx/em28xx-i2c.c
+++ b/linux/drivers/media/video/em28xx/em28xx-i2c.c
@@ -544,7 +544,7 @@ static void do_i2c_scan(char *name, struct i2c_client *c)
unsigned char buf;
int i, rc;
- for (i = 0; i < 128; i++) {
+ for (i = 0; i < ARRAY_SIZE(i2c_devs); i++) {
c->addr = i;
rc = i2c_master_recv(c, &buf, 0);
if (rc < 0)
diff --git a/linux/drivers/media/video/et61x251/Kconfig b/linux/drivers/media/video/et61x251/Kconfig
index c6bff7056..664676f44 100644
--- a/linux/drivers/media/video/et61x251/Kconfig
+++ b/linux/drivers/media/video/et61x251/Kconfig
@@ -1,6 +1,6 @@
config USB_ET61X251
tristate "USB ET61X[12]51 PC Camera Controller support"
- depends on USB && VIDEO_V4L1
+ depends on VIDEO_V4L1
---help---
Say Y here if you want support for cameras based on Etoms ET61X151
or ET61X251 PC Camera Controllers.
diff --git a/linux/drivers/media/video/ir-kbd-i2c.c b/linux/drivers/media/video/ir-kbd-i2c.c
index d20bad700..8d0c49782 100644
--- a/linux/drivers/media/video/ir-kbd-i2c.c
+++ b/linux/drivers/media/video/ir-kbd-i2c.c
@@ -174,7 +174,7 @@ static int get_key_pinnacle(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw,
return -EIO;
}
- for (start = 0; start<4; start++) {
+ for (start = 0; start < ARRAY_SIZE(b); start++) {
if (b[start] == marker) {
code=b[(start+parity_offset+1)%4];
parity=b[(start+parity_offset)%4];
diff --git a/linux/drivers/media/video/ivtv/ivtv-driver.c b/linux/drivers/media/video/ivtv/ivtv-driver.c
index 4031df6db..8fbc34db5 100644
--- a/linux/drivers/media/video/ivtv/ivtv-driver.c
+++ b/linux/drivers/media/video/ivtv/ivtv-driver.c
@@ -74,7 +74,7 @@ int ivtv_first_minor = 0;
struct ivtv *ivtv_cards[IVTV_MAX_CARDS];
/* Protects ivtv_cards_active */
-spinlock_t ivtv_cards_lock = SPIN_LOCK_UNLOCKED;
+DEFINE_SPINLOCK(ivtv_cards_lock);
/* add your revision and whatnot here */
static struct pci_device_id ivtv_pci_tbl[] __devinitdata = {
diff --git a/linux/drivers/media/video/ivtv/ivtv-fileops.c b/linux/drivers/media/video/ivtv/ivtv-fileops.c
index 1637097dd..8976487a6 100644
--- a/linux/drivers/media/video/ivtv/ivtv-fileops.c
+++ b/linux/drivers/media/video/ivtv/ivtv-fileops.c
@@ -804,7 +804,7 @@ int ivtv_v4l2_open(struct inode *inode, struct file *filp)
struct ivtv_open_id *item;
struct ivtv *itv = NULL;
struct ivtv_stream *s = NULL;
- int minor = MINOR(inode->i_rdev);
+ int minor = iminor(inode);
/* Find which card this open was on */
spin_lock(&ivtv_cards_lock);
diff --git a/linux/drivers/media/video/ivtv/ivtv-ioctl.c b/linux/drivers/media/video/ivtv/ivtv-ioctl.c
index d6f0b0235..f29c55d3b 100644
--- a/linux/drivers/media/video/ivtv/ivtv-ioctl.c
+++ b/linux/drivers/media/video/ivtv/ivtv-ioctl.c
@@ -289,7 +289,7 @@ static int ivtv_video_command(struct ivtv *itv, struct ivtv_open_id *id,
}
case VIDEO_CMD_STOP:
- vc->flags &= ~(VIDEO_CMD_STOP_IMMEDIATELY|VIDEO_CMD_STOP_TO_BLACK);
+ vc->flags &= VIDEO_CMD_STOP_IMMEDIATELY|VIDEO_CMD_STOP_TO_BLACK;
if (vc->flags & VIDEO_CMD_STOP_IMMEDIATELY)
vc->stop.pts = 0;
if (try) break;
@@ -302,7 +302,7 @@ static int ivtv_video_command(struct ivtv *itv, struct ivtv_open_id *id,
return ivtv_stop_v4l2_decode_stream(s, vc->flags, vc->stop.pts);
case VIDEO_CMD_FREEZE:
- vc->flags &= ~VIDEO_CMD_FREEZE_TO_BLACK;
+ vc->flags &= VIDEO_CMD_FREEZE_TO_BLACK;
if (try) break;
if (itv->output_mode != OUT_MPG)
return -EBUSY;
@@ -1107,7 +1107,7 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void
return ivtv_start_capture(id);
case V4L2_ENC_CMD_STOP:
- enc->flags &= ~V4L2_ENC_CMD_STOP_AT_GOP_END;
+ enc->flags &= V4L2_ENC_CMD_STOP_AT_GOP_END;
if (try)
return 0;
ivtv_stop_capture(id, enc->flags & V4L2_ENC_CMD_STOP_AT_GOP_END);
diff --git a/linux/drivers/media/video/ov7670.c b/linux/drivers/media/video/ov7670.c
index b033bf334..8b2c19df9 100644
--- a/linux/drivers/media/video/ov7670.c
+++ b/linux/drivers/media/video/ov7670.c
@@ -5,6 +5,8 @@
* by Jonathan Corbet with substantial inspiration from Mark
* McClelland's ovcamchip code.
*
+ * Copyright 2006-7 Jonathan Corbet <corbet@lwn.net>
+ *
* This file may be distributed under the terms of the GNU General
* Public License, version 2.
*/
@@ -164,6 +166,10 @@ MODULE_LICENSE("GPL");
#define REG_GFIX 0x69 /* Fix gain control */
+#define REG_REG76 0x76 /* OV's name */
+#define R76_BLKPCOR 0x80 /* Black pixel correction enable */
+#define R76_WHTPCOR 0x40 /* White pixel correction enable */
+
#define REG_RGB444 0x8c /* RGB 444 control */
#define R444_ENABLE 0x02 /* Turn on RGB444, overrides 5x5 */
#define R444_RGBX 0x01 /* Empty nibble at end */
@@ -257,7 +263,7 @@ static struct regval_list ov7670_default_regs[] = {
/* Almost all of these are magic "reserved" values. */
{ REG_COM5, 0x61 }, { REG_COM6, 0x4b },
- { 0x16, 0x02 }, { REG_MVFP, 0x07|MVFP_MIRROR },
+ { 0x16, 0x02 }, { REG_MVFP, 0x07 },
{ 0x21, 0x02 }, { 0x22, 0x91 },
{ 0x29, 0x07 }, { 0x33, 0x0b },
{ 0x35, 0x0b }, { 0x37, 0x1d },
@@ -382,6 +388,13 @@ static struct regval_list ov7670_fmt_rgb444[] = {
{ 0xff, 0xff },
};
+static struct regval_list ov7670_fmt_raw[] = {
+ { REG_COM7, COM7_BAYER },
+ { REG_COM13, 0x08 }, /* No gamma, magic rsvd bit */
+ { REG_COM16, 0x3d }, /* Edge enhancement, denoise */
+ { REG_REG76, 0xe1 }, /* Pix correction, magic rsvd */
+ { 0xff, 0xff },
+};
@@ -506,32 +519,39 @@ static struct ov7670_format_struct {
__u32 pixelformat;
struct regval_list *regs;
int cmatrix[CMATRIX_LEN];
+ int bpp; /* Bytes per pixel */
} ov7670_formats[] = {
{
.desc = "YUYV 4:2:2",
.pixelformat = V4L2_PIX_FMT_YUYV,
.regs = ov7670_fmt_yuv422,
.cmatrix = { 128, -128, 0, -34, -94, 128 },
+ .bpp = 2,
},
{
.desc = "RGB 444",
.pixelformat = V4L2_PIX_FMT_RGB444,
.regs = ov7670_fmt_rgb444,
.cmatrix = { 179, -179, 0, -61, -176, 228 },
+ .bpp = 2,
},
{
.desc = "RGB 565",
.pixelformat = V4L2_PIX_FMT_RGB565,
.regs = ov7670_fmt_rgb565,
.cmatrix = { 179, -179, 0, -61, -176, 228 },
+ .bpp = 2,
+ },
+ {
+ .desc = "Raw RGB Bayer",
+ .pixelformat = V4L2_PIX_FMT_SBGGR8,
+ .regs = ov7670_fmt_raw,
+ .cmatrix = { 0, 0, 0, 0, 0, 0 },
+ .bpp = 1
},
};
-#define N_OV7670_FMTS (sizeof(ov7670_formats)/sizeof(ov7670_formats[0]))
+#define N_OV7670_FMTS ARRAY_SIZE(ov7670_formats)
-/*
- * All formats we support are 2 bytes/pixel.
- */
-#define BYTES_PER_PIXEL 2
/*
* Then there is the issue of window sizes. Try to capture the info here.
@@ -708,7 +728,7 @@ static int ov7670_try_fmt(struct i2c_client *c, struct v4l2_format *fmt,
*/
pix->width = wsize->width;
pix->height = wsize->height;
- pix->bytesperline = pix->width*BYTES_PER_PIXEL;
+ pix->bytesperline = pix->width*ov7670_formats[index].bpp;
pix->sizeimage = pix->height*pix->bytesperline;
return 0;
}
diff --git a/linux/drivers/media/video/planb.c b/linux/drivers/media/video/planb.c
index c393b26e1..c6f2dc6cf 100644
--- a/linux/drivers/media/video/planb.c
+++ b/linux/drivers/media/video/planb.c
@@ -2216,7 +2216,7 @@ static int find_planb(void)
"membase 0x%x (base reg. 0x%x)\n",
bus, PCI_SLOT(dev_fn), PCI_FUNC(dev_fn), old_base, confreg);
- pdev = pci_find_slot (bus, dev_fn);
+ pdev = pci_get_bus_and_slot(bus, dev_fn);
if (!pdev) {
printk(KERN_ERR "planb: cannot find slot\n");
goto err_out;
@@ -2246,6 +2246,7 @@ static int find_planb(void)
pb->planb_base = planb_regs;
pb->planb_base_phys = (struct planb_registers *)new_base;
pb->irq = irq;
+ pb->dev = pdev;
return planb_num;
@@ -2253,6 +2254,7 @@ err_out_disable:
pci_disable_device(pdev);
err_out:
/* FIXME handle error */ /* comment moved from pci_find_slot, above */
+ pci_dev_put(pdev);
return 0;
}
@@ -2280,6 +2282,8 @@ static void release_planb(void)
printk(KERN_INFO "PlanB: unregistering with v4l\n");
video_unregister_device(&pb->video_dev);
+ pci_dev_put(pb->dev);
+
/* note that iounmap() does nothing on the PPC right now */
iounmap ((void *)pb->planb_base);
}
diff --git a/linux/drivers/media/video/planb.h b/linux/drivers/media/video/planb.h
index 92823211d..e21b5735c 100644
--- a/linux/drivers/media/video/planb.h
+++ b/linux/drivers/media/video/planb.h
@@ -177,6 +177,7 @@ struct planb {
struct mutex lock;
unsigned int irq; /* interrupt number */
volatile unsigned int intr_mask;
+ struct pci_dev *dev; /* Our PCI device */
int overlay; /* overlay running? */
struct planb_window win;
diff --git a/linux/drivers/media/video/pvrusb2/Kconfig b/linux/drivers/media/video/pvrusb2/Kconfig
index 5645c9318..d0c2cd785 100644
--- a/linux/drivers/media/video/pvrusb2/Kconfig
+++ b/linux/drivers/media/video/pvrusb2/Kconfig
@@ -1,6 +1,6 @@
config VIDEO_PVRUSB2
tristate "Hauppauge WinTV-PVR USB2 support"
- depends on VIDEO_V4L2 && USB && I2C && EXPERIMENTAL
+ depends on VIDEO_V4L2 && I2C && EXPERIMENTAL
select FW_LOADER
select VIDEO_TUNER
select VIDEO_TVEEPROM
diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-encoder.c b/linux/drivers/media/video/pvrusb2/pvrusb2-encoder.c
index a7424f847..4abee970c 100644
--- a/linux/drivers/media/video/pvrusb2/pvrusb2-encoder.c
+++ b/linux/drivers/media/video/pvrusb2/pvrusb2-encoder.c
@@ -424,22 +424,29 @@ static int pvr2_encoder_prep_config(struct pvr2_hdw *hdw)
int pvr2_encoder_configure(struct pvr2_hdw *hdw)
{
int ret;
+ int val;
pvr2_trace(PVR2_TRACE_ENCODER,"pvr2_encoder_configure"
" (cx2341x module)");
hdw->enc_ctl_state.port = CX2341X_PORT_STREAMING;
hdw->enc_ctl_state.width = hdw->res_hor_val;
hdw->enc_ctl_state.height = hdw->res_ver_val;
- hdw->enc_ctl_state.is_50hz = ((hdw->std_mask_cur &
- (V4L2_STD_NTSC|V4L2_STD_PAL_M)) ?
+ hdw->enc_ctl_state.is_50hz = ((hdw->std_mask_cur & V4L2_STD_525_60) ?
0 : 1);
ret = 0;
ret |= pvr2_encoder_prep_config(hdw);
+ /* saa7115: 0xf0 */
+ val = 0xf0;
+ if (hdw->hdw_type == PVR2_HDW_TYPE_24XXX) {
+ /* ivtv cx25840: 0x140 */
+ val = 0x140;
+ }
+
if (!ret) ret = pvr2_encoder_vcmd(
hdw,CX2341X_ENC_SET_NUM_VSYNC_LINES, 2,
- 0xf0, 0xf0);
+ val, val);
/* setup firmware to notify us about some events (don't know why...) */
if (!ret) ret = pvr2_encoder_vcmd(
diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h
index db0b02f0f..e8ee1bf73 100644
--- a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h
+++ b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h
@@ -299,6 +299,8 @@ struct pvr2_hdw {
int unit_number; /* ID for driver instance */
unsigned long serial_number; /* ID for hardware itself */
+ char bus_info[32]; /* Bus location info */
+
/* Minor numbers used by v4l logic (yes, this is a hack, as there
should be no v4l junk here). Probably a better way to do this. */
int v4l_minor_number_video;
diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c
index d1de5cd59..52078f4d0 100644
--- a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c
+++ b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c
@@ -84,7 +84,7 @@ static struct pvr2_string_table pvr2_client_lists[] = {
};
static struct pvr2_hdw *unit_pointers[PVR_NUM] = {[ 0 ... PVR_NUM-1 ] = NULL};
-static DECLARE_MUTEX(pvr2_unit_sem);
+static DEFINE_MUTEX(pvr2_unit_mtx);
static int ctlchg = 0;
static int initusbreset = 1;
@@ -1009,6 +1009,13 @@ unsigned long pvr2_hdw_get_sn(struct pvr2_hdw *hdw)
return hdw->serial_number;
}
+
+const char *pvr2_hdw_get_bus_info(struct pvr2_hdw *hdw)
+{
+ return hdw->bus_info;
+}
+
+
unsigned long pvr2_hdw_get_cur_freq(struct pvr2_hdw *hdw)
{
return hdw->freqSelector ? hdw->freqValTelevision : hdw->freqValRadio;
@@ -1258,10 +1265,10 @@ int pvr2_upload_firmware2(struct pvr2_hdw *hdw)
ret |= pvr2_write_register(hdw, 0xaa18, 0x00840000); /*unknown*/
LOCK_TAKE(hdw->ctl_lock); do {
hdw->cmd_buffer[0] = FX2CMD_FWPOST1;
- ret |= pvr2_send_request(hdw,hdw->cmd_buffer,1,0,0);
+ ret |= pvr2_send_request(hdw,hdw->cmd_buffer,1,NULL,0);
hdw->cmd_buffer[0] = FX2CMD_MEMSEL;
hdw->cmd_buffer[1] = 0;
- ret |= pvr2_send_request(hdw,hdw->cmd_buffer,2,0,0);
+ ret |= pvr2_send_request(hdw,hdw->cmd_buffer,2,NULL,0);
} while (0); LOCK_GIVE(hdw->ctl_lock);
if (ret) {
@@ -1330,7 +1337,7 @@ int pvr2_upload_firmware2(struct pvr2_hdw *hdw)
LOCK_TAKE(hdw->ctl_lock); do {
hdw->cmd_buffer[0] = FX2CMD_MEMSEL;
hdw->cmd_buffer[1] = 0;
- ret |= pvr2_send_request(hdw,hdw->cmd_buffer,2,0,0);
+ ret |= pvr2_send_request(hdw,hdw->cmd_buffer,2,NULL,0);
} while (0); LOCK_GIVE(hdw->ctl_lock);
if (ret) {
@@ -2096,14 +2103,14 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf,
hdw->ctl_read_urb = usb_alloc_urb(0,GFP_KERNEL);
if (!hdw->ctl_read_urb) goto fail;
- down(&pvr2_unit_sem); do {
+ mutex_lock(&pvr2_unit_mtx); do {
for (idx = 0; idx < PVR_NUM; idx++) {
if (unit_pointers[idx]) continue;
hdw->unit_number = idx;
unit_pointers[idx] = hdw;
break;
}
- } while (0); up(&pvr2_unit_sem);
+ } while (0); mutex_unlock(&pvr2_unit_mtx);
cnt1 = 0;
cnt2 = scnprintf(hdw->name+cnt1,sizeof(hdw->name)-cnt1,"pvrusb2");
@@ -2132,6 +2139,11 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf,
hdw->usb_intf = intf;
hdw->usb_dev = interface_to_usbdev(intf);
+ scnprintf(hdw->bus_info,sizeof(hdw->bus_info),
+ "usb %s address %d",
+ hdw->usb_dev->dev.bus_id,
+ hdw->usb_dev->devnum);
+
ifnum = hdw->usb_intf->cur_altsetting->desc.bInterfaceNumber;
usb_set_interface(hdw->usb_dev,ifnum,0);
@@ -2201,13 +2213,13 @@ void pvr2_hdw_destroy(struct pvr2_hdw *hdw)
}
pvr2_i2c_core_done(hdw);
pvr2_hdw_remove_usb_stuff(hdw);
- down(&pvr2_unit_sem); do {
+ mutex_lock(&pvr2_unit_mtx); do {
if ((hdw->unit_number >= 0) &&
(hdw->unit_number < PVR_NUM) &&
(unit_pointers[hdw->unit_number] == hdw)) {
unit_pointers[hdw->unit_number] = NULL;
}
- } while (0); up(&pvr2_unit_sem);
+ } while (0); mutex_unlock(&pvr2_unit_mtx);
kfree(hdw->controls);
kfree(hdw->mpeg_ctrl_info);
kfree(hdw->std_defs);
diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.h b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.h
index 319dab523..6e4cd7976 100644
--- a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.h
+++ b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.h
@@ -133,6 +133,9 @@ struct usb_device *pvr2_hdw_get_dev(struct pvr2_hdw *);
/* Retrieve serial number of device */
unsigned long pvr2_hdw_get_sn(struct pvr2_hdw *);
+/* Retrieve bus location info of device */
+const char *pvr2_hdw_get_bus_info(struct pvr2_hdw *);
+
/* Called when hardware has been unplugged */
void pvr2_hdw_disconnect(struct pvr2_hdw *);
diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c b/linux/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
index 22a02dd76..1a9563aa5 100644
--- a/linux/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
+++ b/linux/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
@@ -23,6 +23,7 @@
#include "pvrusb2-hdw-internal.h"
#include "pvrusb2-debug.h"
#include "pvrusb2-fx2-cmd.h"
+#include "pvrusb2.h"
#include "compat.h"
#define trace_i2c(...) pvr2_trace(PVR2_TRACE_I2C,__VA_ARGS__)
@@ -39,6 +40,10 @@ static unsigned int i2c_scan = 0;
module_param(i2c_scan, int, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(i2c_scan,"scan i2c bus at insmod time");
+static int ir_mode[PVR_NUM] = { [0 ... PVR_NUM-1] = 1 };
+module_param_array(ir_mode, int, NULL, 0444);
+MODULE_PARM_DESC(ir_mode,"specify: 0=disable IR reception, 1=normal IR");
+
static unsigned int pvr2_i2c_client_describe(struct pvr2_i2c_client *cp,
unsigned int detail,
char *buf,unsigned int maxlen);
@@ -348,6 +353,15 @@ static int i2c_hack_wm8775(struct pvr2_hdw *hdw,
return pvr2_i2c_basic_op(hdw,i2c_addr,wdata,wlen,rdata,rlen);
}
+/* This is an entry point designed to always fail any attempt to perform a
+ transfer. We use this to cause certain I2C addresses to not be
+ probed. */
+static int i2c_black_hole(struct pvr2_hdw *hdw,
+ u8 i2c_addr,u8 *wdata,u16 wlen,u8 *rdata,u16 rlen)
+{
+ return -EIO;
+}
+
/* This is a special entry point that is entered if an I2C operation is
attempted to a cx25840 chip on model 24xxx hardware. This chip can
sometimes wedge itself. Worse still, when this happens msp3400 can
@@ -1080,10 +1094,17 @@ void pvr2_i2c_core_init(struct pvr2_hdw *hdw)
}
/* However, deal with various special cases for 24xxx hardware. */
+ if (ir_mode[hdw->unit_number] == 0) {
+ printk(KERN_INFO "%s: IR disabled\n",hdw->name);
+ hdw->i2c_func[0x18] = i2c_black_hole;
+ } else if (ir_mode[hdw->unit_number] == 1) {
+ if (hdw->hdw_type == PVR2_HDW_TYPE_24XXX) {
+ hdw->i2c_func[0x18] = i2c_24xxx_ir;
+ }
+ }
if (hdw->hdw_type == PVR2_HDW_TYPE_24XXX) {
hdw->i2c_func[0x1b] = i2c_hack_wm8775;
hdw->i2c_func[0x44] = i2c_hack_cx25840;
- hdw->i2c_func[0x18] = i2c_24xxx_ir;
}
// Configure the adapter and set up everything else related to it.
diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-sysfs.c b/linux/drivers/media/video/pvrusb2/pvrusb2-sysfs.c
index 4e3dd17dc..e28cc23ea 100644
--- a/linux/drivers/media/video/pvrusb2/pvrusb2-sysfs.c
+++ b/linux/drivers/media/video/pvrusb2/pvrusb2-sysfs.c
@@ -43,9 +43,11 @@ struct pvr2_sysfs {
struct class_device_attribute attr_v4l_minor_number;
struct class_device_attribute attr_v4l_radio_minor_number;
struct class_device_attribute attr_unit_number;
+ struct class_device_attribute attr_bus_info;
int v4l_minor_number_created_ok;
int v4l_radio_minor_number_created_ok;
int unit_number_created_ok;
+ int bus_info_created_ok;
};
#ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
@@ -517,40 +519,32 @@ static void pvr2_sysfs_add_control(struct pvr2_sysfs *sfp,int ctl_id)
}
sfp->item_last = cip;
- cip->attr_name.attr.owner = THIS_MODULE;
cip->attr_name.attr.name = "name";
cip->attr_name.attr.mode = S_IRUGO;
cip->attr_name.show = fp->show_name;
- cip->attr_type.attr.owner = THIS_MODULE;
cip->attr_type.attr.name = "type";
cip->attr_type.attr.mode = S_IRUGO;
cip->attr_type.show = fp->show_type;
- cip->attr_min.attr.owner = THIS_MODULE;
cip->attr_min.attr.name = "min_val";
cip->attr_min.attr.mode = S_IRUGO;
cip->attr_min.show = fp->show_min;
- cip->attr_max.attr.owner = THIS_MODULE;
cip->attr_max.attr.name = "max_val";
cip->attr_max.attr.mode = S_IRUGO;
cip->attr_max.show = fp->show_max;
- cip->attr_val.attr.owner = THIS_MODULE;
cip->attr_val.attr.name = "cur_val";
cip->attr_val.attr.mode = S_IRUGO;
- cip->attr_custom.attr.owner = THIS_MODULE;
cip->attr_custom.attr.name = "custom_val";
cip->attr_custom.attr.mode = S_IRUGO;
- cip->attr_enum.attr.owner = THIS_MODULE;
cip->attr_enum.attr.name = "enum_val";
cip->attr_enum.attr.mode = S_IRUGO;
cip->attr_enum.show = fp->show_enum;
- cip->attr_bits.attr.owner = THIS_MODULE;
cip->attr_bits.attr.name = "bit_val";
cip->attr_bits.attr.mode = S_IRUGO;
cip->attr_bits.show = fp->show_bits;
@@ -615,12 +609,10 @@ static void pvr2_sysfs_add_debugifc(struct pvr2_sysfs *sfp)
dip = kzalloc(sizeof(*dip),GFP_KERNEL);
if (!dip) return;
- dip->attr_debugcmd.attr.owner = THIS_MODULE;
dip->attr_debugcmd.attr.name = "debugcmd";
dip->attr_debugcmd.attr.mode = S_IRUGO|S_IWUSR|S_IWGRP;
dip->attr_debugcmd.show = debugcmd_show;
dip->attr_debugcmd.store = debugcmd_store;
- dip->attr_debuginfo.attr.owner = THIS_MODULE;
dip->attr_debuginfo.attr.name = "debuginfo";
dip->attr_debuginfo.attr.mode = S_IRUGO;
dip->attr_debuginfo.show = debuginfo_show;
@@ -706,6 +698,10 @@ static void class_dev_destroy(struct pvr2_sysfs *sfp)
pvr2_sysfs_tear_down_debugifc(sfp);
#endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
pvr2_sysfs_tear_down_controls(sfp);
+ if (sfp->bus_info_created_ok) {
+ class_device_remove_file(sfp->class_dev,
+ &sfp->attr_bus_info);
+ }
if (sfp->v4l_minor_number_created_ok) {
class_device_remove_file(sfp->class_dev,
&sfp->attr_v4l_minor_number);
@@ -736,6 +732,16 @@ static ssize_t v4l_minor_number_show(struct class_device *class_dev,char *buf)
}
+static ssize_t bus_info_show(struct class_device *class_dev,char *buf)
+{
+ struct pvr2_sysfs *sfp;
+ sfp = (struct pvr2_sysfs *)class_dev->class_data;
+ if (!sfp) return -EINVAL;
+ return scnprintf(buf,PAGE_SIZE,"%s\n",
+ pvr2_hdw_get_bus_info(sfp->channel.hdw));
+}
+
+
static ssize_t v4l_radio_minor_number_show(struct class_device *class_dev,
char *buf)
{
@@ -796,7 +802,6 @@ static void class_dev_create(struct pvr2_sysfs *sfp,
return;
}
- sfp->attr_v4l_minor_number.attr.owner = THIS_MODULE;
sfp->attr_v4l_minor_number.attr.name = "v4l_minor_number";
sfp->attr_v4l_minor_number.attr.mode = S_IRUGO;
sfp->attr_v4l_minor_number.show = v4l_minor_number_show;
@@ -810,7 +815,6 @@ static void class_dev_create(struct pvr2_sysfs *sfp,
sfp->v4l_minor_number_created_ok = !0;
}
- sfp->attr_v4l_radio_minor_number.attr.owner = THIS_MODULE;
sfp->attr_v4l_radio_minor_number.attr.name = "v4l_radio_minor_number";
sfp->attr_v4l_radio_minor_number.attr.mode = S_IRUGO;
sfp->attr_v4l_radio_minor_number.show = v4l_radio_minor_number_show;
@@ -824,7 +828,6 @@ static void class_dev_create(struct pvr2_sysfs *sfp,
sfp->v4l_radio_minor_number_created_ok = !0;
}
- sfp->attr_unit_number.attr.owner = THIS_MODULE;
sfp->attr_unit_number.attr.name = "unit_number";
sfp->attr_unit_number.attr.mode = S_IRUGO;
sfp->attr_unit_number.show = unit_number_show;
@@ -837,6 +840,19 @@ static void class_dev_create(struct pvr2_sysfs *sfp,
sfp->unit_number_created_ok = !0;
}
+ sfp->attr_bus_info.attr.name = "bus_info_str";
+ sfp->attr_bus_info.attr.mode = S_IRUGO;
+ sfp->attr_bus_info.show = bus_info_show;
+ sfp->attr_bus_info.store = NULL;
+ ret = class_device_create_file(sfp->class_dev,
+ &sfp->attr_bus_info);
+ if (ret < 0) {
+ printk(KERN_WARNING "%s: class_device_create_file error: %d\n",
+ __FUNCTION__, ret);
+ } else {
+ sfp->bus_info_created_ok = !0;
+ }
+
pvr2_sysfs_add_controls(sfp);
#ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
pvr2_sysfs_add_debugifc(sfp);
diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-v4l2.c b/linux/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
index 9f2f11754..a8a8a36ee 100644
--- a/linux/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
+++ b/linux/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
@@ -204,6 +204,8 @@ static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file,
struct v4l2_capability *cap = arg;
memcpy(cap, &pvr_capability, sizeof(struct v4l2_capability));
+ strlcpy(cap->bus_info,pvr2_hdw_get_bus_info(hdw),
+ sizeof(cap->bus_info));
ret = 0;
break;
@@ -809,11 +811,11 @@ static void pvr2_v4l2_destroy_no_lock(struct pvr2_v4l2 *vp)
{
if (vp->dev_video) {
pvr2_v4l2_dev_destroy(vp->dev_video);
- vp->dev_video = 0;
+ vp->dev_video = NULL;
}
if (vp->dev_radio) {
pvr2_v4l2_dev_destroy(vp->dev_radio);
- vp->dev_radio = 0;
+ vp->dev_radio = NULL;
}
pvr2_trace(PVR2_TRACE_STRUCT,"Destroying pvr2_v4l2 id=%p",vp);
@@ -1142,7 +1144,7 @@ static void pvr2_v4l2_dev_init(struct pvr2_v4l2_dev *dip,
#endif
int mindevnum;
int unit_number;
- int *nr_ptr = 0;
+ int *nr_ptr = NULL;
dip->v4lp = vp;
#if 0
diff --git a/linux/drivers/media/video/pwc/Kconfig b/linux/drivers/media/video/pwc/Kconfig
index 8fdf7101d..7298cf2e1 100644
--- a/linux/drivers/media/video/pwc/Kconfig
+++ b/linux/drivers/media/video/pwc/Kconfig
@@ -1,6 +1,6 @@
config USB_PWC
tristate "USB Philips Cameras"
- depends on USB && VIDEO_V4L1
+ depends on VIDEO_V4L1
---help---
Say Y or M here if you want to use one of these Philips & OEM
webcams:
diff --git a/linux/drivers/media/video/pwc/pwc-ctrl.c b/linux/drivers/media/video/pwc/pwc-ctrl.c
index acd8d4af1..9cc416a59 100644
--- a/linux/drivers/media/video/pwc/pwc-ctrl.c
+++ b/linux/drivers/media/video/pwc/pwc-ctrl.c
@@ -140,6 +140,8 @@ static const char *size2name[PSZ_MAX] =
An alternate value of 0 means this mode is not available at all.
*/
+#define PWC_FPS_MAX_NALA 8
+
struct Nala_table_entry {
char alternate; /* USB alternate setting */
int compressed; /* Compressed yes/no */
@@ -147,7 +149,9 @@ struct Nala_table_entry {
unsigned char mode[3]; /* precomputed mode table */
};
-static struct Nala_table_entry Nala_table[PSZ_MAX][8] =
+static unsigned int Nala_fps_vector[PWC_FPS_MAX_NALA] = { 4, 5, 7, 10, 12, 15, 20, 24 };
+
+static struct Nala_table_entry Nala_table[PSZ_MAX][PWC_FPS_MAX_NALA] =
{
#include "pwc-nala.h"
};
@@ -423,6 +427,59 @@ int pwc_set_video_mode(struct pwc_device *pdev, int width, int height, int frame
return 0;
}
+static unsigned int pwc_get_fps_Nala(struct pwc_device *pdev, unsigned int index, unsigned int size)
+{
+ unsigned int i;
+
+ for (i = 0; i < PWC_FPS_MAX_NALA; i++) {
+ if (Nala_table[size][i].alternate) {
+ if (index--==0) return Nala_fps_vector[i];
+ }
+ }
+ return 0;
+}
+
+static unsigned int pwc_get_fps_Kiara(struct pwc_device *pdev, unsigned int index, unsigned int size)
+{
+ unsigned int i;
+
+ for (i = 0; i < PWC_FPS_MAX_KIARA; i++) {
+ if (Kiara_table[size][i][3].alternate) {
+ if (index--==0) return Kiara_fps_vector[i];
+ }
+ }
+ return 0;
+}
+
+static unsigned int pwc_get_fps_Timon(struct pwc_device *pdev, unsigned int index, unsigned int size)
+{
+ unsigned int i;
+
+ for (i=0; i < PWC_FPS_MAX_TIMON; i++) {
+ if (Timon_table[size][i][3].alternate) {
+ if (index--==0) return Timon_fps_vector[i];
+ }
+ }
+ return 0;
+}
+
+unsigned int pwc_get_fps(struct pwc_device *pdev, unsigned int index, unsigned int size)
+{
+ unsigned int ret;
+
+ if (DEVICE_USE_CODEC1(pdev->type)) {
+ ret = pwc_get_fps_Nala(pdev, index, size);
+
+ } else if (DEVICE_USE_CODEC3(pdev->type)) {
+ ret = pwc_get_fps_Kiara(pdev, index, size);
+
+ } else {
+ ret = pwc_get_fps_Timon(pdev, index, size);
+ }
+
+ return ret;
+}
+
#define BLACK_Y 0
#define BLACK_U 128
#define BLACK_V 128
@@ -1362,7 +1419,7 @@ int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg)
ret = pwc_read_red_gain(pdev, &ARGR(wb).read_red);
if (ret < 0)
break;
- ret =pwc_read_blue_gain(pdev, &ARGR(wb).read_blue);
+ ret = pwc_read_blue_gain(pdev, &ARGR(wb).read_blue);
if (ret < 0)
break;
}
diff --git a/linux/drivers/media/video/pwc/pwc-if.c b/linux/drivers/media/video/pwc/pwc-if.c
index 782699cf9..282ec2153 100644
--- a/linux/drivers/media/video/pwc/pwc-if.c
+++ b/linux/drivers/media/video/pwc/pwc-if.c
@@ -95,8 +95,8 @@ static const struct usb_device_id pwc_device_table [] = {
{ USB_DEVICE(0x046D, 0x08B3) }, /* Logitech QuickCam Zoom (old model) */
{ USB_DEVICE(0x046D, 0x08B4) }, /* Logitech QuickCam Zoom (new model) */
{ USB_DEVICE(0x046D, 0x08B5) }, /* Logitech QuickCam Orbit/Sphere */
- { USB_DEVICE(0x046D, 0x08B6) }, /* Logitech (reserved) */
- { USB_DEVICE(0x046D, 0x08B7) }, /* Logitech (reserved) */
+ { USB_DEVICE(0x046D, 0x08B6) }, /* Cisco VT Camera */
+ { USB_DEVICE(0x046D, 0x08B7) }, /* Logitech ViewPort AV 100 */
{ USB_DEVICE(0x046D, 0x08B8) }, /* Logitech (reserved) */
{ USB_DEVICE(0x055D, 0x9000) }, /* Samsung MPC-C10 */
{ USB_DEVICE(0x055D, 0x9001) }, /* Samsung MPC-C30 */
@@ -1541,7 +1541,7 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
case 0x0329:
PWC_INFO("Philips SPC 900NC USB webcam detected.\n");
name = "Philips SPC 900NC webcam";
- type_id = 720;
+ type_id = 740;
break;
default:
return -ENODEV;
@@ -1595,8 +1595,16 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
features |= FEATURE_MOTOR_PANTILT;
break;
case 0x08b6:
+ PWC_INFO("Logitech/Cisco VT Camera webcam detected.\n");
+ name = "Cisco VT Camera";
+ type_id = 740; /* CCD sensor */
+ break;
case 0x08b7:
- case 0x08b8:
+ PWC_INFO("Logitech ViewPort AV 100 webcam detected.\n");
+ name = "Logitech ViewPort AV 100";
+ type_id = 740; /* CCD sensor */
+ break;
+ case 0x08b8: /* Where this released? */
PWC_INFO("Logitech QuickCam detected (reserved ID).\n");
name = "Logitech QuickCam (res.)";
type_id = 730; /* Assuming CMOS */
diff --git a/linux/drivers/media/video/pwc/pwc-ioctl.h b/linux/drivers/media/video/pwc/pwc-ioctl.h
index 784bc7252..58904acda 100644
--- a/linux/drivers/media/video/pwc/pwc-ioctl.h
+++ b/linux/drivers/media/video/pwc/pwc-ioctl.h
@@ -2,7 +2,7 @@
#define PWC_IOCTL_H
/* (C) 2001-2004 Nemosoft Unv.
- (C) 2004 Luc Saillard (luc@saillard.org)
+ (C) 2004-2006 Luc Saillard (luc@saillard.org)
NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx
driver and thus may have bugs that are not present in the original version.
@@ -25,7 +25,7 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-/* This is pwc-ioctl.h belonging to PWC 8.12.1
+/* This is pwc-ioctl.h belonging to PWC 10.0.10
It contains structures and defines to communicate from user space
directly to the driver.
*/
@@ -51,6 +51,13 @@
... the function
*/
+#include <linux/types.h>
+#include <linux/version.h>
+
+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 10)
+/* Compatibility for older kernel */
+typedef __u16 __le16;
+#endif
/* Enumeration of image sizes */
#define PSZ_SQCIF 0x00
@@ -65,6 +72,8 @@
/* The frame rate is encoded in the video_window.flags parameter using
the upper 16 bits, since some flags are defined nowadays. The following
defines provide a mask and shift to filter out this value.
+ This value can also be passing using the private flag when using v4l2 and
+ VIDIOC_S_FMT ioctl.
In 'Snapshot' mode the camera freezes its automatic exposure and colour
balance controls.
@@ -73,6 +82,8 @@
#define PWC_FPS_MASK 0x00FF0000
#define PWC_FPS_FRMASK 0x003F0000
#define PWC_FPS_SNAPSHOT 0x00400000
+#define PWC_QLT_MASK 0x03000000
+#define PWC_QLT_SHIFT 24
/* structure for transferring x & y coordinates */
@@ -289,4 +300,29 @@ struct pwc_table_init_buffer {
};
#define VIDIOCPWCGVIDTABLE _IOR('v', 216, struct pwc_table_init_buffer)
+/*
+ * This is private command used when communicating with v4l2.
+ * In the future all private ioctl will be remove/replace to
+ * use interface offer by v4l2.
+ */
+
+#define V4L2_CID_PRIVATE_SAVE_USER (V4L2_CID_PRIVATE_BASE + 0)
+#define V4L2_CID_PRIVATE_RESTORE_USER (V4L2_CID_PRIVATE_BASE + 1)
+#define V4L2_CID_PRIVATE_RESTORE_FACTORY (V4L2_CID_PRIVATE_BASE + 2)
+#define V4L2_CID_PRIVATE_COLOUR_MODE (V4L2_CID_PRIVATE_BASE + 3)
+#define V4L2_CID_PRIVATE_AUTOCONTOUR (V4L2_CID_PRIVATE_BASE + 4)
+#define V4L2_CID_PRIVATE_CONTOUR (V4L2_CID_PRIVATE_BASE + 5)
+#define V4L2_CID_PRIVATE_BACKLIGHT (V4L2_CID_PRIVATE_BASE + 6)
+#define V4L2_CID_PRIVATE_FLICKERLESS (V4L2_CID_PRIVATE_BASE + 7)
+#define V4L2_CID_PRIVATE_NOISE_REDUCTION (V4L2_CID_PRIVATE_BASE + 8)
+
+struct pwc_raw_frame {
+ __le16 type; /* type of the webcam */
+ __le16 vbandlength; /* Size of 4lines compressed (used by the decompressor) */
+ __u8 cmd[4]; /* the four byte of the command (in case of nala,
+ only the first 3 bytes is filled) */
+ __u8 rawframe[0]; /* frame_size = H/4*vbandlength */
+} __attribute__ ((packed));
+
+
#endif
diff --git a/linux/drivers/media/video/pwc/pwc-kiara.c b/linux/drivers/media/video/pwc/pwc-kiara.c
index fec39cc5a..f4ae83c0c 100644
--- a/linux/drivers/media/video/pwc/pwc-kiara.c
+++ b/linux/drivers/media/video/pwc/pwc-kiara.c
@@ -42,6 +42,8 @@
#include "pwc-kiara.h"
#include "pwc-uncompress.h"
+const unsigned int Kiara_fps_vector[PWC_FPS_MAX_KIARA] = { 5, 10, 15, 20, 25, 30 };
+
const struct Kiara_table_entry Kiara_table[PSZ_MAX][6][4] =
{
/* SQCIF */
diff --git a/linux/drivers/media/video/pwc/pwc-kiara.h b/linux/drivers/media/video/pwc/pwc-kiara.h
index 0bdb22547..047dad8c1 100644
--- a/linux/drivers/media/video/pwc/pwc-kiara.h
+++ b/linux/drivers/media/video/pwc/pwc-kiara.h
@@ -29,6 +29,8 @@
#include <media/pwc-ioctl.h>
+#define PWC_FPS_MAX_KIARA 6
+
struct Kiara_table_entry
{
char alternate; /* USB alternate interface */
@@ -37,8 +39,9 @@ struct Kiara_table_entry
unsigned char mode[12]; /* precomputed mode settings for cam */
};
-extern const struct Kiara_table_entry Kiara_table[PSZ_MAX][6][4];
+extern const struct Kiara_table_entry Kiara_table[PSZ_MAX][PWC_FPS_MAX_KIARA][4];
extern const unsigned int KiaraRomTable[8][2][16][8];
+extern const unsigned int Kiara_fps_vector[PWC_FPS_MAX_KIARA];
#endif
diff --git a/linux/drivers/media/video/pwc/pwc-timon.c b/linux/drivers/media/video/pwc/pwc-timon.c
index be65bdcd1..c56c174b1 100644
--- a/linux/drivers/media/video/pwc/pwc-timon.c
+++ b/linux/drivers/media/video/pwc/pwc-timon.c
@@ -40,7 +40,9 @@
#include "pwc-timon.h"
-const struct Timon_table_entry Timon_table[PSZ_MAX][6][4] =
+const unsigned int Timon_fps_vector[PWC_FPS_MAX_TIMON] = { 5, 10, 15, 20, 25, 30 };
+
+const struct Timon_table_entry Timon_table[PSZ_MAX][PWC_FPS_MAX_TIMON][4] =
{
/* SQCIF */
{
diff --git a/linux/drivers/media/video/pwc/pwc-timon.h b/linux/drivers/media/video/pwc/pwc-timon.h
index eef9e2cd4..a6e22224c 100644
--- a/linux/drivers/media/video/pwc/pwc-timon.h
+++ b/linux/drivers/media/video/pwc/pwc-timon.h
@@ -44,6 +44,8 @@
#include <media/pwc-ioctl.h>
+#define PWC_FPS_MAX_TIMON 6
+
struct Timon_table_entry
{
char alternate; /* USB alternate interface */
@@ -52,9 +54,9 @@ struct Timon_table_entry
unsigned char mode[13]; /* precomputed mode settings for cam */
};
-extern const struct Timon_table_entry Timon_table[PSZ_MAX][6][4];
+extern const struct Timon_table_entry Timon_table[PSZ_MAX][PWC_FPS_MAX_TIMON][4];
extern const unsigned int TimonRomTable [16][2][16][8];
-
+extern const unsigned int Timon_fps_vector[PWC_FPS_MAX_TIMON];
#endif
diff --git a/linux/drivers/media/video/pwc/pwc-v4l.c b/linux/drivers/media/video/pwc/pwc-v4l.c
index 2d5bb48f3..32fbe1ae6 100644
--- a/linux/drivers/media/video/pwc/pwc-v4l.c
+++ b/linux/drivers/media/video/pwc/pwc-v4l.c
@@ -127,7 +127,6 @@ static struct v4l2_queryctrl pwc_controls[] = {
.step = 1,
.default_value = 0,
},
-#ifndef BROKEN_XAWTV
{
.id = V4L2_CID_PRIVATE_SAVE_USER,
.type = V4L2_CTRL_TYPE_BUTTON,
@@ -209,7 +208,6 @@ static struct v4l2_queryctrl pwc_controls[] = {
.step = 1,
.default_value = 0,
},
-#endif
};
@@ -1170,7 +1168,7 @@ int pwc_video_do_ioctl(struct inode *inode, struct file *file,
buf->sequence = 0;
buf->memory = V4L2_MEMORY_MMAP;
buf->m.offset = pdev->fill_image * pdev->len_per_image;
- buf->length = buf->bytesused;
+ buf->length = pdev->len_per_image;
pwc_next_image(pdev);
PWC_DEBUG_IOCTL("VIDIOC_DQBUF: buf->index=%d\n",buf->index);
@@ -1195,6 +1193,64 @@ int pwc_video_do_ioctl(struct inode *inode, struct file *file,
return 0;
}
+ case VIDIOC_ENUM_FRAMESIZES:
+ {
+ struct v4l2_frmsizeenum *fsize = arg;
+ unsigned int i = 0, index = fsize->index;
+
+ if (fsize->pixel_format == V4L2_PIX_FMT_YUV420) {
+ for (i = 0; i < PSZ_MAX; i++) {
+ if (pdev->image_mask & (1UL << i)) {
+ if (!index--) {
+ fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
+ fsize->discrete.width = pwc_image_sizes[i].x;
+ fsize->discrete.height = pwc_image_sizes[i].y;
+ return 0;
+ }
+ }
+ }
+ } else if (fsize->index == 0 &&
+ ((fsize->pixel_format == V4L2_PIX_FMT_PWC1 && DEVICE_USE_CODEC1(pdev->type)) ||
+ (fsize->pixel_format == V4L2_PIX_FMT_PWC2 && DEVICE_USE_CODEC23(pdev->type)))) {
+
+ fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
+ fsize->discrete.width = pdev->abs_max.x;
+ fsize->discrete.height = pdev->abs_max.y;
+ return 0;
+ }
+ return -EINVAL;
+ }
+
+ case VIDIOC_ENUM_FRAMEINTERVALS:
+ {
+ struct v4l2_frmivalenum *fival = arg;
+ int size = -1;
+ unsigned int i;
+
+ for (i = 0; i < PSZ_MAX; i++) {
+ if (pwc_image_sizes[i].x == fival->width &&
+ pwc_image_sizes[i].y == fival->height) {
+ size = i;
+ break;
+ }
+ }
+
+ /* TODO: Support raw format */
+ if (size < 0 || fival->pixel_format != V4L2_PIX_FMT_YUV420) {
+ return -EINVAL;
+ }
+
+ i = pwc_get_fps(pdev, fival->index, size);
+ if (!i)
+ return -EINVAL;
+
+ fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;
+ fival->discrete.numerator = 1;
+ fival->discrete.denominator = i;
+
+ return 0;
+ }
+
default:
return pwc_ioctl(pdev, cmd, arg);
} /* ..switch */
diff --git a/linux/drivers/media/video/pwc/pwc.h b/linux/drivers/media/video/pwc/pwc.h
index e778a2b8c..acbb93129 100644
--- a/linux/drivers/media/video/pwc/pwc.h
+++ b/linux/drivers/media/video/pwc/pwc.h
@@ -44,7 +44,7 @@
#define PWC_MINOR 0
#define PWC_EXTRAMINOR 12
#define PWC_VERSION_CODE KERNEL_VERSION(PWC_MAJOR,PWC_MINOR,PWC_EXTRAMINOR)
-#define PWC_VERSION "10.0.12"
+#define PWC_VERSION "10.0.13"
#define PWC_NAME "pwc"
#define PFX PWC_NAME ": "
@@ -85,7 +85,7 @@
#define PWC_INFO(fmt, args...) printk(KERN_INFO PFX fmt, ##args)
#define PWC_TRACE(fmt, args...) PWC_DEBUG(TRACE, fmt, ##args)
-#else /* if ! CONFIG_PWC_DEBUG */
+#else /* if ! CONFIG_USB_PWC_DEBUG */
#define PWC_ERROR(fmt, args...) printk(KERN_ERR PFX fmt, ##args)
#define PWC_WARNING(fmt, args...) printk(KERN_WARNING PFX fmt, ##args)
@@ -287,6 +287,7 @@ void pwc_construct(struct pwc_device *pdev);
/** Functions in pwc-ctrl.c */
/* Request a certain video mode. Returns < 0 if not possible */
extern int pwc_set_video_mode(struct pwc_device *pdev, int width, int height, int frames, int compression, int snapshot);
+extern unsigned int pwc_get_fps(struct pwc_device *pdev, unsigned int index, unsigned int size);
/* Calculate the number of bytes per image (not frame) */
extern int pwc_mpt_reset(struct pwc_device *pdev, int flags);
extern int pwc_mpt_set_angle(struct pwc_device *pdev, int pan, int tilt);
diff --git a/linux/drivers/media/video/saa7134/saa7134-cards.c b/linux/drivers/media/video/saa7134/saa7134-cards.c
index 5e8a2f498..a722ae8bd 100644
--- a/linux/drivers/media/video/saa7134/saa7134-cards.c
+++ b/linux/drivers/media/video/saa7134/saa7134-cards.c
@@ -1171,6 +1171,42 @@ struct saa7134_board saa7134_boards[] = {
.amux = LINE2,
},
},
+ [SAA7134_BOARD_ECS_TVP3XP_4CB6] = {
+ /* Barry Scott <barry.scott@onelan.co.uk> */
+ .name = "Elitegroup ECS TVP3XP FM1246 Tuner Card (PAL,FM)",
+ .audio_clock = 0x187de7,
+ .tuner_type = TUNER_PHILIPS_PAL_I,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .inputs = {{
+ .name = name_tv,
+ .vmux = 1,
+ .amux = TV,
+ .tv = 1,
+ },{
+ .name = name_tv_mono,
+ .vmux = 1,
+ .amux = LINE2,
+ .tv = 1,
+ },{
+ .name = name_comp1,
+ .vmux = 3,
+ .amux = LINE1,
+ },{
+ .name = name_svideo,
+ .vmux = 8,
+ .amux = LINE1,
+ },{
+ .name = "CVid over SVid",
+ .vmux = 0,
+ .amux = LINE1,
+ }},
+ .radio = {
+ .name = name_radio,
+ .amux = LINE2,
+ },
+ },
[SAA7134_BOARD_AVACSSMARTTV] = {
/* Roman Pszonczenko <romka@kolos.math.uni.lodz.pl> */
.name = "AVACS SmartTV",
@@ -1544,12 +1580,12 @@ struct saa7134_board saa7134_boards[] = {
},{
.name = name_comp1,
.vmux = 0,
- .amux = LINE2,
+ .amux = LINE1,
.gpio = 0x02,
},{
.name = name_svideo,
.vmux = 6,
- .amux = LINE2,
+ .amux = LINE1,
.gpio = 0x02,
}},
.radio = {
@@ -2755,6 +2791,35 @@ struct saa7134_board saa7134_boards[] = {
.amux = LINE1,
},
},
+ [SAA7134_BOARD_KWORLD_DVBT_210] = {
+ .name = "KWorld DVB-T 210",
+ .audio_clock = 0x00187de7,
+ .tuner_type = TUNER_PHILIPS_TDA8290,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .mpeg = SAA7134_MPEG_DVB,
+ .gpiomask = 1 << 21,
+ .inputs = {{
+ .name = name_tv,
+ .vmux = 1,
+ .amux = TV,
+ .tv = 1,
+ },{
+ .name = name_comp1,
+ .vmux = 3,
+ .amux = LINE1,
+ },{
+ .name = name_svideo,
+ .vmux = 8,
+ .amux = LINE1,
+ }},
+ .radio = {
+ .name = name_radio,
+ .amux = TV,
+ .gpio = 0x0200000,
+ },
+ },
[SAA7134_BOARD_KWORLD_ATSC110] = {
.name = "Kworld ATSC110",
.audio_clock = 0x00187de7,
@@ -3447,6 +3512,36 @@ struct saa7134_board saa7134_boards[] = {
.gpio = 0x0200000,
},
},
+ [SAA7134_BOARD_SABRENT_TV_PCB05] = {
+ .name = "Sabrent PCMCIA TV-PCB05",
+ .audio_clock = 0x00187de7,
+ .tuner_type = TUNER_PHILIPS_TDA8290,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .inputs = {{
+ .name = name_tv,
+ .vmux = 1,
+ .amux = TV,
+ .tv = 1,
+ },{
+ .name = name_comp1,
+ .vmux = 3,
+ .amux = LINE1,
+ },{
+ .name = name_comp2,
+ .vmux = 0,
+ .amux = LINE1,
+ },{
+ .name = name_svideo,
+ .vmux = 8,
+ .amux = LINE1,
+ }},
+ .mute = {
+ .name = name_mute,
+ .amux = TV,
+ },
+ },
};
const unsigned int saa7134_bcount = ARRAY_SIZE(saa7134_boards);
@@ -3555,7 +3650,13 @@ struct pci_device_id saa7134_pci_tbl[] = {
.vendor = PCI_VENDOR_ID_PHILIPS,
.device = PCI_DEVICE_ID_PHILIPS_SAA7133,
.subvendor = 0x5168, /* Animation Technologies (LifeView) */
- .subdevice = 0x0214, /* Standard PCI, LR214WF */
+ .subdevice = 0x0214, /* Standard PCI, LR214 Rev E and earlier (SAA7135) */
+ .driver_data = SAA7134_BOARD_FLYTVPLATINUM_FM,
+ },{
+ .vendor = PCI_VENDOR_ID_PHILIPS,
+ .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
+ .subvendor = 0x5168, /* Animation Technologies (LifeView) */
+ .subdevice = 0x5214, /* Standard PCI, LR214 Rev F onwards (SAA7131) */
.driver_data = SAA7134_BOARD_FLYTVPLATINUM_FM,
},{
.vendor = PCI_VENDOR_ID_PHILIPS,
@@ -3729,6 +3830,12 @@ struct pci_device_id saa7134_pci_tbl[] = {
.driver_data = SAA7134_BOARD_ECS_TVP3XP_4CB5,
},{
.vendor = PCI_VENDOR_ID_PHILIPS,
+ .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
+ .subvendor = 0x1019,
+ .subdevice = 0x4cb6,
+ .driver_data = SAA7134_BOARD_ECS_TVP3XP_4CB6,
+ },{
+ .vendor = PCI_VENDOR_ID_PHILIPS,
.device = PCI_DEVICE_ID_PHILIPS_SAA7133,
.subvendor = 0x12ab,
.subdevice = 0x0800,
@@ -3955,6 +4062,12 @@ struct pci_device_id saa7134_pci_tbl[] = {
.driver_data = SAA7134_BOARD_TEVION_DVBT_220RF,
},{
.vendor = PCI_VENDOR_ID_PHILIPS,
+ .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
+ .subvendor = 0x17de,
+ .subdevice = 0x7250,
+ .driver_data = SAA7134_BOARD_KWORLD_DVBT_210,
+ },{
+ .vendor = PCI_VENDOR_ID_PHILIPS,
.device = PCI_DEVICE_ID_PHILIPS_SAA7133, /* SAA7135HL */
.subvendor = 0x17de,
.subdevice = 0x7350,
@@ -4140,6 +4253,12 @@ struct pci_device_id saa7134_pci_tbl[] = {
.subdevice = 0x4857,
.driver_data = SAA7134_BOARD_ASUSTeK_P7131_DUAL,
},{
+ .vendor = PCI_VENDOR_ID_PHILIPS,
+ .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
+ .subvendor = 0x0919, /* SinoVideo PCI 2309 Proteus (7134) */
+ .subdevice = 0x2003, /* OEM cardbus */
+ .driver_data = SAA7134_BOARD_SABRENT_TV_PCB05,
+ },{
/* --- boards without eeprom + subsystem ID --- */
.vendor = PCI_VENDOR_ID_PHILIPS,
.device = PCI_DEVICE_ID_PHILIPS_SAA7134,
@@ -4255,6 +4374,7 @@ int saa7134_board_init1(struct saa7134_dev *dev)
case SAA7134_BOARD_CINERGY600_MK3:
case SAA7134_BOARD_ECS_TVP3XP:
case SAA7134_BOARD_ECS_TVP3XP_4CB5:
+ case SAA7134_BOARD_ECS_TVP3XP_4CB6:
case SAA7134_BOARD_MD2819:
case SAA7134_BOARD_KWORLD_VSTREAM_XPERT:
case SAA7134_BOARD_KWORLD_XPERT:
@@ -4503,6 +4623,7 @@ int saa7134_board_init2(struct saa7134_dev *dev)
}
break;
case SAA7134_BOARD_PINNACLE_PCTV_310i:
+ case SAA7134_BOARD_KWORLD_DVBT_210:
case SAA7134_BOARD_TEVION_DVBT_220RF:
case SAA7134_BOARD_ASUSTeK_P7131_DUAL:
case SAA7134_BOARD_ASUSTeK_P7131_HYBRID_LNA:
diff --git a/linux/drivers/media/video/saa7134/saa7134-dvb.c b/linux/drivers/media/video/saa7134/saa7134-dvb.c
index 752e90e97..12af25bd1 100644
--- a/linux/drivers/media/video/saa7134/saa7134-dvb.c
+++ b/linux/drivers/media/video/saa7134/saa7134-dvb.c
@@ -888,6 +888,20 @@ static struct tda1004x_config asus_p7131_hybrid_lna_config = {
.antenna_switch= 2,
.request_firmware = philips_tda1004x_request_firmware
};
+static struct tda1004x_config kworld_dvb_t_210_config = {
+ .demod_address = 0x08,
+ .invert = 1,
+ .invert_oclk = 0,
+ .xtal_freq = TDA10046_XTAL_16M,
+ .agc_config = TDA10046_AGC_TDA827X,
+ .gpio_config = TDA10046_GP11_I,
+ .if_freq = TDA10046_FREQ_045,
+ .i2c_gate = 0x4b,
+ .tuner_address = 0x61,
+ .tuner_config = 2,
+ .antenna_switch= 1,
+ .request_firmware = philips_tda1004x_request_firmware
+};
/* ------------------------------------------------------------------
* special case: this card uses saa713x GPIO22 for the mode switch
*/
@@ -1040,6 +1054,9 @@ static int dvb_init(struct saa7134_dev *dev)
dev->dvb.frontend->ops.tuner_ops.set_params = philips_tda6651_pll_set;
}
break;
+ case SAA7134_BOARD_KWORLD_DVBT_210:
+ configure_tda827x_fe(dev, &kworld_dvb_t_210_config);
+ break;
case SAA7134_BOARD_PHILIPS_TIGER:
configure_tda827x_fe(dev, &philips_tiger_config);
break;
@@ -1178,6 +1195,8 @@ static int dvb_init(struct saa7134_dev *dev)
dev->dvb.frontend->ops.init(dev->dvb.frontend);
if (dev->dvb.frontend->ops.sleep)
dev->dvb.frontend->ops.sleep(dev->dvb.frontend);
+ if (dev->dvb.frontend->ops.tuner_ops.sleep)
+ dev->dvb.frontend->ops.tuner_ops.sleep(dev->dvb.frontend);
}
return ret;
}
diff --git a/linux/drivers/media/video/saa7134/saa7134-i2c.c b/linux/drivers/media/video/saa7134/saa7134-i2c.c
index 1d41abee5..f470c85e7 100644
--- a/linux/drivers/media/video/saa7134/saa7134-i2c.c
+++ b/linux/drivers/media/video/saa7134/saa7134-i2c.c
@@ -465,7 +465,7 @@ static void do_i2c_scan(char *name, struct i2c_client *c)
unsigned char buf;
int i,rc;
- for (i = 0; i < 128; i++) {
+ for (i = 0; i < ARRAY_SIZE(i2c_devs); i++) {
c->addr = i;
rc = i2c_master_recv(c,&buf,0);
if (rc < 0)
diff --git a/linux/drivers/media/video/saa7134/saa7134-input.c b/linux/drivers/media/video/saa7134/saa7134-input.c
index 24d3f5088..c1ab20e63 100644
--- a/linux/drivers/media/video/saa7134/saa7134-input.c
+++ b/linux/drivers/media/video/saa7134/saa7134-input.c
@@ -322,6 +322,7 @@ int saa7134_input_init1(struct saa7134_dev *dev)
mask_keydown = 0x0040000;
break;
case SAA7134_BOARD_ASUSTeK_P7131_DUAL:
+ case SAA7134_BOARD_ASUSTeK_P7131_HYBRID_LNA:
ir_codes = ir_codes_asus_pc39;
mask_keydown = 0x0040000;
rc5_gpio = 1;
diff --git a/linux/drivers/media/video/saa7134/saa7134.h b/linux/drivers/media/video/saa7134/saa7134.h
index aa9d73c6b..dd028dec3 100644
--- a/linux/drivers/media/video/saa7134/saa7134.h
+++ b/linux/drivers/media/video/saa7134/saa7134.h
@@ -242,6 +242,9 @@ struct saa7134_format {
#define SAA7134_BOARD_AVERMEDIA_M102 110
#define SAA7134_BOARD_ASUS_P7131_4871 111
#define SAA7134_BOARD_ASUSTeK_P7131_HYBRID_LNA 112
+#define SAA7134_BOARD_ECS_TVP3XP_4CB6 113
+#define SAA7134_BOARD_KWORLD_DVBT_210 114
+#define SAA7134_BOARD_SABRENT_TV_PCB05 115
#define SAA7134_MAXBOARDS 8
#define SAA7134_INPUT_MAX 8
diff --git a/linux/drivers/media/video/se401.c b/linux/drivers/media/video/se401.c
index eecb4002e..bf8a6d560 100644
--- a/linux/drivers/media/video/se401.c
+++ b/linux/drivers/media/video/se401.c
@@ -458,6 +458,13 @@ static int se401_start_stream(struct usb_se401 *se401)
}
for (i=0; i<SE401_NUMSBUF; i++) {
se401->sbuf[i].data=kmalloc(SE401_PACKETSIZE, GFP_KERNEL);
+ if (!se401->sbuf[i].data) {
+ for(i = i - 1; i >= 0; i--) {
+ kfree(se401->sbuf[i].data);
+ se401->sbuf[i].data = NULL;
+ }
+ return -ENOMEM;
+ }
}
se401->bayeroffset=0;
@@ -466,13 +473,26 @@ static int se401_start_stream(struct usb_se401 *se401)
se401->scratch_overflow=0;
for (i=0; i<SE401_NUMSCRATCH; i++) {
se401->scratch[i].data=kmalloc(SE401_PACKETSIZE, GFP_KERNEL);
+ if (!se401->scratch[i].data) {
+ for(i = i - 1; i >= 0; i--) {
+ kfree(se401->scratch[i].data);
+ se401->scratch[i].data = NULL;
+ }
+ goto nomem_sbuf;
+ }
se401->scratch[i].state=BUFFER_UNUSED;
}
for (i=0; i<SE401_NUMSBUF; i++) {
urb=usb_alloc_urb(0, GFP_KERNEL);
- if(!urb)
- return -ENOMEM;
+ if(!urb) {
+ for(i = i - 1; i >= 0; i--) {
+ usb_kill_urb(se401->urb[i]);
+ usb_free_urb(se401->urb[i]);
+ se401->urb[i] = NULL;
+ }
+ goto nomem_scratch;
+ }
usb_fill_bulk_urb(urb, se401->dev,
usb_rcvbulkpipe(se401->dev, SE401_VIDEO_ENDPOINT),
@@ -490,6 +510,18 @@ static int se401_start_stream(struct usb_se401 *se401)
se401->framecount=0;
return 0;
+
+ nomem_scratch:
+ for (i=0; i<SE401_NUMSCRATCH; i++) {
+ kfree(se401->scratch[i].data);
+ se401->scratch[i].data = NULL;
+ }
+ nomem_sbuf:
+ for (i=0; i<SE401_NUMSBUF; i++) {
+ kfree(se401->sbuf[i].data);
+ se401->sbuf[i].data = NULL;
+ }
+ return -ENOMEM;
}
static int se401_stop_stream(struct usb_se401 *se401)
diff --git a/linux/drivers/media/video/sn9c102/Kconfig b/linux/drivers/media/video/sn9c102/Kconfig
index 1a7ccb666..f71f27277 100644
--- a/linux/drivers/media/video/sn9c102/Kconfig
+++ b/linux/drivers/media/video/sn9c102/Kconfig
@@ -1,6 +1,6 @@
config USB_SN9C102
tristate "USB SN9C1xx PC Camera Controller support"
- depends on USB && VIDEO_V4L1
+ depends on VIDEO_V4L2
---help---
Say Y here if you want support for cameras based on SONiX SN9C101,
SN9C102, SN9C103, SN9C105 and SN9C120 PC Camera Controllers.
diff --git a/linux/drivers/media/video/sn9c102/Makefile b/linux/drivers/media/video/sn9c102/Makefile
index 30e3dfe53..a56d16f69 100644
--- a/linux/drivers/media/video/sn9c102/Makefile
+++ b/linux/drivers/media/video/sn9c102/Makefile
@@ -1,7 +1,14 @@
-sn9c102-objs := sn9c102_core.o sn9c102_hv7131d.o sn9c102_mi0343.o \
- sn9c102_ov7630.o sn9c102_ov7660.o sn9c102_pas106b.o \
- sn9c102_pas202bcb.o sn9c102_tas5110c1b.o \
- sn9c102_tas5130d1b.o
+sn9c102-objs := sn9c102_core.o \
+ sn9c102_hv7131d.o \
+ sn9c102_hv7131r.o \
+ sn9c102_mi0343.o \
+ sn9c102_mi0360.o \
+ sn9c102_ov7630.o \
+ sn9c102_ov7660.o \
+ sn9c102_pas106b.o \
+ sn9c102_pas202bcb.o \
+ sn9c102_tas5110c1b.o \
+ sn9c102_tas5110d.o \
+ sn9c102_tas5130d1b.o
obj-$(CONFIG_USB_SN9C102) += sn9c102.o
-
diff --git a/linux/drivers/media/video/sn9c102/sn9c102.h b/linux/drivers/media/video/sn9c102/sn9c102.h
index d6af8fa87..4561c294f 100644
--- a/linux/drivers/media/video/sn9c102/sn9c102.h
+++ b/linux/drivers/media/video/sn9c102/sn9c102.h
@@ -23,7 +23,6 @@
#include <linux/version.h>
#include <linux/usb.h>
-#include "compat.h"
#include <linux/videodev2.h>
#include <media/v4l2-common.h>
#include <linux/device.h>
@@ -39,6 +38,7 @@
#endif
#include <linux/string.h>
#include <linux/stddef.h>
+#include "compat.h"
#include "sn9c102_config.h"
#include "sn9c102_sensor.h"
@@ -81,8 +81,13 @@ enum sn9c102_stream_state {
typedef char sn9c102_sof_header_t[62];
+struct sn9c102_sof_t {
+ sn9c102_sof_header_t header;
+ u16 bytesread;
+};
+
struct sn9c102_sysfs_attr {
- u8 reg, i2c_reg;
+ u16 reg, i2c_reg;
sn9c102_sof_header_t frame_header;
};
@@ -115,7 +120,7 @@ struct sn9c102_device {
struct v4l2_jpegcompression compression;
struct sn9c102_sysfs_attr sysfs;
- sn9c102_sof_header_t sof_header;
+ struct sn9c102_sof_t sof;
u16 reg[384];
struct sn9c102_module_param module_param;
@@ -143,7 +148,7 @@ sn9c102_match_id(struct sn9c102_device* cam, const struct usb_device_id *id)
void
sn9c102_attach_sensor(struct sn9c102_device* cam,
- struct sn9c102_sensor* sensor)
+ const struct sn9c102_sensor* sensor)
{
memcpy(&cam->sensor, sensor, sizeof(struct sn9c102_sensor));
}
@@ -189,8 +194,8 @@ do { \
if ((level) == 1 || (level) == 2) \
pr_info("sn9c102: " fmt "\n", ## args); \
else if ((level) == 3) \
- pr_debug("sn9c102: [%s:%d] " fmt "\n", __FUNCTION__, \
- __LINE__ , ## args); \
+ pr_debug("sn9c102: [%s:%d] " fmt "\n", \
+ __FUNCTION__, __LINE__ , ## args); \
} \
} while (0)
#else
@@ -201,8 +206,8 @@ do { \
#undef PDBG
#define PDBG(fmt, args...) \
-dev_info(&cam->usbdev->dev, "[%s:%d] " fmt "\n", \
- __FUNCTION__, __LINE__ , ## args)
+dev_info(&cam->usbdev->dev, "[%s:%s:%d] " fmt "\n", __FILE__, __FUNCTION__, \
+ __LINE__ , ## args)
#undef PDBGG
#define PDBGG(fmt, args...) do {;} while(0) /* placeholder */
diff --git a/linux/drivers/media/video/sn9c102/sn9c102_core.c b/linux/drivers/media/video/sn9c102/sn9c102_core.c
index a02d43ece..d22638c01 100644
--- a/linux/drivers/media/video/sn9c102/sn9c102_core.c
+++ b/linux/drivers/media/video/sn9c102/sn9c102_core.c
@@ -44,11 +44,12 @@
/*****************************************************************************/
#define SN9C102_MODULE_NAME "V4L2 driver for SN9C1xx PC Camera Controllers"
-#define SN9C102_MODULE_AUTHOR "(C) 2004-2006 Luca Risolia"
+#define SN9C102_MODULE_ALIAS "sn9c1xx"
+#define SN9C102_MODULE_AUTHOR "(C) 2004-2007 Luca Risolia"
#define SN9C102_AUTHOR_EMAIL "<luca.risolia@studio.unibo.it>"
#define SN9C102_MODULE_LICENSE "GPL"
-#define SN9C102_MODULE_VERSION "1:1.34"
-#define SN9C102_MODULE_VERSION_CODE KERNEL_VERSION(1, 1, 34)
+#define SN9C102_MODULE_VERSION "1:1.44"
+#define SN9C102_MODULE_VERSION_CODE KERNEL_VERSION(1, 1, 44)
/*****************************************************************************/
@@ -56,6 +57,7 @@ MODULE_DEVICE_TABLE(usb, sn9c102_id_table);
MODULE_AUTHOR(SN9C102_MODULE_AUTHOR " " SN9C102_AUTHOR_EMAIL);
MODULE_DESCRIPTION(SN9C102_MODULE_NAME);
+MODULE_ALIAS(SN9C102_MODULE_ALIAS);
MODULE_VERSION(SN9C102_MODULE_VERSION);
MODULE_LICENSE(SN9C102_MODULE_LICENSE);
@@ -106,8 +108,7 @@ MODULE_PARM_DESC(debug,
"\n1 = critical errors"
"\n2 = significant informations"
"\n3 = more verbose messages"
- "\nLevel 3 is useful for testing only, when only "
- "one device is used."
+ "\nLevel 3 is useful for testing only."
"\nDefault value is "__MODULE_STRING(SN9C102_DEBUG_LEVEL)"."
"\n");
#endif
@@ -121,8 +122,8 @@ sn9c102_request_buffers(struct sn9c102_device* cam, u32 count,
struct v4l2_pix_format* p = &(cam->sensor.pix_format);
struct v4l2_rect* r = &(cam->sensor.cropcap.bounds);
size_t imagesize = cam->module_param.force_munmap || io == IO_READ ?
- (p->width * p->height * p->priv) / 8 :
- (r->width * r->height * p->priv) / 8;
+ (p->width * p->height * p->priv) / 8 :
+ (r->width * r->height * p->priv) / 8;
void* buff = NULL;
u32 i;
@@ -209,25 +210,41 @@ static void sn9c102_queue_unusedframes(struct sn9c102_device* cam)
/*****************************************************************************/
-int sn9c102_write_regs(struct sn9c102_device* cam, u8* buff, u16 index)
+/*
+ Write a sequence of count value/register pairs. Returns -1 after the first
+ failed write, or 0 for no errors.
+*/
+int sn9c102_write_regs(struct sn9c102_device* cam, const u8 valreg[][2],
+ int count)
{
struct usb_device* udev = cam->usbdev;
+ u8* buff = cam->control_buffer;
int i, res;
- if (index + sizeof(buff) >= ARRAY_SIZE(cam->reg))
- return -1;
+ for (i = 0; i < count; i++) {
+ u8 index = valreg[i][1];
- res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x08, 0x41,
- index, 0, buff, sizeof(buff),
- SN9C102_CTRL_TIMEOUT*sizeof(buff));
- if (res < 0) {
- DBG(3, "Failed to write registers (index 0x%02X, error %d)",
- index, res);
- return -1;
- }
+ /*
+ index is a u8, so it must be <256 and can't be out of range.
+ If we put in a check anyway, gcc annoys us with a warning
+ hat our check is useless. People get all uppity when they
+ see warnings in the kernel compile.
+ */
+
+ *buff = valreg[i][0];
+
+ res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x08,
+ 0x41, index, 0, buff, 1,
+ SN9C102_CTRL_TIMEOUT);
+
+ if (res < 0) {
+ DBG(3, "Failed to write a register (value 0x%02X, "
+ "index 0x%02X, error %d)", *buff, index, res);
+ return -1;
+ }
- for (i = 0; i < sizeof(buff); i++)
- cam->reg[index+i] = buff[i];
+ cam->reg[index] = *buff;
+ }
return 0;
}
@@ -258,8 +275,8 @@ int sn9c102_write_reg(struct sn9c102_device* cam, u8 value, u16 index)
}
-/* NOTE: reading some registers always returns 0 */
-static int sn9c102_read_reg(struct sn9c102_device* cam, u16 index)
+/* NOTE: with the SN9C10[123] reading some registers always returns 0 */
+int sn9c102_read_reg(struct sn9c102_device* cam, u16 index)
{
struct usb_device* udev = cam->usbdev;
u8* buff = cam->control_buffer;
@@ -285,7 +302,8 @@ int sn9c102_pread_reg(struct sn9c102_device* cam, u16 index)
static int
-sn9c102_i2c_wait(struct sn9c102_device* cam, struct sn9c102_sensor* sensor)
+sn9c102_i2c_wait(struct sn9c102_device* cam,
+ const struct sn9c102_sensor* sensor)
{
int i, r;
@@ -306,7 +324,7 @@ sn9c102_i2c_wait(struct sn9c102_device* cam, struct sn9c102_sensor* sensor)
static int
sn9c102_i2c_detect_read_error(struct sn9c102_device* cam,
- struct sn9c102_sensor* sensor)
+ const struct sn9c102_sensor* sensor)
{
int r , err = 0;
@@ -328,7 +346,7 @@ sn9c102_i2c_detect_read_error(struct sn9c102_device* cam,
static int
sn9c102_i2c_detect_write_error(struct sn9c102_device* cam,
- struct sn9c102_sensor* sensor)
+ const struct sn9c102_sensor* sensor)
{
int r;
r = sn9c102_read_reg(cam, 0x08);
@@ -338,12 +356,12 @@ sn9c102_i2c_detect_write_error(struct sn9c102_device* cam,
int
sn9c102_i2c_try_raw_read(struct sn9c102_device* cam,
- struct sn9c102_sensor* sensor, u8 data0, u8 data1,
- u8 n, u8 buffer[])
+ const struct sn9c102_sensor* sensor, u8 data0,
+ u8 data1, u8 n, u8 buffer[])
{
struct usb_device* udev = cam->usbdev;
u8* data = cam->control_buffer;
- int err = 0, res;
+ int i = 0, err = 0, res;
/* Write cycle */
data[0] = ((sensor->interface == SN9C102_I2C_2WIRES) ? 0x80 : 0) |
@@ -388,7 +406,8 @@ sn9c102_i2c_try_raw_read(struct sn9c102_device* cam,
}
if (buffer)
- memcpy(buffer, data, sizeof(buffer));
+ for (i = 0; i < n && i < 5; i++)
+ buffer[n-i-1] = data[4-i];
return (int)data[4];
}
@@ -396,7 +415,7 @@ sn9c102_i2c_try_raw_read(struct sn9c102_device* cam,
int
sn9c102_i2c_try_raw_write(struct sn9c102_device* cam,
- struct sn9c102_sensor* sensor, u8 n, u8 data0,
+ const struct sn9c102_sensor* sensor, u8 n, u8 data0,
u8 data1, u8 data2, u8 data3, u8 data4, u8 data5)
{
struct usb_device* udev = cam->usbdev;
@@ -435,7 +454,7 @@ sn9c102_i2c_try_raw_write(struct sn9c102_device* cam,
int
sn9c102_i2c_try_read(struct sn9c102_device* cam,
- struct sn9c102_sensor* sensor, u8 address)
+ const struct sn9c102_sensor* sensor, u8 address)
{
return sn9c102_i2c_try_raw_read(cam, sensor, sensor->i2c_slave_id,
address, 1, NULL);
@@ -444,7 +463,7 @@ sn9c102_i2c_try_read(struct sn9c102_device* cam,
int
sn9c102_i2c_try_write(struct sn9c102_device* cam,
- struct sn9c102_sensor* sensor, u8 address, u8 value)
+ const struct sn9c102_sensor* sensor, u8 address, u8 value)
{
return sn9c102_i2c_try_raw_write(cam, sensor, 3,
sensor->i2c_slave_id, address,
@@ -485,18 +504,43 @@ static size_t sn9c102_sof_length(struct sn9c102_device* cam)
static void*
sn9c102_find_sof_header(struct sn9c102_device* cam, void* mem, size_t len)
{
- char sof_header[6] = {0xff, 0xff, 0x00, 0xc4, 0xc4, 0x96};
- size_t soflen = 0, i;
+ static const char marker[6] = {0xff, 0xff, 0x00, 0xc4, 0xc4, 0x96};
+ const char *m = mem;
+ size_t soflen = 0, i, j;
soflen = sn9c102_sof_length(cam);
- for (i = 0; (len >= soflen) && (i <= len - soflen); i++)
- if (!memcmp(mem + i, sof_header, sizeof(sof_header))) {
- memcpy(cam->sof_header, mem + i,
- sizeof(sn9c102_sof_header_t));
- /* Skip the header */
- return mem + i + soflen;
+ for (i = 0; i < len; i++) {
+ size_t b;
+
+ /* Read the variable part of the header */
+ if (unlikely(cam->sof.bytesread >= sizeof(marker))) {
+ cam->sof.header[cam->sof.bytesread] = *(m+i);
+ if (++cam->sof.bytesread == soflen) {
+ cam->sof.bytesread = 0;
+ return mem + i;
}
+ continue;
+ }
+
+ /* Search for the SOF marker (fixed part) in the header */
+ for (j = 0, b=cam->sof.bytesread; j+b < sizeof(marker); j++) {
+ if (unlikely(i+j) == len)
+ return NULL;
+ if (*(m+i+j) == marker[cam->sof.bytesread]) {
+ cam->sof.header[cam->sof.bytesread] = *(m+i+j);
+ if (++cam->sof.bytesread == sizeof(marker)) {
+ PDBGG("Bytes to analyze: %zd. SOF "
+ "starts at byte #%zd", len, i);
+ i += j+1;
+ break;
+ }
+ } else {
+ cam->sof.bytesread = 0;
+ break;
+ }
+ }
+ }
return NULL;
}
@@ -505,7 +549,7 @@ sn9c102_find_sof_header(struct sn9c102_device* cam, void* mem, size_t len)
static void*
sn9c102_find_eof_header(struct sn9c102_device* cam, void* mem, size_t len)
{
- char eof_header[4][4] = {
+ static const u8 eof_header[4][4] = {
{0x00, 0x00, 0x00, 0x00},
{0x40, 0x00, 0x00, 0x00},
{0x80, 0x00, 0x00, 0x00},
@@ -513,10 +557,16 @@ sn9c102_find_eof_header(struct sn9c102_device* cam, void* mem, size_t len)
};
size_t i, j;
+ /* The EOF header does not exist in compressed data */
if (cam->sensor.pix_format.pixelformat == V4L2_PIX_FMT_SN9C10X ||
cam->sensor.pix_format.pixelformat == V4L2_PIX_FMT_JPEG)
- return NULL; /* EOF header does not exist in compressed data */
+ return NULL;
+ /*
+ The EOF header might cross the packet boundary, but this is not a
+ problem, since the end of a frame is determined by checking its size
+ in the first place.
+ */
for (i = 0; (len >= 4) && (i <= len - 4); i++)
for (j = 0; j < ARRAY_SIZE(eof_header); j++)
if (!memcmp(mem + i, eof_header[j], 4))
@@ -529,7 +579,7 @@ sn9c102_find_eof_header(struct sn9c102_device* cam, void* mem, size_t len)
static void
sn9c102_write_jpegheader(struct sn9c102_device* cam, struct sn9c102_frame_t* f)
{
- static u8 jpeg_header[589] = {
+ static const u8 jpeg_header[589] = {
0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x06, 0x04, 0x05,
0x06, 0x05, 0x04, 0x06, 0x06, 0x05, 0x06, 0x07, 0x07, 0x06,
0x08, 0x0a, 0x10, 0x0a, 0x0a, 0x09, 0x09, 0x0a, 0x14, 0x0e,
@@ -612,16 +662,6 @@ sn9c102_write_jpegheader(struct sn9c102_device* cam, struct sn9c102_frame_t* f)
}
-static void
-sn9c102_write_eoimarker(struct sn9c102_device* cam, struct sn9c102_frame_t* f)
-{
- static const u8 eoi_marker[2] = {0xff, 0xd9};
-
- memcpy(f->bufmem + f->buf.bytesused, eoi_marker, sizeof(eoi_marker));
- f->buf.bytesused += sizeof(eoi_marker);
-}
-
-
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
static void sn9c102_urb_complete(struct urb *urb, struct pt_regs* regs)
#else
@@ -643,6 +683,7 @@ static void sn9c102_urb_complete(struct urb *urb)
cam->stream = STREAM_OFF;
if ((*f))
(*f)->state = F_QUEUED;
+ cam->sof.bytesread = 0;
DBG(3, "Stream interrupted by application");
wake_up(&cam->wait_stream);
}
@@ -680,6 +721,7 @@ static void sn9c102_urb_complete(struct urb *urb)
if (status) {
DBG(3, "Error in isochronous frame");
(*f)->state = F_ERROR;
+ cam->sof.bytesread = 0;
continue;
}
@@ -696,13 +738,13 @@ end_of_frame:
if (eof)
img = (eof > pos) ? eof - pos - 1 : 0;
- if ((*f)->buf.bytesused+img > imagesize) {
+ if ((*f)->buf.bytesused + img > imagesize) {
u32 b;
b = (*f)->buf.bytesused + img -
imagesize;
img = imagesize - (*f)->buf.bytesused;
- DBG(3, "Expected EOF not found: "
- "video frame cut");
+ PDBGG("Expected EOF not found: video "
+ "frame cut");
if (eof)
DBG(3, "Exceeded limit: +%u "
"bytes", (unsigned)(b));
@@ -723,11 +765,6 @@ end_of_frame:
V4L2_PIX_FMT_JPEG) && eof)) {
u32 b;
- if (cam->sensor.pix_format.pixelformat
- == V4L2_PIX_FMT_JPEG)
- sn9c102_write_eoimarker(cam,
- (*f));
-
b = (*f)->buf.bytesused;
(*f)->state = F_DONE;
(*f)->buf.sequence= ++cam->frame_count;
@@ -745,7 +782,7 @@ end_of_frame:
spin_unlock(&cam->queue_lock);
memcpy(cam->sysfs.frame_header,
- cam->sof_header, soflen);
+ cam->sof.header, soflen);
DBG(3, "Video frame captured: %lu "
"bytes", (unsigned long)(b));
@@ -795,7 +832,13 @@ start_of_frame:
V4L2_PIX_FMT_SN9C10X ||
cam->sensor.pix_format.pixelformat ==
V4L2_PIX_FMT_JPEG) {
- eof = sof - soflen;
+ if (sof - pos >= soflen) {
+ eof = sof - soflen;
+ } else { /* remove header */
+ eof = pos;
+ (*f)->buf.bytesused -=
+ (soflen - (sof - pos));
+ }
goto end_of_frame;
} else {
DBG(3, "SOF before expected EOF after "
@@ -882,6 +925,7 @@ static int sn9c102_start_transfer(struct sn9c102_device* cam)
}
cam->frame_current = NULL;
+ cam->sof.bytesread = 0;
for (i = 0; i < SN9C102_URBS; i++) {
err = usb_submit_urb(cam->urb[i], GFP_KERNEL);
@@ -963,9 +1007,9 @@ static u16 sn9c102_strtou16(const char* buff, size_t len, ssize_t* count)
if (len < 6) {
strncpy(str, buff, len);
- str[len+1] = '\0';
+ str[len] = '\0';
} else {
- strncpy(str, buff, 4);
+ strncpy(str, buff, 6);
str[6] = '\0';
}
@@ -1066,7 +1110,7 @@ static ssize_t sn9c102_show_val(struct class_device* cd, char* buf)
count = sprintf(buf, "%d\n", val);
- DBG(3, "Read bytes: %zd", count);
+ DBG(3, "Read bytes: %zd, value: %d", count, val);
mutex_unlock(&sn9c102_sysfs_lock);
@@ -1201,7 +1245,7 @@ static ssize_t sn9c102_show_i2c_val(struct class_device* cd, char* buf)
count = sprintf(buf, "%d\n", val);
- DBG(3, "Read bytes: %zd", count);
+ DBG(3, "Read bytes: %zd, value: %d", count, val);
mutex_unlock(&sn9c102_sysfs_lock);
@@ -1375,35 +1419,35 @@ static CLASS_DEVICE_ATTR(frame_header, S_IRUGO,
static int sn9c102_create_sysfs(struct sn9c102_device* cam)
{
- struct video_device *v4ldev = cam->v4ldev;
+ struct class_device *classdev = &(cam->v4ldev->class_dev);
int err = 0;
- if ((err = video_device_create_file(v4ldev, &class_device_attr_reg)))
+ if ((err = class_device_create_file(classdev, &class_device_attr_reg)))
goto err_out;
- if ((err = video_device_create_file(v4ldev, &class_device_attr_val)))
+ if ((err = class_device_create_file(classdev, &class_device_attr_val)))
goto err_reg;
- if ((err = video_device_create_file(v4ldev,
+ if ((err = class_device_create_file(classdev,
&class_device_attr_frame_header)))
goto err_val;
if (cam->sensor.sysfs_ops) {
- if ((err = video_device_create_file(v4ldev,
+ if ((err = class_device_create_file(classdev,
&class_device_attr_i2c_reg)))
goto err_frame_header;
- if ((err = video_device_create_file(v4ldev,
+ if ((err = class_device_create_file(classdev,
&class_device_attr_i2c_val)))
goto err_i2c_reg;
}
if (cam->bridge == BRIDGE_SN9C101 || cam->bridge == BRIDGE_SN9C102) {
- if ((err = video_device_create_file(v4ldev,
+ if ((err = class_device_create_file(classdev,
&class_device_attr_green)))
goto err_i2c_val;
} else {
- if ((err = video_device_create_file(v4ldev,
+ if ((err = class_device_create_file(classdev,
&class_device_attr_blue)))
goto err_i2c_val;
- if ((err = video_device_create_file(v4ldev,
+ if ((err = class_device_create_file(classdev,
&class_device_attr_red)))
goto err_blue;
}
@@ -1411,19 +1455,19 @@ static int sn9c102_create_sysfs(struct sn9c102_device* cam)
return 0;
err_blue:
- video_device_remove_file(v4ldev, &class_device_attr_blue);
+ class_device_remove_file(classdev, &class_device_attr_blue);
err_i2c_val:
if (cam->sensor.sysfs_ops)
- video_device_remove_file(v4ldev, &class_device_attr_i2c_val);
+ class_device_remove_file(classdev, &class_device_attr_i2c_val);
err_i2c_reg:
if (cam->sensor.sysfs_ops)
- video_device_remove_file(v4ldev, &class_device_attr_i2c_reg);
+ class_device_remove_file(classdev, &class_device_attr_i2c_reg);
err_frame_header:
- video_device_remove_file(v4ldev, &class_device_attr_frame_header);
+ class_device_remove_file(classdev, &class_device_attr_frame_header);
err_val:
- video_device_remove_file(v4ldev, &class_device_attr_val);
+ class_device_remove_file(classdev, &class_device_attr_val);
err_reg:
- video_device_remove_file(v4ldev, &class_device_attr_reg);
+ class_device_remove_file(classdev, &class_device_attr_reg);
err_out:
return err;
}
@@ -1481,10 +1525,10 @@ sn9c102_set_compression(struct sn9c102_device* cam,
case BRIDGE_SN9C101:
case BRIDGE_SN9C102:
case BRIDGE_SN9C103:
- if (compression->quality == 0)
+ if (compression->quality == 0)
err += sn9c102_write_reg(cam, cam->reg[0x17] | 0x01,
0x17);
- else if (compression->quality == 1)
+ else if (compression->quality == 1)
err += sn9c102_write_reg(cam, cam->reg[0x17] & 0xfe,
0x17);
break;
@@ -1493,10 +1537,10 @@ sn9c102_set_compression(struct sn9c102_device* cam,
if (compression->quality == 0) {
for (i = 0; i <= 63; i++) {
err += sn9c102_write_reg(cam,
- SN9C102_Y_QTABLE0[i],
+ SN9C102_Y_QTABLE1[i],
0x100 + i);
err += sn9c102_write_reg(cam,
- SN9C102_UV_QTABLE0[i],
+ SN9C102_UV_QTABLE1[i],
0x140 + i);
}
err += sn9c102_write_reg(cam, cam->reg[0x18] & 0xbf,
@@ -1601,9 +1645,13 @@ static int sn9c102_init(struct sn9c102_device* cam)
if (cam->bridge == BRIDGE_SN9C101 ||
cam->bridge == BRIDGE_SN9C102 ||
cam->bridge == BRIDGE_SN9C103) {
+ if (s->pix_format.pixelformat == V4L2_PIX_FMT_JPEG)
+ s->pix_format.pixelformat= V4L2_PIX_FMT_SBGGR8;
cam->compression.quality = cam->reg[0x17] & 0x01 ?
0 : 1;
} else {
+ if (s->pix_format.pixelformat == V4L2_PIX_FMT_SN9C10X)
+ s->pix_format.pixelformat = V4L2_PIX_FMT_JPEG;
cam->compression.quality = cam->reg[0x18] & 0x40 ?
0 : 1;
err += sn9c102_set_compression(cam, &cam->compression);
@@ -1809,7 +1857,7 @@ sn9c102_read(struct file* filp, char __user * buf, size_t count, loff_t* f_pos)
DBG(3, "Close and open the device again to choose "
"the read method");
mutex_unlock(&cam->fileop_mutex);
- return -EINVAL;
+ return -EBUSY;
}
if (cam->io == IO_NONE) {
@@ -1849,16 +1897,16 @@ sn9c102_read(struct file* filp, char __user * buf, size_t count, loff_t* f_pos)
return err;
}
} else {
- timeout = wait_event_interruptible_timeout
- ( cam->wait_frame,
- (!list_empty(&cam->outqueue)) ||
- (cam->state & DEV_DISCONNECTED) ||
- (cam->state & DEV_MISCONFIGURED),
- cam->module_param.frame_timeout *
- 1000 * msecs_to_jiffies(1) );
- if (timeout < 0) {
- mutex_unlock(&cam->fileop_mutex);
- return timeout;
+ timeout = wait_event_interruptible_timeout
+ ( cam->wait_frame,
+ (!list_empty(&cam->outqueue)) ||
+ (cam->state & DEV_DISCONNECTED) ||
+ (cam->state & DEV_MISCONFIGURED),
+ cam->module_param.frame_timeout *
+ 1000 * msecs_to_jiffies(1) );
+ if (timeout < 0) {
+ mutex_unlock(&cam->fileop_mutex);
+ return timeout;
} else if (timeout == 0 &&
!(cam->state & DEV_DISCONNECTED)) {
DBG(1, "Video frame timeout elapsed");
@@ -2005,7 +2053,12 @@ static int sn9c102_mmap(struct file* filp, struct vm_area_struct *vma)
return -EIO;
}
- if (cam->io != IO_MMAP || !(vma->vm_flags & VM_WRITE) ||
+ if (!(vma->vm_flags & (VM_WRITE | VM_READ))) {
+ mutex_unlock(&cam->fileop_mutex);
+ return -EACCES;
+ }
+
+ if (cam->io != IO_MMAP ||
size != PAGE_ALIGN(cam->frame[0].buf.length)) {
mutex_unlock(&cam->fileop_mutex);
return -EINVAL;
@@ -2271,7 +2324,7 @@ sn9c102_vidioc_s_crop(struct sn9c102_device* cam, void __user * arg)
if (cam->frame[i].vma_use_count) {
DBG(3, "VIDIOC_S_CROP failed. "
"Unmap the buffers first.");
- return -EINVAL;
+ return -EBUSY;
}
/* Preserve R,G or B origin */
@@ -2414,8 +2467,8 @@ sn9c102_vidioc_enum_fmt(struct sn9c102_device* cam, void __user * arg)
case BRIDGE_SN9C101:
case BRIDGE_SN9C102:
case BRIDGE_SN9C103:
- strcpy(fmtd.description, "compressed");
- fmtd.pixelformat = V4L2_PIX_FMT_SN9C10X;
+ strcpy(fmtd.description, "compressed");
+ fmtd.pixelformat = V4L2_PIX_FMT_SN9C10X;
break;
case BRIDGE_SN9C105:
case BRIDGE_SN9C120:
@@ -2449,8 +2502,10 @@ sn9c102_vidioc_g_fmt(struct sn9c102_device* cam, void __user * arg)
if (format.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
return -EINVAL;
- pfmt->bytesperline = (pfmt->pixelformat==V4L2_PIX_FMT_SN9C10X ||
- pfmt->pixelformat==V4L2_PIX_FMT_JPEG)
+ pfmt->colorspace = (pfmt->pixelformat == V4L2_PIX_FMT_JPEG) ?
+ V4L2_COLORSPACE_JPEG : V4L2_COLORSPACE_SRGB;
+ pfmt->bytesperline = (pfmt->pixelformat == V4L2_PIX_FMT_SN9C10X ||
+ pfmt->pixelformat == V4L2_PIX_FMT_JPEG)
? 0 : (pfmt->width * pfmt->priv) / 8;
pfmt->sizeimage = pfmt->height * ((pfmt->width*pfmt->priv)/8);
pfmt->field = V4L2_FIELD_NONE;
@@ -2525,9 +2580,9 @@ sn9c102_vidioc_try_s_fmt(struct sn9c102_device* cam, unsigned int cmd,
case BRIDGE_SN9C101:
case BRIDGE_SN9C102:
case BRIDGE_SN9C103:
- if (pix->pixelformat != V4L2_PIX_FMT_SN9C10X &&
- pix->pixelformat != V4L2_PIX_FMT_SBGGR8)
- pix->pixelformat = pfmt->pixelformat;
+ if (pix->pixelformat != V4L2_PIX_FMT_SN9C10X &&
+ pix->pixelformat != V4L2_PIX_FMT_SBGGR8)
+ pix->pixelformat = pfmt->pixelformat;
break;
case BRIDGE_SN9C105:
case BRIDGE_SN9C120:
@@ -2537,7 +2592,8 @@ sn9c102_vidioc_try_s_fmt(struct sn9c102_device* cam, unsigned int cmd,
break;
}
pix->priv = pfmt->priv; /* bpp */
- pix->colorspace = pfmt->colorspace;
+ pix->colorspace = (pix->pixelformat == V4L2_PIX_FMT_JPEG) ?
+ V4L2_COLORSPACE_JPEG : V4L2_COLORSPACE_SRGB;
pix->bytesperline = (pix->pixelformat == V4L2_PIX_FMT_SN9C10X ||
pix->pixelformat == V4L2_PIX_FMT_JPEG)
? 0 : (pix->width * pix->priv) / 8;
@@ -2555,7 +2611,7 @@ sn9c102_vidioc_try_s_fmt(struct sn9c102_device* cam, unsigned int cmd,
if (cam->frame[i].vma_use_count) {
DBG(3, "VIDIOC_S_FMT failed. Unmap the "
"buffers first.");
- return -EINVAL;
+ return -EBUSY;
}
if (cam->stream == STREAM_ON)
@@ -2670,14 +2726,14 @@ sn9c102_vidioc_reqbufs(struct sn9c102_device* cam, void __user * arg)
if (cam->io == IO_READ) {
DBG(3, "Close and open the device again to choose the mmap "
"I/O method");
- return -EINVAL;
+ return -EBUSY;
}
for (i = 0; i < cam->nbuffers; i++)
if (cam->frame[i].vma_use_count) {
DBG(3, "VIDIOC_REQBUFS failed. Previous buffers are "
"still mapped.");
- return -EINVAL;
+ return -EBUSY;
}
if (cam->stream == STREAM_ON)
@@ -2789,15 +2845,15 @@ sn9c102_vidioc_dqbuf(struct sn9c102_device* cam, struct file* filp,
if (err)
return err;
} else {
- timeout = wait_event_interruptible_timeout
- ( cam->wait_frame,
- (!list_empty(&cam->outqueue)) ||
- (cam->state & DEV_DISCONNECTED) ||
- (cam->state & DEV_MISCONFIGURED),
- cam->module_param.frame_timeout *
- 1000 * msecs_to_jiffies(1) );
- if (timeout < 0)
- return timeout;
+ timeout = wait_event_interruptible_timeout
+ ( cam->wait_frame,
+ (!list_empty(&cam->outqueue)) ||
+ (cam->state & DEV_DISCONNECTED) ||
+ (cam->state & DEV_MISCONFIGURED),
+ cam->module_param.frame_timeout *
+ 1000 * msecs_to_jiffies(1) );
+ if (timeout < 0)
+ return timeout;
else if (timeout == 0 &&
!(cam->state & DEV_DISCONNECTED)) {
DBG(1, "Video frame timeout elapsed");
@@ -2841,9 +2897,6 @@ sn9c102_vidioc_streamon(struct sn9c102_device* cam, void __user * arg)
if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE || cam->io != IO_MMAP)
return -EINVAL;
- if (list_empty(&cam->inqueue))
- return -EINVAL;
-
cam->stream = STREAM_ON;
DBG(3, "Stream on");
@@ -3127,14 +3180,14 @@ static int sn9c102_ioctl(struct inode* inode, struct file* filp,
static const struct file_operations sn9c102_fops = {
.owner = THIS_MODULE,
- .open = sn9c102_open,
+ .open = sn9c102_open,
.release = sn9c102_release,
- .ioctl = sn9c102_ioctl,
+ .ioctl = sn9c102_ioctl,
.compat_ioctl = v4l_compat_ioctl32,
- .read = sn9c102_read,
- .poll = sn9c102_poll,
- .mmap = sn9c102_mmap,
- .llseek = no_llseek,
+ .read = sn9c102_read,
+ .poll = sn9c102_poll,
+ .mmap = sn9c102_mmap,
+ .llseek = no_llseek,
};
/*****************************************************************************/
@@ -3170,8 +3223,8 @@ sn9c102_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
r = sn9c102_read_reg(cam, 0x00);
if (r < 0 || (r != 0x10 && r != 0x11 && r != 0x12)) {
- DBG(1, "Sorry, this is not a SN9C1xx based camera "
- "(vid/pid 0x%04X:0x%04X)", id->idVendor, id->idProduct);
+ DBG(1, "Sorry, this is not a SN9C1xx-based camera "
+ "(vid:pid 0x%04X:0x%04X)", id->idVendor, id->idProduct);
err = -ENODEV;
goto fail;
}
@@ -3181,23 +3234,23 @@ sn9c102_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
case BRIDGE_SN9C101:
case BRIDGE_SN9C102:
DBG(2, "SN9C10[12] PC Camera Controller detected "
- "(vid/pid 0x%04X:0x%04X)", id->idVendor, id->idProduct);
+ "(vid:pid 0x%04X:0x%04X)", id->idVendor, id->idProduct);
break;
case BRIDGE_SN9C103:
DBG(2, "SN9C103 PC Camera Controller detected "
- "(vid/pid 0x%04X:0x%04X)", id->idVendor, id->idProduct);
+ "(vid:pid 0x%04X:0x%04X)", id->idVendor, id->idProduct);
break;
case BRIDGE_SN9C105:
DBG(2, "SN9C105 PC Camera Controller detected "
- "(vid/pid 0x%04X:0x%04X)", id->idVendor, id->idProduct);
+ "(vid:pid 0x%04X:0x%04X)", id->idVendor, id->idProduct);
break;
case BRIDGE_SN9C120:
DBG(2, "SN9C120 PC Camera Controller detected "
- "(vid/pid 0x%04X:0x%04X)", id->idVendor, id->idProduct);
+ "(vid:pid 0x%04X:0x%04X)", id->idVendor, id->idProduct);
break;
}
- for (i = 0; sn9c102_sensor_table[i]; i++) {
+ for (i = 0; i < ARRAY_SIZE(sn9c102_sensor_table); i++) {
err = sn9c102_sensor_table[i](cam);
if (!err)
break;
@@ -3208,7 +3261,7 @@ sn9c102_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
DBG(3, "Support for %s maintained by %s",
cam->sensor.name, cam->sensor.maintainer);
} else {
- DBG(1, "No supported image sensor detected");
+ DBG(1, "No supported image sensor detected for this bridge");
err = -ENODEV;
goto fail;
}
@@ -3264,6 +3317,8 @@ sn9c102_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
"device controlling. Error #%d", err);
#else
DBG(2, "Optional device control through 'sysfs' interface disabled");
+ DBG(3, "Compile the kernel with the 'CONFIG_VIDEO_ADV_DEBUG' "
+ "configuration option to enable it.");
#endif
usb_set_intfdata(intf, cam);
diff --git a/linux/drivers/media/video/sn9c102/sn9c102_devtable.h b/linux/drivers/media/video/sn9c102/sn9c102_devtable.h
index 3a682eca6..916054faf 100644
--- a/linux/drivers/media/video/sn9c102/sn9c102_devtable.h
+++ b/linux/drivers/media/video/sn9c102/sn9c102_devtable.h
@@ -86,19 +86,28 @@ static const struct usb_device_id sn9c102_id_table[] = {
{ SN9C102_USB_DEVICE(0x0c45, 0x60bc, BRIDGE_SN9C103), },
{ SN9C102_USB_DEVICE(0x0c45, 0x60be, BRIDGE_SN9C103), },
/* SN9C105 */
+ { SN9C102_USB_DEVICE(0x045e, 0x00f5, BRIDGE_SN9C105), },
+ { SN9C102_USB_DEVICE(0x045e, 0x00f7, BRIDGE_SN9C105), },
{ SN9C102_USB_DEVICE(0x0471, 0x0327, BRIDGE_SN9C105), },
{ SN9C102_USB_DEVICE(0x0471, 0x0328, BRIDGE_SN9C105), },
{ SN9C102_USB_DEVICE(0x0c45, 0x60c0, BRIDGE_SN9C105), },
+ { SN9C102_USB_DEVICE(0x0c45, 0x60c2, BRIDGE_SN9C105), },
{ SN9C102_USB_DEVICE(0x0c45, 0x60c8, BRIDGE_SN9C105), },
{ SN9C102_USB_DEVICE(0x0c45, 0x60cc, BRIDGE_SN9C105), },
{ SN9C102_USB_DEVICE(0x0c45, 0x60ea, BRIDGE_SN9C105), },
{ SN9C102_USB_DEVICE(0x0c45, 0x60ec, BRIDGE_SN9C105), },
+ { SN9C102_USB_DEVICE(0x0c45, 0x60ef, BRIDGE_SN9C105), },
{ SN9C102_USB_DEVICE(0x0c45, 0x60fa, BRIDGE_SN9C105), },
{ SN9C102_USB_DEVICE(0x0c45, 0x60fb, BRIDGE_SN9C105), },
{ SN9C102_USB_DEVICE(0x0c45, 0x60fc, BRIDGE_SN9C105), },
{ SN9C102_USB_DEVICE(0x0c45, 0x60fe, BRIDGE_SN9C105), },
/* SN9C120 */
+ { SN9C102_USB_DEVICE(0x0458, 0x7025, BRIDGE_SN9C120), },
+ { SN9C102_USB_DEVICE(0x0c45, 0x6102, BRIDGE_SN9C120), },
+ { SN9C102_USB_DEVICE(0x0c45, 0x6108, BRIDGE_SN9C120), },
+ { SN9C102_USB_DEVICE(0x0c45, 0x610f, BRIDGE_SN9C120), },
{ SN9C102_USB_DEVICE(0x0c45, 0x6130, BRIDGE_SN9C120), },
+ { SN9C102_USB_DEVICE(0x0c45, 0x6138, BRIDGE_SN9C120), },
{ SN9C102_USB_DEVICE(0x0c45, 0x613a, BRIDGE_SN9C120), },
{ SN9C102_USB_DEVICE(0x0c45, 0x613b, BRIDGE_SN9C120), },
{ SN9C102_USB_DEVICE(0x0c45, 0x613c, BRIDGE_SN9C120), },
@@ -114,12 +123,15 @@ static const struct usb_device_id sn9c102_id_table[] = {
Functions must return 0 on success, the appropriate error otherwise.
*/
extern int sn9c102_probe_hv7131d(struct sn9c102_device* cam);
+extern int sn9c102_probe_hv7131r(struct sn9c102_device* cam);
extern int sn9c102_probe_mi0343(struct sn9c102_device* cam);
+extern int sn9c102_probe_mi0360(struct sn9c102_device* cam);
extern int sn9c102_probe_ov7630(struct sn9c102_device* cam);
extern int sn9c102_probe_ov7660(struct sn9c102_device* cam);
extern int sn9c102_probe_pas106b(struct sn9c102_device* cam);
extern int sn9c102_probe_pas202bcb(struct sn9c102_device* cam);
extern int sn9c102_probe_tas5110c1b(struct sn9c102_device* cam);
+extern int sn9c102_probe_tas5110d(struct sn9c102_device* cam);
extern int sn9c102_probe_tas5130d1b(struct sn9c102_device* cam);
/*
@@ -128,15 +140,17 @@ extern int sn9c102_probe_tas5130d1b(struct sn9c102_device* cam);
the order of the list below, from top to bottom.
*/
static int (*sn9c102_sensor_table[])(struct sn9c102_device*) = {
+ &sn9c102_probe_hv7131d, /* strong detection based on SENSOR ids */
+ &sn9c102_probe_hv7131r, /* strong detection based on SENSOR ids */
&sn9c102_probe_mi0343, /* strong detection based on SENSOR ids */
+ &sn9c102_probe_mi0360, /* strong detection based on SENSOR ids */
&sn9c102_probe_pas106b, /* strong detection based on SENSOR ids */
&sn9c102_probe_pas202bcb, /* strong detection based on SENSOR ids */
- &sn9c102_probe_hv7131d, /* strong detection based on SENSOR ids */
&sn9c102_probe_ov7630, /* strong detection based on SENSOR ids */
&sn9c102_probe_ov7660, /* strong detection based on SENSOR ids */
&sn9c102_probe_tas5110c1b, /* detection based on USB pid/vid */
+ &sn9c102_probe_tas5110d, /* detection based on USB pid/vid */
&sn9c102_probe_tas5130d1b, /* detection based on USB pid/vid */
- NULL,
};
#endif /* _SN9C102_DEVTABLE_H_ */
diff --git a/linux/drivers/media/video/sn9c102/sn9c102_hv7131d.c b/linux/drivers/media/video/sn9c102/sn9c102_hv7131d.c
index 7ae368f60..eaf9ad0dc 100644
--- a/linux/drivers/media/video/sn9c102/sn9c102_hv7131d.c
+++ b/linux/drivers/media/video/sn9c102/sn9c102_hv7131d.c
@@ -22,19 +22,13 @@
#include "sn9c102_sensor.h"
-static struct sn9c102_sensor hv7131d;
-
-
static int hv7131d_init(struct sn9c102_device* cam)
{
- int err = 0;
+ int err;
- err += sn9c102_write_reg(cam, 0x00, 0x10);
- err += sn9c102_write_reg(cam, 0x00, 0x11);
- err += sn9c102_write_reg(cam, 0x00, 0x14);
- err += sn9c102_write_reg(cam, 0x60, 0x17);
- err += sn9c102_write_reg(cam, 0x0e, 0x18);
- err += sn9c102_write_reg(cam, 0xf2, 0x19);
+ err = sn9c102_write_const_regs(cam, {0x00, 0x10}, {0x00, 0x11},
+ {0x00, 0x14}, {0x60, 0x17},
+ {0x0e, 0x18}, {0xf2, 0x19});
err += sn9c102_i2c_write(cam, 0x01, 0x04);
err += sn9c102_i2c_write(cam, 0x02, 0x00);
@@ -150,10 +144,10 @@ static int hv7131d_set_pix_format(struct sn9c102_device* cam,
}
-static struct sn9c102_sensor hv7131d = {
+static const struct sn9c102_sensor hv7131d = {
.name = "HV7131D",
.maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
- .supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102 | BRIDGE_SN9C103,
+ .supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102,
.sysfs_ops = SN9C102_I2C_READ | SN9C102_I2C_WRITE,
.frequency = SN9C102_I2C_100KHZ,
.interface = SN9C102_I2C_2WIRES,
@@ -250,20 +244,17 @@ static struct sn9c102_sensor hv7131d = {
int sn9c102_probe_hv7131d(struct sn9c102_device* cam)
{
- int r0 = 0, r1 = 0, err = 0;
+ int r0 = 0, r1 = 0, err;
- err += sn9c102_write_reg(cam, 0x01, 0x01);
- err += sn9c102_write_reg(cam, 0x00, 0x01);
- err += sn9c102_write_reg(cam, 0x28, 0x17);
- if (err)
- return -EIO;
+ err = sn9c102_write_const_regs(cam, {0x01, 0x01}, {0x00, 0x01},
+ {0x28, 0x17});
r0 = sn9c102_i2c_try_read(cam, &hv7131d, 0x00);
r1 = sn9c102_i2c_try_read(cam, &hv7131d, 0x01);
- if (r0 < 0 || r1 < 0)
+ if (err || r0 < 0 || r1 < 0)
return -EIO;
- if (r0 != 0x00 && r1 != 0x04)
+ if (r0 != 0x00 || r1 != 0x04)
return -ENODEV;
sn9c102_attach_sensor(cam, &hv7131d);
diff --git a/linux/drivers/media/video/sn9c102/sn9c102_hv7131r.c b/linux/drivers/media/video/sn9c102/sn9c102_hv7131r.c
new file mode 100644
index 000000000..0fc401223
--- /dev/null
+++ b/linux/drivers/media/video/sn9c102/sn9c102_hv7131r.c
@@ -0,0 +1,362 @@
+/***************************************************************************
+ * Plug-in for HV7131R image sensor connected to the SN9C1xx PC Camera *
+ * Controllers *
+ * *
+ * Copyright (C) 2007 by Luca Risolia <luca.risolia@studio.unibo.it> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the Free Software *
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
+ ***************************************************************************/
+
+#include "sn9c102_sensor.h"
+
+
+static int hv7131r_init(struct sn9c102_device* cam)
+{
+ int err = 0;
+
+ switch (sn9c102_get_bridge(cam)) {
+ case BRIDGE_SN9C103:
+ err = sn9c102_write_const_regs(cam, {0x00, 0x03}, {0x1a, 0x04},
+ {0x20, 0x05}, {0x20, 0x06},
+ {0x03, 0x10}, {0x00, 0x14},
+ {0x60, 0x17}, {0x0a, 0x18},
+ {0xf0, 0x19}, {0x1d, 0x1a},
+ {0x10, 0x1b}, {0x02, 0x1c},
+ {0x03, 0x1d}, {0x0f, 0x1e},
+ {0x0c, 0x1f}, {0x00, 0x20},
+ {0x10, 0x21}, {0x20, 0x22},
+ {0x30, 0x23}, {0x40, 0x24},
+ {0x50, 0x25}, {0x60, 0x26},
+ {0x70, 0x27}, {0x80, 0x28},
+ {0x90, 0x29}, {0xa0, 0x2a},
+ {0xb0, 0x2b}, {0xc0, 0x2c},
+ {0xd0, 0x2d}, {0xe0, 0x2e},
+ {0xf0, 0x2f}, {0xff, 0x30});
+ break;
+ case BRIDGE_SN9C105:
+ case BRIDGE_SN9C120:
+ err = sn9c102_write_const_regs(cam, {0x44, 0x01}, {0x40, 0x02},
+ {0x00, 0x03}, {0x1a, 0x04},
+ {0x44, 0x05}, {0x3e, 0x06},
+ {0x1a, 0x07}, {0x03, 0x10},
+ {0x08, 0x14}, {0xa3, 0x17},
+ {0x4b, 0x18}, {0x00, 0x19},
+ {0x1d, 0x1a}, {0x10, 0x1b},
+ {0x02, 0x1c}, {0x03, 0x1d},
+ {0x0f, 0x1e}, {0x0c, 0x1f},
+ {0x00, 0x20}, {0x29, 0x21},
+ {0x40, 0x22}, {0x54, 0x23},
+ {0x66, 0x24}, {0x76, 0x25},
+ {0x85, 0x26}, {0x94, 0x27},
+ {0xa1, 0x28}, {0xae, 0x29},
+ {0xbb, 0x2a}, {0xc7, 0x2b},
+ {0xd3, 0x2c}, {0xde, 0x2d},
+ {0xea, 0x2e}, {0xf4, 0x2f},
+ {0xff, 0x30}, {0x00, 0x3F},
+ {0xC7, 0x40}, {0x01, 0x41},
+ {0x44, 0x42}, {0x00, 0x43},
+ {0x44, 0x44}, {0x00, 0x45},
+ {0x44, 0x46}, {0x00, 0x47},
+ {0xC7, 0x48}, {0x01, 0x49},
+ {0xC7, 0x4A}, {0x01, 0x4B},
+ {0xC7, 0x4C}, {0x01, 0x4D},
+ {0x44, 0x4E}, {0x00, 0x4F},
+ {0x44, 0x50}, {0x00, 0x51},
+ {0x44, 0x52}, {0x00, 0x53},
+ {0xC7, 0x54}, {0x01, 0x55},
+ {0xC7, 0x56}, {0x01, 0x57},
+ {0xC7, 0x58}, {0x01, 0x59},
+ {0x44, 0x5A}, {0x00, 0x5B},
+ {0x44, 0x5C}, {0x00, 0x5D},
+ {0x44, 0x5E}, {0x00, 0x5F},
+ {0xC7, 0x60}, {0x01, 0x61},
+ {0xC7, 0x62}, {0x01, 0x63},
+ {0xC7, 0x64}, {0x01, 0x65},
+ {0x44, 0x66}, {0x00, 0x67},
+ {0x44, 0x68}, {0x00, 0x69},
+ {0x44, 0x6A}, {0x00, 0x6B},
+ {0xC7, 0x6C}, {0x01, 0x6D},
+ {0xC7, 0x6E}, {0x01, 0x6F},
+ {0xC7, 0x70}, {0x01, 0x71},
+ {0x44, 0x72}, {0x00, 0x73},
+ {0x44, 0x74}, {0x00, 0x75},
+ {0x44, 0x76}, {0x00, 0x77},
+ {0xC7, 0x78}, {0x01, 0x79},
+ {0xC7, 0x7A}, {0x01, 0x7B},
+ {0xC7, 0x7C}, {0x01, 0x7D},
+ {0x44, 0x7E}, {0x00, 0x7F},
+ {0x14, 0x84}, {0x00, 0x85},
+ {0x27, 0x86}, {0x00, 0x87},
+ {0x07, 0x88}, {0x00, 0x89},
+ {0xEC, 0x8A}, {0x0f, 0x8B},
+ {0xD8, 0x8C}, {0x0f, 0x8D},
+ {0x3D, 0x8E}, {0x00, 0x8F},
+ {0x3D, 0x90}, {0x00, 0x91},
+ {0xCD, 0x92}, {0x0f, 0x93},
+ {0xf7, 0x94}, {0x0f, 0x95},
+ {0x0C, 0x96}, {0x00, 0x97},
+ {0x00, 0x98}, {0x66, 0x99},
+ {0x05, 0x9A}, {0x00, 0x9B},
+ {0x04, 0x9C}, {0x00, 0x9D},
+ {0x08, 0x9E}, {0x00, 0x9F},
+ {0x2D, 0xC0}, {0x2D, 0xC1},
+ {0x3A, 0xC2}, {0x05, 0xC3},
+ {0x04, 0xC4}, {0x3F, 0xC5},
+ {0x00, 0xC6}, {0x00, 0xC7},
+ {0x50, 0xC8}, {0x3C, 0xC9},
+ {0x28, 0xCA}, {0xD8, 0xCB},
+ {0x14, 0xCC}, {0xEC, 0xCD},
+ {0x32, 0xCE}, {0xDD, 0xCF},
+ {0x32, 0xD0}, {0xDD, 0xD1},
+ {0x6A, 0xD2}, {0x50, 0xD3},
+ {0x00, 0xD4}, {0x00, 0xD5},
+ {0x00, 0xD6});
+ break;
+ default:
+ break;
+ }
+
+ err += sn9c102_i2c_write(cam, 0x20, 0x00);
+ err += sn9c102_i2c_write(cam, 0x21, 0xd6);
+ err += sn9c102_i2c_write(cam, 0x25, 0x06);
+
+ return err;
+}
+
+
+static int hv7131r_get_ctrl(struct sn9c102_device* cam,
+ struct v4l2_control* ctrl)
+{
+ switch (ctrl->id) {
+ case V4L2_CID_GAIN:
+ if ((ctrl->value = sn9c102_i2c_read(cam, 0x30)) < 0)
+ return -EIO;
+ return 0;
+ case V4L2_CID_RED_BALANCE:
+ if ((ctrl->value = sn9c102_i2c_read(cam, 0x31)) < 0)
+ return -EIO;
+ ctrl->value = ctrl->value & 0x3f;
+ return 0;
+ case V4L2_CID_BLUE_BALANCE:
+ if ((ctrl->value = sn9c102_i2c_read(cam, 0x33)) < 0)
+ return -EIO;
+ ctrl->value = ctrl->value & 0x3f;
+ return 0;
+ case SN9C102_V4L2_CID_GREEN_BALANCE:
+ if ((ctrl->value = sn9c102_i2c_read(cam, 0x32)) < 0)
+ return -EIO;
+ ctrl->value = ctrl->value & 0x3f;
+ return 0;
+ case V4L2_CID_BLACK_LEVEL:
+ if ((ctrl->value = sn9c102_i2c_read(cam, 0x01)) < 0)
+ return -EIO;
+ ctrl->value = (ctrl->value & 0x08) ? 1 : 0;
+ return 0;
+ default:
+ return -EINVAL;
+ }
+}
+
+
+static int hv7131r_set_ctrl(struct sn9c102_device* cam,
+ const struct v4l2_control* ctrl)
+{
+ int err = 0;
+
+ switch (ctrl->id) {
+ case V4L2_CID_GAIN:
+ err += sn9c102_i2c_write(cam, 0x30, ctrl->value);
+ break;
+ case V4L2_CID_RED_BALANCE:
+ err += sn9c102_i2c_write(cam, 0x31, ctrl->value);
+ break;
+ case V4L2_CID_BLUE_BALANCE:
+ err += sn9c102_i2c_write(cam, 0x33, ctrl->value);
+ break;
+ case SN9C102_V4L2_CID_GREEN_BALANCE:
+ err += sn9c102_i2c_write(cam, 0x32, ctrl->value);
+ break;
+ case V4L2_CID_BLACK_LEVEL:
+ {
+ int r = sn9c102_i2c_read(cam, 0x01);
+ if (r < 0)
+ return -EIO;
+ err += sn9c102_i2c_write(cam, 0x01,
+ (ctrl->value<<3) | (r&0xf7));
+ }
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return err ? -EIO : 0;
+}
+
+
+static int hv7131r_set_crop(struct sn9c102_device* cam,
+ const struct v4l2_rect* rect)
+{
+ struct sn9c102_sensor* s = sn9c102_get_sensor(cam);
+ int err = 0;
+ u8 h_start = (u8)(rect->left - s->cropcap.bounds.left) + 1,
+ v_start = (u8)(rect->top - s->cropcap.bounds.top) + 1;
+
+ err += sn9c102_write_reg(cam, h_start, 0x12);
+ err += sn9c102_write_reg(cam, v_start, 0x13);
+
+ return err;
+}
+
+
+static int hv7131r_set_pix_format(struct sn9c102_device* cam,
+ const struct v4l2_pix_format* pix)
+{
+ int err = 0;
+
+ switch (sn9c102_get_bridge(cam)) {
+ case BRIDGE_SN9C103:
+ if (pix->pixelformat == V4L2_PIX_FMT_SBGGR8) {
+ err += sn9c102_write_reg(cam, 0xa0, 0x19);
+ err += sn9c102_i2c_write(cam, 0x01, 0x04);
+ } else {
+ err += sn9c102_write_reg(cam, 0x30, 0x19);
+ err += sn9c102_i2c_write(cam, 0x01, 0x04);
+ }
+ break;
+ case BRIDGE_SN9C105:
+ case BRIDGE_SN9C120:
+ if (pix->pixelformat == V4L2_PIX_FMT_SBGGR8) {
+ err += sn9c102_write_reg(cam, 0xa5, 0x17);
+ err += sn9c102_i2c_write(cam, 0x01, 0x24);
+ } else {
+ err += sn9c102_write_reg(cam, 0xa3, 0x17);
+ err += sn9c102_i2c_write(cam, 0x01, 0x04);
+ }
+ break;
+ default:
+ break;
+ }
+
+ return err;
+}
+
+
+static const struct sn9c102_sensor hv7131r = {
+ .name = "HV7131R",
+ .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
+ .supported_bridge = BRIDGE_SN9C103 | BRIDGE_SN9C105 | BRIDGE_SN9C120,
+ .sysfs_ops = SN9C102_I2C_READ | SN9C102_I2C_WRITE,
+ .frequency = SN9C102_I2C_100KHZ,
+ .interface = SN9C102_I2C_2WIRES,
+ .i2c_slave_id = 0x11,
+ .init = &hv7131r_init,
+ .qctrl = {
+ {
+ .id = V4L2_CID_GAIN,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "global gain",
+ .minimum = 0x00,
+ .maximum = 0xff,
+ .step = 0x01,
+ .default_value = 0x40,
+ .flags = 0,
+ },
+ {
+ .id = V4L2_CID_RED_BALANCE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "red balance",
+ .minimum = 0x00,
+ .maximum = 0x3f,
+ .step = 0x01,
+ .default_value = 0x08,
+ .flags = 0,
+ },
+ {
+ .id = V4L2_CID_BLUE_BALANCE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "blue balance",
+ .minimum = 0x00,
+ .maximum = 0x3f,
+ .step = 0x01,
+ .default_value = 0x1a,
+ .flags = 0,
+ },
+ {
+ .id = SN9C102_V4L2_CID_GREEN_BALANCE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "green balance",
+ .minimum = 0x00,
+ .maximum = 0x3f,
+ .step = 0x01,
+ .default_value = 0x2f,
+ .flags = 0,
+ },
+ {
+ .id = V4L2_CID_BLACK_LEVEL,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "auto black level compensation",
+ .minimum = 0x00,
+ .maximum = 0x01,
+ .step = 0x01,
+ .default_value = 0x00,
+ .flags = 0,
+ },
+ },
+ .get_ctrl = &hv7131r_get_ctrl,
+ .set_ctrl = &hv7131r_set_ctrl,
+ .cropcap = {
+ .bounds = {
+ .left = 0,
+ .top = 0,
+ .width = 640,
+ .height = 480,
+ },
+ .defrect = {
+ .left = 0,
+ .top = 0,
+ .width = 640,
+ .height = 480,
+ },
+ },
+ .set_crop = &hv7131r_set_crop,
+ .pix_format = {
+ .width = 640,
+ .height = 480,
+ .pixelformat = V4L2_PIX_FMT_SBGGR8,
+ .priv = 8,
+ },
+ .set_pix_format = &hv7131r_set_pix_format
+};
+
+
+int sn9c102_probe_hv7131r(struct sn9c102_device* cam)
+{
+ int devid, err;
+
+ err = sn9c102_write_const_regs(cam, {0x09, 0x01}, {0x44, 0x02},
+ {0x34, 0x01}, {0x20, 0x17},
+ {0x34, 0x01}, {0x46, 0x01});
+
+ devid = sn9c102_i2c_try_read(cam, &hv7131r, 0x00);
+ if (err || devid < 0)
+ return -EIO;
+
+ if (devid != 0x02)
+ return -ENODEV;
+
+ sn9c102_attach_sensor(cam, &hv7131r);
+
+ return 0;
+}
diff --git a/linux/drivers/media/video/sn9c102/sn9c102_mi0343.c b/linux/drivers/media/video/sn9c102/sn9c102_mi0343.c
index a33d1bc10..00b134ca0 100644
--- a/linux/drivers/media/video/sn9c102/sn9c102_mi0343.c
+++ b/linux/drivers/media/video/sn9c102/sn9c102_mi0343.c
@@ -22,36 +22,30 @@
#include "sn9c102_sensor.h"
-static struct sn9c102_sensor mi0343;
-static u8 mi0343_i2c_data[5+1];
-
-
static int mi0343_init(struct sn9c102_device* cam)
{
+ struct sn9c102_sensor* s = sn9c102_get_sensor(cam);
int err = 0;
- err += sn9c102_write_reg(cam, 0x00, 0x10);
- err += sn9c102_write_reg(cam, 0x00, 0x11);
- err += sn9c102_write_reg(cam, 0x0a, 0x14);
- err += sn9c102_write_reg(cam, 0x40, 0x01);
- err += sn9c102_write_reg(cam, 0x20, 0x17);
- err += sn9c102_write_reg(cam, 0x07, 0x18);
- err += sn9c102_write_reg(cam, 0xa0, 0x19);
-
- err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4, mi0343.i2c_slave_id,
- 0x0d, 0x00, 0x01, 0, 0);
- err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4, mi0343.i2c_slave_id,
- 0x0d, 0x00, 0x00, 0, 0);
- err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4, mi0343.i2c_slave_id,
- 0x03, 0x01, 0xe1, 0, 0);
- err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4, mi0343.i2c_slave_id,
- 0x04, 0x02, 0x81, 0, 0);
- err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4, mi0343.i2c_slave_id,
- 0x05, 0x00, 0x17, 0, 0);
- err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4, mi0343.i2c_slave_id,
- 0x06, 0x00, 0x11, 0, 0);
- err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4, mi0343.i2c_slave_id,
- 0x62, 0x04, 0x9a, 0, 0);
+ err = sn9c102_write_const_regs(cam, {0x00, 0x10}, {0x00, 0x11},
+ {0x0a, 0x14}, {0x40, 0x01},
+ {0x20, 0x17}, {0x07, 0x18},
+ {0xa0, 0x19});
+
+ err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x0d,
+ 0x00, 0x01, 0, 0);
+ err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x0d,
+ 0x00, 0x00, 0, 0);
+ err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x03,
+ 0x01, 0xe1, 0, 0);
+ err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x04,
+ 0x02, 0x81, 0, 0);
+ err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x05,
+ 0x00, 0x17, 0, 0);
+ err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x06,
+ 0x00, 0x11, 0, 0);
+ err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x62,
+ 0x04, 0x9a, 0, 0);
return err;
}
@@ -60,43 +54,46 @@ static int mi0343_init(struct sn9c102_device* cam)
static int mi0343_get_ctrl(struct sn9c102_device* cam,
struct v4l2_control* ctrl)
{
+ struct sn9c102_sensor* s = sn9c102_get_sensor(cam);
+ u8 data[2];
+
switch (ctrl->id) {
case V4L2_CID_EXPOSURE:
- if (sn9c102_i2c_try_raw_read(cam, &mi0343, mi0343.i2c_slave_id,
- 0x09, 2+1, mi0343_i2c_data) < 0)
+ if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x09, 2,
+ data) < 0)
return -EIO;
- ctrl->value = mi0343_i2c_data[2];
+ ctrl->value = data[0];
return 0;
case V4L2_CID_GAIN:
- if (sn9c102_i2c_try_raw_read(cam, &mi0343, mi0343.i2c_slave_id,
- 0x35, 2+1, mi0343_i2c_data) < 0)
+ if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x35, 2,
+ data) < 0)
return -EIO;
break;
case V4L2_CID_HFLIP:
- if (sn9c102_i2c_try_raw_read(cam, &mi0343, mi0343.i2c_slave_id,
- 0x20, 2+1, mi0343_i2c_data) < 0)
+ if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x20, 2,
+ data) < 0)
return -EIO;
- ctrl->value = mi0343_i2c_data[3] & 0x20 ? 1 : 0;
+ ctrl->value = data[1] & 0x20 ? 1 : 0;
return 0;
case V4L2_CID_VFLIP:
- if (sn9c102_i2c_try_raw_read(cam, &mi0343, mi0343.i2c_slave_id,
- 0x20, 2+1, mi0343_i2c_data) < 0)
+ if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x20, 2,
+ data) < 0)
return -EIO;
- ctrl->value = mi0343_i2c_data[3] & 0x80 ? 1 : 0;
+ ctrl->value = data[1] & 0x80 ? 1 : 0;
return 0;
case V4L2_CID_RED_BALANCE:
- if (sn9c102_i2c_try_raw_read(cam, &mi0343, mi0343.i2c_slave_id,
- 0x2d, 2+1, mi0343_i2c_data) < 0)
+ if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x2d, 2,
+ data) < 0)
return -EIO;
break;
case V4L2_CID_BLUE_BALANCE:
- if (sn9c102_i2c_try_raw_read(cam, &mi0343, mi0343.i2c_slave_id,
- 0x2c, 2+1, mi0343_i2c_data) < 0)
+ if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x2c, 2,
+ data) < 0)
return -EIO;
break;
case SN9C102_V4L2_CID_GREEN_BALANCE:
- if (sn9c102_i2c_try_raw_read(cam, &mi0343, mi0343.i2c_slave_id,
- 0x2e, 2+1, mi0343_i2c_data) < 0)
+ if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x2e, 2,
+ data) < 0)
return -EIO;
break;
default:
@@ -108,7 +105,7 @@ static int mi0343_get_ctrl(struct sn9c102_device* cam,
case V4L2_CID_RED_BALANCE:
case V4L2_CID_BLUE_BALANCE:
case SN9C102_V4L2_CID_GREEN_BALANCE:
- ctrl->value = mi0343_i2c_data[3] | (mi0343_i2c_data[2] << 8);
+ ctrl->value = data[1] | (data[0] << 8);
if (ctrl->value >= 0x10 && ctrl->value <= 0x3f)
ctrl->value -= 0x10;
else if (ctrl->value >= 0x60 && ctrl->value <= 0x7f)
@@ -124,6 +121,7 @@ static int mi0343_get_ctrl(struct sn9c102_device* cam,
static int mi0343_set_ctrl(struct sn9c102_device* cam,
const struct v4l2_control* ctrl)
{
+ struct sn9c102_sensor* s = sn9c102_get_sensor(cam);
u16 reg = 0;
int err = 0;
@@ -143,50 +141,42 @@ static int mi0343_set_ctrl(struct sn9c102_device* cam,
switch (ctrl->id) {
case V4L2_CID_EXPOSURE:
- err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4,
- mi0343.i2c_slave_id,
+ err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
0x09, ctrl->value, 0x00,
0, 0);
break;
case V4L2_CID_GAIN:
- err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4,
- mi0343.i2c_slave_id,
+ err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
0x35, reg >> 8, reg & 0xff,
0, 0);
break;
case V4L2_CID_HFLIP:
- err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4,
- mi0343.i2c_slave_id,
+ err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
0x20, ctrl->value ? 0x40:0x00,
ctrl->value ? 0x20:0x00,
0, 0);
break;
case V4L2_CID_VFLIP:
- err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4,
- mi0343.i2c_slave_id,
+ err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
0x20, ctrl->value ? 0x80:0x00,
ctrl->value ? 0x80:0x00,
0, 0);
break;
case V4L2_CID_RED_BALANCE:
- err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4,
- mi0343.i2c_slave_id,
+ err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
0x2d, reg >> 8, reg & 0xff,
0, 0);
break;
case V4L2_CID_BLUE_BALANCE:
- err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4,
- mi0343.i2c_slave_id,
+ err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
0x2c, reg >> 8, reg & 0xff,
0, 0);
break;
case SN9C102_V4L2_CID_GREEN_BALANCE:
- err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4,
- mi0343.i2c_slave_id,
+ err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
0x2b, reg >> 8, reg & 0xff,
0, 0);
- err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4,
- mi0343.i2c_slave_id,
+ err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
0x2e, reg >> 8, reg & 0xff,
0, 0);
break;
@@ -216,16 +206,15 @@ static int mi0343_set_crop(struct sn9c102_device* cam,
static int mi0343_set_pix_format(struct sn9c102_device* cam,
const struct v4l2_pix_format* pix)
{
+ struct sn9c102_sensor* s = sn9c102_get_sensor(cam);
int err = 0;
if (pix->pixelformat == V4L2_PIX_FMT_SN9C10X) {
- err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4,
- mi0343.i2c_slave_id,
+ err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
0x0a, 0x00, 0x03, 0, 0);
err += sn9c102_write_reg(cam, 0x20, 0x19);
} else {
- err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4,
- mi0343.i2c_slave_id,
+ err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
0x0a, 0x00, 0x05, 0, 0);
err += sn9c102_write_reg(cam, 0xa0, 0x19);
}
@@ -234,10 +223,10 @@ static int mi0343_set_pix_format(struct sn9c102_device* cam,
}
-static struct sn9c102_sensor mi0343 = {
+static const struct sn9c102_sensor mi0343 = {
.name = "MI-0343",
.maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
- .supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102 | BRIDGE_SN9C103,
+ .supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102,
.frequency = SN9C102_I2C_100KHZ,
.interface = SN9C102_I2C_2WIRES,
.i2c_slave_id = 0x5d,
@@ -343,19 +332,17 @@ static struct sn9c102_sensor mi0343 = {
int sn9c102_probe_mi0343(struct sn9c102_device* cam)
{
- int err = 0;
+ u8 data[2];
- err += sn9c102_write_reg(cam, 0x01, 0x01);
- err += sn9c102_write_reg(cam, 0x00, 0x01);
- err += sn9c102_write_reg(cam, 0x28, 0x17);
- if (err)
+ if (sn9c102_write_const_regs(cam, {0x01, 0x01}, {0x00, 0x01},
+ {0x28, 0x17}))
return -EIO;
if (sn9c102_i2c_try_raw_read(cam, &mi0343, mi0343.i2c_slave_id, 0x00,
- 2, mi0343_i2c_data) < 0)
+ 2, data) < 0)
return -EIO;
- if (mi0343_i2c_data[4] != 0x32 && mi0343_i2c_data[3] != 0xe3)
+ if (data[1] != 0x42 || data[0] != 0xe3)
return -ENODEV;
sn9c102_attach_sensor(cam, &mi0343);
diff --git a/linux/drivers/media/video/sn9c102/sn9c102_mi0360.c b/linux/drivers/media/video/sn9c102/sn9c102_mi0360.c
new file mode 100644
index 000000000..f8d81d82e
--- /dev/null
+++ b/linux/drivers/media/video/sn9c102/sn9c102_mi0360.c
@@ -0,0 +1,452 @@
+/***************************************************************************
+ * Plug-in for MI-0360 image sensor connected to the SN9C1xx PC Camera *
+ * Controllers *
+ * *
+ * Copyright (C) 2007 by Luca Risolia <luca.risolia@studio.unibo.it> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the Free Software *
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
+ ***************************************************************************/
+
+#include "sn9c102_sensor.h"
+
+
+static int mi0360_init(struct sn9c102_device* cam)
+{
+ struct sn9c102_sensor* s = sn9c102_get_sensor(cam);
+ int err = 0;
+
+ switch (sn9c102_get_bridge(cam)) {
+ case BRIDGE_SN9C103:
+ err = sn9c102_write_const_regs(cam, {0x00, 0x10}, {0x00, 0x11},
+ {0x0a, 0x14}, {0x40, 0x01},
+ {0x20, 0x17}, {0x07, 0x18},
+ {0xa0, 0x19}, {0x02, 0x1c},
+ {0x03, 0x1d}, {0x0f, 0x1e},
+ {0x0c, 0x1f}, {0x00, 0x20},
+ {0x10, 0x21}, {0x20, 0x22},
+ {0x30, 0x23}, {0x40, 0x24},
+ {0x50, 0x25}, {0x60, 0x26},
+ {0x70, 0x27}, {0x80, 0x28},
+ {0x90, 0x29}, {0xa0, 0x2a},
+ {0xb0, 0x2b}, {0xc0, 0x2c},
+ {0xd0, 0x2d}, {0xe0, 0x2e},
+ {0xf0, 0x2f}, {0xff, 0x30});
+ break;
+ case BRIDGE_SN9C105:
+ case BRIDGE_SN9C120:
+ err = sn9c102_write_const_regs(cam, {0x44, 0x01}, {0x40, 0x02},
+ {0x00, 0x03}, {0x1a, 0x04},
+ {0x50, 0x05}, {0x20, 0x06},
+ {0x10, 0x07}, {0x03, 0x10},
+ {0x08, 0x14}, {0xa2, 0x17},
+ {0x47, 0x18}, {0x00, 0x19},
+ {0x1d, 0x1a}, {0x10, 0x1b},
+ {0x02, 0x1c}, {0x03, 0x1d},
+ {0x0f, 0x1e}, {0x0c, 0x1f},
+ {0x00, 0x20}, {0x29, 0x21},
+ {0x40, 0x22}, {0x54, 0x23},
+ {0x66, 0x24}, {0x76, 0x25},
+ {0x85, 0x26}, {0x94, 0x27},
+ {0xa1, 0x28}, {0xae, 0x29},
+ {0xbb, 0x2a}, {0xc7, 0x2b},
+ {0xd3, 0x2c}, {0xde, 0x2d},
+ {0xea, 0x2e}, {0xf4, 0x2f},
+ {0xff, 0x30}, {0x00, 0x3F},
+ {0xC7, 0x40}, {0x01, 0x41},
+ {0x44, 0x42}, {0x00, 0x43},
+ {0x44, 0x44}, {0x00, 0x45},
+ {0x44, 0x46}, {0x00, 0x47},
+ {0xC7, 0x48}, {0x01, 0x49},
+ {0xC7, 0x4A}, {0x01, 0x4B},
+ {0xC7, 0x4C}, {0x01, 0x4D},
+ {0x44, 0x4E}, {0x00, 0x4F},
+ {0x44, 0x50}, {0x00, 0x51},
+ {0x44, 0x52}, {0x00, 0x53},
+ {0xC7, 0x54}, {0x01, 0x55},
+ {0xC7, 0x56}, {0x01, 0x57},
+ {0xC7, 0x58}, {0x01, 0x59},
+ {0x44, 0x5A}, {0x00, 0x5B},
+ {0x44, 0x5C}, {0x00, 0x5D},
+ {0x44, 0x5E}, {0x00, 0x5F},
+ {0xC7, 0x60}, {0x01, 0x61},
+ {0xC7, 0x62}, {0x01, 0x63},
+ {0xC7, 0x64}, {0x01, 0x65},
+ {0x44, 0x66}, {0x00, 0x67},
+ {0x44, 0x68}, {0x00, 0x69},
+ {0x44, 0x6A}, {0x00, 0x6B},
+ {0xC7, 0x6C}, {0x01, 0x6D},
+ {0xC7, 0x6E}, {0x01, 0x6F},
+ {0xC7, 0x70}, {0x01, 0x71},
+ {0x44, 0x72}, {0x00, 0x73},
+ {0x44, 0x74}, {0x00, 0x75},
+ {0x44, 0x76}, {0x00, 0x77},
+ {0xC7, 0x78}, {0x01, 0x79},
+ {0xC7, 0x7A}, {0x01, 0x7B},
+ {0xC7, 0x7C}, {0x01, 0x7D},
+ {0x44, 0x7E}, {0x00, 0x7F},
+ {0x14, 0x84}, {0x00, 0x85},
+ {0x27, 0x86}, {0x00, 0x87},
+ {0x07, 0x88}, {0x00, 0x89},
+ {0xEC, 0x8A}, {0x0f, 0x8B},
+ {0xD8, 0x8C}, {0x0f, 0x8D},
+ {0x3D, 0x8E}, {0x00, 0x8F},
+ {0x3D, 0x90}, {0x00, 0x91},
+ {0xCD, 0x92}, {0x0f, 0x93},
+ {0xf7, 0x94}, {0x0f, 0x95},
+ {0x0C, 0x96}, {0x00, 0x97},
+ {0x00, 0x98}, {0x66, 0x99},
+ {0x05, 0x9A}, {0x00, 0x9B},
+ {0x04, 0x9C}, {0x00, 0x9D},
+ {0x08, 0x9E}, {0x00, 0x9F},
+ {0x2D, 0xC0}, {0x2D, 0xC1},
+ {0x3A, 0xC2}, {0x05, 0xC3},
+ {0x04, 0xC4}, {0x3F, 0xC5},
+ {0x00, 0xC6}, {0x00, 0xC7},
+ {0x50, 0xC8}, {0x3C, 0xC9},
+ {0x28, 0xCA}, {0xD8, 0xCB},
+ {0x14, 0xCC}, {0xEC, 0xCD},
+ {0x32, 0xCE}, {0xDD, 0xCF},
+ {0x32, 0xD0}, {0xDD, 0xD1},
+ {0x6A, 0xD2}, {0x50, 0xD3},
+ {0x00, 0xD4}, {0x00, 0xD5},
+ {0x00, 0xD6});
+ break;
+ default:
+ break;
+ }
+
+ err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x0d,
+ 0x00, 0x01, 0, 0);
+ err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x0d,
+ 0x00, 0x00, 0, 0);
+ err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x03,
+ 0x01, 0xe1, 0, 0);
+ err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x04,
+ 0x02, 0x81, 0, 0);
+ err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x05,
+ 0x00, 0x17, 0, 0);
+ err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x06,
+ 0x00, 0x11, 0, 0);
+ err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x62,
+ 0x04, 0x9a, 0, 0);
+
+ return err;
+}
+
+
+static int mi0360_get_ctrl(struct sn9c102_device* cam,
+ struct v4l2_control* ctrl)
+{
+ struct sn9c102_sensor* s = sn9c102_get_sensor(cam);
+ u8 data[2];
+
+ switch (ctrl->id) {
+ case V4L2_CID_EXPOSURE:
+ if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x09, 2,
+ data) < 0)
+ return -EIO;
+ ctrl->value = data[0];
+ return 0;
+ case V4L2_CID_GAIN:
+ if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x35, 2,
+ data) < 0)
+ return -EIO;
+ ctrl->value = data[1];
+ return 0;
+ case V4L2_CID_RED_BALANCE:
+ if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x2c, 2,
+ data) < 0)
+ return -EIO;
+ ctrl->value = data[1];
+ return 0;
+ case V4L2_CID_BLUE_BALANCE:
+ if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x2d, 2,
+ data) < 0)
+ return -EIO;
+ ctrl->value = data[1];
+ return 0;
+ case SN9C102_V4L2_CID_GREEN_BALANCE:
+ if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x2e, 2,
+ data) < 0)
+ return -EIO;
+ ctrl->value = data[1];
+ return 0;
+ case V4L2_CID_HFLIP:
+ if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x20, 2,
+ data) < 0)
+ return -EIO;
+ ctrl->value = data[1] & 0x20 ? 1 : 0;
+ return 0;
+ case V4L2_CID_VFLIP:
+ if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x20, 2,
+ data) < 0)
+ return -EIO;
+ ctrl->value = data[1] & 0x80 ? 1 : 0;
+ return 0;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+
+static int mi0360_set_ctrl(struct sn9c102_device* cam,
+ const struct v4l2_control* ctrl)
+{
+ struct sn9c102_sensor* s = sn9c102_get_sensor(cam);
+ int err = 0;
+
+ switch (ctrl->id) {
+ case V4L2_CID_EXPOSURE:
+ err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
+ 0x09, ctrl->value, 0x00,
+ 0, 0);
+ break;
+ case V4L2_CID_GAIN:
+ err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
+ 0x35, 0x03, ctrl->value,
+ 0, 0);
+ break;
+ case V4L2_CID_RED_BALANCE:
+ err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
+ 0x2c, 0x03, ctrl->value,
+ 0, 0);
+ break;
+ case V4L2_CID_BLUE_BALANCE:
+ err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
+ 0x2d, 0x03, ctrl->value,
+ 0, 0);
+ break;
+ case SN9C102_V4L2_CID_GREEN_BALANCE:
+ err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
+ 0x2b, 0x03, ctrl->value,
+ 0, 0);
+ err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
+ 0x2e, 0x03, ctrl->value,
+ 0, 0);
+ break;
+ case V4L2_CID_HFLIP:
+ err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
+ 0x20, ctrl->value ? 0x40:0x00,
+ ctrl->value ? 0x20:0x00,
+ 0, 0);
+ break;
+ case V4L2_CID_VFLIP:
+ err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
+ 0x20, ctrl->value ? 0x80:0x00,
+ ctrl->value ? 0x80:0x00,
+ 0, 0);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return err ? -EIO : 0;
+}
+
+
+static int mi0360_set_crop(struct sn9c102_device* cam,
+ const struct v4l2_rect* rect)
+{
+ struct sn9c102_sensor* s = sn9c102_get_sensor(cam);
+ int err = 0;
+ u8 h_start = 0, v_start = (u8)(rect->top - s->cropcap.bounds.top) + 1;
+
+ switch (sn9c102_get_bridge(cam)) {
+ case BRIDGE_SN9C103:
+ h_start = (u8)(rect->left - s->cropcap.bounds.left) + 0;
+ break;
+ case BRIDGE_SN9C105:
+ case BRIDGE_SN9C120:
+ h_start = (u8)(rect->left - s->cropcap.bounds.left) + 1;
+ break;
+ default:
+ break;
+ }
+
+ err += sn9c102_write_reg(cam, h_start, 0x12);
+ err += sn9c102_write_reg(cam, v_start, 0x13);
+
+ return err;
+}
+
+
+static int mi0360_set_pix_format(struct sn9c102_device* cam,
+ const struct v4l2_pix_format* pix)
+{
+ struct sn9c102_sensor* s = sn9c102_get_sensor(cam);
+ int err = 0;
+
+ if (pix->pixelformat == V4L2_PIX_FMT_SBGGR8) {
+ err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
+ 0x0a, 0x00, 0x05, 0, 0);
+ err += sn9c102_write_reg(cam, 0x60, 0x19);
+ if (sn9c102_get_bridge(cam) == BRIDGE_SN9C105 ||
+ sn9c102_get_bridge(cam) == BRIDGE_SN9C120)
+ err += sn9c102_write_reg(cam, 0xa6, 0x17);
+ } else {
+ err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
+ 0x0a, 0x00, 0x02, 0, 0);
+ err += sn9c102_write_reg(cam, 0x20, 0x19);
+ if (sn9c102_get_bridge(cam) == BRIDGE_SN9C105 ||
+ sn9c102_get_bridge(cam) == BRIDGE_SN9C120)
+ err += sn9c102_write_reg(cam, 0xa2, 0x17);
+ }
+
+ return err;
+}
+
+
+static const struct sn9c102_sensor mi0360 = {
+ .name = "MI-0360",
+ .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
+ .supported_bridge = BRIDGE_SN9C103 | BRIDGE_SN9C105 | BRIDGE_SN9C120,
+ .frequency = SN9C102_I2C_100KHZ,
+ .interface = SN9C102_I2C_2WIRES,
+ .i2c_slave_id = 0x5d,
+ .init = &mi0360_init,
+ .qctrl = {
+ {
+ .id = V4L2_CID_EXPOSURE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "exposure",
+ .minimum = 0x00,
+ .maximum = 0x0f,
+ .step = 0x01,
+ .default_value = 0x05,
+ .flags = 0,
+ },
+ {
+ .id = V4L2_CID_GAIN,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "global gain",
+ .minimum = 0x00,
+ .maximum = 0x7f,
+ .step = 0x01,
+ .default_value = 0x25,
+ .flags = 0,
+ },
+ {
+ .id = V4L2_CID_HFLIP,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "horizontal mirror",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0,
+ .flags = 0,
+ },
+ {
+ .id = V4L2_CID_VFLIP,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "vertical mirror",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0,
+ .flags = 0,
+ },
+ {
+ .id = V4L2_CID_BLUE_BALANCE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "blue balance",
+ .minimum = 0x00,
+ .maximum = 0x7f,
+ .step = 0x01,
+ .default_value = 0x0f,
+ .flags = 0,
+ },
+ {
+ .id = V4L2_CID_RED_BALANCE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "red balance",
+ .minimum = 0x00,
+ .maximum = 0x7f,
+ .step = 0x01,
+ .default_value = 0x32,
+ .flags = 0,
+ },
+ {
+ .id = SN9C102_V4L2_CID_GREEN_BALANCE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "green balance",
+ .minimum = 0x00,
+ .maximum = 0x7f,
+ .step = 0x01,
+ .default_value = 0x25,
+ .flags = 0,
+ },
+ },
+ .get_ctrl = &mi0360_get_ctrl,
+ .set_ctrl = &mi0360_set_ctrl,
+ .cropcap = {
+ .bounds = {
+ .left = 0,
+ .top = 0,
+ .width = 640,
+ .height = 480,
+ },
+ .defrect = {
+ .left = 0,
+ .top = 0,
+ .width = 640,
+ .height = 480,
+ },
+ },
+ .set_crop = &mi0360_set_crop,
+ .pix_format = {
+ .width = 640,
+ .height = 480,
+ .pixelformat = V4L2_PIX_FMT_SBGGR8,
+ .priv = 8,
+ },
+ .set_pix_format = &mi0360_set_pix_format
+};
+
+
+int sn9c102_probe_mi0360(struct sn9c102_device* cam)
+{
+
+ u8 data[2];
+
+ switch (sn9c102_get_bridge(cam)) {
+ case BRIDGE_SN9C103:
+ if (sn9c102_write_const_regs(cam, {0x01, 0x01}, {0x00, 0x01},
+ {0x28, 0x17}))
+ return -EIO;
+ break;
+ case BRIDGE_SN9C105:
+ case BRIDGE_SN9C120:
+ if (sn9c102_write_const_regs(cam, {0x01, 0xf1}, {0x00, 0xf1},
+ {0x01, 0x01}, {0x00, 0x01},
+ {0x28, 0x17}))
+ return -EIO;
+ break;
+ default:
+ break;
+ }
+
+ if (sn9c102_i2c_try_raw_read(cam, &mi0360, mi0360.i2c_slave_id, 0x00,
+ 2, data) < 0)
+ return -EIO;
+
+ if (data[0] != 0x82 || data[1] != 0x43)
+ return -ENODEV;
+
+ sn9c102_attach_sensor(cam, &mi0360);
+
+ return 0;
+}
diff --git a/linux/drivers/media/video/sn9c102/sn9c102_ov7630.c b/linux/drivers/media/video/sn9c102/sn9c102_ov7630.c
index 7df09ff38..e68323478 100644
--- a/linux/drivers/media/video/sn9c102/sn9c102_ov7630.c
+++ b/linux/drivers/media/video/sn9c102/sn9c102_ov7630.c
@@ -22,9 +22,6 @@
#include "sn9c102_sensor.h"
-static struct sn9c102_sensor ov7630;
-
-
static int ov7630_init(struct sn9c102_device* cam)
{
int err = 0;
@@ -32,21 +29,19 @@ static int ov7630_init(struct sn9c102_device* cam)
switch (sn9c102_get_bridge(cam)) {
case BRIDGE_SN9C101:
case BRIDGE_SN9C102:
- err += sn9c102_write_reg(cam, 0x00, 0x14);
- err += sn9c102_write_reg(cam, 0x60, 0x17);
- err += sn9c102_write_reg(cam, 0x0f, 0x18);
- err += sn9c102_write_reg(cam, 0x50, 0x19);
+ err = sn9c102_write_const_regs(cam, {0x00, 0x14}, {0x60, 0x17},
+ {0x0f, 0x18}, {0x50, 0x19});
err += sn9c102_i2c_write(cam, 0x12, 0x8d);
err += sn9c102_i2c_write(cam, 0x12, 0x0d);
err += sn9c102_i2c_write(cam, 0x11, 0x00);
- err += sn9c102_i2c_write(cam, 0x15, 0x34);
- err += sn9c102_i2c_write(cam, 0x16, 0x03);
- err += sn9c102_i2c_write(cam, 0x17, 0x1c);
- err += sn9c102_i2c_write(cam, 0x18, 0xbd);
- err += sn9c102_i2c_write(cam, 0x19, 0x06);
- err += sn9c102_i2c_write(cam, 0x1a, 0xf6);
- err += sn9c102_i2c_write(cam, 0x1b, 0x04);
+ err += sn9c102_i2c_write(cam, 0x15, 0x35);
+ err += sn9c102_i2c_write(cam, 0x16, 0x03);
+ err += sn9c102_i2c_write(cam, 0x17, 0x1c);
+ err += sn9c102_i2c_write(cam, 0x18, 0xbd);
+ err += sn9c102_i2c_write(cam, 0x19, 0x06);
+ err += sn9c102_i2c_write(cam, 0x1a, 0xf6);
+ err += sn9c102_i2c_write(cam, 0x1b, 0x04);
err += sn9c102_i2c_write(cam, 0x20, 0x44);
err += sn9c102_i2c_write(cam, 0x23, 0xee);
err += sn9c102_i2c_write(cam, 0x26, 0xa0);
@@ -67,40 +62,23 @@ static int ov7630_init(struct sn9c102_device* cam)
err += sn9c102_i2c_write(cam, 0x7d, 0xf7);
break;
case BRIDGE_SN9C103:
- err += sn9c102_write_reg(cam, 0x00, 0x02);
- err += sn9c102_write_reg(cam, 0x00, 0x03);
- err += sn9c102_write_reg(cam, 0x1a, 0x04);
- err += sn9c102_write_reg(cam, 0x20, 0x05);
- err += sn9c102_write_reg(cam, 0x20, 0x06);
- err += sn9c102_write_reg(cam, 0x20, 0x07);
- err += sn9c102_write_reg(cam, 0x03, 0x10);
- err += sn9c102_write_reg(cam, 0x0a, 0x14);
- err += sn9c102_write_reg(cam, 0x60, 0x17);
- err += sn9c102_write_reg(cam, 0x0f, 0x18);
- err += sn9c102_write_reg(cam, 0x50, 0x19);
- err += sn9c102_write_reg(cam, 0x1d, 0x1a);
- err += sn9c102_write_reg(cam, 0x10, 0x1b);
- err += sn9c102_write_reg(cam, 0x02, 0x1c);
- err += sn9c102_write_reg(cam, 0x03, 0x1d);
- err += sn9c102_write_reg(cam, 0x0f, 0x1e);
- err += sn9c102_write_reg(cam, 0x0c, 0x1f);
- err += sn9c102_write_reg(cam, 0x00, 0x20);
- err += sn9c102_write_reg(cam, 0x10, 0x21);
- err += sn9c102_write_reg(cam, 0x20, 0x22);
- err += sn9c102_write_reg(cam, 0x30, 0x23);
- err += sn9c102_write_reg(cam, 0x40, 0x24);
- err += sn9c102_write_reg(cam, 0x50, 0x25);
- err += sn9c102_write_reg(cam, 0x60, 0x26);
- err += sn9c102_write_reg(cam, 0x70, 0x27);
- err += sn9c102_write_reg(cam, 0x80, 0x28);
- err += sn9c102_write_reg(cam, 0x90, 0x29);
- err += sn9c102_write_reg(cam, 0xa0, 0x2a);
- err += sn9c102_write_reg(cam, 0xb0, 0x2b);
- err += sn9c102_write_reg(cam, 0xc0, 0x2c);
- err += sn9c102_write_reg(cam, 0xd0, 0x2d);
- err += sn9c102_write_reg(cam, 0xe0, 0x2e);
- err += sn9c102_write_reg(cam, 0xf0, 0x2f);
- err += sn9c102_write_reg(cam, 0xff, 0x30);
+ err = sn9c102_write_const_regs(cam, {0x00, 0x02}, {0x00, 0x03},
+ {0x1a, 0x04}, {0x20, 0x05},
+ {0x20, 0x06}, {0x20, 0x07},
+ {0x03, 0x10}, {0x0a, 0x14},
+ {0x60, 0x17}, {0x0f, 0x18},
+ {0x50, 0x19}, {0x1d, 0x1a},
+ {0x10, 0x1b}, {0x02, 0x1c},
+ {0x03, 0x1d}, {0x0f, 0x1e},
+ {0x0c, 0x1f}, {0x00, 0x20},
+ {0x10, 0x21}, {0x20, 0x22},
+ {0x30, 0x23}, {0x40, 0x24},
+ {0x50, 0x25}, {0x60, 0x26},
+ {0x70, 0x27}, {0x80, 0x28},
+ {0x90, 0x29}, {0xa0, 0x2a},
+ {0xb0, 0x2b}, {0xc0, 0x2c},
+ {0xd0, 0x2d}, {0xe0, 0x2e},
+ {0xf0, 0x2f}, {0xff, 0x30});
err += sn9c102_i2c_write(cam, 0x12, 0x8d);
err += sn9c102_i2c_write(cam, 0x12, 0x0d);
@@ -108,23 +86,23 @@ static int ov7630_init(struct sn9c102_device* cam)
err += sn9c102_i2c_write(cam, 0x11, 0x01);
err += sn9c102_i2c_write(cam, 0x1b, 0x04);
err += sn9c102_i2c_write(cam, 0x20, 0x44);
- err += sn9c102_i2c_write(cam, 0x23, 0xee);
- err += sn9c102_i2c_write(cam, 0x26, 0xa0);
- err += sn9c102_i2c_write(cam, 0x27, 0x9a);
+ err += sn9c102_i2c_write(cam, 0x23, 0xee);
+ err += sn9c102_i2c_write(cam, 0x26, 0xa0);
+ err += sn9c102_i2c_write(cam, 0x27, 0x9a);
err += sn9c102_i2c_write(cam, 0x28, 0x20);
- err += sn9c102_i2c_write(cam, 0x29, 0x30);
- err += sn9c102_i2c_write(cam, 0x2f, 0x3d);
- err += sn9c102_i2c_write(cam, 0x30, 0x24);
- err += sn9c102_i2c_write(cam, 0x32, 0x86);
- err += sn9c102_i2c_write(cam, 0x60, 0xa9);
- err += sn9c102_i2c_write(cam, 0x61, 0x42);
- err += sn9c102_i2c_write(cam, 0x65, 0x00);
- err += sn9c102_i2c_write(cam, 0x69, 0x38);
- err += sn9c102_i2c_write(cam, 0x6f, 0x88);
- err += sn9c102_i2c_write(cam, 0x70, 0x0b);
- err += sn9c102_i2c_write(cam, 0x71, 0x00);
- err += sn9c102_i2c_write(cam, 0x74, 0x21);
- err += sn9c102_i2c_write(cam, 0x7d, 0xf7);
+ err += sn9c102_i2c_write(cam, 0x29, 0x30);
+ err += sn9c102_i2c_write(cam, 0x2f, 0x3d);
+ err += sn9c102_i2c_write(cam, 0x30, 0x24);
+ err += sn9c102_i2c_write(cam, 0x32, 0x86);
+ err += sn9c102_i2c_write(cam, 0x60, 0xa9);
+ err += sn9c102_i2c_write(cam, 0x61, 0x42);
+ err += sn9c102_i2c_write(cam, 0x65, 0x00);
+ err += sn9c102_i2c_write(cam, 0x69, 0x38);
+ err += sn9c102_i2c_write(cam, 0x6f, 0x88);
+ err += sn9c102_i2c_write(cam, 0x70, 0x0b);
+ err += sn9c102_i2c_write(cam, 0x71, 0x00);
+ err += sn9c102_i2c_write(cam, 0x74, 0x21);
+ err += sn9c102_i2c_write(cam, 0x7d, 0xf7);
break;
default:
break;
@@ -273,7 +251,7 @@ static int ov7630_set_pix_format(struct sn9c102_device* cam,
}
-static struct sn9c102_sensor ov7630 = {
+static const struct sn9c102_sensor ov7630 = {
.name = "OV7630",
.maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
.supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102 | BRIDGE_SN9C103,
@@ -428,20 +406,16 @@ int sn9c102_probe_ov7630(struct sn9c102_device* cam)
switch (sn9c102_get_bridge(cam)) {
case BRIDGE_SN9C101:
case BRIDGE_SN9C102:
- err += sn9c102_write_reg(cam, 0x01, 0x01);
- err += sn9c102_write_reg(cam, 0x00, 0x01);
- err += sn9c102_write_reg(cam, 0x28, 0x17);
+ err = sn9c102_write_const_regs(cam, {0x01, 0x01}, {0x00, 0x01},
+ {0x28, 0x17});
break;
case BRIDGE_SN9C103: /* do _not_ change anything! */
- err += sn9c102_write_reg(cam, 0x09, 0x01);
- err += sn9c102_write_reg(cam, 0x42, 0x01);
- err += sn9c102_write_reg(cam, 0x28, 0x17);
- err += sn9c102_write_reg(cam, 0x44, 0x02);
+ err = sn9c102_write_const_regs(cam, {0x09, 0x01}, {0x42, 0x01},
+ {0x28, 0x17}, {0x44, 0x02});
pid = sn9c102_i2c_try_read(cam, &ov7630, 0x0a);
- if (err || pid < 0) { /* try a different initialization */
- err = sn9c102_write_reg(cam, 0x01, 0x01);
- err += sn9c102_write_reg(cam, 0x00, 0x01);
- }
+ if (err || pid < 0) /* try a different initialization */
+ err += sn9c102_write_const_regs(cam, {0x01, 0x01},
+ {0x00, 0x01});
break;
default:
break;
diff --git a/linux/drivers/media/video/sn9c102/sn9c102_ov7660.c b/linux/drivers/media/video/sn9c102/sn9c102_ov7660.c
index d670c24d4..4b6474048 100644
--- a/linux/drivers/media/video/sn9c102/sn9c102_ov7660.c
+++ b/linux/drivers/media/video/sn9c102/sn9c102_ov7660.c
@@ -22,166 +22,90 @@
#include "sn9c102_sensor.h"
-static struct sn9c102_sensor ov7660;
-
-
static int ov7660_init(struct sn9c102_device* cam)
{
int err = 0;
- err += sn9c102_write_reg(cam, 0x40, 0x02);
- err += sn9c102_write_reg(cam, 0x00, 0x03);
- err += sn9c102_write_reg(cam, 0x1a, 0x04);
- err += sn9c102_write_reg(cam, 0x03, 0x10);
- err += sn9c102_write_reg(cam, 0x08, 0x14);
- err += sn9c102_write_reg(cam, 0x20, 0x17);
- err += sn9c102_write_reg(cam, 0x8b, 0x18);
- err += sn9c102_write_reg(cam, 0x00, 0x19);
- err += sn9c102_write_reg(cam, 0x1d, 0x1a);
- err += sn9c102_write_reg(cam, 0x10, 0x1b);
- err += sn9c102_write_reg(cam, 0x02, 0x1c);
- err += sn9c102_write_reg(cam, 0x03, 0x1d);
- err += sn9c102_write_reg(cam, 0x0f, 0x1e);
- err += sn9c102_write_reg(cam, 0x0c, 0x1f);
- err += sn9c102_write_reg(cam, 0x00, 0x20);
- err += sn9c102_write_reg(cam, 0x29, 0x21);
- err += sn9c102_write_reg(cam, 0x40, 0x22);
- err += sn9c102_write_reg(cam, 0x54, 0x23);
- err += sn9c102_write_reg(cam, 0x66, 0x24);
- err += sn9c102_write_reg(cam, 0x76, 0x25);
- err += sn9c102_write_reg(cam, 0x85, 0x26);
- err += sn9c102_write_reg(cam, 0x94, 0x27);
- err += sn9c102_write_reg(cam, 0xa1, 0x28);
- err += sn9c102_write_reg(cam, 0xae, 0x29);
- err += sn9c102_write_reg(cam, 0xbb, 0x2a);
- err += sn9c102_write_reg(cam, 0xc7, 0x2b);
- err += sn9c102_write_reg(cam, 0xd3, 0x2c);
- err += sn9c102_write_reg(cam, 0xde, 0x2d);
- err += sn9c102_write_reg(cam, 0xea, 0x2e);
- err += sn9c102_write_reg(cam, 0xf4, 0x2f);
- err += sn9c102_write_reg(cam, 0xff, 0x30);
- err += sn9c102_write_reg(cam, 0x00, 0x3F);
- err += sn9c102_write_reg(cam, 0xC7, 0x40);
- err += sn9c102_write_reg(cam, 0x01, 0x41);
- err += sn9c102_write_reg(cam, 0x44, 0x42);
- err += sn9c102_write_reg(cam, 0x00, 0x43);
- err += sn9c102_write_reg(cam, 0x44, 0x44);
- err += sn9c102_write_reg(cam, 0x00, 0x45);
- err += sn9c102_write_reg(cam, 0x44, 0x46);
- err += sn9c102_write_reg(cam, 0x00, 0x47);
- err += sn9c102_write_reg(cam, 0xC7, 0x48);
- err += sn9c102_write_reg(cam, 0x01, 0x49);
- err += sn9c102_write_reg(cam, 0xC7, 0x4A);
- err += sn9c102_write_reg(cam, 0x01, 0x4B);
- err += sn9c102_write_reg(cam, 0xC7, 0x4C);
- err += sn9c102_write_reg(cam, 0x01, 0x4D);
- err += sn9c102_write_reg(cam, 0x44, 0x4E);
- err += sn9c102_write_reg(cam, 0x00, 0x4F);
- err += sn9c102_write_reg(cam, 0x44, 0x50);
- err += sn9c102_write_reg(cam, 0x00, 0x51);
- err += sn9c102_write_reg(cam, 0x44, 0x52);
- err += sn9c102_write_reg(cam, 0x00, 0x53);
- err += sn9c102_write_reg(cam, 0xC7, 0x54);
- err += sn9c102_write_reg(cam, 0x01, 0x55);
- err += sn9c102_write_reg(cam, 0xC7, 0x56);
- err += sn9c102_write_reg(cam, 0x01, 0x57);
- err += sn9c102_write_reg(cam, 0xC7, 0x58);
- err += sn9c102_write_reg(cam, 0x01, 0x59);
- err += sn9c102_write_reg(cam, 0x44, 0x5A);
- err += sn9c102_write_reg(cam, 0x00, 0x5B);
- err += sn9c102_write_reg(cam, 0x44, 0x5C);
- err += sn9c102_write_reg(cam, 0x00, 0x5D);
- err += sn9c102_write_reg(cam, 0x44, 0x5E);
- err += sn9c102_write_reg(cam, 0x00, 0x5F);
- err += sn9c102_write_reg(cam, 0xC7, 0x60);
- err += sn9c102_write_reg(cam, 0x01, 0x61);
- err += sn9c102_write_reg(cam, 0xC7, 0x62);
- err += sn9c102_write_reg(cam, 0x01, 0x63);
- err += sn9c102_write_reg(cam, 0xC7, 0x64);
- err += sn9c102_write_reg(cam, 0x01, 0x65);
- err += sn9c102_write_reg(cam, 0x44, 0x66);
- err += sn9c102_write_reg(cam, 0x00, 0x67);
- err += sn9c102_write_reg(cam, 0x44, 0x68);
- err += sn9c102_write_reg(cam, 0x00, 0x69);
- err += sn9c102_write_reg(cam, 0x44, 0x6A);
- err += sn9c102_write_reg(cam, 0x00, 0x6B);
- err += sn9c102_write_reg(cam, 0xC7, 0x6C);
- err += sn9c102_write_reg(cam, 0x01, 0x6D);
- err += sn9c102_write_reg(cam, 0xC7, 0x6E);
- err += sn9c102_write_reg(cam, 0x01, 0x6F);
- err += sn9c102_write_reg(cam, 0xC7, 0x70);
- err += sn9c102_write_reg(cam, 0x01, 0x71);
- err += sn9c102_write_reg(cam, 0x44, 0x72);
- err += sn9c102_write_reg(cam, 0x00, 0x73);
- err += sn9c102_write_reg(cam, 0x44, 0x74);
- err += sn9c102_write_reg(cam, 0x00, 0x75);
- err += sn9c102_write_reg(cam, 0x44, 0x76);
- err += sn9c102_write_reg(cam, 0x00, 0x77);
- err += sn9c102_write_reg(cam, 0xC7, 0x78);
- err += sn9c102_write_reg(cam, 0x01, 0x79);
- err += sn9c102_write_reg(cam, 0xC7, 0x7A);
- err += sn9c102_write_reg(cam, 0x01, 0x7B);
- err += sn9c102_write_reg(cam, 0xC7, 0x7C);
- err += sn9c102_write_reg(cam, 0x01, 0x7D);
- err += sn9c102_write_reg(cam, 0x44, 0x7E);
- err += sn9c102_write_reg(cam, 0x00, 0x7F);
- err += sn9c102_write_reg(cam, 0x14, 0x84);
- err += sn9c102_write_reg(cam, 0x00, 0x85);
- err += sn9c102_write_reg(cam, 0x27, 0x86);
- err += sn9c102_write_reg(cam, 0x00, 0x87);
- err += sn9c102_write_reg(cam, 0x07, 0x88);
- err += sn9c102_write_reg(cam, 0x00, 0x89);
- err += sn9c102_write_reg(cam, 0xEC, 0x8A);
- err += sn9c102_write_reg(cam, 0x0f, 0x8B);
- err += sn9c102_write_reg(cam, 0xD8, 0x8C);
- err += sn9c102_write_reg(cam, 0x0f, 0x8D);
- err += sn9c102_write_reg(cam, 0x3D, 0x8E);
- err += sn9c102_write_reg(cam, 0x00, 0x8F);
- err += sn9c102_write_reg(cam, 0x3D, 0x90);
- err += sn9c102_write_reg(cam, 0x00, 0x91);
- err += sn9c102_write_reg(cam, 0xCD, 0x92);
- err += sn9c102_write_reg(cam, 0x0f, 0x93);
- err += sn9c102_write_reg(cam, 0xf7, 0x94);
- err += sn9c102_write_reg(cam, 0x0f, 0x95);
- err += sn9c102_write_reg(cam, 0x0C, 0x96);
- err += sn9c102_write_reg(cam, 0x00, 0x97);
- err += sn9c102_write_reg(cam, 0x00, 0x98);
- err += sn9c102_write_reg(cam, 0x66, 0x99);
- err += sn9c102_write_reg(cam, 0x05, 0x9A);
- err += sn9c102_write_reg(cam, 0x00, 0x9B);
- err += sn9c102_write_reg(cam, 0x04, 0x9C);
- err += sn9c102_write_reg(cam, 0x00, 0x9D);
- err += sn9c102_write_reg(cam, 0x08, 0x9E);
- err += sn9c102_write_reg(cam, 0x00, 0x9F);
- err += sn9c102_write_reg(cam, 0x2D, 0xC0);
- err += sn9c102_write_reg(cam, 0x2D, 0xC1);
- err += sn9c102_write_reg(cam, 0x3A, 0xC2);
- err += sn9c102_write_reg(cam, 0x05, 0xC3);
- err += sn9c102_write_reg(cam, 0x04, 0xC4);
- err += sn9c102_write_reg(cam, 0x3F, 0xC5);
- err += sn9c102_write_reg(cam, 0x00, 0xC6);
- err += sn9c102_write_reg(cam, 0x00, 0xC7);
- err += sn9c102_write_reg(cam, 0x50, 0xC8);
- err += sn9c102_write_reg(cam, 0x3C, 0xC9);
- err += sn9c102_write_reg(cam, 0x28, 0xCA);
- err += sn9c102_write_reg(cam, 0xD8, 0xCB);
- err += sn9c102_write_reg(cam, 0x14, 0xCC);
- err += sn9c102_write_reg(cam, 0xEC, 0xCD);
- err += sn9c102_write_reg(cam, 0x32, 0xCE);
- err += sn9c102_write_reg(cam, 0xDD, 0xCF);
- err += sn9c102_write_reg(cam, 0x32, 0xD0);
- err += sn9c102_write_reg(cam, 0xDD, 0xD1);
- err += sn9c102_write_reg(cam, 0x6A, 0xD2);
- err += sn9c102_write_reg(cam, 0x50, 0xD3);
- err += sn9c102_write_reg(cam, 0x00, 0xD4);
- err += sn9c102_write_reg(cam, 0x00, 0xD5);
- err += sn9c102_write_reg(cam, 0x00, 0xD6);
+ err = sn9c102_write_const_regs(cam, {0x40, 0x02}, {0x00, 0x03},
+ {0x1a, 0x04}, {0x03, 0x10},
+ {0x08, 0x14}, {0x20, 0x17},
+ {0x8b, 0x18}, {0x00, 0x19},
+ {0x1d, 0x1a}, {0x10, 0x1b},
+ {0x02, 0x1c}, {0x03, 0x1d},
+ {0x0f, 0x1e}, {0x0c, 0x1f},
+ {0x00, 0x20}, {0x29, 0x21},
+ {0x40, 0x22}, {0x54, 0x23},
+ {0x66, 0x24}, {0x76, 0x25},
+ {0x85, 0x26}, {0x94, 0x27},
+ {0xa1, 0x28}, {0xae, 0x29},
+ {0xbb, 0x2a}, {0xc7, 0x2b},
+ {0xd3, 0x2c}, {0xde, 0x2d},
+ {0xea, 0x2e}, {0xf4, 0x2f},
+ {0xff, 0x30}, {0x00, 0x3F},
+ {0xC7, 0x40}, {0x01, 0x41},
+ {0x44, 0x42}, {0x00, 0x43},
+ {0x44, 0x44}, {0x00, 0x45},
+ {0x44, 0x46}, {0x00, 0x47},
+ {0xC7, 0x48}, {0x01, 0x49},
+ {0xC7, 0x4A}, {0x01, 0x4B},
+ {0xC7, 0x4C}, {0x01, 0x4D},
+ {0x44, 0x4E}, {0x00, 0x4F},
+ {0x44, 0x50}, {0x00, 0x51},
+ {0x44, 0x52}, {0x00, 0x53},
+ {0xC7, 0x54}, {0x01, 0x55},
+ {0xC7, 0x56}, {0x01, 0x57},
+ {0xC7, 0x58}, {0x01, 0x59},
+ {0x44, 0x5A}, {0x00, 0x5B},
+ {0x44, 0x5C}, {0x00, 0x5D},
+ {0x44, 0x5E}, {0x00, 0x5F},
+ {0xC7, 0x60}, {0x01, 0x61},
+ {0xC7, 0x62}, {0x01, 0x63},
+ {0xC7, 0x64}, {0x01, 0x65},
+ {0x44, 0x66}, {0x00, 0x67},
+ {0x44, 0x68}, {0x00, 0x69},
+ {0x44, 0x6A}, {0x00, 0x6B},
+ {0xC7, 0x6C}, {0x01, 0x6D},
+ {0xC7, 0x6E}, {0x01, 0x6F},
+ {0xC7, 0x70}, {0x01, 0x71},
+ {0x44, 0x72}, {0x00, 0x73},
+ {0x44, 0x74}, {0x00, 0x75},
+ {0x44, 0x76}, {0x00, 0x77},
+ {0xC7, 0x78}, {0x01, 0x79},
+ {0xC7, 0x7A}, {0x01, 0x7B},
+ {0xC7, 0x7C}, {0x01, 0x7D},
+ {0x44, 0x7E}, {0x00, 0x7F},
+ {0x14, 0x84}, {0x00, 0x85},
+ {0x27, 0x86}, {0x00, 0x87},
+ {0x07, 0x88}, {0x00, 0x89},
+ {0xEC, 0x8A}, {0x0f, 0x8B},
+ {0xD8, 0x8C}, {0x0f, 0x8D},
+ {0x3D, 0x8E}, {0x00, 0x8F},
+ {0x3D, 0x90}, {0x00, 0x91},
+ {0xCD, 0x92}, {0x0f, 0x93},
+ {0xf7, 0x94}, {0x0f, 0x95},
+ {0x0C, 0x96}, {0x00, 0x97},
+ {0x00, 0x98}, {0x66, 0x99},
+ {0x05, 0x9A}, {0x00, 0x9B},
+ {0x04, 0x9C}, {0x00, 0x9D},
+ {0x08, 0x9E}, {0x00, 0x9F},
+ {0x2D, 0xC0}, {0x2D, 0xC1},
+ {0x3A, 0xC2}, {0x05, 0xC3},
+ {0x04, 0xC4}, {0x3F, 0xC5},
+ {0x00, 0xC6}, {0x00, 0xC7},
+ {0x50, 0xC8}, {0x3C, 0xC9},
+ {0x28, 0xCA}, {0xD8, 0xCB},
+ {0x14, 0xCC}, {0xEC, 0xCD},
+ {0x32, 0xCE}, {0xDD, 0xCF},
+ {0x32, 0xD0}, {0xDD, 0xD1},
+ {0x6A, 0xD2}, {0x50, 0xD3},
+ {0x00, 0xD4}, {0x00, 0xD5},
+ {0x00, 0xD6});
err += sn9c102_i2c_write(cam, 0x12, 0x80);
err += sn9c102_i2c_write(cam, 0x11, 0x09);
err += sn9c102_i2c_write(cam, 0x00, 0x0A);
- err += sn9c102_i2c_write(cam, 0x01, 0x78);
- err += sn9c102_i2c_write(cam, 0x02, 0x90);
+ err += sn9c102_i2c_write(cam, 0x01, 0x80);
+ err += sn9c102_i2c_write(cam, 0x02, 0x80);
err += sn9c102_i2c_write(cam, 0x03, 0x00);
err += sn9c102_i2c_write(cam, 0x04, 0x00);
err += sn9c102_i2c_write(cam, 0x05, 0x08);
@@ -198,7 +122,7 @@ static int ov7660_init(struct sn9c102_device* cam)
err += sn9c102_i2c_write(cam, 0x10, 0x20);
err += sn9c102_i2c_write(cam, 0x11, 0x03);
err += sn9c102_i2c_write(cam, 0x12, 0x05);
- err += sn9c102_i2c_write(cam, 0x13, 0xF8);
+ err += sn9c102_i2c_write(cam, 0x13, 0xC7);
err += sn9c102_i2c_write(cam, 0x14, 0x2C);
err += sn9c102_i2c_write(cam, 0x15, 0x00);
err += sn9c102_i2c_write(cam, 0x16, 0x02);
@@ -238,7 +162,7 @@ static int ov7660_init(struct sn9c102_device* cam)
err += sn9c102_i2c_write(cam, 0x38, 0x02);
err += sn9c102_i2c_write(cam, 0x39, 0x43);
err += sn9c102_i2c_write(cam, 0x3A, 0x00);
- err += sn9c102_i2c_write(cam, 0x3B, 0x02);
+ err += sn9c102_i2c_write(cam, 0x3B, 0x0A);
err += sn9c102_i2c_write(cam, 0x3C, 0x6C);
err += sn9c102_i2c_write(cam, 0x3D, 0x99);
err += sn9c102_i2c_write(cam, 0x3E, 0x0E);
@@ -357,25 +281,34 @@ static int ov7660_get_ctrl(struct sn9c102_device* cam,
return -EIO;
break;
case V4L2_CID_DO_WHITE_BALANCE:
- ctrl->value = sn9c102_pread_reg(cam, 0x02);
+ if ((ctrl->value = sn9c102_read_reg(cam, 0x02)) < 0)
+ return -EIO;
ctrl->value = (ctrl->value & 0x04) ? 1 : 0;
break;
case V4L2_CID_RED_BALANCE:
- ctrl->value = sn9c102_pread_reg(cam, 0x05);
+ if ((ctrl->value = sn9c102_read_reg(cam, 0x05)) < 0)
+ return -EIO;
ctrl->value &= 0x7f;
break;
case V4L2_CID_BLUE_BALANCE:
- ctrl->value = sn9c102_pread_reg(cam, 0x06);
+ if ((ctrl->value = sn9c102_read_reg(cam, 0x06)) < 0)
+ return -EIO;
ctrl->value &= 0x7f;
break;
case SN9C102_V4L2_CID_GREEN_BALANCE:
- ctrl->value = sn9c102_pread_reg(cam, 0x07);
+ if ((ctrl->value = sn9c102_read_reg(cam, 0x07)) < 0)
+ return -EIO;
ctrl->value &= 0x7f;
break;
+ case SN9C102_V4L2_CID_BAND_FILTER:
+ if ((ctrl->value = sn9c102_i2c_read(cam, 0x3b)) < 0)
+ return -EIO;
+ ctrl->value &= 0x08;
+ break;
case V4L2_CID_GAIN:
if ((ctrl->value = sn9c102_i2c_read(cam, 0x00)) < 0)
return -EIO;
- ctrl->value &= 0x7f;
+ ctrl->value &= 0x1f;
break;
case V4L2_CID_AUTOGAIN:
if ((ctrl->value = sn9c102_i2c_read(cam, 0x13)) < 0)
@@ -411,12 +344,15 @@ static int ov7660_set_ctrl(struct sn9c102_device* cam,
case SN9C102_V4L2_CID_GREEN_BALANCE:
err += sn9c102_write_reg(cam, ctrl->value, 0x07);
break;
+ case SN9C102_V4L2_CID_BAND_FILTER:
+ err += sn9c102_i2c_write(cam, ctrl->value << 3, 0x3b);
+ break;
case V4L2_CID_GAIN:
- err += sn9c102_i2c_write(cam, 0x00, ctrl->value);
+ err += sn9c102_i2c_write(cam, 0x00, 0x60 + ctrl->value);
break;
case V4L2_CID_AUTOGAIN:
- err += sn9c102_i2c_write(cam, 0x13, 0xf0 | ctrl->value |
- (ctrl->value << 1));
+ err += sn9c102_i2c_write(cam, 0x13, 0xc0 |
+ (ctrl->value * 0x07));
break;
default:
return -EINVAL;
@@ -462,7 +398,7 @@ static int ov7660_set_pix_format(struct sn9c102_device* cam,
}
-static struct sn9c102_sensor ov7660 = {
+static const struct sn9c102_sensor ov7660 = {
.name = "OV7660",
.maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
.supported_bridge = BRIDGE_SN9C105 | BRIDGE_SN9C120,
@@ -477,9 +413,9 @@ static struct sn9c102_sensor ov7660 = {
.type = V4L2_CTRL_TYPE_INTEGER,
.name = "global gain",
.minimum = 0x00,
- .maximum = 0x7f,
+ .maximum = 0x1f,
.step = 0x01,
- .default_value = 0x0a,
+ .default_value = 0x09,
.flags = 0,
},
{
@@ -489,7 +425,7 @@ static struct sn9c102_sensor ov7660 = {
.minimum = 0x00,
.maximum = 0xff,
.step = 0x01,
- .default_value = 0x50,
+ .default_value = 0x27,
.flags = 0,
},
{
@@ -509,7 +445,7 @@ static struct sn9c102_sensor ov7660 = {
.minimum = 0x00,
.maximum = 0x7f,
.step = 0x01,
- .default_value = 0x1f,
+ .default_value = 0x14,
.flags = 0,
},
{
@@ -519,7 +455,7 @@ static struct sn9c102_sensor ov7660 = {
.minimum = 0x00,
.maximum = 0x7f,
.step = 0x01,
- .default_value = 0x1e,
+ .default_value = 0x14,
.flags = 0,
},
{
@@ -529,7 +465,7 @@ static struct sn9c102_sensor ov7660 = {
.minimum = 0x00,
.maximum = 0x01,
.step = 0x01,
- .default_value = 0x00,
+ .default_value = 0x01,
.flags = 0,
},
{
@@ -539,7 +475,17 @@ static struct sn9c102_sensor ov7660 = {
.minimum = 0x00,
.maximum = 0x7f,
.step = 0x01,
- .default_value = 0x20,
+ .default_value = 0x14,
+ .flags = 0,
+ },
+ {
+ .id = SN9C102_V4L2_CID_BAND_FILTER,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "band filter",
+ .minimum = 0x00,
+ .maximum = 0x01,
+ .step = 0x01,
+ .default_value = 0x00,
.flags = 0,
},
},
@@ -572,13 +518,11 @@ static struct sn9c102_sensor ov7660 = {
int sn9c102_probe_ov7660(struct sn9c102_device* cam)
{
- int pid, ver, err = 0;
+ int pid, ver, err;
- err += sn9c102_write_reg(cam, 0x01, 0xf1);
- err += sn9c102_write_reg(cam, 0x00, 0xf1);
- err += sn9c102_write_reg(cam, 0x01, 0x01);
- err += sn9c102_write_reg(cam, 0x00, 0x01);
- err += sn9c102_write_reg(cam, 0x28, 0x17);
+ err = sn9c102_write_const_regs(cam, {0x01, 0xf1}, {0x00, 0xf1},
+ {0x01, 0x01}, {0x00, 0x01},
+ {0x28, 0x17});
pid = sn9c102_i2c_try_read(cam, &ov7660, 0x0a);
ver = sn9c102_i2c_try_read(cam, &ov7660, 0x0b);
@@ -586,6 +530,7 @@ int sn9c102_probe_ov7660(struct sn9c102_device* cam)
return -EIO;
if (pid != 0x76 || ver != 0x60)
return -ENODEV;
+
sn9c102_attach_sensor(cam, &ov7660);
return 0;
diff --git a/linux/drivers/media/video/sn9c102/sn9c102_pas106b.c b/linux/drivers/media/video/sn9c102/sn9c102_pas106b.c
index 8d79a5fae..360f2a848 100644
--- a/linux/drivers/media/video/sn9c102/sn9c102_pas106b.c
+++ b/linux/drivers/media/video/sn9c102/sn9c102_pas106b.c
@@ -23,19 +23,13 @@
#include "sn9c102_sensor.h"
-static struct sn9c102_sensor pas106b;
-
-
static int pas106b_init(struct sn9c102_device* cam)
{
int err = 0;
- err += sn9c102_write_reg(cam, 0x00, 0x10);
- err += sn9c102_write_reg(cam, 0x00, 0x11);
- err += sn9c102_write_reg(cam, 0x00, 0x14);
- err += sn9c102_write_reg(cam, 0x20, 0x17);
- err += sn9c102_write_reg(cam, 0x20, 0x19);
- err += sn9c102_write_reg(cam, 0x09, 0x18);
+ err = sn9c102_write_const_regs(cam, {0x00, 0x10}, {0x00, 0x11},
+ {0x00, 0x14}, {0x20, 0x17},
+ {0x20, 0x19}, {0x09, 0x18});
err += sn9c102_i2c_write(cam, 0x02, 0x0c);
err += sn9c102_i2c_write(cam, 0x05, 0x5a);
@@ -169,10 +163,10 @@ static int pas106b_set_pix_format(struct sn9c102_device* cam,
}
-static struct sn9c102_sensor pas106b = {
+static const struct sn9c102_sensor pas106b = {
.name = "PAS106B",
.maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
- .supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102 | BRIDGE_SN9C103,
+ .supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102,
.sysfs_ops = SN9C102_I2C_READ | SN9C102_I2C_WRITE,
.frequency = SN9C102_I2C_400KHZ | SN9C102_I2C_100KHZ,
.interface = SN9C102_I2C_2WIRES,
@@ -279,22 +273,21 @@ static struct sn9c102_sensor pas106b = {
int sn9c102_probe_pas106b(struct sn9c102_device* cam)
{
- int r0 = 0, r1 = 0, err = 0;
+ int r0 = 0, r1 = 0;
unsigned int pid = 0;
/*
Minimal initialization to enable the I2C communication
NOTE: do NOT change the values!
*/
- err += sn9c102_write_reg(cam, 0x01, 0x01); /* sensor power down */
- err += sn9c102_write_reg(cam, 0x00, 0x01); /* sensor power on */
- err += sn9c102_write_reg(cam, 0x28, 0x17); /* sensor clock at 24 MHz */
- if (err)
+ if (sn9c102_write_const_regs(cam,
+ {0x01, 0x01}, /* sensor power down */
+ {0x00, 0x01}, /* sensor power on */
+ {0x28, 0x17})) /* sensor clock at 24 MHz */
return -EIO;
r0 = sn9c102_i2c_try_read(cam, &pas106b, 0x00);
r1 = sn9c102_i2c_try_read(cam, &pas106b, 0x01);
-
if (r0 < 0 || r1 < 0)
return -EIO;
diff --git a/linux/drivers/media/video/sn9c102/sn9c102_pas202bcb.c b/linux/drivers/media/video/sn9c102/sn9c102_pas202bcb.c
index 7894f01b5..ca4a1506e 100644
--- a/linux/drivers/media/video/sn9c102/sn9c102_pas202bcb.c
+++ b/linux/drivers/media/video/sn9c102/sn9c102_pas202bcb.c
@@ -28,9 +28,6 @@
#include "sn9c102_sensor.h"
-static struct sn9c102_sensor pas202bcb;
-
-
static int pas202bcb_init(struct sn9c102_device* cam)
{
int err = 0;
@@ -38,47 +35,28 @@ static int pas202bcb_init(struct sn9c102_device* cam)
switch (sn9c102_get_bridge(cam)) {
case BRIDGE_SN9C101:
case BRIDGE_SN9C102:
- err += sn9c102_write_reg(cam, 0x00, 0x10);
- err += sn9c102_write_reg(cam, 0x00, 0x11);
- err += sn9c102_write_reg(cam, 0x00, 0x14);
- err += sn9c102_write_reg(cam, 0x20, 0x17);
- err += sn9c102_write_reg(cam, 0x30, 0x19);
- err += sn9c102_write_reg(cam, 0x09, 0x18);
+ err = sn9c102_write_const_regs(cam, {0x00, 0x10}, {0x00, 0x11},
+ {0x00, 0x14}, {0x20, 0x17},
+ {0x30, 0x19}, {0x09, 0x18});
break;
case BRIDGE_SN9C103:
- err += sn9c102_write_reg(cam, 0x00, 0x02);
- err += sn9c102_write_reg(cam, 0x00, 0x03);
- err += sn9c102_write_reg(cam, 0x1a, 0x04);
- err += sn9c102_write_reg(cam, 0x20, 0x05);
- err += sn9c102_write_reg(cam, 0x20, 0x06);
- err += sn9c102_write_reg(cam, 0x20, 0x07);
- err += sn9c102_write_reg(cam, 0x00, 0x10);
- err += sn9c102_write_reg(cam, 0x00, 0x11);
- err += sn9c102_write_reg(cam, 0x00, 0x14);
- err += sn9c102_write_reg(cam, 0x20, 0x17);
- err += sn9c102_write_reg(cam, 0x30, 0x19);
- err += sn9c102_write_reg(cam, 0x09, 0x18);
- err += sn9c102_write_reg(cam, 0x02, 0x1c);
- err += sn9c102_write_reg(cam, 0x03, 0x1d);
- err += sn9c102_write_reg(cam, 0x0f, 0x1e);
- err += sn9c102_write_reg(cam, 0x0c, 0x1f);
- err += sn9c102_write_reg(cam, 0x00, 0x20);
- err += sn9c102_write_reg(cam, 0x10, 0x21);
- err += sn9c102_write_reg(cam, 0x20, 0x22);
- err += sn9c102_write_reg(cam, 0x30, 0x23);
- err += sn9c102_write_reg(cam, 0x40, 0x24);
- err += sn9c102_write_reg(cam, 0x50, 0x25);
- err += sn9c102_write_reg(cam, 0x60, 0x26);
- err += sn9c102_write_reg(cam, 0x70, 0x27);
- err += sn9c102_write_reg(cam, 0x80, 0x28);
- err += sn9c102_write_reg(cam, 0x90, 0x29);
- err += sn9c102_write_reg(cam, 0xa0, 0x2a);
- err += sn9c102_write_reg(cam, 0xb0, 0x2b);
- err += sn9c102_write_reg(cam, 0xc0, 0x2c);
- err += sn9c102_write_reg(cam, 0xd0, 0x2d);
- err += sn9c102_write_reg(cam, 0xe0, 0x2e);
- err += sn9c102_write_reg(cam, 0xf0, 0x2f);
- err += sn9c102_write_reg(cam, 0xff, 0x30);
+ err = sn9c102_write_const_regs(cam, {0x00, 0x02}, {0x00, 0x03},
+ {0x1a, 0x04}, {0x20, 0x05},
+ {0x20, 0x06}, {0x20, 0x07},
+ {0x00, 0x10}, {0x00, 0x11},
+ {0x00, 0x14}, {0x20, 0x17},
+ {0x30, 0x19}, {0x09, 0x18},
+ {0x02, 0x1c}, {0x03, 0x1d},
+ {0x0f, 0x1e}, {0x0c, 0x1f},
+ {0x00, 0x20}, {0x10, 0x21},
+ {0x20, 0x22}, {0x30, 0x23},
+ {0x40, 0x24}, {0x50, 0x25},
+ {0x60, 0x26}, {0x70, 0x27},
+ {0x80, 0x28}, {0x90, 0x29},
+ {0xa0, 0x2a}, {0xb0, 0x2b},
+ {0xc0, 0x2c}, {0xd0, 0x2d},
+ {0xe0, 0x2e}, {0xf0, 0x2f},
+ {0xff, 0x30});
break;
default:
break;
@@ -218,7 +196,7 @@ static int pas202bcb_set_crop(struct sn9c102_device* cam,
}
-static struct sn9c102_sensor pas202bcb = {
+static const struct sn9c102_sensor pas202bcb = {
.name = "PAS202BCB",
.maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
.supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102 | BRIDGE_SN9C103,
@@ -328,15 +306,14 @@ int sn9c102_probe_pas202bcb(struct sn9c102_device* cam)
switch (sn9c102_get_bridge(cam)) {
case BRIDGE_SN9C101:
case BRIDGE_SN9C102:
- err += sn9c102_write_reg(cam, 0x01, 0x01); /* power down */
- err += sn9c102_write_reg(cam, 0x40, 0x01); /* power on */
- err += sn9c102_write_reg(cam, 0x28, 0x17); /* clock 24 MHz */
+ err = sn9c102_write_const_regs(cam,
+ {0x01, 0x01}, /* power down */
+ {0x40, 0x01}, /* power on */
+ {0x28, 0x17});/* clock 24 MHz */
break;
case BRIDGE_SN9C103: /* do _not_ change anything! */
- err += sn9c102_write_reg(cam, 0x09, 0x01);
- err += sn9c102_write_reg(cam, 0x44, 0x01);
- err += sn9c102_write_reg(cam, 0x44, 0x02);
- err += sn9c102_write_reg(cam, 0x29, 0x17);
+ err = sn9c102_write_const_regs(cam, {0x09, 0x01}, {0x44, 0x01},
+ {0x44, 0x02}, {0x29, 0x17});
break;
default:
break;
diff --git a/linux/drivers/media/video/sn9c102/sn9c102_sensor.h b/linux/drivers/media/video/sn9c102/sn9c102_sensor.h
index 4fceceab6..d5fffc569 100644
--- a/linux/drivers/media/video/sn9c102/sn9c102_sensor.h
+++ b/linux/drivers/media/video/sn9c102/sn9c102_sensor.h
@@ -22,12 +22,12 @@
#define _SN9C102_SENSOR_H_
#include <linux/usb.h>
-#include "compat.h"
-#include <linux/videodev.h>
+#include <linux/videodev2.h>
#include <linux/device.h>
#include <linux/stddef.h>
#include <linux/errno.h>
#include <asm/types.h>
+#include "compat.h"
struct sn9c102_device;
struct sn9c102_sensor;
@@ -75,7 +75,7 @@ sn9c102_match_id(struct sn9c102_device* cam, const struct usb_device_id *id);
/* Attach a probed sensor to the camera. */
extern void
sn9c102_attach_sensor(struct sn9c102_device* cam,
- struct sn9c102_sensor* sensor);
+ const struct sn9c102_sensor* sensor);
/*
Read/write routines: they always return -1 on error, 0 or the read value
@@ -86,10 +86,11 @@ sn9c102_attach_sensor(struct sn9c102_device* cam,
*/
/* The "try" I2C I/O versions are used when probing the sensor */
-extern int sn9c102_i2c_try_write(struct sn9c102_device*,struct sn9c102_sensor*,
- u8 address, u8 value);
-extern int sn9c102_i2c_try_read(struct sn9c102_device*,struct sn9c102_sensor*,
- u8 address);
+extern int sn9c102_i2c_try_write(struct sn9c102_device*,
+ const struct sn9c102_sensor*, u8 address,
+ u8 value);
+extern int sn9c102_i2c_try_read(struct sn9c102_device*,
+ const struct sn9c102_sensor*, u8 address);
/*
These must be used if and only if the sensor doesn't implement the standard
@@ -103,21 +104,31 @@ extern int sn9c102_i2c_try_read(struct sn9c102_device*,struct sn9c102_sensor*,
byte.
*/
extern int sn9c102_i2c_try_raw_write(struct sn9c102_device* cam,
- struct sn9c102_sensor* sensor, u8 n,
+ const struct sn9c102_sensor* sensor, u8 n,
u8 data0, u8 data1, u8 data2, u8 data3,
u8 data4, u8 data5);
extern int sn9c102_i2c_try_raw_read(struct sn9c102_device* cam,
- struct sn9c102_sensor* sensor, u8 data0,
- u8 data1, u8 n, u8 buffer[]);
+ const struct sn9c102_sensor* sensor,
+ u8 data0, u8 data1, u8 n, u8 buffer[]);
/* To be used after the sensor struct has been attached to the camera struct */
extern int sn9c102_i2c_write(struct sn9c102_device*, u8 address, u8 value);
extern int sn9c102_i2c_read(struct sn9c102_device*, u8 address);
/* I/O on registers in the bridge. Could be used by the sensor methods too */
-extern int sn9c102_write_regs(struct sn9c102_device*, u8* buff, u16 index);
-extern int sn9c102_write_reg(struct sn9c102_device*, u8 value, u16 index);
+extern int sn9c102_read_reg(struct sn9c102_device*, u16 index);
extern int sn9c102_pread_reg(struct sn9c102_device*, u16 index);
+extern int sn9c102_write_reg(struct sn9c102_device*, u8 value, u16 index);
+extern int sn9c102_write_regs(struct sn9c102_device*, const u8 valreg[][2],
+ int count);
+/*
+ Write multiple registers with constant values. For example:
+ sn9c102_write_const_regs(cam, {0x00, 0x14}, {0x60, 0x17}, {0x0f, 0x18});
+ Register adresses must be < 256.
+*/
+#define sn9c102_write_const_regs(sn9c102_device, data...) \
+ ({ const static u8 _valreg[][2] = {data}; \
+ sn9c102_write_regs(sn9c102_device, _valreg, ARRAY_SIZE(_valreg)); })
/*****************************************************************************/
diff --git a/linux/drivers/media/video/sn9c102/sn9c102_tas5110c1b.c b/linux/drivers/media/video/sn9c102/sn9c102_tas5110c1b.c
index 90023ad63..e7d2de2ba 100644
--- a/linux/drivers/media/video/sn9c102/sn9c102_tas5110c1b.c
+++ b/linux/drivers/media/video/sn9c102/sn9c102_tas5110c1b.c
@@ -22,21 +22,14 @@
#include "sn9c102_sensor.h"
-static struct sn9c102_sensor tas5110c1b;
-
-
static int tas5110c1b_init(struct sn9c102_device* cam)
{
int err = 0;
- err += sn9c102_write_reg(cam, 0x01, 0x01);
- err += sn9c102_write_reg(cam, 0x44, 0x01);
- err += sn9c102_write_reg(cam, 0x00, 0x10);
- err += sn9c102_write_reg(cam, 0x00, 0x11);
- err += sn9c102_write_reg(cam, 0x0a, 0x14);
- err += sn9c102_write_reg(cam, 0x60, 0x17);
- err += sn9c102_write_reg(cam, 0x06, 0x18);
- err += sn9c102_write_reg(cam, 0xfb, 0x19);
+ err = sn9c102_write_const_regs(cam, {0x01, 0x01}, {0x44, 0x01},
+ {0x00, 0x10}, {0x00, 0x11},
+ {0x0a, 0x14}, {0x60, 0x17},
+ {0x06, 0x18}, {0xfb, 0x19});
err += sn9c102_i2c_write(cam, 0xc0, 0x80);
@@ -95,10 +88,10 @@ static int tas5110c1b_set_pix_format(struct sn9c102_device* cam,
}
-static struct sn9c102_sensor tas5110c1b = {
+static const struct sn9c102_sensor tas5110c1b = {
.name = "TAS5110C1B",
.maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
- .supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102 | BRIDGE_SN9C103,
+ .supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102,
.sysfs_ops = SN9C102_I2C_WRITE,
.frequency = SN9C102_I2C_100KHZ,
.interface = SN9C102_I2C_3WIRES,
@@ -146,7 +139,6 @@ int sn9c102_probe_tas5110c1b(struct sn9c102_device* cam)
const struct usb_device_id tas5110c1b_id_table[] = {
{ USB_DEVICE(0x0c45, 0x6001), },
{ USB_DEVICE(0x0c45, 0x6005), },
- { USB_DEVICE(0x0c45, 0x6007), },
{ USB_DEVICE(0x0c45, 0x60ab), },
{ }
};
diff --git a/linux/drivers/media/video/sn9c102/sn9c102_tas5110d.c b/linux/drivers/media/video/sn9c102/sn9c102_tas5110d.c
new file mode 100644
index 000000000..d32fdbccd
--- /dev/null
+++ b/linux/drivers/media/video/sn9c102/sn9c102_tas5110d.c
@@ -0,0 +1,118 @@
+/***************************************************************************
+ * Plug-in for TAS5110D image sensor connected to the SN9C1xx PC Camera *
+ * Controllers *
+ * *
+ * Copyright (C) 2007 by Luca Risolia <luca.risolia@studio.unibo.it> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the Free Software *
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
+ ***************************************************************************/
+
+#include "sn9c102_sensor.h"
+
+
+static int tas5110d_init(struct sn9c102_device* cam)
+{
+ int err;
+
+ err = sn9c102_write_const_regs(cam, {0x01, 0x01}, {0x04, 0x01},
+ {0x0a, 0x14}, {0x60, 0x17},
+ {0x06, 0x18}, {0xfb, 0x19});
+
+ err += sn9c102_i2c_write(cam, 0x9a, 0xca);
+
+ return err;
+}
+
+
+static int tas5110d_set_crop(struct sn9c102_device* cam,
+ const struct v4l2_rect* rect)
+{
+ struct sn9c102_sensor* s = sn9c102_get_sensor(cam);
+ int err = 0;
+ u8 h_start = (u8)(rect->left - s->cropcap.bounds.left) + 69,
+ v_start = (u8)(rect->top - s->cropcap.bounds.top) + 9;
+
+ err += sn9c102_write_reg(cam, h_start, 0x12);
+ err += sn9c102_write_reg(cam, v_start, 0x13);
+
+ err += sn9c102_write_reg(cam, 0x14, 0x1a);
+ err += sn9c102_write_reg(cam, 0x0a, 0x1b);
+
+ return err;
+}
+
+
+static int tas5110d_set_pix_format(struct sn9c102_device* cam,
+ const struct v4l2_pix_format* pix)
+{
+ int err = 0;
+
+ if (pix->pixelformat == V4L2_PIX_FMT_SN9C10X)
+ err += sn9c102_write_reg(cam, 0x3b, 0x19);
+ else
+ err += sn9c102_write_reg(cam, 0xfb, 0x19);
+
+ return err;
+}
+
+
+static const struct sn9c102_sensor tas5110d = {
+ .name = "TAS5110D",
+ .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
+ .supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102,
+ .sysfs_ops = SN9C102_I2C_WRITE,
+ .frequency = SN9C102_I2C_100KHZ,
+ .interface = SN9C102_I2C_2WIRES,
+ .i2c_slave_id = 0x61,
+ .init = &tas5110d_init,
+ .cropcap = {
+ .bounds = {
+ .left = 0,
+ .top = 0,
+ .width = 352,
+ .height = 288,
+ },
+ .defrect = {
+ .left = 0,
+ .top = 0,
+ .width = 352,
+ .height = 288,
+ },
+ },
+ .set_crop = &tas5110d_set_crop,
+ .pix_format = {
+ .width = 352,
+ .height = 288,
+ .pixelformat = V4L2_PIX_FMT_SBGGR8,
+ .priv = 8,
+ },
+ .set_pix_format = &tas5110d_set_pix_format
+};
+
+
+int sn9c102_probe_tas5110d(struct sn9c102_device* cam)
+{
+ const struct usb_device_id tas5110d_id_table[] = {
+ { USB_DEVICE(0x0c45, 0x6007), },
+ { }
+ };
+
+ if (!sn9c102_match_id(cam, tas5110d_id_table))
+ return -ENODEV;
+
+ sn9c102_attach_sensor(cam, &tas5110d);
+
+ return 0;
+}
diff --git a/linux/drivers/media/video/sn9c102/sn9c102_tas5130d1b.c b/linux/drivers/media/video/sn9c102/sn9c102_tas5130d1b.c
index cb1b318bc..56fb1d575 100644
--- a/linux/drivers/media/video/sn9c102/sn9c102_tas5130d1b.c
+++ b/linux/drivers/media/video/sn9c102/sn9c102_tas5130d1b.c
@@ -22,21 +22,14 @@
#include "sn9c102_sensor.h"
-static struct sn9c102_sensor tas5130d1b;
-
-
static int tas5130d1b_init(struct sn9c102_device* cam)
{
- int err = 0;
+ int err;
- err += sn9c102_write_reg(cam, 0x01, 0x01);
- err += sn9c102_write_reg(cam, 0x20, 0x17);
- err += sn9c102_write_reg(cam, 0x04, 0x01);
- err += sn9c102_write_reg(cam, 0x01, 0x10);
- err += sn9c102_write_reg(cam, 0x00, 0x11);
- err += sn9c102_write_reg(cam, 0x00, 0x14);
- err += sn9c102_write_reg(cam, 0x60, 0x17);
- err += sn9c102_write_reg(cam, 0x07, 0x18);
+ err = sn9c102_write_const_regs(cam, {0x01, 0x01}, {0x20, 0x17},
+ {0x04, 0x01}, {0x01, 0x10},
+ {0x00, 0x11}, {0x00, 0x14},
+ {0x60, 0x17}, {0x07, 0x18});
return err;
}
@@ -96,10 +89,10 @@ static int tas5130d1b_set_pix_format(struct sn9c102_device* cam,
}
-static struct sn9c102_sensor tas5130d1b = {
+static const struct sn9c102_sensor tas5130d1b = {
.name = "TAS5130D1B",
.maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
- .supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102 | BRIDGE_SN9C103,
+ .supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102,
.sysfs_ops = SN9C102_I2C_WRITE,
.frequency = SN9C102_I2C_100KHZ,
.interface = SN9C102_I2C_3WIRES,
diff --git a/linux/drivers/media/video/tda7432.c b/linux/drivers/media/video/tda7432.c
index 849309fff..3e9ca9ace 100644
--- a/linux/drivers/media/video/tda7432.c
+++ b/linux/drivers/media/video/tda7432.c
@@ -46,7 +46,6 @@
#include "compat.h"
#include <linux/videodev.h>
#include <linux/i2c.h>
-#include <linux/i2c-algo-bit.h>
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
#include "i2c-compat.h"
diff --git a/linux/drivers/media/video/tda8290.c b/linux/drivers/media/video/tda8290.c
index 109eb44a9..90ba0384e 100644
--- a/linux/drivers/media/video/tda8290.c
+++ b/linux/drivers/media/video/tda8290.c
@@ -466,7 +466,6 @@ static void set_audio(struct tuner *t)
char* mode;
t->tda827x_lpsel = 0;
- mode = "xx";
if (t->std & V4L2_STD_MN) {
t->sgIF = 92;
t->tda8290_easy_mode = 0x01;
@@ -496,8 +495,12 @@ static void set_audio(struct tuner *t)
t->sgIF = 20;
t->tda8290_easy_mode = 0x40;
mode = "LC";
+ } else {
+ t->sgIF = 124;
+ t->tda8290_easy_mode = 0x10;
+ mode = "xx";
}
- tuner_dbg("setting tda8290 to system %s\n", mode);
+ tuner_dbg("setting tda8290 to system %s\n", mode);
}
static void set_tv_freq(struct i2c_client *c, unsigned int freq)
@@ -640,6 +643,7 @@ int tda8290_init(struct i2c_client *c)
t->has_signal = has_signal;
t->standby = standby;
t->tda827x_lpsel = 0;
+ t->mode = V4L2_TUNER_ANALOG_TV;
tda8290_init_tuner(c);
tda8290_init_if(c);
diff --git a/linux/drivers/media/video/tda9875.c b/linux/drivers/media/video/tda9875.c
index c7fbfc1b3..12abefad7 100644
--- a/linux/drivers/media/video/tda9875.c
+++ b/linux/drivers/media/video/tda9875.c
@@ -28,7 +28,6 @@
#include <linux/videodev.h>
#include <media/v4l2-common.h>
#include <linux/i2c.h>
-#include <linux/i2c-algo-bit.h>
#include <linux/init.h>
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
diff --git a/linux/drivers/media/video/tvaudio.c b/linux/drivers/media/video/tvaudio.c
index cc885951e..4b4153939 100644
--- a/linux/drivers/media/video/tvaudio.c
+++ b/linux/drivers/media/video/tvaudio.c
@@ -26,7 +26,6 @@
#include "compat.h"
#include <linux/videodev.h>
#include <linux/i2c.h>
-#include <linux/i2c-algo-bit.h>
#include <linux/init.h>
#include <linux/smp_lock.h>
#include <linux/kthread.h>
diff --git a/linux/drivers/media/video/usbvideo/Kconfig b/linux/drivers/media/video/usbvideo/Kconfig
index a0fd82b92..e4cb99c1f 100644
--- a/linux/drivers/media/video/usbvideo/Kconfig
+++ b/linux/drivers/media/video/usbvideo/Kconfig
@@ -3,7 +3,7 @@ config VIDEO_USBVIDEO
config USB_VICAM
tristate "USB 3com HomeConnect (aka vicam) support (EXPERIMENTAL)"
- depends on USB && VIDEO_DEV && VIDEO_V4L1 && EXPERIMENTAL
+ depends on VIDEO_V4L1 && EXPERIMENTAL
select VIDEO_USBVIDEO
---help---
Say Y here if you have 3com homeconnect camera (vicam).
@@ -13,7 +13,7 @@ config USB_VICAM
config USB_IBMCAM
tristate "USB IBM (Xirlink) C-it Camera support"
- depends on USB && VIDEO_DEV && VIDEO_V4L1
+ depends on VIDEO_V4L1
select VIDEO_USBVIDEO
---help---
Say Y here if you want to connect a IBM "C-It" camera, also known as
@@ -28,7 +28,7 @@ config USB_IBMCAM
config USB_KONICAWC
tristate "USB Konica Webcam support"
- depends on USB && VIDEO_DEV && VIDEO_V4L1
+ depends on VIDEO_V4L1
select VIDEO_USBVIDEO
---help---
Say Y here if you want support for webcams based on a Konica
@@ -39,7 +39,7 @@ config USB_KONICAWC
config USB_QUICKCAM_MESSENGER
tristate "USB Logitech Quickcam Messenger"
- depends on USB && VIDEO_DEV && VIDEO_V4L1
+ depends on VIDEO_V4L1
select VIDEO_USBVIDEO
---help---
Say Y or M here to enable support for the USB Logitech Quickcam
diff --git a/linux/drivers/media/video/usbvision/Kconfig b/linux/drivers/media/video/usbvision/Kconfig
index c43a5d899..fc24ef05b 100644
--- a/linux/drivers/media/video/usbvision/Kconfig
+++ b/linux/drivers/media/video/usbvision/Kconfig
@@ -1,6 +1,6 @@
config VIDEO_USBVISION
tristate "USB video devices based on Nogatech NT1003/1004/1005"
- depends on I2C && VIDEO_V4L2 && USB
+ depends on I2C && VIDEO_V4L2
select VIDEO_TUNER
select VIDEO_SAA711X if VIDEO_HELPER_CHIPS_AUTO
---help---
diff --git a/linux/drivers/media/video/usbvision/usbvision-cards.c b/linux/drivers/media/video/usbvision/usbvision-cards.c
index b23672ad9..3a704d07b 100644
--- a/linux/drivers/media/video/usbvision/usbvision-cards.c
+++ b/linux/drivers/media/video/usbvision/usbvision-cards.c
@@ -1,6 +1,6 @@
/*
- * USBVISION.H
- * usbvision header file
+ * usbvision-cards.c
+ * usbvision cards definition file
*
* Copyright (c) 1999-2005 Joerg Heckenbach <joerg@heckenbach-aw.de>
*
@@ -29,147 +29,1060 @@
#include <media/v4l2-dev.h>
#include <media/tuner.h>
#include "usbvision.h"
+#include "usbvision-cards.h"
/* Supported Devices: A table for usbvision.c*/
struct usbvision_device_data_st usbvision_device_data[] = {
- {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"},
- {0x0a6f, 0x0400, -1, CODEC_SAA7113, 4, V4L2_STD_NTSC, 1, 0, 1, 0, 0, -1, -1, -1, -1, -1, "Xanboo"},
- {0x050d, 0x0106, -1, CODEC_SAA7113, 2, V4L2_STD_PAL, 1, 0, 1, 0, 0, -1, -1, 0, 3, 7, "Belkin USB VideoBus II Adapter"},
- {0x050d, 0x0207, -1, CODEC_SAA7111, 2, V4L2_STD_NTSC, 1, 0, 1, 0, 0, -1, -1, -1, -1, -1, "Belkin Components USB VideoBus"},
- {0x050d, 0x0208, -1, CODEC_SAA7113, 2, V4L2_STD_PAL, 1, 0, 1, 0, 0, -1, -1, 0, 3, 7, "Belkin USB VideoBus II"},
- {0x0571, 0x0002, 0, CODEC_SAA7111, 2, V4L2_STD_PAL, 0, 0, 1, 0, 0, -1, -1, -1, -1, 7, "echoFX InterView Lite"},
- {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"},
- {0x0573, 0x0400, -1, CODEC_SAA7113, 4, V4L2_STD_NTSC, 0, 0, 1, 0, 0, -1, -1, 0, 3, 7, "D-Link V100"},
- {0x0573, 0x2000, -1, CODEC_SAA7111, 2, V4L2_STD_NTSC, 1, 0, 1, 0, 0, -1, -1, -1, -1, -1, "X10 USB Camera"},
- {0x0573, 0x2d00, -1, CODEC_SAA7111, 2, V4L2_STD_PAL, 1, 0, 1, 0, 0, -1, -1, -1, 3, 7, "Hauppauge WinTV USB Live (PAL B/G)"},
- {0x0573, 0x2d01, -1, CODEC_SAA7113, 2, V4L2_STD_NTSC, 0, 0, 1, 0, 0, -1, -1, 0, 3, 7, "Hauppauge WinTV USB Live Pro (NTSC M/N)"},
- {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"},
- {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"},
- {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"},
- {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"},
- {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"},
- {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 (NTSC M/N)"},
- {0x0573, 0x4d01, -1, CODEC_SAA7111, 3, V4L2_STD_PAL, 1, 0, 1, 1, TUNER_PHILIPS_PAL, -1, -1, -1, -1, -1, "Hauppauge WinTV USB (PAL B/G)"},
- {0x0573, 0x4d02, -1, CODEC_SAA7111, 3, V4L2_STD_PAL, 1, 0, 1, 1, TUNER_PHILIPS_PAL, -1, -1, -1, -1, -1, "Hauppauge WinTV USB (PAL I)"},
- {0x0573, 0x4d03, -1, CODEC_SAA7111, 3, V4L2_STD_SECAM, 1, 0, 1, 1, TUNER_PHILIPS_SECAM, -1, -1, -1, -1, -1, "Hauppauge WinTV USB (PAL/SECAM L)"},
- {0x0573, 0x4d04, -1, CODEC_SAA7111, 3, V4L2_STD_PAL, 1, 0, 1, 1, TUNER_PHILIPS_PAL, -1, -1, -1, -1, -1, "Hauppauge WinTV USB (PAL D/K)"},
- {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)"},
- {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 B/G FM)"},
- {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 I FM)"},
- {0x0573, 0x4d14, -1, CODEC_SAA7111, 3, V4L2_STD_PAL, 1, 1, 1, 1, TUNER_PHILIPS_PAL, -1, -1, -1, -1, -1, "Hauppauge WinTV USB (PAL D/K FM)"},
- {0x0573, 0x4d2a, 0, CODEC_SAA7113, 3, V4L2_STD_NTSC, 1, 1, 1, 1, TUNER_MICROTUNE_4049FM5, -1, -1, 0, 3, 7, "Hauppauge WinTV USB Pro (NTSC M/N)"},
- {0x0573, 0x4d2b, 0, CODEC_SAA7113, 3, V4L2_STD_NTSC, 1, 1, 1, 1, TUNER_MICROTUNE_4049FM5, -1, -1, 0, 3, 7, "Hauppauge WinTV USB Pro (NTSC M/N)"},
- {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 Pro (PAL/SECAM B/G/I/D/K/L)"},
- {0x0573, 0x4d20, 0, CODEC_SAA7113, 3, V4L2_STD_NTSC, 1, 1, 1, 1, TUNER_PHILIPS_NTSC_M, -1, -1, 0, 3, 7, "Hauppauge WinTV USB Pro (NTSC M/N)"},
- {0x0573, 0x4d21, 0, CODEC_SAA7113, 3, V4L2_STD_PAL, 1, 0, 1, 1, TUNER_PHILIPS_PAL, -1, -1, 0, 3, 7, "Hauppauge WinTV USB Pro (PAL B/G)"},
- {0x0573, 0x4d22, 0, CODEC_SAA7113, 3, V4L2_STD_PAL, 1, 0, 1, 1, TUNER_PHILIPS_PAL, -1, -1, 0, 3, 7, "Hauppauge WinTV USB Pro (PAL I)"},
- {0x0573, 0x4d23, -1, CODEC_SAA7113, 3, V4L2_STD_SECAM, 1, 0, 1, 1, TUNER_PHILIPS_SECAM, -1, -1, 0, 3, 7, "Hauppauge WinTV USB Pro (PAL/SECAM L)"},
- {0x0573, 0x4d24, -1, CODEC_SAA7113, 3, V4L2_STD_PAL, 1, 0, 1, 1, TUNER_PHILIPS_PAL, -1, -1, 0, 3, 7, "Hauppauge WinTV USB Pro (PAL D/K)"},
- {0x0573, 0x4d25, -1, CODEC_SAA7113, 3, V4L2_STD_SECAM, 1, 0, 1, 1, TUNER_PHILIPS_SECAM, -1, -1, 0, 3, 7, "Hauppauge WinTV USB Pro (PAL/SECAM BGDK/I/L)"},
- {0x0573, 0x4d26, -1, CODEC_SAA7113, 3, V4L2_STD_SECAM, 1, 0, 1, 1, TUNER_PHILIPS_SECAM, -1, -1, 0, 3, 7, "Hauppauge WinTV USB Pro (PAL/SECAM BGDK/I/L)"},
- {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 Pro (PAL B/G)"},
- {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 Pro (PAL B/G,D/K)"},
- {0x0573, 0x4d29, -1, CODEC_SAA7113, 3, V4L2_STD_PAL, 1, 0, 1, 1, TUNER_PHILIPS_PAL, -1, -1, 0, 3, 7, "Hauppauge WinTV USB Pro (PAL I,D/K)"},
- {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 Pro (NTSC M/N FM)"},
- {0x0573, 0x4d31, 0, CODEC_SAA7113, 3, V4L2_STD_PAL, 1, 1, 1, 1, TUNER_PHILIPS_PAL, -1, -1, 0, 3, 7, "Hauppauge WinTV USB Pro (PAL B/G FM)"},
- {0x0573, 0x4d32, 0, CODEC_SAA7113, 3, V4L2_STD_PAL, 1, 1, 1, 1, TUNER_PHILIPS_PAL, -1, -1, 0, 3, 7, "Hauppauge WinTV USB Pro (PAL I FM)"},
- {0x0573, 0x4d34, 0, CODEC_SAA7113, 3, V4L2_STD_PAL, 1, 1, 1, 1, TUNER_PHILIPS_PAL, -1, -1, 0, 3, 7, "Hauppauge WinTV USB Pro (PAL D/K FM)"},
- {0x0573, 0x4d35, 0, CODEC_SAA7113, 3, V4L2_STD_PAL, 1, 1, 1, 1, TUNER_MICROTUNE_4049FM5, -1, -1, 0, 3, 7, "Hauppauge WinTV USB Pro (Temic PAL/SECAM B/G/I/D/K/L FM)"},
- {0x0573, 0x4d36, 0, CODEC_SAA7113, 3, V4L2_STD_PAL, 1, 1, 1, 1, TUNER_MICROTUNE_4049FM5, -1, -1, 0, 3, 7, "Hauppauge WinTV USB Pro (Temic PAL B/G FM)"},
- {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 Pro (PAL/SECAM B/G/I/D/K/L FM)"},
- {0x0573, 0x4d38, 0, CODEC_SAA7113, 3, V4L2_STD_NTSC, 1, 1, 1, 1, TUNER_PHILIPS_NTSC_M, -1, -1, 0, 3, 7, "Hauppauge WinTV USB Pro (NTSC M/N FM)"},
- {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"},
- {0x07d0, 0x0001, -1, CODEC_SAA7113, 2, V4L2_STD_PAL, 0, 0, 1, 0, 0, -1, -1, 0, 3, 7, "Digital Video Creator I"},
- {0x07d0, 0x0002, -1, CODEC_SAA7111, 2, V4L2_STD_NTSC, 0, 0, 1, 0, 0, -1, -1, 82, 20, 7, "Global Village GV-007 (NTSC)"},
- {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)"},
- {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)"},
- {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)"},
- {0x07f8, 0x9104, 0, CODEC_SAA7113, 2, V4L2_STD_PAL, 1, 1, 1, 1, TUNER_PHILIPS_FM1216ME_MK3, -1, -1, 0, 3, 7, "Eskape Labs MyTV2Go"},
- {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)"},
- {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)"},
- {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"},
- {0x2304, 0x0111, -1, CODEC_SAA7111, 3, V4L2_STD_PAL, 1, 0, 1, 1, TUNER_PHILIPS_PAL, -1, -1, -1, -1, -1, "Miro PCTV USB"},
- {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"},
- {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"},
- {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"},
- {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"},
- {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)"},
- {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)"},
- {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"},
- {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"},
- {} /* Terminating entry */
+ [XANBOO] = {
+ .Interface = -1,
+ .Codec = CODEC_SAA7113,
+ .VideoChannels = 4,
+ .VideoNorm = V4L2_STD_NTSC,
+ .AudioChannels = 1,
+ .Radio = 0,
+ .vbi = 1,
+ .Tuner = 0,
+ .TunerType = 0,
+ .X_Offset = -1,
+ .Y_Offset = -1,
+ .ModelString = "Xanboo",
+ },
+ [BELKIN_VIDEOBUS_II] = {
+ .Interface = -1,
+ .Codec = CODEC_SAA7113,
+ .VideoChannels = 2,
+ .VideoNorm = V4L2_STD_PAL,
+ .AudioChannels = 1,
+ .Radio = 0,
+ .vbi = 1,
+ .Tuner = 0,
+ .TunerType = 0,
+ .X_Offset = 0,
+ .Y_Offset = 3,
+ .Dvi_yuv_override = 1,
+ .Dvi_yuv = 7,
+ .ModelString = "Belkin USB VideoBus II Adapter",
+ },
+ [BELKIN_VIDEOBUS] = {
+ .Interface = -1,
+ .Codec = CODEC_SAA7111,
+ .VideoChannels = 2,
+ .VideoNorm = V4L2_STD_NTSC,
+ .AudioChannels = 1,
+ .Radio = 0,
+ .vbi = 1,
+ .Tuner = 0,
+ .TunerType = 0,
+ .X_Offset = -1,
+ .Y_Offset = -1,
+ .ModelString = "Belkin Components USB VideoBus",
+ },
+ [BELKIN_USB_VIDEOBUS_II] = {
+ .Interface = -1,
+ .Codec = CODEC_SAA7113,
+ .VideoChannels = 2,
+ .VideoNorm = V4L2_STD_PAL,
+ .AudioChannels = 1,
+ .Radio = 0,
+ .vbi = 1,
+ .Tuner = 0,
+ .TunerType = 0,
+ .X_Offset = 0,
+ .Y_Offset = 3,
+ .Dvi_yuv_override = 1,
+ .Dvi_yuv = 7,
+ .ModelString = "Belkin USB VideoBus II",
+ },
+ [ECHOFX_INTERVIEW_LITE] = {
+ .Interface = 0,
+ .Codec = CODEC_SAA7111,
+ .VideoChannels = 2,
+ .VideoNorm = V4L2_STD_PAL,
+ .AudioChannels = 0,
+ .Radio = 0,
+ .vbi = 1,
+ .Tuner = 0,
+ .TunerType = 0,
+ .X_Offset = -1,
+ .Y_Offset = -1,
+ .Dvi_yuv_override = 1,
+ .Dvi_yuv = 7,
+ .ModelString = "echoFX InterView Lite",
+ },
+ [USBGEAR_USBG_V1] = {
+ .Interface = -1,
+ .Codec = CODEC_SAA7111,
+ .VideoChannels = 2,
+ .VideoNorm = V4L2_STD_NTSC,
+ .AudioChannels = 1,
+ .Radio = 0,
+ .vbi = 1,
+ .Tuner = 0,
+ .TunerType = 0,
+ .X_Offset = -1,
+ .Y_Offset = -1,
+ .ModelString = "USBGear USBG-V1 resp. HAMA USB",
+ },
+ [D_LINK_V100] = {
+ .Interface = -1,
+ .Codec = CODEC_SAA7113,
+ .VideoChannels = 4,
+ .VideoNorm = V4L2_STD_NTSC,
+ .AudioChannels = 0,
+ .Radio = 0,
+ .vbi = 1,
+ .Tuner = 0,
+ .TunerType = 0,
+ .X_Offset = 0,
+ .Y_Offset = 3,
+ .Dvi_yuv_override = 1,
+ .Dvi_yuv = 7,
+ .ModelString = "D-Link V100",
+ },
+ [X10_USB_CAMERA] = {
+ .Interface = -1,
+ .Codec = CODEC_SAA7111,
+ .VideoChannels = 2,
+ .VideoNorm = V4L2_STD_NTSC,
+ .AudioChannels = 1,
+ .Radio = 0,
+ .vbi = 1,
+ .Tuner = 0,
+ .TunerType = 0,
+ .X_Offset = -1,
+ .Y_Offset = -1,
+ .ModelString = "X10 USB Camera",
+ },
+ [HPG_WINTV_LIVE_PAL_BG] = {
+ .Interface = -1,
+ .Codec = CODEC_SAA7111,
+ .VideoChannels = 2,
+ .VideoNorm = V4L2_STD_PAL,
+ .AudioChannels = 1,
+ .Radio = 0,
+ .vbi = 1,
+ .Tuner = 0,
+ .TunerType = 0,
+ .X_Offset = -1,
+ .Y_Offset = 3,
+ .Dvi_yuv_override = 1,
+ .Dvi_yuv = 7,
+ .ModelString = "Hauppauge WinTV USB Live (PAL B/G)",
+ },
+ [HPG_WINTV_LIVE_PRO_NTSC_MN] = {
+ .Interface = -1,
+ .Codec = CODEC_SAA7113,
+ .VideoChannels = 2,
+ .VideoNorm = V4L2_STD_NTSC,
+ .AudioChannels = 0,
+ .Radio = 0,
+ .vbi = 1,
+ .Tuner = 0,
+ .TunerType = 0,
+ .X_Offset = 0,
+ .Y_Offset = 3,
+ .Dvi_yuv_override = 1,
+ .Dvi_yuv = 7,
+ .ModelString = "Hauppauge WinTV USB Live Pro (NTSC M/N)",
+ },
+ [ZORAN_PMD_NOGATECH] = {
+ .Interface = -1,
+ .Codec = CODEC_SAA7113,
+ .VideoChannels = 2,
+ .VideoNorm = V4L2_STD_PAL,
+ .AudioChannels = 2,
+ .Radio = 0,
+ .vbi = 1,
+ .Tuner = 0,
+ .TunerType = 0,
+ .X_Offset = 0,
+ .Y_Offset = 3,
+ .Dvi_yuv_override = 1,
+ .Dvi_yuv = 7,
+ .ModelString = "Zoran Co. PMD (Nogatech) AV-grabber Manhattan",
+ },
+ [NOGATECH_USB_TV_NTSC_FM] = {
+ .Interface = -1,
+ .Codec = CODEC_SAA7111,
+ .VideoChannels = 3,
+ .VideoNorm = V4L2_STD_NTSC,
+ .AudioChannels = 1,
+ .Radio = 1,
+ .vbi = 1,
+ .Tuner = 1,
+ .TunerType = TUNER_PHILIPS_NTSC_M,
+ .X_Offset = -1,
+ .Y_Offset = 20,
+ .ModelString = "Nogatech USB-TV (NTSC) FM",
+ },
+ [PNY_USB_TV_NTSC_FM] = {
+ .Interface = -1,
+ .Codec = CODEC_SAA7111,
+ .VideoChannels = 3,
+ .VideoNorm = V4L2_STD_NTSC,
+ .AudioChannels = 1,
+ .Radio = 1,
+ .vbi = 1,
+ .Tuner = 1,
+ .TunerType = TUNER_PHILIPS_NTSC_M,
+ .X_Offset = -1,
+ .Y_Offset = 20,
+ .ModelString = "PNY USB-TV (NTSC) FM",
+ },
+ [PV_PLAYTV_USB_PRO_PAL_FM] = {
+ .Interface = 0,
+ .Codec = CODEC_SAA7113,
+ .VideoChannels = 3,
+ .VideoNorm = V4L2_STD_PAL,
+ .AudioChannels = 1,
+ .Radio = 1,
+ .vbi = 1,
+ .Tuner = 1,
+ .TunerType = TUNER_PHILIPS_PAL,
+ .X_Offset = 0,
+ .Y_Offset = 3,
+ .Dvi_yuv_override = 1,
+ .Dvi_yuv = 7,
+ .ModelString = "PixelView PlayTv-USB PRO (PAL) FM",
+ },
+ [ZT_721] = {
+ .Interface = 0,
+ .Codec = CODEC_SAA7113,
+ .VideoChannels = 3,
+ .VideoNorm = V4L2_STD_PAL,
+ .AudioChannels = 1,
+ .Radio = 1,
+ .vbi = 1,
+ .Tuner = 1,
+ .TunerType = TUNER_PHILIPS_PAL,
+ .X_Offset = 0,
+ .Y_Offset = 3,
+ .Dvi_yuv_override = 1,
+ .Dvi_yuv = 7,
+ .ModelString = "ZTV ZT-721 2.4GHz USB A/V Receiver",
+ },
+ [HPG_WINTV_NTSC_MN] = {
+ .Interface = -1,
+ .Codec = CODEC_SAA7111,
+ .VideoChannels = 3,
+ .VideoNorm = V4L2_STD_NTSC,
+ .AudioChannels = 1,
+ .Radio = 0,
+ .vbi = 1,
+ .Tuner = 1,
+ .TunerType = TUNER_PHILIPS_NTSC_M,
+ .X_Offset = -1,
+ .Y_Offset = 20,
+ .ModelString = "Hauppauge WinTV USB (NTSC M/N)",
+ },
+ [HPG_WINTV_PAL_BG] = {
+ .Interface = -1,
+ .Codec = CODEC_SAA7111,
+ .VideoChannels = 3,
+ .VideoNorm = V4L2_STD_PAL,
+ .AudioChannels = 1,
+ .Radio = 0,
+ .vbi = 1,
+ .Tuner = 1,
+ .TunerType = TUNER_PHILIPS_PAL,
+ .X_Offset = -1,
+ .Y_Offset = -1,
+ .ModelString = "Hauppauge WinTV USB (PAL B/G)",
+ },
+ [HPG_WINTV_PAL_I] = {
+ .Interface = -1,
+ .Codec = CODEC_SAA7111,
+ .VideoChannels = 3,
+ .VideoNorm = V4L2_STD_PAL,
+ .AudioChannels = 1,
+ .Radio = 0,
+ .vbi = 1,
+ .Tuner = 1,
+ .TunerType = TUNER_PHILIPS_PAL,
+ .X_Offset = -1,
+ .Y_Offset = -1,
+ .ModelString = "Hauppauge WinTV USB (PAL I)",
+ },
+ [HPG_WINTV_PAL_SECAM_L] = {
+ .Interface = -1,
+ .Codec = CODEC_SAA7111,
+ .VideoChannels = 3,
+ .VideoNorm = V4L2_STD_SECAM,
+ .AudioChannels = 1,
+ .Radio = 0,
+ .vbi = 1,
+ .Tuner = 1,
+ .TunerType = TUNER_PHILIPS_SECAM,
+ .X_Offset = -1,
+ .Y_Offset = -1,
+ .ModelString = "Hauppauge WinTV USB (PAL/SECAM L)",
+ },
+ [HPG_WINTV_PAL_D_K] = {
+ .Interface = -1,
+ .Codec = CODEC_SAA7111,
+ .VideoChannels = 3,
+ .VideoNorm = V4L2_STD_PAL,
+ .AudioChannels = 1,
+ .Radio = 0,
+ .vbi = 1,
+ .Tuner = 1,
+ .TunerType = TUNER_PHILIPS_PAL,
+ .X_Offset = -1,
+ .Y_Offset = -1,
+ .ModelString = "Hauppauge WinTV USB (PAL D/K)",
+ },
+ [HPG_WINTV_NTSC_FM] = {
+ .Interface = -1,
+ .Codec = CODEC_SAA7111,
+ .VideoChannels = 3,
+ .VideoNorm = V4L2_STD_NTSC,
+ .AudioChannels = 1,
+ .Radio = 1,
+ .vbi = 1,
+ .Tuner = 1,
+ .TunerType = TUNER_PHILIPS_NTSC_M,
+ .X_Offset = -1,
+ .Y_Offset = -1,
+ .ModelString = "Hauppauge WinTV USB (NTSC FM)",
+ },
+ [HPG_WINTV_PAL_BG_FM] = {
+ .Interface = -1,
+ .Codec = CODEC_SAA7111,
+ .VideoChannels = 3,
+ .VideoNorm = V4L2_STD_PAL,
+ .AudioChannels = 1,
+ .Radio = 1,
+ .vbi = 1,
+ .Tuner = 1,
+ .TunerType = TUNER_PHILIPS_PAL,
+ .X_Offset = -1,
+ .Y_Offset = -1,
+ .ModelString = "Hauppauge WinTV USB (PAL B/G FM)",
+ },
+ [HPG_WINTV_PAL_I_FM] = {
+ .Interface = -1,
+ .Codec = CODEC_SAA7111,
+ .VideoChannels = 3,
+ .VideoNorm = V4L2_STD_PAL,
+ .AudioChannels = 1,
+ .Radio = 1,
+ .vbi = 1,
+ .Tuner = 1,
+ .TunerType = TUNER_PHILIPS_PAL,
+ .X_Offset = -1,
+ .Y_Offset = -1,
+ .ModelString = "Hauppauge WinTV USB (PAL I FM)",
+ },
+ [HPG_WINTV_PAL_D_K_FM] = {
+ .Interface = -1,
+ .Codec = CODEC_SAA7111,
+ .VideoChannels = 3,
+ .VideoNorm = V4L2_STD_PAL,
+ .AudioChannels = 1,
+ .Radio = 1,
+ .vbi = 1,
+ .Tuner = 1,
+ .TunerType = TUNER_PHILIPS_PAL,
+ .X_Offset = -1,
+ .Y_Offset = -1,
+ .ModelString = "Hauppauge WinTV USB (PAL D/K FM)",
+ },
+ [HPG_WINTV_PRO_NTSC_MN] = {
+ .Interface = 0,
+ .Codec = CODEC_SAA7113,
+ .VideoChannels = 3,
+ .VideoNorm = V4L2_STD_NTSC,
+ .AudioChannels = 1,
+ .Radio = 1,
+ .vbi = 1,
+ .Tuner = 1,
+ .TunerType = TUNER_MICROTUNE_4049FM5,
+ .X_Offset = 0,
+ .Y_Offset = 3,
+ .Dvi_yuv_override = 1,
+ .Dvi_yuv = 7,
+ .ModelString = "Hauppauge WinTV USB Pro (NTSC M/N)",
+ },
+ [HPG_WINTV_PRO_NTSC_MN_V2] = {
+ .Interface = 0,
+ .Codec = CODEC_SAA7113,
+ .VideoChannels = 3,
+ .VideoNorm = V4L2_STD_NTSC,
+ .AudioChannels = 1,
+ .Radio = 1,
+ .vbi = 1,
+ .Tuner = 1,
+ .TunerType = TUNER_MICROTUNE_4049FM5,
+ .X_Offset = 0,
+ .Y_Offset = 3,
+ .Dvi_yuv_override = 1,
+ .Dvi_yuv = 7,
+ .ModelString = "Hauppauge WinTV USB Pro (NTSC M/N) V2",
+ },
+ [HPG_WINTV_PRO_PAL] = {
+ .Interface = 0,
+ .Codec = CODEC_SAA7113,
+ .VideoChannels = 3,
+ .VideoNorm = V4L2_STD_PAL,
+ .AudioChannels = 1,
+ .Radio = 0,
+ .vbi = 1,
+ .Tuner = 1,
+ .TunerType = TUNER_PHILIPS_FM1216ME_MK3,
+ .X_Offset = 0,
+ .Y_Offset = 3,
+ .Dvi_yuv_override = 1,
+ .Dvi_yuv = 7,
+ .ModelString = "Hauppauge WinTV USB Pro (PAL/SECAM B/G/I/D/K/L)",
+ },
+ [HPG_WINTV_PRO_NTSC_MN_V3] = {
+ .Interface = 0,
+ .Codec = CODEC_SAA7113,
+ .VideoChannels = 3,
+ .VideoNorm = V4L2_STD_NTSC,
+ .AudioChannels = 1,
+ .Radio = 1,
+ .vbi = 1,
+ .Tuner = 1,
+ .TunerType = TUNER_PHILIPS_NTSC_M,
+ .X_Offset = 0,
+ .Y_Offset = 3,
+ .Dvi_yuv_override = 1,
+ .Dvi_yuv = 7,
+ .ModelString = "Hauppauge WinTV USB Pro (NTSC M/N) V3",
+ },
+ [HPG_WINTV_PRO_PAL_BG] = {
+ .Interface = 0,
+ .Codec = CODEC_SAA7113,
+ .VideoChannels = 3,
+ .VideoNorm = V4L2_STD_PAL,
+ .AudioChannels = 1,
+ .Radio = 0,
+ .vbi = 1,
+ .Tuner = 1,
+ .TunerType = TUNER_PHILIPS_PAL,
+ .X_Offset = 0,
+ .Y_Offset = 3,
+ .Dvi_yuv_override = 1,
+ .Dvi_yuv = 7,
+ .ModelString = "Hauppauge WinTV USB Pro (PAL B/G)",
+ },
+ [HPG_WINTV_PRO_PAL_I] = {
+ .Interface = 0,
+ .Codec = CODEC_SAA7113,
+ .VideoChannels = 3,
+ .VideoNorm = V4L2_STD_PAL,
+ .AudioChannels = 1,
+ .Radio = 0,
+ .vbi = 1,
+ .Tuner = 1,
+ .TunerType = TUNER_PHILIPS_PAL,
+ .X_Offset = 0,
+ .Y_Offset = 3,
+ .Dvi_yuv_override = 1,
+ .Dvi_yuv = 7,
+ .ModelString = "Hauppauge WinTV USB Pro (PAL I)",
+ },
+ [HPG_WINTV_PRO_PAL_SECAM_L] = {
+ .Interface = -1,
+ .Codec = CODEC_SAA7113,
+ .VideoChannels = 3,
+ .VideoNorm = V4L2_STD_SECAM,
+ .AudioChannels = 1,
+ .Radio = 0,
+ .vbi = 1,
+ .Tuner = 1,
+ .TunerType = TUNER_PHILIPS_SECAM,
+ .X_Offset = 0,
+ .Y_Offset = 3,
+ .Dvi_yuv_override = 1,
+ .Dvi_yuv = 7,
+ .ModelString = "Hauppauge WinTV USB Pro (PAL/SECAM L)",
+ },
+ [HPG_WINTV_PRO_PAL_D_K] = {
+ .Interface = -1,
+ .Codec = CODEC_SAA7113,
+ .VideoChannels = 3,
+ .VideoNorm = V4L2_STD_PAL,
+ .AudioChannels = 1,
+ .Radio = 0,
+ .vbi = 1,
+ .Tuner = 1,
+ .TunerType = TUNER_PHILIPS_PAL,
+ .X_Offset = 0,
+ .Y_Offset = 3,
+ .Dvi_yuv_override = 1,
+ .Dvi_yuv = 7,
+ .ModelString = "Hauppauge WinTV USB Pro (PAL D/K)",
+ },
+ [HPG_WINTV_PRO_PAL_SECAM] = {
+ .Interface = -1,
+ .Codec = CODEC_SAA7113,
+ .VideoChannels = 3,
+ .VideoNorm = V4L2_STD_SECAM,
+ .AudioChannels = 1,
+ .Radio = 0,
+ .vbi = 1,
+ .Tuner = 1,
+ .TunerType = TUNER_PHILIPS_SECAM,
+ .X_Offset = 0,
+ .Y_Offset = 3,
+ .Dvi_yuv_override = 1,
+ .Dvi_yuv = 7,
+ .ModelString = "Hauppauge WinTV USB Pro (PAL/SECAM BGDK/I/L)",
+ },
+ [HPG_WINTV_PRO_PAL_SECAM_V2] = {
+ .Interface = -1,
+ .Codec = CODEC_SAA7113,
+ .VideoChannels = 3,
+ .VideoNorm = V4L2_STD_SECAM,
+ .AudioChannels = 1,
+ .Radio = 0,
+ .vbi = 1,
+ .Tuner = 1,
+ .TunerType = TUNER_PHILIPS_SECAM,
+ .X_Offset = 0,
+ .Y_Offset = 3,
+ .Dvi_yuv_override = 1,
+ .Dvi_yuv = 7,
+ .ModelString = "Hauppauge WinTV USB Pro (PAL/SECAM BGDK/I/L) V2",
+ },
+ [HPG_WINTV_PRO_PAL_BG_V2] = {
+ .Interface = -1,
+ .Codec = CODEC_SAA7113,
+ .VideoChannels = 3,
+ .VideoNorm = V4L2_STD_PAL,
+ .AudioChannels = 1,
+ .Radio = 0,
+ .vbi = 1,
+ .Tuner = 1,
+ .TunerType = TUNER_ALPS_TSBE1_PAL,
+ .X_Offset = 0,
+ .Y_Offset = 3,
+ .Dvi_yuv_override = 1,
+ .Dvi_yuv = 7,
+ .ModelString = "Hauppauge WinTV USB Pro (PAL B/G) V2",
+ },
+ [HPG_WINTV_PRO_PAL_BG_D_K] = {
+ .Interface = -1,
+ .Codec = CODEC_SAA7113,
+ .VideoChannels = 3,
+ .VideoNorm = V4L2_STD_PAL,
+ .AudioChannels = 1,
+ .Radio = 0,
+ .vbi = 1,
+ .Tuner = 1,
+ .TunerType = TUNER_ALPS_TSBE1_PAL,
+ .X_Offset = 0,
+ .Y_Offset = 3,
+ .Dvi_yuv_override = 1,
+ .Dvi_yuv = 7,
+ .ModelString = "Hauppauge WinTV USB Pro (PAL B/G,D/K)",
+ },
+ [HPG_WINTV_PRO_PAL_I_D_K] = {
+ .Interface = -1,
+ .Codec = CODEC_SAA7113,
+ .VideoChannels = 3,
+ .VideoNorm = V4L2_STD_PAL,
+ .AudioChannels = 1,
+ .Radio = 0,
+ .vbi = 1,
+ .Tuner = 1,
+ .TunerType = TUNER_PHILIPS_PAL,
+ .X_Offset = 0,
+ .Y_Offset = 3,
+ .Dvi_yuv_override = 1,
+ .Dvi_yuv = 7,
+ .ModelString = "Hauppauge WinTV USB Pro (PAL I,D/K)",
+ },
+ [HPG_WINTV_PRO_NTSC_MN_FM] = {
+ .Interface = -1,
+ .Codec = CODEC_SAA7113,
+ .VideoChannels = 3,
+ .VideoNorm = V4L2_STD_NTSC,
+ .AudioChannels = 1,
+ .Radio = 1,
+ .vbi = 1,
+ .Tuner = 1,
+ .TunerType = TUNER_PHILIPS_NTSC_M,
+ .X_Offset = 0,
+ .Y_Offset = 3,
+ .Dvi_yuv_override = 1,
+ .Dvi_yuv = 7,
+ .ModelString = "Hauppauge WinTV USB Pro (NTSC M/N FM)",
+ },
+ [HPG_WINTV_PRO_PAL_BG_FM] = {
+ .Interface = 0,
+ .Codec = CODEC_SAA7113,
+ .VideoChannels = 3,
+ .VideoNorm = V4L2_STD_PAL,
+ .AudioChannels = 1,
+ .Radio = 1,
+ .vbi = 1,
+ .Tuner = 1,
+ .TunerType = TUNER_PHILIPS_PAL,
+ .X_Offset = 0,
+ .Y_Offset = 3,
+ .Dvi_yuv_override = 1,
+ .Dvi_yuv = 7,
+ .ModelString = "Hauppauge WinTV USB Pro (PAL B/G FM)",
+ },
+ [HPG_WINTV_PRO_PAL_I_FM] = {
+ .Interface = 0,
+ .Codec = CODEC_SAA7113,
+ .VideoChannels = 3,
+ .VideoNorm = V4L2_STD_PAL,
+ .AudioChannels = 1,
+ .Radio = 1,
+ .vbi = 1,
+ .Tuner = 1,
+ .TunerType = TUNER_PHILIPS_PAL,
+ .X_Offset = 0,
+ .Y_Offset = 3,
+ .Dvi_yuv_override = 1,
+ .Dvi_yuv = 7,
+ .ModelString = "Hauppauge WinTV USB Pro (PAL I FM)",
+ },
+ [HPG_WINTV_PRO_PAL_D_K_FM] = {
+ .Interface = 0,
+ .Codec = CODEC_SAA7113,
+ .VideoChannels = 3,
+ .VideoNorm = V4L2_STD_PAL,
+ .AudioChannels = 1,
+ .Radio = 1,
+ .vbi = 1,
+ .Tuner = 1,
+ .TunerType = TUNER_PHILIPS_PAL,
+ .X_Offset = 0,
+ .Y_Offset = 3,
+ .Dvi_yuv_override = 1,
+ .Dvi_yuv = 7,
+ .ModelString = "Hauppauge WinTV USB Pro (PAL D/K FM)",
+ },
+ [HPG_WINTV_PRO_TEMIC_PAL_FM] = {
+ .Interface = 0,
+ .Codec = CODEC_SAA7113,
+ .VideoChannels = 3,
+ .VideoNorm = V4L2_STD_PAL,
+ .AudioChannels = 1,
+ .Radio = 1,
+ .vbi = 1,
+ .Tuner = 1,
+ .TunerType = TUNER_MICROTUNE_4049FM5,
+ .X_Offset = 0,
+ .Y_Offset = 3,
+ .Dvi_yuv_override = 1,
+ .Dvi_yuv = 7,
+ .ModelString = "Hauppauge WinTV USB Pro (Temic PAL/SECAM B/G/I/D/K/L FM)",
+ },
+ [HPG_WINTV_PRO_TEMIC_PAL_BG_FM] = {
+ .Interface = 0,
+ .Codec = CODEC_SAA7113,
+ .VideoChannels = 3,
+ .VideoNorm = V4L2_STD_PAL,
+ .AudioChannels = 1,
+ .Radio = 1,
+ .vbi = 1,
+ .Tuner = 1,
+ .TunerType = TUNER_MICROTUNE_4049FM5,
+ .X_Offset = 0,
+ .Y_Offset = 3,
+ .Dvi_yuv_override = 1,
+ .Dvi_yuv = 7,
+ .ModelString = "Hauppauge WinTV USB Pro (Temic PAL B/G FM)",
+ },
+ [HPG_WINTV_PRO_PAL_FM] = {
+ .Interface = 0,
+ .Codec = CODEC_SAA7113,
+ .VideoChannels = 3,
+ .VideoNorm = V4L2_STD_PAL,
+ .AudioChannels = 1,
+ .Radio = 1,
+ .vbi = 1,
+ .Tuner = 1,
+ .TunerType = TUNER_PHILIPS_FM1216ME_MK3,
+ .X_Offset = 0,
+ .Y_Offset = 3,
+ .Dvi_yuv_override = 1,
+ .Dvi_yuv = 7,
+ .ModelString = "Hauppauge WinTV USB Pro (PAL/SECAM B/G/I/D/K/L FM)",
+ },
+ [HPG_WINTV_PRO_NTSC_MN_FM_V2] = {
+ .Interface = 0,
+ .Codec = CODEC_SAA7113,
+ .VideoChannels = 3,
+ .VideoNorm = V4L2_STD_NTSC,
+ .AudioChannels = 1,
+ .Radio = 1,
+ .vbi = 1,
+ .Tuner = 1,
+ .TunerType = TUNER_PHILIPS_NTSC_M,
+ .X_Offset = 0,
+ .Y_Offset = 3,
+ .Dvi_yuv_override = 1,
+ .Dvi_yuv = 7,
+ .ModelString = "Hauppauge WinTV USB Pro (NTSC M/N FM) V2",
+ },
+ [CAMTEL_TVB330] = {
+ .Interface = -1,
+ .Codec = CODEC_SAA7113,
+ .VideoChannels = 3,
+ .VideoNorm = V4L2_STD_NTSC,
+ .AudioChannels = 1,
+ .Radio = 1,
+ .vbi = 1,
+ .Tuner = 1,
+ .TunerType = TUNER_PHILIPS_NTSC_M,
+ .X_Offset = 5,
+ .Y_Offset = 5,
+ .ModelString = "Camtel Technology USB TV Genie Pro FM Model TVB330",
+ },
+ [DIGITAL_VIDEO_CREATOR_I] = {
+ .Interface = -1,
+ .Codec = CODEC_SAA7113,
+ .VideoChannels = 2,
+ .VideoNorm = V4L2_STD_PAL,
+ .AudioChannels = 0,
+ .Radio = 0,
+ .vbi = 1,
+ .Tuner = 0,
+ .TunerType = 0,
+ .X_Offset = 0,
+ .Y_Offset = 3,
+ .Dvi_yuv_override = 1,
+ .Dvi_yuv = 7,
+ .ModelString = "Digital Video Creator I",
+ },
+ [GLOBAL_VILLAGE_GV_007_NTSC] = {
+ .Interface = -1,
+ .Codec = CODEC_SAA7111,
+ .VideoChannels = 2,
+ .VideoNorm = V4L2_STD_NTSC,
+ .AudioChannels = 0,
+ .Radio = 0,
+ .vbi = 1,
+ .Tuner = 0,
+ .TunerType = 0,
+ .X_Offset = 82,
+ .Y_Offset = 20,
+ .Dvi_yuv_override = 1,
+ .Dvi_yuv = 7,
+ .ModelString = "Global Village GV-007 (NTSC)",
+ },
+ [DAZZLE_DVC_50_REV_1_NTSC] = {
+ .Interface = 0,
+ .Codec = CODEC_SAA7113,
+ .VideoChannels = 2,
+ .VideoNorm = V4L2_STD_NTSC,
+ .AudioChannels = 0,
+ .Radio = 0,
+ .vbi = 1,
+ .Tuner = 0,
+ .TunerType = 0,
+ .X_Offset = 0,
+ .Y_Offset = 3,
+ .Dvi_yuv_override = 1,
+ .Dvi_yuv = 7,
+ .ModelString = "Dazzle Fusion Model DVC-50 Rev 1 (NTSC)",
+ },
+ [DAZZLE_DVC_80_REV_1_PAL] = {
+ .Interface = 0,
+ .Codec = CODEC_SAA7113,
+ .VideoChannels = 2,
+ .VideoNorm = V4L2_STD_PAL,
+ .AudioChannels = 0,
+ .Radio = 0,
+ .vbi = 1,
+ .Tuner = 0,
+ .TunerType = 0,
+ .X_Offset = 0,
+ .Y_Offset = 3,
+ .Dvi_yuv_override = 1,
+ .Dvi_yuv = 7,
+ .ModelString = "Dazzle Fusion Model DVC-80 Rev 1 (PAL)",
+ },
+ [DAZZLE_DVC_90_REV_1_SECAM] = {
+ .Interface = 0,
+ .Codec = CODEC_SAA7113,
+ .VideoChannels = 2,
+ .VideoNorm = V4L2_STD_SECAM,
+ .AudioChannels = 0,
+ .Radio = 0,
+ .vbi = 1,
+ .Tuner = 0,
+ .TunerType = 0,
+ .X_Offset = 0,
+ .Y_Offset = 3,
+ .Dvi_yuv_override = 1,
+ .Dvi_yuv = 7,
+ .ModelString = "Dazzle Fusion Model DVC-90 Rev 1 (SECAM)",
+ },
+ [ESKAPE_LABS_MYTV2GO] = {
+ .Interface = 0,
+ .Codec = CODEC_SAA7113,
+ .VideoChannels = 2,
+ .VideoNorm = V4L2_STD_PAL,
+ .AudioChannels = 1,
+ .Radio = 1,
+ .vbi = 1,
+ .Tuner = 1,
+ .TunerType = TUNER_PHILIPS_FM1216ME_MK3,
+ .X_Offset = 0,
+ .Y_Offset = 3,
+ .Dvi_yuv_override = 1,
+ .Dvi_yuv = 7,
+ .ModelString = "Eskape Labs MyTV2Go",
+ },
+ [PINNA_PCTV_USB_PAL] = {
+ .Interface = -1,
+ .Codec = CODEC_SAA7111,
+ .VideoChannels = 3,
+ .VideoNorm = V4L2_STD_PAL,
+ .AudioChannels = 1,
+ .Radio = 0,
+ .vbi = 0,
+ .Tuner = 1,
+ .TunerType = TUNER_TEMIC_4066FY5_PAL_I,
+ .X_Offset = -1,
+ .Y_Offset = -1,
+ .ModelString = "Pinnacle Studio PCTV USB (PAL)",
+ },
+ [PINNA_PCTV_USB_SECAM] = {
+ .Interface = -1,
+ .Codec = CODEC_SAA7111,
+ .VideoChannels = 3,
+ .VideoNorm = V4L2_STD_SECAM,
+ .AudioChannels = 1,
+ .Radio = 0,
+ .vbi = 1,
+ .Tuner = 1,
+ .TunerType = TUNER_PHILIPS_SECAM,
+ .X_Offset = -1,
+ .Y_Offset = -1,
+ .ModelString = "Pinnacle Studio PCTV USB (SECAM)",
+ },
+ [PINNA_PCTV_USB_PAL_FM] = {
+ .Interface = -1,
+ .Codec = CODEC_SAA7111,
+ .VideoChannels = 3,
+ .VideoNorm = V4L2_STD_PAL,
+ .AudioChannels = 1,
+ .Radio = 1,
+ .vbi = 1,
+ .Tuner = 1,
+ .TunerType = TUNER_PHILIPS_PAL,
+ .X_Offset = 128,
+ .Y_Offset = 23,
+ .ModelString = "Pinnacle Studio PCTV USB (PAL) FM",
+ },
+ [MIRO_PCTV_USB] = {
+ .Interface = -1,
+ .Codec = CODEC_SAA7111,
+ .VideoChannels = 3,
+ .VideoNorm = V4L2_STD_PAL,
+ .AudioChannels = 1,
+ .Radio = 0,
+ .vbi = 1,
+ .Tuner = 1,
+ .TunerType = TUNER_PHILIPS_PAL,
+ .X_Offset = -1,
+ .Y_Offset = -1,
+ .ModelString = "Miro PCTV USB",
+ },
+ [PINNA_PCTV_USB_NTSC_FM] = {
+ .Interface = -1,
+ .Codec = CODEC_SAA7111,
+ .VideoChannels = 3,
+ .VideoNorm = V4L2_STD_NTSC,
+ .AudioChannels = 1,
+ .Radio = 1,
+ .vbi = 1,
+ .Tuner = 1,
+ .TunerType = TUNER_PHILIPS_NTSC_M,
+ .X_Offset = -1,
+ .Y_Offset = -1,
+ .ModelString = "Pinnacle Studio PCTV USB (NTSC) FM",
+ },
+ [PINNA_PCTV_USB_PAL_FM_V2] = {
+ .Interface = -1,
+ .Codec = CODEC_SAA7113,
+ .VideoChannels = 3,
+ .VideoNorm = V4L2_STD_PAL,
+ .AudioChannels = 1,
+ .Radio = 1,
+ .vbi = 1,
+ .Tuner = 1,
+ .TunerType = TUNER_TEMIC_4009FR5_PAL,
+ .X_Offset = 0,
+ .Y_Offset = 3,
+ .Dvi_yuv_override = 1,
+ .Dvi_yuv = 7,
+ .ModelString = "Pinnacle Studio PCTV USB (PAL) FM V2",
+ },
+ [PINNA_PCTV_USB_NTSC_FM_V2] = {
+ .Interface = -1,
+ .Codec = CODEC_SAA7111,
+ .VideoChannels = 3,
+ .VideoNorm = V4L2_STD_NTSC,
+ .AudioChannels = 1,
+ .Radio = 1,
+ .vbi = 1,
+ .Tuner = 1,
+ .TunerType = TUNER_TEMIC_4039FR5_NTSC,
+ .X_Offset = 0,
+ .Y_Offset = 3,
+ .Dvi_yuv_override = 1,
+ .Dvi_yuv = 7,
+ .ModelString = "Pinnacle Studio PCTV USB (NTSC) FM V2",
+ },
+ [PINNA_PCTV_USB_PAL_FM_V3] = {
+ .Interface = -1,
+ .Codec = CODEC_SAA7113,
+ .VideoChannels = 3,
+ .VideoNorm = V4L2_STD_PAL,
+ .AudioChannels = 1,
+ .Radio = 1,
+ .vbi = 1,
+ .Tuner = 1,
+ .TunerType = TUNER_TEMIC_4009FR5_PAL,
+ .X_Offset = 0,
+ .Y_Offset = 3,
+ .Dvi_yuv_override = 1,
+ .Dvi_yuv = 7,
+ .ModelString = "Pinnacle Studio PCTV USB (PAL) FM V3",
+ },
+ [PINNA_LINX_VD_IN_CAB_NTSC] = {
+ .Interface = -1,
+ .Codec = CODEC_SAA7113,
+ .VideoChannels = 2,
+ .VideoNorm = V4L2_STD_NTSC,
+ .AudioChannels = 1,
+ .Radio = 0,
+ .vbi = 1,
+ .Tuner = 0,
+ .TunerType = 0,
+ .X_Offset = 0,
+ .Y_Offset = 3,
+ .Dvi_yuv_override = 1,
+ .Dvi_yuv = 7,
+ .ModelString = "Pinnacle Studio Linx Video input cable (NTSC)",
+ },
+ [PINNA_LINX_VD_IN_CAB_PAL] = {
+ .Interface = -1,
+ .Codec = CODEC_SAA7113,
+ .VideoChannels = 2,
+ .VideoNorm = V4L2_STD_PAL,
+ .AudioChannels = 1,
+ .Radio = 0,
+ .vbi = 1,
+ .Tuner = 0,
+ .TunerType = 0,
+ .X_Offset = 0,
+ .Y_Offset = 3,
+ .Dvi_yuv_override = 1,
+ .Dvi_yuv = 7,
+ .ModelString = "Pinnacle Studio Linx Video input cable (PAL)",
+ },
+ [PINNA_PCTV_BUNGEE_PAL_FM] = {
+ .Interface = -1,
+ .Codec = CODEC_SAA7113,
+ .VideoChannels = 3,
+ .VideoNorm = V4L2_STD_PAL,
+ .AudioChannels = 1,
+ .Radio = 1,
+ .vbi = 1,
+ .Tuner = 1,
+ .TunerType = TUNER_TEMIC_4009FR5_PAL,
+ .X_Offset = 0,
+ .Y_Offset = 3,
+ .Dvi_yuv_override = 1,
+ .Dvi_yuv = 7,
+ .ModelString = "Pinnacle PCTV Bungee USB (PAL) FM",
+ },
+ [HPG_WINTV] = {
+ .Interface = -1,
+ .Codec = CODEC_SAA7111,
+ .VideoChannels = 3,
+ .VideoNorm = V4L2_STD_NTSC,
+ .AudioChannels = 1,
+ .Radio = 0,
+ .vbi = 1,
+ .Tuner = 1,
+ .TunerType = TUNER_PHILIPS_NTSC_M,
+ .X_Offset = -1,
+ .Y_Offset = -1,
+ .ModelString = "Hauppauge WinTv-USB",
+ },
};
+const int usbvision_device_data_size=ARRAY_SIZE(usbvision_device_data);
/* Supported Devices */
struct usb_device_id usbvision_table [] = {
- { USB_DEVICE(0xfff0, 0xfff0) }, /* Custom Dummy USBVision Device */
- { USB_DEVICE(0x0a6f, 0x0400) }, /* Xanboo */
- { USB_DEVICE(0x050d, 0x0106) }, /* Belkin USB VideoBus II Adapter */
- { USB_DEVICE(0x050d, 0x0207) }, /* Belkin Components USB VideoBus */
- { USB_DEVICE(0x050d, 0x0208) }, /* Belkin USB VideoBus II */
- { USB_DEVICE(0x0571, 0x0002) }, /* echoFX InterView Lite */
- { USB_DEVICE(0x0573, 0x0003) }, /* USBGear USBG-V1 resp. HAMA USB */
- { USB_DEVICE(0x0573, 0x0400) }, /* D-Link V100 */
- { USB_DEVICE(0x0573, 0x2000) }, /* X10 USB Camera */
- { USB_DEVICE(0x0573, 0x2d00) }, /* Hauppauge WinTV USB Live (PAL B/G) */
- { USB_DEVICE(0x0573, 0x2d01) }, /* Hauppauge WinTV USB Live Pro (NTSC M/N) */
- { USB_DEVICE(0x0573, 0x2101) }, /* Zoran Co. PMD (Nogatech) AV-grabber Manhattan */
- { USB_DEVICE(0x0573, 0x4100) }, /* Nogatech USB-TV FM (NTSC) */
- { USB_DEVICE(0x0573, 0x4110) }, /* PNY USB-TV (NTSC) FM */
- { USB_DEVICE(0x0573, 0x4450) }, /* PixelView PlayTv-USB PRO (PAL) FM */
- { USB_DEVICE(0x0573, 0x4550) }, /* ZTV ZT-721 2.4GHz USB A/V Receiver */
- { USB_DEVICE(0x0573, 0x4d00) }, /* Hauppauge WinTV USB (NTSC M/N) */
- { USB_DEVICE(0x0573, 0x4d01) }, /* Hauppauge WinTV USB (PAL B/G) */
- { USB_DEVICE(0x0573, 0x4d02) }, /* Hauppauge WinTV USB (PAL I) */
- { USB_DEVICE(0x0573, 0x4d03) }, /* Hauppauge WinTV USB (PAL/SECAM L) */
- { USB_DEVICE(0x0573, 0x4d04) }, /* Hauppauge WinTV USB (PAL D/K) */
- { USB_DEVICE(0x0573, 0x4d10) }, /* Hauppauge WinTV USB (NTSC FM) */
- { USB_DEVICE(0x0573, 0x4d11) }, /* Hauppauge WinTV USB (PAL B/G FM) */
- { USB_DEVICE(0x0573, 0x4d12) }, /* Hauppauge WinTV USB (PAL I FM) */
- { USB_DEVICE(0x0573, 0x4d14) }, /* Hauppauge WinTV USB (PAL D/K FM) */
- { USB_DEVICE(0x0573, 0x4d2a) }, /* Hauppauge WinTV USB Pro (NTSC M/N) */
- { USB_DEVICE(0x0573, 0x4d2b) }, /* Hauppauge WinTV USB Pro (NTSC M/N) */
- { USB_DEVICE(0x0573, 0x4d2c) }, /* Hauppauge WinTV USB Pro (PAL/SECAM B/G/I/D/K/L) */
- { USB_DEVICE(0x0573, 0x4d20) }, /* Hauppauge WinTV USB Pro (NTSC M/N) */
- { USB_DEVICE(0x0573, 0x4d21) }, /* Hauppauge WinTV USB Pro (PAL B/G) */
- { USB_DEVICE(0x0573, 0x4d22) }, /* Hauppauge WinTV USB Pro (PAL I) */
- { USB_DEVICE(0x0573, 0x4d23) }, /* Hauppauge WinTV USB Pro (PAL/SECAM L) */
- { USB_DEVICE(0x0573, 0x4d24) }, /* Hauppauge WinTV USB Pro (PAL D/K) */
- { USB_DEVICE(0x0573, 0x4d25) }, /* Hauppauge WinTV USB Pro (PAL/SECAM BGDK/I/L) */
- { USB_DEVICE(0x0573, 0x4d26) }, /* Hauppauge WinTV USB Pro (PAL/SECAM BGDK/I/L) */
- { USB_DEVICE(0x0573, 0x4d27) }, /* Hauppauge WinTV USB Pro (PAL B/G) */
- { USB_DEVICE(0x0573, 0x4d28) }, /* Hauppauge WinTV USB Pro (PAL B/G,D/K) */
- { USB_DEVICE(0x0573, 0x4d29) }, /* Hauppauge WinTV USB Pro (PAL I,D/K) */
- { USB_DEVICE(0x0573, 0x4d30) }, /* Hauppauge WinTV USB Pro (NTSC M/N FM) */
- { USB_DEVICE(0x0573, 0x4d31) }, /* Hauppauge WinTV USB Pro (PAL B/G FM) */
- { USB_DEVICE(0x0573, 0x4d32) }, /* Hauppauge WinTV USB Pro (PAL I FM) */
- { USB_DEVICE(0x0573, 0x4d34) }, /* Hauppauge WinTV USB Pro (PAL D/K FM) */
- { USB_DEVICE(0x0573, 0x4d35) }, /* Hauppauge WinTV USB Pro (Temic PAL/SECAM B/G/I/D/K/L FM) */
- { USB_DEVICE(0x0573, 0x4d36) }, /* Hauppauge WinTV USB Pro (Temic PAL B/G FM) */
- { USB_DEVICE(0x0573, 0x4d37) }, /* Hauppauge WinTV USB Pro (PAL/SECAM B/G/I/D/K/L FM) */
- { USB_DEVICE(0x0573, 0x4d38) }, /* Hauppauge WinTV USB Pro (NTSC M/N FM) */
- { USB_DEVICE(0x0768, 0x0006) }, /* Camtel Technology USB TV Genie Pro FM Model TVB330 */
- { USB_DEVICE(0x07d0, 0x0001) }, /* Digital Video Creator I */
- { USB_DEVICE(0x07d0, 0x0002) }, /* Global Village GV-007 (NTSC) */
- { USB_DEVICE(0x07d0, 0x0003) }, /* Dazzle Fusion Model DVC-50 Rev 1 (NTSC) */
- { USB_DEVICE(0x07d0, 0x0004) }, /* Dazzle Fusion Model DVC-80 Rev 1 (PAL) */
- { USB_DEVICE(0x07d0, 0x0005) }, /* Dazzle Fusion Model DVC-90 Rev 1 (SECAM) */
- { USB_DEVICE(0x07f8, 0x9104) }, /* Eskape Labs MyTV2Go */
- { USB_DEVICE(0x2304, 0x010d) }, /* Pinnacle Studio PCTV USB (PAL) */
- { USB_DEVICE(0x2304, 0x0109) }, /* Pinnacle Studio PCTV USB (SECAM) */
- { USB_DEVICE(0x2304, 0x0110) }, /* Pinnacle Studio PCTV USB (PAL) */
- { USB_DEVICE(0x2304, 0x0111) }, /* Miro PCTV USB */
- { USB_DEVICE(0x2304, 0x0112) }, /* Pinnacle Studio PCTV USB (NTSC) with FM radio */
- { USB_DEVICE(0x2304, 0x0210) }, /* Pinnacle Studio PCTV USB (PAL) with FM radio */
- { USB_DEVICE(0x2304, 0x0212) }, /* Pinnacle Studio PCTV USB (NTSC) with FM radio */
- { USB_DEVICE(0x2304, 0x0214) }, /* Pinnacle Studio PCTV USB (PAL) with FM radio */
- { USB_DEVICE(0x2304, 0x0300) }, /* Pinnacle Studio Linx Video input cable (NTSC) */
- { USB_DEVICE(0x2304, 0x0301) }, /* Pinnacle Studio Linx Video input cable (PAL) */
- { USB_DEVICE(0x2304, 0x0419) }, /* Pinnacle PCTV Bungee USB (PAL) FM */
- { USB_DEVICE(0x2400, 0x4200) }, /* Hauppauge WinTv-USB2 Model 42012 */
-
- { } /* Terminating entry */
+ { USB_DEVICE(0x0a6f, 0x0400), .driver_info=XANBOO },
+ { USB_DEVICE(0x050d, 0x0106), .driver_info=BELKIN_VIDEOBUS_II },
+ { USB_DEVICE(0x050d, 0x0207), .driver_info=BELKIN_VIDEOBUS },
+ { USB_DEVICE(0x050d, 0x0208), .driver_info=BELKIN_USB_VIDEOBUS_II },
+ { USB_DEVICE(0x0571, 0x0002), .driver_info=ECHOFX_INTERVIEW_LITE },
+ { USB_DEVICE(0x0573, 0x0003), .driver_info=USBGEAR_USBG_V1 },
+ { USB_DEVICE(0x0573, 0x0400), .driver_info=D_LINK_V100 },
+ { USB_DEVICE(0x0573, 0x2000), .driver_info=X10_USB_CAMERA },
+ { USB_DEVICE(0x0573, 0x2d00), .driver_info=HPG_WINTV_LIVE_PAL_BG },
+ { USB_DEVICE(0x0573, 0x2d01), .driver_info=HPG_WINTV_LIVE_PRO_NTSC_MN },
+ { USB_DEVICE(0x0573, 0x2101), .driver_info=ZORAN_PMD_NOGATECH },
+ { USB_DEVICE(0x0573, 0x4100), .driver_info=NOGATECH_USB_TV_NTSC_FM },
+ { USB_DEVICE(0x0573, 0x4110), .driver_info=PNY_USB_TV_NTSC_FM },
+ { USB_DEVICE(0x0573, 0x4450), .driver_info=PV_PLAYTV_USB_PRO_PAL_FM },
+ { USB_DEVICE(0x0573, 0x4550), .driver_info=ZT_721 },
+ { USB_DEVICE(0x0573, 0x4d00), .driver_info=HPG_WINTV_NTSC_MN },
+ { USB_DEVICE(0x0573, 0x4d01), .driver_info=HPG_WINTV_PAL_BG },
+ { USB_DEVICE(0x0573, 0x4d02), .driver_info=HPG_WINTV_PAL_I },
+ { USB_DEVICE(0x0573, 0x4d03), .driver_info=HPG_WINTV_PAL_SECAM_L },
+ { USB_DEVICE(0x0573, 0x4d04), .driver_info=HPG_WINTV_PAL_D_K },
+ { USB_DEVICE(0x0573, 0x4d10), .driver_info=HPG_WINTV_NTSC_FM },
+ { USB_DEVICE(0x0573, 0x4d11), .driver_info=HPG_WINTV_PAL_BG_FM },
+ { USB_DEVICE(0x0573, 0x4d12), .driver_info=HPG_WINTV_PAL_I_FM },
+ { USB_DEVICE(0x0573, 0x4d14), .driver_info=HPG_WINTV_PAL_D_K_FM },
+ { USB_DEVICE(0x0573, 0x4d2a), .driver_info=HPG_WINTV_PRO_NTSC_MN },
+ { USB_DEVICE(0x0573, 0x4d2b), .driver_info=HPG_WINTV_PRO_NTSC_MN_V2 },
+ { USB_DEVICE(0x0573, 0x4d2c), .driver_info=HPG_WINTV_PRO_PAL },
+ { USB_DEVICE(0x0573, 0x4d20), .driver_info=HPG_WINTV_PRO_NTSC_MN_V3 },
+ { USB_DEVICE(0x0573, 0x4d21), .driver_info=HPG_WINTV_PRO_PAL_BG },
+ { USB_DEVICE(0x0573, 0x4d22), .driver_info=HPG_WINTV_PRO_PAL_I },
+ { USB_DEVICE(0x0573, 0x4d23), .driver_info=HPG_WINTV_PRO_PAL_SECAM_L },
+ { USB_DEVICE(0x0573, 0x4d24), .driver_info=HPG_WINTV_PRO_PAL_D_K },
+ { USB_DEVICE(0x0573, 0x4d25), .driver_info=HPG_WINTV_PRO_PAL_SECAM },
+ { USB_DEVICE(0x0573, 0x4d26), .driver_info=HPG_WINTV_PRO_PAL_SECAM_V2 },
+ { USB_DEVICE(0x0573, 0x4d27), .driver_info=HPG_WINTV_PRO_PAL_BG_V2 },
+ { USB_DEVICE(0x0573, 0x4d28), .driver_info=HPG_WINTV_PRO_PAL_BG_D_K },
+ { USB_DEVICE(0x0573, 0x4d29), .driver_info=HPG_WINTV_PRO_PAL_I_D_K },
+ { USB_DEVICE(0x0573, 0x4d30), .driver_info=HPG_WINTV_PRO_NTSC_MN_FM },
+ { USB_DEVICE(0x0573, 0x4d31), .driver_info=HPG_WINTV_PRO_PAL_BG_FM },
+ { USB_DEVICE(0x0573, 0x4d32), .driver_info=HPG_WINTV_PRO_PAL_I_FM },
+ { USB_DEVICE(0x0573, 0x4d34), .driver_info=HPG_WINTV_PRO_PAL_D_K_FM },
+ { USB_DEVICE(0x0573, 0x4d35), .driver_info=HPG_WINTV_PRO_TEMIC_PAL_FM },
+ { USB_DEVICE(0x0573, 0x4d36), .driver_info=HPG_WINTV_PRO_TEMIC_PAL_BG_FM },
+ { USB_DEVICE(0x0573, 0x4d37), .driver_info=HPG_WINTV_PRO_PAL_FM },
+ { USB_DEVICE(0x0573, 0x4d38), .driver_info=HPG_WINTV_PRO_NTSC_MN_FM_V2 },
+ { USB_DEVICE(0x0768, 0x0006), .driver_info=CAMTEL_TVB330 },
+ { USB_DEVICE(0x07d0, 0x0001), .driver_info=DIGITAL_VIDEO_CREATOR_I },
+ { USB_DEVICE(0x07d0, 0x0002), .driver_info=GLOBAL_VILLAGE_GV_007_NTSC },
+ { USB_DEVICE(0x07d0, 0x0003), .driver_info=DAZZLE_DVC_50_REV_1_NTSC },
+ { USB_DEVICE(0x07d0, 0x0004), .driver_info=DAZZLE_DVC_80_REV_1_PAL },
+ { USB_DEVICE(0x07d0, 0x0005), .driver_info=DAZZLE_DVC_90_REV_1_SECAM },
+ { USB_DEVICE(0x07f8, 0x9104), .driver_info=ESKAPE_LABS_MYTV2GO },
+ { USB_DEVICE(0x2304, 0x010d), .driver_info=PINNA_PCTV_USB_PAL },
+ { USB_DEVICE(0x2304, 0x0109), .driver_info=PINNA_PCTV_USB_SECAM },
+ { USB_DEVICE(0x2304, 0x0110), .driver_info=PINNA_PCTV_USB_PAL_FM },
+ { USB_DEVICE(0x2304, 0x0111), .driver_info=MIRO_PCTV_USB },
+ { USB_DEVICE(0x2304, 0x0112), .driver_info=PINNA_PCTV_USB_NTSC_FM },
+ { USB_DEVICE(0x2304, 0x0210), .driver_info=PINNA_PCTV_USB_PAL_FM_V2 },
+ { USB_DEVICE(0x2304, 0x0212), .driver_info=PINNA_PCTV_USB_NTSC_FM_V2 },
+ { USB_DEVICE(0x2304, 0x0214), .driver_info=PINNA_PCTV_USB_PAL_FM_V3 },
+ { USB_DEVICE(0x2304, 0x0300), .driver_info=PINNA_LINX_VD_IN_CAB_NTSC },
+ { USB_DEVICE(0x2304, 0x0301), .driver_info=PINNA_LINX_VD_IN_CAB_PAL },
+ { USB_DEVICE(0x2304, 0x0419), .driver_info=PINNA_PCTV_BUNGEE_PAL_FM },
+ { USB_DEVICE(0x2400, 0x4200), .driver_info=HPG_WINTV },
};
MODULE_DEVICE_TABLE (usb, usbvision_table);
diff --git a/linux/drivers/media/video/usbvision/usbvision-cards.h b/linux/drivers/media/video/usbvision/usbvision-cards.h
new file mode 100644
index 000000000..512c5cee4
--- /dev/null
+++ b/linux/drivers/media/video/usbvision/usbvision-cards.h
@@ -0,0 +1,66 @@
+#define XANBOO 0
+#define BELKIN_VIDEOBUS_II 1
+#define BELKIN_VIDEOBUS 2
+#define BELKIN_USB_VIDEOBUS_II 3
+#define ECHOFX_INTERVIEW_LITE 4
+#define USBGEAR_USBG_V1 5
+#define D_LINK_V100 6
+#define X10_USB_CAMERA 7
+#define HPG_WINTV_LIVE_PAL_BG 8
+#define HPG_WINTV_LIVE_PRO_NTSC_MN 9
+#define ZORAN_PMD_NOGATECH 10
+#define NOGATECH_USB_TV_NTSC_FM 11
+#define PNY_USB_TV_NTSC_FM 12
+#define PV_PLAYTV_USB_PRO_PAL_FM 13
+#define ZT_721 14
+#define HPG_WINTV_NTSC_MN 15
+#define HPG_WINTV_PAL_BG 16
+#define HPG_WINTV_PAL_I 17
+#define HPG_WINTV_PAL_SECAM_L 18
+#define HPG_WINTV_PAL_D_K 19
+#define HPG_WINTV_NTSC_FM 20
+#define HPG_WINTV_PAL_BG_FM 21
+#define HPG_WINTV_PAL_I_FM 22
+#define HPG_WINTV_PAL_D_K_FM 23
+#define HPG_WINTV_PRO_NTSC_MN 24
+#define HPG_WINTV_PRO_NTSC_MN_V2 25
+#define HPG_WINTV_PRO_PAL 26
+#define HPG_WINTV_PRO_NTSC_MN_V3 27
+#define HPG_WINTV_PRO_PAL_BG 28
+#define HPG_WINTV_PRO_PAL_I 29
+#define HPG_WINTV_PRO_PAL_SECAM_L 30
+#define HPG_WINTV_PRO_PAL_D_K 31
+#define HPG_WINTV_PRO_PAL_SECAM 32
+#define HPG_WINTV_PRO_PAL_SECAM_V2 33
+#define HPG_WINTV_PRO_PAL_BG_V2 34
+#define HPG_WINTV_PRO_PAL_BG_D_K 35
+#define HPG_WINTV_PRO_PAL_I_D_K 36
+#define HPG_WINTV_PRO_NTSC_MN_FM 37
+#define HPG_WINTV_PRO_PAL_BG_FM 38
+#define HPG_WINTV_PRO_PAL_I_FM 39
+#define HPG_WINTV_PRO_PAL_D_K_FM 40
+#define HPG_WINTV_PRO_TEMIC_PAL_FM 41
+#define HPG_WINTV_PRO_TEMIC_PAL_BG_FM 42
+#define HPG_WINTV_PRO_PAL_FM 43
+#define HPG_WINTV_PRO_NTSC_MN_FM_V2 44
+#define CAMTEL_TVB330 45
+#define DIGITAL_VIDEO_CREATOR_I 46
+#define GLOBAL_VILLAGE_GV_007_NTSC 47
+#define DAZZLE_DVC_50_REV_1_NTSC 48
+#define DAZZLE_DVC_80_REV_1_PAL 49
+#define DAZZLE_DVC_90_REV_1_SECAM 50
+#define ESKAPE_LABS_MYTV2GO 51
+#define PINNA_PCTV_USB_PAL 52
+#define PINNA_PCTV_USB_SECAM 53
+#define PINNA_PCTV_USB_PAL_FM 54
+#define MIRO_PCTV_USB 55
+#define PINNA_PCTV_USB_NTSC_FM 56
+#define PINNA_PCTV_USB_PAL_FM_V2 57
+#define PINNA_PCTV_USB_NTSC_FM_V2 58
+#define PINNA_PCTV_USB_PAL_FM_V3 59
+#define PINNA_LINX_VD_IN_CAB_NTSC 60
+#define PINNA_LINX_VD_IN_CAB_PAL 61
+#define PINNA_PCTV_BUNGEE_PAL_FM 62
+#define HPG_WINTV 63
+
+extern const int usbvision_device_data_size;
diff --git a/linux/drivers/media/video/usbvision/usbvision-core.c b/linux/drivers/media/video/usbvision/usbvision-core.c
index 2d8dc023d..325561324 100644
--- a/linux/drivers/media/video/usbvision/usbvision-core.c
+++ b/linux/drivers/media/video/usbvision/usbvision-core.c
@@ -2103,8 +2103,8 @@ int usbvision_set_input(struct usb_usbvision *usbvision)
return 0;
/* Set input format expected from decoder*/
- if (usbvision_device_data[usbvision->DevModel].Vin_Reg1 >= 0) {
- value[0] = usbvision_device_data[usbvision->DevModel].Vin_Reg1 & 0xff;
+ if (usbvision_device_data[usbvision->DevModel].Vin_Reg1_override) {
+ value[0] = usbvision_device_data[usbvision->DevModel].Vin_Reg1;
} else if(usbvision_device_data[usbvision->DevModel].Codec == CODEC_SAA7113) {
/* SAA7113 uses 8 bit output */
value[0] = USBVISION_8_422_SYNC;
@@ -2175,8 +2175,8 @@ int usbvision_set_input(struct usb_usbvision *usbvision)
dvi_yuv_value = 0x00; /* U comes after V, Ya comes after U/V, Yb comes after Yb */
- if(usbvision_device_data[usbvision->DevModel].Dvi_yuv >= 0){
- dvi_yuv_value = usbvision_device_data[usbvision->DevModel].Dvi_yuv & 0xff;
+ if(usbvision_device_data[usbvision->DevModel].Dvi_yuv_override){
+ dvi_yuv_value = usbvision_device_data[usbvision->DevModel].Dvi_yuv;
}
else if(usbvision_device_data[usbvision->DevModel].Codec == CODEC_SAA7113) {
/* This changes as the fine sync control changes. Further investigation necessary */
@@ -2309,7 +2309,7 @@ static void call_usbvision_power_off(struct work_struct *work)
PDEBUG(DBG_FUNC, "");
down_interruptible(&usbvision->lock);
if(usbvision->user == 0) {
- usbvision_i2c_usb_del_bus(&usbvision->i2c_adap);
+ usbvision_i2c_unregister(usbvision);
usbvision_power_off(usbvision);
usbvision->initialized = 0;
diff --git a/linux/drivers/media/video/usbvision/usbvision-i2c.c b/linux/drivers/media/video/usbvision/usbvision-i2c.c
index e942b1bf2..e91add952 100644
--- a/linux/drivers/media/video/usbvision/usbvision-i2c.c
+++ b/linux/drivers/media/video/usbvision/usbvision-i2c.c
@@ -1,8 +1,8 @@
/*
- * I2C_ALGO_USB.C
+ * usbvision_i2c.c
* i2c algorithm for USB-I2C Bridges
*
- * Copyright (c) 1999-2005 Joerg Heckenbach <joerg@heckenbach-aw.de>
+ * Copyright (c) 1999-2007 Joerg Heckenbach <joerg@heckenbach-aw.de>
* Dwaine Garden <dwainegarden@rogers.com>
*
* This module is part of usbvision driver project.
@@ -42,7 +42,6 @@
#include "usbvision.h"
#define DBG_I2C 1<<0
-#define DBG_ALGO 1<<1
static int i2c_debug = 0;
@@ -52,22 +51,22 @@ MODULE_PARM_DESC(i2c_debug, "enable debug messages [i2c]");
#define PDEBUG(level, fmt, args...) \
if (i2c_debug & (level)) info("[%s:%d] " fmt, __PRETTY_FUNCTION__, __LINE__ , ## args)
-static int usbvision_i2c_write(void *data, unsigned char addr, char *buf,
+static int usbvision_i2c_write(struct usb_usbvision *usbvision, unsigned char addr, char *buf,
short len);
-static int usbvision_i2c_read(void *data, unsigned char addr, char *buf,
+static int usbvision_i2c_read(struct usb_usbvision *usbvision, unsigned char addr, char *buf,
short len);
static inline int try_write_address(struct i2c_adapter *i2c_adap,
unsigned char addr, int retries)
{
- void *data;
+ struct usb_usbvision *usbvision;
int i, ret = -1;
char buf[4];
- data = i2c_get_adapdata(i2c_adap);
+ usbvision = (struct usb_usbvision *)i2c_get_adapdata(i2c_adap);
buf[0] = 0x00;
for (i = 0; i <= retries; i++) {
- ret = (usbvision_i2c_write(data, addr, buf, 1));
+ ret = (usbvision_i2c_write(usbvision, addr, buf, 1));
if (ret == 1)
break; /* success! */
udelay(5);
@@ -76,8 +75,8 @@ static inline int try_write_address(struct i2c_adapter *i2c_adap,
udelay(10);
}
if (i) {
- PDEBUG(DBG_ALGO,"Needed %d retries for address %#2x", i, addr);
- PDEBUG(DBG_ALGO,"Maybe there's no device at this address");
+ PDEBUG(DBG_I2C,"Needed %d retries for address %#2x", i, addr);
+ PDEBUG(DBG_I2C,"Maybe there's no device at this address");
}
return ret;
}
@@ -85,13 +84,13 @@ static inline int try_write_address(struct i2c_adapter *i2c_adap,
static inline int try_read_address(struct i2c_adapter *i2c_adap,
unsigned char addr, int retries)
{
- void *data;
+ struct usb_usbvision *usbvision;
int i, ret = -1;
char buf[4];
- data = i2c_get_adapdata(i2c_adap);
+ usbvision = (struct usb_usbvision *)i2c_get_adapdata(i2c_adap);
for (i = 0; i <= retries; i++) {
- ret = (usbvision_i2c_read(data, addr, buf, 1));
+ ret = (usbvision_i2c_read(usbvision, addr, buf, 1));
if (ret == 1)
break; /* success! */
udelay(5);
@@ -100,8 +99,8 @@ static inline int try_read_address(struct i2c_adapter *i2c_adap,
udelay(10);
}
if (i) {
- PDEBUG(DBG_ALGO,"Needed %d retries for address %#2x", i, addr);
- PDEBUG(DBG_ALGO,"Maybe there's no device at this address");
+ PDEBUG(DBG_I2C,"Needed %d retries for address %#2x", i, addr);
+ PDEBUG(DBG_I2C,"Maybe there's no device at this address");
}
return ret;
}
@@ -155,32 +154,32 @@ static inline int usb_find_address(struct i2c_adapter *i2c_adap,
}
static int
-usb_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msgs[], int num)
+usbvision_i2c_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msgs[], int num)
{
struct i2c_msg *pmsg;
- void *data;
+ struct usb_usbvision *usbvision;
int i, ret;
unsigned char addr;
- data = i2c_get_adapdata(i2c_adap);
+ usbvision = (struct usb_usbvision *)i2c_get_adapdata(i2c_adap);
for (i = 0; i < num; i++) {
pmsg = &msgs[i];
ret = usb_find_address(i2c_adap, pmsg, i2c_adap->retries, &addr);
if (ret != 0) {
- PDEBUG(DBG_ALGO,"got NAK from device, message #%d", i);
+ PDEBUG(DBG_I2C,"got NAK from device, message #%d", i);
return (ret < 0) ? ret : -EREMOTEIO;
}
if (pmsg->flags & I2C_M_RD) {
/* read bytes into buffer */
- ret = (usbvision_i2c_read(data, addr, pmsg->buf, pmsg->len));
+ ret = (usbvision_i2c_read(usbvision, addr, pmsg->buf, pmsg->len));
if (ret < pmsg->len) {
return (ret < 0) ? ret : -EREMOTEIO;
}
} else {
/* write bytes from buffer */
- ret = (usbvision_i2c_write(data, addr, pmsg->buf, pmsg->len));
+ ret = (usbvision_i2c_write(usbvision, addr, pmsg->buf, pmsg->len));
if (ret < pmsg->len) {
return (ret < 0) ? ret : -EREMOTEIO;
}
@@ -194,7 +193,7 @@ static int algo_control(struct i2c_adapter *adapter, unsigned int cmd, unsigned
return 0;
}
-static u32 usb_func(struct i2c_adapter *adap)
+static u32 functionality(struct i2c_adapter *adap)
{
return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_10BIT_ADDR | I2C_FUNC_PROTOCOL_MANGLING;
}
@@ -213,7 +212,7 @@ static void dec_use(struct i2c_adapter *adap)
/* -----exported algorithm data: ------------------------------------- */
-static struct i2c_algorithm i2c_usb_algo = {
+static struct i2c_algorithm usbvision_algo = {
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)) && (LINUX_VERSION_CODE > KERNEL_VERSION(2,4,30))
.owner = THIS_MODULE,
#endif
@@ -221,10 +220,10 @@ static struct i2c_algorithm i2c_usb_algo = {
.name = "USB algorithm",
.id = I2C_ALGO_BIT, /* FIXME */
#endif
- .master_xfer = usb_xfer,
+ .master_xfer = usbvision_i2c_xfer,
.smbus_xfer = NULL,
.algo_control = algo_control,
- .functionality = usb_func,
+ .functionality = functionality,
};
@@ -234,44 +233,32 @@ static struct i2c_algorithm i2c_usb_algo = {
static int usbvision_i2c_usb_add_bus(struct i2c_adapter *adap)
{
PDEBUG(DBG_I2C, "I2C debugging is enabled [i2c]");
- PDEBUG(DBG_ALGO, "ALGO debugging is enabled [i2c]");
+ PDEBUG(DBG_I2C, "ALGO debugging is enabled [i2c]");
/* register new adapter to i2c module... */
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,14)
- adap->id |= i2c_usb_algo.id;
+ adap->id |= usbvision_algo.id;
#endif
- adap->algo = &i2c_usb_algo;
+ adap->algo = &usbvision_algo;
adap->timeout = 100; /* default values, should */
adap->retries = 3; /* be replaced by defines */
i2c_add_adapter(adap);
- PDEBUG(DBG_ALGO,"i2c bus for %s registered", adap->name);
+ PDEBUG(DBG_I2C,"i2c bus for %s registered", adap->name);
return 0;
}
-
-int usbvision_i2c_usb_del_bus(struct i2c_adapter *adap)
-{
-
- i2c_del_adapter(adap);
-
- PDEBUG(DBG_ALGO,"i2c bus for %s unregistered", adap->name);
-
- return 0;
-}
-
-
/* ----------------------------------------------------------------------- */
/* usbvision specific I2C functions */
/* ----------------------------------------------------------------------- */
static struct i2c_adapter i2c_adap_template;
static struct i2c_client i2c_client_template;
-int usbvision_init_i2c(struct usb_usbvision *usbvision)
+int usbvision_i2c_register(struct usb_usbvision *usbvision)
{
memcpy(&usbvision->i2c_adap, &i2c_adap_template,
sizeof(struct i2c_adapter));
@@ -289,7 +276,7 @@ int usbvision_init_i2c(struct usb_usbvision *usbvision)
usbvision->i2c_client.adapter = &usbvision->i2c_adap;
if (usbvision_write_reg(usbvision, USBVISION_SER_MODE, USBVISION_IIC_LRNACK) < 0) {
- printk(KERN_ERR "usbvision_init_i2c: can't write reg\n");
+ printk(KERN_ERR "usbvision_register: can't write reg\n");
return -EBUSY;
}
@@ -311,6 +298,16 @@ int usbvision_init_i2c(struct usb_usbvision *usbvision)
return usbvision_i2c_usb_add_bus(&usbvision->i2c_adap);
}
+int usbvision_i2c_unregister(struct usb_usbvision *usbvision)
+{
+
+ i2c_del_adapter(&(usbvision->i2c_adap));
+
+ PDEBUG(DBG_I2C,"i2c bus for %s unregistered", usbvision->i2c_adap.name);
+
+ return 0;
+}
+
void call_i2c_clients(struct usb_usbvision *usbvision, unsigned int cmd,
void *arg)
{
@@ -324,19 +321,12 @@ static int attach_inform(struct i2c_client *client)
usbvision = (struct usb_usbvision *)i2c_get_adapdata(client->adapter);
switch (client->addr << 1) {
- case 0x43:
- case 0x4b:
- {
- struct tuner_setup tun_setup;
-
- tun_setup.mode_mask = T_ANALOG_TV | T_RADIO;
- tun_setup.type = TUNER_TDA9887;
- tun_setup.addr = client->addr;
-
- call_i2c_clients(usbvision, TUNER_SET_TYPE_ADDR, &tun_setup);
-
+ case 0x42 << 1:
+ case 0x43 << 1:
+ case 0x4a << 1:
+ case 0x4b << 1:
+ PDEBUG(DBG_I2C,"attach_inform: tda9887 detected.");
break;
- }
case 0x42:
PDEBUG(DBG_I2C,"attach_inform: saa7114 detected.");
break;
@@ -373,11 +363,7 @@ static int detach_inform(struct i2c_client *client)
{
struct usb_usbvision *usbvision;
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
- usbvision = (struct usb_usbvision *)client->adapter->data;
-#else
usbvision = (struct usb_usbvision *)i2c_get_adapdata(client->adapter);
-#endif
PDEBUG(DBG_I2C,"usbvision[%d] detaches %s", usbvision->nr, client->name);
return 0;
@@ -508,7 +494,7 @@ static int usbvision_i2c_write_max4(struct usb_usbvision *usbvision,
return len;
}
-static int usbvision_i2c_write(void *data, unsigned char addr, char *buf,
+static int usbvision_i2c_write(struct usb_usbvision *usbvision, unsigned char addr, char *buf,
short len)
{
char *bufPtr = buf;
@@ -516,7 +502,6 @@ static int usbvision_i2c_write(void *data, unsigned char addr, char *buf,
int wrcount = 0;
int count;
int maxLen = 4;
- struct usb_usbvision *usbvision = (struct usb_usbvision *) data;
while (len > 0) {
count = (len > maxLen) ? maxLen : len;
@@ -531,14 +516,13 @@ static int usbvision_i2c_write(void *data, unsigned char addr, char *buf,
return wrcount;
}
-static int usbvision_i2c_read(void *data, unsigned char addr, char *buf,
+static int usbvision_i2c_read(struct usb_usbvision *usbvision, unsigned char addr, char *buf,
short len)
{
char temp[4];
int retval, i;
int rdcount = 0;
int count;
- struct usb_usbvision *usbvision = (struct usb_usbvision *) data;
while (len > 0) {
count = (len > 3) ? 4 : len;
diff --git a/linux/drivers/media/video/usbvision/usbvision-video.c b/linux/drivers/media/video/usbvision/usbvision-video.c
index 89aedd783..6a32c1479 100644
--- a/linux/drivers/media/video/usbvision/usbvision-video.c
+++ b/linux/drivers/media/video/usbvision/usbvision-video.c
@@ -83,6 +83,7 @@
#endif
#include "usbvision.h"
+#include "usbvision-cards.h"
#define DRIVER_AUTHOR "Joerg Heckenbach <joerg@heckenbach-aw.de>, Dwaine Garden <DwaineGarden@rogers.com>"
#define DRIVER_NAME "usbvision"
@@ -157,7 +158,6 @@ static int PowerOnAtOpen = 1; // Set the default device to power on at startu
static int video_nr = -1; // Sequential Number of Video Device
static int radio_nr = -1; // Sequential Number of Radio Device
static int vbi_nr = -1; // Sequential Number of VBI Device
-static char *CustomDevice=NULL; // Set as nothing....
// Grab parameters for the device driver
@@ -168,7 +168,6 @@ module_param(PowerOnAtOpen, int, 0444);
module_param(video_nr, int, 0444);
module_param(radio_nr, int, 0444);
module_param(vbi_nr, int, 0444);
-module_param(CustomDevice, charp, 0444);
#else // Old Style
MODULE_PARAM(isocMode, "i");
MODULE_PARM(video_debug, "i"); // Grab the Debug Mode of the device driver
@@ -178,7 +177,6 @@ MODULE_PARM(SwitchSVideoInput, "i"); // To help people with Black and White ou
MODULE_PARM(video_nr, "i"); // video_nr option allows to specify a certain /dev/videoX device (like /dev/video0 or /dev/video1 ...)
MODULE_PARM(radio_nr, "i"); // radio_nr option allows to specify a certain /dev/radioX device (like /dev/radio0 or /dev/radio1 ...)
MODULE_PARM(vbi_nr, "i"); // vbi_nr option allows to specify a certain /dev/vbiX device (like /dev/vbi0 or /dev/vbi1 ...)
-MODULE_PARM(CustomDevice, "s"); // .... CustomDevice
#endif
MODULE_PARM_DESC(isocMode, " Set the default format for ISOC endpoint. Default: 0x60 (Compression On)");
@@ -187,7 +185,6 @@ MODULE_PARM_DESC(PowerOnAtOpen, " Set the default device to power on when device
MODULE_PARM_DESC(video_nr, "Set video device number (/dev/videoX). Default: -1 (autodetect)");
MODULE_PARM_DESC(radio_nr, "Set radio device number (/dev/radioX). Default: -1 (autodetect)");
MODULE_PARM_DESC(vbi_nr, "Set vbi device number (/dev/vbiX). Default: -1 (autodetect)");
-MODULE_PARM_DESC(CustomDevice, " Define the fine tuning parameters for the device. Default: null");
// Misc stuff
@@ -429,7 +426,7 @@ static int usbvision_v4l2_open(struct inode *inode, struct file *file)
down(&usbvision->lock);
if (usbvision->power == 0) {
usbvision_power_on(usbvision);
- usbvision_init_i2c(usbvision);
+ usbvision_i2c_register(usbvision);
}
/* Send init sequence only once, it's large! */
@@ -451,7 +448,7 @@ static int usbvision_v4l2_open(struct inode *inode, struct file *file)
}
else {
if (PowerOnAtOpen) {
- usbvision_i2c_usb_del_bus(&usbvision->i2c_adap);
+ usbvision_i2c_unregister(usbvision);
usbvision_power_off(usbvision);
usbvision->initialized = 0;
}
@@ -1302,7 +1299,7 @@ static int usbvision_radio_open(struct inode *inode, struct file *file)
usbvision_reset_powerOffTimer(usbvision);
if (usbvision->power == 0) {
usbvision_power_on(usbvision);
- usbvision_init_i2c(usbvision);
+ usbvision_i2c_register(usbvision);
}
}
@@ -1327,7 +1324,7 @@ static int usbvision_radio_open(struct inode *inode, struct file *file)
MOD_DEC_USE_COUNT;
#endif
if (PowerOnAtOpen) {
- usbvision_i2c_usb_del_bus(&usbvision->i2c_adap);
+ usbvision_i2c_unregister(usbvision);
usbvision_power_off(usbvision);
usbvision->initialized = 0;
}
@@ -1913,8 +1910,8 @@ static void usbvision_configure_video(struct usb_usbvision *usbvision)
model = usbvision->DevModel;
usbvision->palette = usbvision_v4l2_format[2]; // V4L2_PIX_FMT_RGB24;
- if (usbvision_device_data[usbvision->DevModel].Vin_Reg2 >= 0) {
- usbvision->Vin_Reg2_Preset = usbvision_device_data[usbvision->DevModel].Vin_Reg2 & 0xff;
+ if (usbvision_device_data[usbvision->DevModel].Vin_Reg2_override) {
+ usbvision->Vin_Reg2_Preset = usbvision_device_data[usbvision->DevModel].Vin_Reg2;
} else {
usbvision->Vin_Reg2_Preset = 0;
}
@@ -1933,7 +1930,7 @@ static void usbvision_configure_video(struct usb_usbvision *usbvision)
usbvision_audio_off(usbvision); //first switch off audio
if (!PowerOnAtOpen) {
usbvision_power_on(usbvision); //and then power up the noisy tuner
- usbvision_init_i2c(usbvision);
+ usbvision_i2c_register(usbvision);
}
}
@@ -1944,74 +1941,29 @@ static void usbvision_configure_video(struct usb_usbvision *usbvision)
* if it looks like USBVISION video device
*
*/
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
-static void *usbvision_probe(struct usb_device *dev, unsigned int ifnum,
- const struct usb_device_id *id)
-{
- const struct usb_interface_descriptor *interface;
-#else
-static int __devinit usbvision_probe(struct usb_interface *intf, const struct usb_device_id *devid)
+static int __devinit usbvision_probe(struct usb_interface *intf,
+ const struct usb_device_id *devid)
{
struct usb_device *dev = usb_get_dev(interface_to_usbdev(intf));
struct usb_interface *uif;
__u8 ifnum = intf->altsetting->desc.bInterfaceNumber;
const struct usb_host_interface *interface;
-#endif
struct usb_usbvision *usbvision = NULL;
const struct usb_endpoint_descriptor *endpoint;
int model,i;
PDEBUG(DBG_PROBE, "VID=%#04x, PID=%#04x, ifnum=%u",
- dev->descriptor.idVendor, dev->descriptor.idProduct, ifnum);
-
- /* Is it an USBVISION video dev? */
- model = 0;
- for(model = 0; usbvision_device_data[model].idVendor; model++) {
- if (le16_to_cpu(dev->descriptor.idVendor) != usbvision_device_data[model].idVendor) {
- continue;
- }
- if (le16_to_cpu(dev->descriptor.idProduct) != usbvision_device_data[model].idProduct) {
- continue;
- }
+ dev->descriptor.idVendor,
+ dev->descriptor.idProduct, ifnum);
- printk(KERN_INFO "%s: %s found\n", __FUNCTION__, usbvision_device_data[model].ModelString);
- break;
- }
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
- if (usbvision_device_data[model].idVendor == 0) {
- return NULL; //no matching device
- }
- if (usbvision_device_data[model].Interface >= 0) {
- interface = &dev->actconfig->interface[usbvision_device_data[model].Interface].altsetting[0];
- }
- else {
- interface = &dev->actconfig->interface[ifnum].altsetting[0];
- }
- endpoint = &interface->endpoint[1];
-
- if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_ISOC) {
- err("%s: USBVision interface %d. has non-ISO endpoint!", __FUNCTION__, ifnum);
- err("%s: USBVision Endpoint attributes %d", __FUNCTION__, endpoint->bmAttributes);
- return NULL;
- }
- if ((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT) {
- err("%s: USBVision interface %d. has ISO OUT endpoint!", __FUNCTION__, ifnum);
- return NULL;
+ model = devid->driver_info;
+ if ( (model<0) || (model>=usbvision_device_data_size) ) {
+ PDEBUG(DBG_PROBE, "model out of bounds %d",model);
+ return -ENODEV;
}
+ printk(KERN_INFO "%s: %s found\n", __FUNCTION__,
+ usbvision_device_data[model].ModelString);
- MOD_INC_USE_COUNT;
-
- /* Allocate the usbvision device structure so that we can set some variables */
- if ((usbvision = usbvision_alloc(dev)) == NULL) {
- err("%s: couldn't allocate USBVision struct", __FUNCTION__);
- MOD_DEC_USE_COUNT;
- return NULL;
- }
-#else
- if (usbvision_device_data[model].idVendor == 0) {
- return -ENODEV; //no matching device
- }
if (usbvision_device_data[model].Interface >= 0) {
interface = &dev->actconfig->interface[usbvision_device_data[model].Interface]->altsetting[0];
}
@@ -2029,17 +1981,15 @@ static int __devinit usbvision_probe(struct usb_interface *intf, const struct us
return -ENODEV;
}
- usb_get_dev(dev);
-
if ((usbvision = usbvision_alloc(dev)) == NULL) {
err("%s: couldn't allocate USBVision struct", __FUNCTION__);
return -ENOMEM;
}
-#endif
+
if (dev->descriptor.bNumConfigurations > 1) {
usbvision->bridgeType = BRIDGE_NT1004;
}
- else if (usbvision_device_data[model].ModelString == "Dazzle Fusion Model DVC-90 Rev 1 (SECAM)") {
+ else if (model == DAZZLE_DVC_90_REV_1_SECAM) {
usbvision->bridgeType = BRIDGE_NT1005;
}
else {
@@ -2143,7 +2093,7 @@ static void __devexit usbvision_disconnect(struct usb_interface *intf)
usbvision_stop_isoc(usbvision);
if (usbvision->power) {
- usbvision_i2c_usb_del_bus(&usbvision->i2c_adap);
+ usbvision_i2c_unregister(usbvision);
usbvision_power_off(usbvision);
}
usbvision->remove_pending = 1; // Now all ISO data will be ignored
@@ -2182,124 +2132,6 @@ static struct usb_driver usbvision_driver = {
};
/*
- * customdevice_process()
- *
- * This procedure preprocesses CustomDevice parameter if any
- *
- */
-static void customdevice_process(void)
-{
- usbvision_device_data[0]=usbvision_device_data[1];
- usbvision_table[0]=usbvision_table[1];
-
- if(CustomDevice)
- {
- char *parse=CustomDevice;
-
- PDEBUG(DBG_PROBE, "CustomDevide=%s", CustomDevice);
-
- /*format is CustomDevice="0x0573 0x4D31 0 7113 3 PAL 1 1 1 5 -1 -1 -1 -1 -1"
- usbvision_device_data[0].idVendor;
- usbvision_device_data[0].idProduct;
- usbvision_device_data[0].Interface;
- usbvision_device_data[0].Codec;
- usbvision_device_data[0].VideoChannels;
- usbvision_device_data[0].VideoNorm;
- usbvision_device_data[0].AudioChannels;
- usbvision_device_data[0].Radio;
- usbvision_device_data[0].Tuner;
- usbvision_device_data[0].TunerType;
- usbvision_device_data[0].Vin_Reg1;
- usbvision_device_data[0].Vin_Reg2;
- usbvision_device_data[0].X_Offset;
- usbvision_device_data[0].Y_Offset;
- usbvision_device_data[0].Dvi_yuv;
- usbvision_device_data[0].ModelString;
- */
-
- rmspace(parse);
- usbvision_device_data[0].ModelString="USBVISION Custom Device";
-
- parse+=2;
- sscanf(parse,"%x",&usbvision_device_data[0].idVendor);
- goto2next(parse);
- PDEBUG(DBG_PROBE, "idVendor=0x%.4X", usbvision_device_data[0].idVendor);
- parse+=2;
- sscanf(parse,"%x",&usbvision_device_data[0].idProduct);
- goto2next(parse);
- PDEBUG(DBG_PROBE, "idProduct=0x%.4X", usbvision_device_data[0].idProduct);
- sscanf(parse,"%d",&usbvision_device_data[0].Interface);
- goto2next(parse);
- PDEBUG(DBG_PROBE, "Interface=%d", usbvision_device_data[0].Interface);
- sscanf(parse,"%d",&usbvision_device_data[0].Codec);
- goto2next(parse);
- PDEBUG(DBG_PROBE, "Codec=%d", usbvision_device_data[0].Codec);
- sscanf(parse,"%d",&usbvision_device_data[0].VideoChannels);
- goto2next(parse);
- PDEBUG(DBG_PROBE, "VideoChannels=%d", usbvision_device_data[0].VideoChannels);
-
- switch(*parse)
- {
- case 'P':
- PDEBUG(DBG_PROBE, "VideoNorm=PAL");
- usbvision_device_data[0].VideoNorm=V4L2_STD_PAL;
- break;
-
- case 'S':
- PDEBUG(DBG_PROBE, "VideoNorm=SECAM");
- usbvision_device_data[0].VideoNorm=V4L2_STD_SECAM;
- break;
-
- case 'N':
- PDEBUG(DBG_PROBE, "VideoNorm=NTSC");
- usbvision_device_data[0].VideoNorm=V4L2_STD_NTSC;
- break;
-
- default:
- PDEBUG(DBG_PROBE, "VideoNorm=PAL (by default)");
- usbvision_device_data[0].VideoNorm=V4L2_STD_PAL;
- break;
- }
- goto2next(parse);
-
- sscanf(parse,"%d",&usbvision_device_data[0].AudioChannels);
- goto2next(parse);
- PDEBUG(DBG_PROBE, "AudioChannels=%d", usbvision_device_data[0].AudioChannels);
- sscanf(parse,"%d",&usbvision_device_data[0].Radio);
- goto2next(parse);
- PDEBUG(DBG_PROBE, "Radio=%d", usbvision_device_data[0].Radio);
- sscanf(parse,"%d",&usbvision_device_data[0].Tuner);
- goto2next(parse);
- PDEBUG(DBG_PROBE, "Tuner=%d", usbvision_device_data[0].Tuner);
- sscanf(parse,"%d",&usbvision_device_data[0].TunerType);
- goto2next(parse);
- PDEBUG(DBG_PROBE, "TunerType=%d", usbvision_device_data[0].TunerType);
- sscanf(parse,"%d",&usbvision_device_data[0].Vin_Reg1);
- goto2next(parse);
- PDEBUG(DBG_PROBE, "Vin_Reg1=%d", usbvision_device_data[0].Vin_Reg1);
- sscanf(parse,"%d",&usbvision_device_data[0].Vin_Reg2);
- goto2next(parse);
- PDEBUG(DBG_PROBE, "Vin_Reg2=%d", usbvision_device_data[0].Vin_Reg2);
- sscanf(parse,"%d",&usbvision_device_data[0].X_Offset);
- goto2next(parse);
- PDEBUG(DBG_PROBE, "X_Offset=%d", usbvision_device_data[0].X_Offset);
- sscanf(parse,"%d",&usbvision_device_data[0].Y_Offset);
- goto2next(parse);
- PDEBUG(DBG_PROBE, "Y_Offset=%d", usbvision_device_data[0].Y_Offset);
- sscanf(parse,"%d",&usbvision_device_data[0].Dvi_yuv);
- PDEBUG(DBG_PROBE, "Dvi_yuv=%d", usbvision_device_data[0].Dvi_yuv);
-
- //add to usbvision_table also
- usbvision_table[0].match_flags=USB_DEVICE_ID_MATCH_DEVICE;
- usbvision_table[0].idVendor=usbvision_device_data[0].idVendor;
- usbvision_table[0].idProduct=usbvision_device_data[0].idProduct;
-
- }
-}
-
-
-
-/*
* usbvision_init()
*
* This code is run to initialize the driver.
@@ -2323,8 +2155,6 @@ static int __init usbvision_init(void)
usbvision_v4l2_format[7].supported = 0; // V4L2_PIX_FMT_YUV422P
}
- customdevice_process();
-
errCode = usb_register(&usbvision_driver);
if (errCode == 0) {
diff --git a/linux/drivers/media/video/usbvision/usbvision.h b/linux/drivers/media/video/usbvision/usbvision.h
index bee7d06bc..c810a6bda 100644
--- a/linux/drivers/media/video/usbvision/usbvision.h
+++ b/linux/drivers/media/video/usbvision/usbvision.h
@@ -342,23 +342,24 @@ struct usbvision_frame {
#define BRIDGE_NT1005 1005
struct usbvision_device_data_st {
- int idVendor;
- int idProduct;
- int Interface; /* to handle special interface number like BELKIN and Hauppauge WinTV-USB II */
- int Codec;
- int VideoChannels;
__u64 VideoNorm;
- int AudioChannels;
- int Radio;
- int vbi;
- int Tuner;
- int TunerType;
- int Vin_Reg1;
- int Vin_Reg2;
- int X_Offset;
- int Y_Offset;
- int Dvi_yuv;
- char *ModelString;
+ const char *ModelString;
+ int Interface; /* to handle special interface number like BELKIN and Hauppauge WinTV-USB II */
+ __u16 Codec;
+ unsigned VideoChannels:3;
+ unsigned AudioChannels:2;
+ unsigned Radio:1;
+ unsigned vbi:1;
+ unsigned Tuner:1;
+ unsigned Vin_Reg1_override:1; /* Override default value with */
+ unsigned Vin_Reg2_override:1; /* Vin_Reg1, Vin_Reg2, etc. */
+ unsigned Dvi_yuv_override:1;
+ __u8 Vin_Reg1;
+ __u8 Vin_Reg2;
+ __u8 Dvi_yuv;
+ __u8 TunerType;
+ __s16 X_Offset;
+ __s16 Y_Offset;
};
/* Declared on usbvision-cards.c */
@@ -485,34 +486,11 @@ struct usb_usbvision {
/* i2c-algo-usb declaration */
/* --------------------------------------------------------------- */
-int usbvision_i2c_usb_del_bus(struct i2c_adapter *);
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
-static inline void *i2c_get_clientdata (struct i2c_client *dev)
-{
- return dev->data;
-}
-
-static inline void i2c_set_clientdata (struct i2c_client *dev, void *data)
-{
- dev->data = data;
-}
-
-static inline void *i2c_get_adapdata (struct i2c_adapter *dev)
-{
- return dev->data;
-}
-
-static inline void i2c_set_adapdata (struct i2c_adapter *dev, void *data)
-{
- dev->data = data;
-}
-#endif
-
/* ----------------------------------------------------------------------- */
/* usbvision specific I2C functions */
/* ----------------------------------------------------------------------- */
-int usbvision_init_i2c(struct usb_usbvision *usbvision);
+int usbvision_i2c_register(struct usb_usbvision *usbvision);
+int usbvision_i2c_unregister(struct usb_usbvision *usbvision);
void call_i2c_clients(struct usb_usbvision *usbvision, unsigned int cmd,void *arg);
/* defined in usbvision-core.c */
diff --git a/linux/drivers/media/video/v4l1-compat.c b/linux/drivers/media/video/v4l1-compat.c
index 2e42ee3a2..253771b0b 100644
--- a/linux/drivers/media/video/v4l1-compat.c
+++ b/linux/drivers/media/video/v4l1-compat.c
@@ -129,7 +129,7 @@ set_v4l_control(struct inode *inode,
/* ----------------------------------------------------------------- */
-static int palette2pixelformat[] = {
+const static unsigned int palette2pixelformat[] = {
[VIDEO_PALETTE_GREY] = V4L2_PIX_FMT_GREY,
[VIDEO_PALETTE_RGB555] = V4L2_PIX_FMT_RGB555,
[VIDEO_PALETTE_RGB565] = V4L2_PIX_FMT_RGB565,
@@ -147,7 +147,7 @@ static int palette2pixelformat[] = {
[VIDEO_PALETTE_YUV422P] = V4L2_PIX_FMT_YUV422P,
};
-static unsigned int
+static unsigned int __attribute_pure__
palette_to_pixelformat(unsigned int palette)
{
if (palette < ARRAY_SIZE(palette2pixelformat))
@@ -156,8 +156,8 @@ palette_to_pixelformat(unsigned int palette)
return 0;
}
-static unsigned int
-pixelformat_to_palette(int pixelformat)
+static unsigned int __attribute_const__
+pixelformat_to_palette(unsigned int pixelformat)
{
int palette = 0;
switch (pixelformat)
@@ -629,6 +629,8 @@ v4l_compat_translate_ioctl(struct inode *inode,
case VIDIOCSPICT: /* set tone controls & partial capture format */
{
struct video_picture *pict = arg;
+ int mem_err = 0, ovl_err = 0;
+
memset(&fbuf2, 0, sizeof(fbuf2));
set_v4l_control(inode, file,
@@ -641,33 +643,61 @@ v4l_compat_translate_ioctl(struct inode *inode,
V4L2_CID_SATURATION, pict->colour, drv);
set_v4l_control(inode, file,
V4L2_CID_WHITENESS, pict->whiteness, drv);
+ /*
+ * V4L1 uses this ioctl to set both memory capture and overlay
+ * pixel format, while V4L2 has two different ioctls for this.
+ * Some cards may not support one or the other, and may support
+ * different pixel formats for memory vs overlay.
+ */
fmt2 = kzalloc(sizeof(*fmt2),GFP_KERNEL);
fmt2->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
err = drv(inode, file, VIDIOC_G_FMT, fmt2);
- if (err < 0)
+ /* If VIDIOC_G_FMT failed, then the driver likely doesn't
+ support memory capture. Trying to set the memory capture
+ parameters would be pointless. */
+ if (err < 0) {
dprintk("VIDIOCSPICT / VIDIOC_G_FMT: %d\n",err);
- if (fmt2->fmt.pix.pixelformat !=
- palette_to_pixelformat(pict->palette)) {
+ mem_err = -1000; /* didn't even try */
+ } else if (fmt2->fmt.pix.pixelformat !=
+ palette_to_pixelformat(pict->palette)) {
fmt2->fmt.pix.pixelformat = palette_to_pixelformat(
pict->palette);
- err = drv(inode, file, VIDIOC_S_FMT, fmt2);
- if (err < 0)
- dprintk("VIDIOCSPICT / VIDIOC_S_FMT: %d\n",err);
+ mem_err = drv(inode, file, VIDIOC_S_FMT, fmt2);
+ if (mem_err < 0)
+ dprintk("VIDIOCSPICT / VIDIOC_S_FMT: %d\n",
+ mem_err);
}
err = drv(inode, file, VIDIOC_G_FBUF, &fbuf2);
- if (err < 0)
+ /* If VIDIOC_G_FBUF failed, then the driver likely doesn't
+ support overlay. Trying to set the overlay parameters
+ would be quite pointless. */
+ if (err < 0) {
dprintk("VIDIOCSPICT / VIDIOC_G_FBUF: %d\n",err);
- if (fbuf2.fmt.pixelformat !=
- palette_to_pixelformat(pict->palette)) {
+ ovl_err = -1000; /* didn't even try */
+ } else if (fbuf2.fmt.pixelformat !=
+ palette_to_pixelformat(pict->palette)) {
fbuf2.fmt.pixelformat = palette_to_pixelformat(
pict->palette);
- err = drv(inode, file, VIDIOC_S_FBUF, &fbuf2);
- if (err < 0)
- dprintk("VIDIOCSPICT / VIDIOC_S_FBUF: %d\n",err);
- err = 0; /* likely fails for non-root */
+ ovl_err = drv(inode, file, VIDIOC_S_FBUF, &fbuf2);
+ if (ovl_err < 0)
+ dprintk("VIDIOCSPICT / VIDIOC_S_FBUF: %d\n",
+ ovl_err);
+ if (ovl_err == -EPERM)
+ ovl_err = 0;
}
+ if (ovl_err < 0 && mem_err < 0)
+ /* ioctl failed, couldn't set either parameter */
+ if (mem_err != -1000) {
+ err = mem_err;
+ } else if (ovl_err == -EPERM) {
+ err = 0;
+ } else {
+ err = ovl_err;
+ }
+ else
+ err = 0;
break;
}
case VIDIOCGTUNER: /* get tuner information */
diff --git a/linux/drivers/media/video/video-buf.c b/linux/drivers/media/video/video-buf.c
index 5564e20af..c053375bb 100644
--- a/linux/drivers/media/video/video-buf.c
+++ b/linux/drivers/media/video/video-buf.c
@@ -708,9 +708,7 @@ videobuf_qbuf(struct videobuf_queue *q,
dprintk(1,"qbuf: memory type is wrong.\n");
goto done;
}
- if (buf->state == STATE_QUEUED ||
- buf->state == STATE_PREPARED ||
- buf->state == STATE_ACTIVE) {
+ if (buf->state != STATE_NEEDS_INIT && buf->state != STATE_IDLE) {
dprintk(1,"qbuf: buffer is already queued or active.\n");
goto done;
}
diff --git a/linux/drivers/media/video/videocodec.c b/linux/drivers/media/video/videocodec.c
index 290e64135..f2bbd7a4d 100644
--- a/linux/drivers/media/video/videocodec.c
+++ b/linux/drivers/media/video/videocodec.c
@@ -348,6 +348,9 @@ videocodec_build_table (void)
kfree(videocodec_buf);
videocodec_buf = kmalloc(size, GFP_KERNEL);
+ if (!videocodec_buf)
+ return 0;
+
i = 0;
i += scnprintf(videocodec_buf + i, size - 1,
"<S>lave or attached <M>aster name type flags magic ");
diff --git a/linux/drivers/media/video/videodev.c b/linux/drivers/media/video/videodev.c
index acb3c4fbf..b8e022aed 100644
--- a/linux/drivers/media/video/videodev.c
+++ b/linux/drivers/media/video/videodev.c
@@ -461,9 +461,39 @@ static int __video_do_ioctl(struct inode *inode, struct file *file,
v4l_print_ioctl(vfd->name, cmd);
}
+#ifdef CONFIG_VIDEO_V4L1_COMPAT
+ /***********************************************************
+ Handles calls to the obsoleted V4L1 API
+ Due to the nature of VIDIOCGMBUF, each driver that supports
+ V4L1 should implement its own handler for this ioctl.
+ ***********************************************************/
+
+ /* --- streaming capture ------------------------------------- */
+ if (cmd == VIDIOCGMBUF) {
+ struct video_mbuf *p=arg;
+
+ memset(p,0,sizeof(p));
+
+ if (!vfd->vidiocgmbuf)
+ return ret;
+ ret=vfd->vidiocgmbuf(file, fh, p);
+ if (!ret)
+ dbgarg (cmd, "size=%d, frames=%d, offsets=0x%08lx\n",
+ p->size, p->frames,
+ (unsigned long)p->offsets);
+ return ret;
+ }
+
+ /********************************************************
+ All other V4L1 calls are handled by v4l1_compat module.
+ Those calls will be translated into V4L2 calls, and
+ __video_do_ioctl will be called again, with one or more
+ V4L2 ioctls.
+ ********************************************************/
if (_IOC_TYPE(cmd)=='v')
return v4l_compat_translate_ioctl(inode,file,cmd,arg,
__video_do_ioctl);
+#endif
switch(cmd) {
/* --- capabilities ------------------------------------------ */
@@ -815,24 +845,6 @@ static int __video_do_ioctl(struct inode *inode, struct file *file,
ret=vfd->vidioc_overlay(file, fh, *i);
break;
}
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
- /* --- streaming capture ------------------------------------- */
- case VIDIOCGMBUF:
- {
- struct video_mbuf *p=arg;
-
- memset(p,0,sizeof(p));
-
- if (!vfd->vidiocgmbuf)
- break;
- ret=vfd->vidiocgmbuf(file, fh, p);
- if (!ret)
- dbgarg (cmd, "size=%d, frames=%d, offsets=0x%08lx\n",
- p->size, p->frames,
- (unsigned long)p->offsets);
- break;
- }
-#endif
case VIDIOC_G_FBUF:
{
struct v4l2_framebuffer *p=arg;
@@ -1427,6 +1439,11 @@ static int __video_do_ioctl(struct inode *inode, struct file *file,
case VIDIOC_G_PARM:
{
struct v4l2_streamparm *p=arg;
+ __u32 type=p->type;
+
+ memset(p,0,sizeof(*p));
+ p->type=type;
+
if (vfd->vidioc_g_parm) {
ret=vfd->vidioc_g_parm(file, fh, p);
} else {
@@ -1438,8 +1455,6 @@ static int __video_do_ioctl(struct inode *inode, struct file *file,
v4l2_video_std_construct(&s, vfd->current_norm,
v4l2_norm_to_name(vfd->current_norm));
- memset(p,0,sizeof(*p));
-
p->parm.capture.timeperframe = s.frameperiod;
ret=0;
}
diff --git a/linux/drivers/media/video/zc0301/Kconfig b/linux/drivers/media/video/zc0301/Kconfig
index a859a6920..47cd93f9c 100644
--- a/linux/drivers/media/video/zc0301/Kconfig
+++ b/linux/drivers/media/video/zc0301/Kconfig
@@ -1,6 +1,6 @@
config USB_ZC0301
tristate "USB ZC0301[P] Image Processor and Control Chip support"
- depends on USB && VIDEO_V4L1
+ depends on VIDEO_V4L1
---help---
Say Y here if you want support for cameras based on the ZC0301 or
ZC0301P Image Processors and Control Chips.
diff --git a/linux/include/media/saa7146.h b/linux/include/media/saa7146.h
index ab0a60b4d..1904940e3 100644
--- a/linux/include/media/saa7146.h
+++ b/linux/include/media/saa7146.h
@@ -70,6 +70,7 @@ struct saa7146_pgtable {
unsigned long offset;
/* used for custom pagetables (used for example by budget dvb cards) */
struct scatterlist *slist;
+ int nents;
};
struct saa7146_pci_extension_data {
@@ -181,6 +182,7 @@ int saa7146_pgtable_alloc(struct pci_dev *pci, struct saa7146_pgtable *pt);
void saa7146_pgtable_free(struct pci_dev *pci, struct saa7146_pgtable *pt);
int saa7146_pgtable_build_single(struct pci_dev *pci, struct saa7146_pgtable *pt, struct scatterlist *list, int length );
char *saa7146_vmalloc_build_pgtable(struct pci_dev *pci, long length, struct saa7146_pgtable *pt);
+void saa7146_vfree_destroy_pgtable(struct pci_dev *pci, char *mem, struct saa7146_pgtable *pt);
void saa7146_setgpio(struct saa7146_dev *dev, int port, u32 data);
int saa7146_wait_for_debi_done(struct saa7146_dev *dev, int nobusyloop);
diff --git a/linux/include/media/saa7146_vv.h b/linux/include/media/saa7146_vv.h
index 50e33b0e9..cce20ed5c 100644
--- a/linux/include/media/saa7146_vv.h
+++ b/linux/include/media/saa7146_vv.h
@@ -216,6 +216,8 @@ void saa7146_set_gpio(struct saa7146_dev *saa, u8 pin, u8 data);
extern struct saa7146_use_ops saa7146_video_uops;
int saa7146_start_preview(struct saa7146_fh *fh);
int saa7146_stop_preview(struct saa7146_fh *fh);
+int saa7146_video_do_ioctl(struct inode *inode, struct file *file,
+ unsigned int cmd, void *arg);
/* from saa7146_vbi.c */
extern struct saa7146_use_ops saa7146_vbi_uops;