Commit aa5bc2b5 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'master' of ssh://master.kernel.org/pub/scm/linux/kernel/git/mchehab/v4l-dvb

* 'master' of ssh://master.kernel.org/pub/scm/linux/kernel/git/mchehab/v4l-dvb: (184 commits)
  V4L/DVB (5563): Radio-maestro.c Replace radio_ioctl to use video_ioctl2
  V4L/DVB (5562): Radio-gemtek-pci.c Replace gemtek_pci_ioctl to use video_ioctl2
  V4L/DVB (5560): Ivtv: fix incorrect bitwise-and for command flags.
  V4L/DVB (5558): Opera: use 7-bit i2c addresses
  V4L/DVB (5557): Cafe_ccic: check return value of pci_enable_device
  V4L/DVB (5556): Radio-gemtek.c Replace gemtek_ioctl to use video_ioctl2
  V4L/DVB (5555): Radio-aimslab.c Replace rt_ioctl to use video_ioctl2
  V4L/DVB (5554): Fix: vidioc_g_parm were not zeroing the memory
  V4L/DVB (5553): Replace typhoon_do_ioctl to use video_ioctl2
  V4L/DVB (5552): Plan-b: Switch to refcounting PCI API
  V4L/DVB (5551): Plan-b: header change
  V4L/DVB (5550): Radio-sf16fmi.c Replace fmi_do_ioctl to use video_ioctl2
  V4L/DVB (5549): Radio-sf16fmr2.c Replace fmr2_do_ioctl to use video_ioctl2
  V4L/DVB (5548): Fix v4l2 buffer to the length
  V4L/DVB (5547): Add ENUM_FRAMESIZES and ENUM_FRAMEINTERVALS ioctls
  V4L/DVB (5546): Radio-terratec.c Replace tt_do_ioctl to use video_ioctl2
  V4L/DVB (5545): Saa7146: Release capture buffers on device close
  V4L/DVB (5544): Budget-av: Make inversion setting configurable, add KNC ONE V1.0 card
  V4L/DVB (5543): Tda10023: Add support for frontend TDA10023
  V4L/DVB (5542): Budget-av: Remove polarity switching of the clock for DVB-C
  ...
parents d868772f d455cf5d
...@@ -6,6 +6,18 @@ be removed from this file. ...@@ -6,6 +6,18 @@ be removed from this file.
--------------------------- ---------------------------
What: V4L2 VIDIOC_G_MPEGCOMP and VIDIOC_S_MPEGCOMP
When: October 2007
Why: Broken attempt to set MPEG compression parameters. These ioctls are
not able to implement the wide variety of parameters that can be set
by hardware MPEG encoders. A new MPEG control mechanism was created
in kernel 2.6.18 that replaces these ioctls. See the V4L2 specification
(section 1.9: Extended controls) for more information on this topic.
Who: Hans Verkuil <hverkuil@xs4all.nl> and
Mauro Carvalho Chehab <mchehab@infradead.org>
---------------------------
What: /sys/devices/.../power/state What: /sys/devices/.../power/state
dev->power.power_state dev->power.power_state
dpm_runtime_{suspend,resume)() dpm_runtime_{suspend,resume)()
......
...@@ -143,3 +143,5 @@ ...@@ -143,3 +143,5 @@
142 -> Sabrent TV-FM (bttv version) 142 -> Sabrent TV-FM (bttv version)
143 -> Hauppauge ImpactVCB (bt878) [0070:13eb] 143 -> Hauppauge ImpactVCB (bt878) [0070:13eb]
144 -> MagicTV 144 -> MagicTV
145 -> SSAI Security Video Interface [4149:5353]
146 -> SSAI Ultrasound Video Interface [414a:5353]
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
36 -> AVerTV 303 (M126) [1461:000a] 36 -> AVerTV 303 (M126) [1461:000a]
37 -> Hauppauge Nova-S-Plus DVB-S [0070:9201,0070:9202] 37 -> Hauppauge Nova-S-Plus DVB-S [0070:9201,0070:9202]
38 -> Hauppauge Nova-SE2 DVB-S [0070:9200] 38 -> Hauppauge Nova-SE2 DVB-S [0070:9200]
39 -> KWorld DVB-S 100 [17de:08b2] 39 -> KWorld DVB-S 100 [17de:08b2,1421:0341]
40 -> Hauppauge WinTV-HVR1100 DVB-T/Hybrid [0070:9400,0070:9402] 40 -> Hauppauge WinTV-HVR1100 DVB-T/Hybrid [0070:9400,0070:9402]
41 -> Hauppauge WinTV-HVR1100 DVB-T/Hybrid (Low Profile) [0070:9800,0070:9802] 41 -> Hauppauge WinTV-HVR1100 DVB-T/Hybrid (Low Profile) [0070:9800,0070:9802]
42 -> digitalnow DNTV Live! DVB-T Pro [1822:0025,1822:0019] 42 -> digitalnow DNTV Live! DVB-T Pro [1822:0025,1822:0019]
......
1 -> Hauppauge WinTV PVR-250
2 -> Hauppauge WinTV PVR-350
3 -> Hauppauge WinTV PVR-150 or PVR-500
4 -> AVerMedia M179 [1461:a3ce,1461:a3cf]
5 -> Yuan MPG600/Kuroutoshikou iTVC16-STVLP [12ab:fff3,12ab:ffff]
6 -> Yuan MPG160/Kuroutoshikou iTVC15-STVLP [12ab:0000,10fc:40a0]
7 -> Yuan PG600/DiamondMM PVR-550 [ff92:0070,ffab:0600]
8 -> Adaptec AVC-2410 [9005:0093]
9 -> Adaptec AVC-2010 [9005:0092]
10 -> NAGASE TRANSGEAR 5000TV [1461:bfff]
11 -> AOpen VA2000MAX-STN6 [0000:ff5f]
12 -> YUAN MPG600GR/Kuroutoshikou CX23416GYC-STVLP [12ab:0600,fbab:0600,1154:0523]
13 -> I/O Data GV-MVP/RX [10fc:d01e,10fc:d038,10fc:d039]
14 -> I/O Data GV-MVP/RX2E [10fc:d025]
15 -> GOTVIEW PCI DVD (partial support only) [12ab:0600]
16 -> GOTVIEW PCI DVD2 Deluxe [ffac:0600]
17 -> Yuan MPC622 [ff01:d998]
18 -> Digital Cowboy DCT-MTVP1 [1461:bfff]
...@@ -53,7 +53,7 @@ ...@@ -53,7 +53,7 @@
52 -> AverMedia AverTV/305 [1461:2108] 52 -> AverMedia AverTV/305 [1461:2108]
53 -> ASUS TV-FM 7135 [1043:4845] 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,1489:0214,5168:0304]
55 -> LifeView FlyDVB-T DUO [5168:0306] 55 -> LifeView FlyDVB-T DUO / MSI TV@nywhere Duo [5168:0306,4E42:0306]
56 -> Avermedia AVerTV 307 [1461:a70a] 56 -> Avermedia AVerTV 307 [1461:a70a]
57 -> Avermedia AVerTV GO 007 FM [1461:f31f] 57 -> Avermedia AVerTV GO 007 FM [1461:f31f]
58 -> ADS Tech Instant TV (saa7135) [1421:0350,1421:0351,1421:0370,1421:1370] 58 -> ADS Tech Instant TV (saa7135) [1421:0350,1421:0351,1421:0370,1421:1370]
...@@ -76,7 +76,7 @@ ...@@ -76,7 +76,7 @@
75 -> AVerMedia AVerTVHD MCE A180 [1461:1044] 75 -> AVerMedia AVerTVHD MCE A180 [1461:1044]
76 -> SKNet MonsterTV Mobile [1131:4ee9] 76 -> SKNet MonsterTV Mobile [1131:4ee9]
77 -> Pinnacle PCTV 40i/50i/110i (saa7133) [11bd:002e] 77 -> Pinnacle PCTV 40i/50i/110i (saa7133) [11bd:002e]
78 -> ASUSTeK P7131 Dual [1043:4862,1043:4876] 78 -> ASUSTeK P7131 Dual [1043:4862,1043:4857]
79 -> Sedna/MuchTV PC TV Cardbus TV/Radio (ITO25 Rev:2B) 79 -> Sedna/MuchTV PC TV Cardbus TV/Radio (ITO25 Rev:2B)
80 -> ASUS Digimatrix TV [1043:0210] 80 -> ASUS Digimatrix TV [1043:0210]
81 -> Philips Tiger reference design [1131:2018] 81 -> Philips Tiger reference design [1131:2018]
...@@ -107,3 +107,7 @@ ...@@ -107,3 +107,7 @@
106 -> Encore ENLTV [1131:2342,1131:2341,3016:2344] 106 -> Encore ENLTV [1131:2342,1131:2341,3016:2344]
107 -> Encore ENLTV-FM [1131:230f] 107 -> Encore ENLTV-FM [1131:230f]
108 -> Terratec Cinergy HT PCI [153b:1175] 108 -> Terratec Cinergy HT PCI [153b:1175]
109 -> Philips Tiger - S Reference design
110 -> Avermedia M102 [1461:f31e]
111 -> ASUS P7131 4871 [1043:4871]
112 -> ASUSTeK P7131 Hybrid [1043:4876]
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]
ivtv release notes
==================
This is a v4l2 device driver for the Conexant cx23415/6 MPEG encoder/decoder.
The cx23415 can do both encoding and decoding, the cx23416 can only do MPEG
encoding. Currently the only card featuring full decoding support is the
Hauppauge PVR-350.
NOTE: this driver requires the latest encoder firmware (version 2.06.039, size
376836 bytes). Get the firmware from here:
http://dl.ivtvdriver.org/ivtv/firmware/firmware.tar.gz
NOTE: 'normal' TV applications do not work with this driver, you need
an application that can handle MPEG input such as mplayer, xine, MythTV,
etc.
The primary goal of the IVTV project is to provide a "clean room" Linux
Open Source driver implementation for video capture cards based on the
iCompression iTVC15 or Conexant CX23415/CX23416 MPEG Codec.
Features:
* Hardware mpeg2 capture of broadcast video (and sound) via the tuner or
S-Video/Composite and audio line-in.
* Hardware mpeg2 capture of FM radio where hardware support exists
* Supports NTSC, PAL, SECAM with stereo sound
* Supports SAP and bilingual transmissions.
* Supports raw VBI (closed captions and teletext).
* Supports sliced VBI (closed captions and teletext) and is able to insert
this into the captured MPEG stream.
* Supports raw YUV and PCM input.
Additional features for the PVR-350 (CX23415 based):
* Provides hardware mpeg2 playback
* Provides comprehensive OSD (On Screen Display: ie. graphics overlaying the
video signal)
* Provides a framebuffer (allowing X applications to appear on the video
device) (this framebuffer is not yet part of the kernel. In the meantime it
is available from www.ivtvdriver.org).
* Supports raw YUV output.
IMPORTANT: In case of problems first read this page:
http://www.ivtvdriver.org/index.php/Troubleshooting
See also:
Homepage + Wiki
http://www.ivtvdriver.org
IRC
irc://irc.freenode.net/ivtv-dev
----------------------------------------------------------
Devices
=======
A maximum of 12 ivtv boards are allowed at the moment.
Cards that don't have a video output capability (i.e. non PVR350 cards)
lack the vbi8, vbi16, video16 and video48 devices. They also do not
support the framebuffer device /dev/fbx for OSD.
The radio0 device may or may not be present, depending on whether the
card has a radio tuner or not.
Here is a list of the base v4l devices:
crw-rw---- 1 root video 81, 0 Jun 19 22:22 /dev/video0
crw-rw---- 1 root video 81, 16 Jun 19 22:22 /dev/video16
crw-rw---- 1 root video 81, 24 Jun 19 22:22 /dev/video24
crw-rw---- 1 root video 81, 32 Jun 19 22:22 /dev/video32
crw-rw---- 1 root video 81, 48 Jun 19 22:22 /dev/video48
crw-rw---- 1 root video 81, 64 Jun 19 22:22 /dev/radio0
crw-rw---- 1 root video 81, 224 Jun 19 22:22 /dev/vbi0
crw-rw---- 1 root video 81, 228 Jun 19 22:22 /dev/vbi8
crw-rw---- 1 root video 81, 232 Jun 19 22:22 /dev/vbi16
Base devices
============
For every extra card you have the numbers increased by one. For example,
/dev/video0 is listed as the 'base' encoding capture device so we have:
/dev/video0 is the encoding capture device for the first card (card 0)
/dev/video1 is the encoding capture device for the second card (card 1)
/dev/video2 is the encoding capture device for the third card (card 2)
Note that if the first card doesn't have a feature (eg no decoder, so no
video16, the second card will still use video17. The simple rule is 'add
the card number to the base device number'. If you have other capture
cards (e.g. WinTV PCI) that are detected first, then you have to tell
the ivtv module about it so that it will start counting at 1 (or 2, or
whatever). Otherwise the device numbers can get confusing. The ivtv
'ivtv_first_minor' module option can be used for that.
/dev/video0
The encoding capture device(s).
Read-only.
Reading from this device gets you the MPEG1/2 program stream.
Example:
cat /dev/video0 > my.mpg (you need to hit ctrl-c to exit)
/dev/video16
The decoder output device(s)
Write-only. Only present if the MPEG decoder (i.e. CX23415) exists.
An mpeg2 stream sent to this device will appear on the selected video
display, audio will appear on the line-out/audio out. It is only
available for cards that support video out. Example:
cat my.mpg >/dev/video16
/dev/video24
The raw audio capture device(s).
Read-only
The raw audio PCM stereo stream from the currently selected
tuner or audio line-in. Reading from this device results in a raw
(signed 16 bit Little Endian, 48000 Hz, stereo pcm) capture.
This device only captures audio. This should be replaced by an ALSA
device in the future.
Note that there is no corresponding raw audio output device, this is
not supported in the decoder firmware.
/dev/video32
The raw video capture device(s)
Read-only
The raw YUV video output from the current video input. The YUV format
is non-standard (V4L2_PIX_FMT_HM12).
Note that the YUV and PCM streams are not synchronized, so they are of
limited use.
/dev/video48
The raw video display device(s)
Write-only. Only present if the MPEG decoder (i.e. CX23415) exists.
Writes a YUV stream to the decoder of the card.
/dev/radio0
The radio tuner device(s)
Cannot be read or written.
Used to enable the radio tuner and tune to a frequency. You cannot
read or write audio streams with this device. Once you use this
device to tune the radio, use /dev/video24 to read the raw pcm stream
or /dev/video0 to get an mpeg2 stream with black video.
/dev/vbi0
The 'vertical blank interval' (Teletext, CC, WSS etc) capture device(s)
Read-only
Captures the raw (or sliced) video data sent during the Vertical Blank
Interval. This data is used to encode teletext, closed captions, VPS,
widescreen signalling, electronic program guide information, and other
services.
/dev/vbi8
Processed vbi feedback device(s)
Read-only. Only present if the MPEG decoder (i.e. CX23415) exists.
The sliced VBI data embedded in an MPEG stream is reproduced on this
device. So while playing back a recording on /dev/video16, you can
read the embedded VBI data from /dev/vbi8.
/dev/vbi16
The vbi 'display' device(s)
Write-only. Only present if the MPEG decoder (i.e. CX23415) exists.
Can be used to send sliced VBI data to the video-out connector.
---------------------------------
Hans Verkuil <hverkuil@xs4all.nl>
...@@ -624,11 +624,11 @@ out what values are bad when it hangs. ...@@ -624,11 +624,11 @@ out what values are bad when it hangs.
2A00 2A00
bits 0:2 bits 0:2
osd colour mode osd colour mode
000 = 8 bit indexed
001 = 16 bit (565) 001 = 16 bit (565)
010 = 15 bit (555) 010 = 15 bit (555)
011 = 12 bit (444) 011 = 12 bit (444)
100 = 32 bit (8888) 100 = 32 bit (8888)
101 = 8 bit indexed
bits 4:5 bits 4:5
osd display bpp osd display bpp
...@@ -676,9 +676,11 @@ out what values are bad when it hangs. ...@@ -676,9 +676,11 @@ out what values are bad when it hangs.
completely transparent. When using 565, 555 or 444 colour modes, the completely transparent. When using 565, 555 or 444 colour modes, the
colour key is always 16 bits wide. The colour to key on is set in Reg 2A18. colour key is always 16 bits wide. The colour to key on is set in Reg 2A18.
Local alpha is a per-pixel 256 step transparency, with 0 being transparent Local alpha works differently depending on the colour mode. For 32bpp & 8
and 255 being solid. This is only available in 32 bit & 8 bit indexed bit indexed, local alpha is a per-pixel 256 step transparency, with 0 being
colour modes. transparent and 255 being solid. For the 16bpp modes 555 & 444, the unused
bit(s) act as a simple transparency switch, with 0 being solid & 1 being
fully transparent. There is no local alpha support for 16bit 565.
Global alpha is a 256 step transparency that applies to the entire osd, Global alpha is a 256 step transparency that applies to the entire osd,
with 0 being transparent & 255 being solid. with 0 being transparent & 255 being solid.
...@@ -811,5 +813,5 @@ out what values are bad when it hangs. ...@@ -811,5 +813,5 @@ out what values are bad when it hangs.
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
v0.3 - 2 February 2007 - Ian Armstrong (ian@iarmst.demon.co.uk) v0.4 - 12 March 2007 - Ian Armstrong (ian@iarmst.demon.co.uk)
...@@ -663,12 +663,13 @@ Param[0] ...@@ -663,12 +663,13 @@ Param[0]
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Name CX2341X_ENC_UNKNOWN Name CX2341X_ENC_SET_VERT_CROP_LINE
Enum 219/0xDB Enum 219/0xDB
Description Description
Unknown API, it's used by Hauppauge though. Something to do with 'Vertical Crop Line'
Param[0] Param[0]
0 This is the value Hauppauge uses, Unknown what it means. If saa7114 and raw VBI capture and 60 Hz, then set to 10001.
Else 0.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
...@@ -682,11 +683,9 @@ Param[0] ...@@ -682,11 +683,9 @@ Param[0]
Command number: Command number:
1=set initial SCR value when starting encoding (works). 1=set initial SCR value when starting encoding (works).
2=set quality mode (apparently some test setting). 2=set quality mode (apparently some test setting).
3=setup advanced VIM protection handling (supposedly only for the cx23416 3=setup advanced VIM protection handling.
for raw YUV). Always 1 for the cx23416 and 0 for cx23415.
Actually it looks like this should be 0 for saa7114/5 based card and 1 4=generate DVD compatible PTS timestamps
for cx25840 based cards.
4=generate artificial PTS timestamps
5=USB flush mode 5=USB flush mode
6=something to do with the quantization matrix 6=something to do with the quantization matrix
7=set navigation pack insertion for DVD: adds 0xbf (private stream 2) 7=set navigation pack insertion for DVD: adds 0xbf (private stream 2)
...@@ -698,7 +697,9 @@ Param[0] ...@@ -698,7 +697,9 @@ Param[0]
9=set history parameters of the video input module 9=set history parameters of the video input module
10=set input field order of VIM 10=set input field order of VIM
11=set quantization matrix 11=set quantization matrix
12=reset audio interface 12=reset audio interface after channel change or input switch (has no argument).
Needed for the cx2584x, not needed for the mspx4xx, but it doesn't seem to
do any harm calling it regardless.
13=set audio volume delay 13=set audio volume delay
14=set audio delay 14=set audio delay
......
...@@ -21,7 +21,11 @@ Enum 66/0x42 ...@@ -21,7 +21,11 @@ Enum 66/0x42
Description Description
Query OSD format Query OSD format
Result[0] Result[0]
0=8bit index, 4=AlphaRGB 8:8:8:8 0=8bit index
1=16bit RGB 5:6:5
2=16bit ARGB 1:5:5:5
3=16bit ARGB 1:4:4:4
4=32bit ARGB 8:8:8:8
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
...@@ -30,7 +34,11 @@ Enum 67/0x43 ...@@ -30,7 +34,11 @@ Enum 67/0x43
Description Description
Assign pixel format Assign pixel format
Param[0] Param[0]
0=8bit index, 4=AlphaRGB 8:8:8:8 0=8bit index
1=16bit RGB 5:6:5
2=16bit ARGB 1:5:5:5
3=16bit ARGB 1:4:4:4
4=32bit ARGB 8:8:8:8
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
......
...@@ -25,7 +25,7 @@ Index ...@@ -25,7 +25,7 @@ Index
1. Copyright 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 2. Disclaimer
...@@ -216,10 +216,10 @@ Description: Debugging information level, from 0 to 3: ...@@ -216,10 +216,10 @@ Description: Debugging information level, from 0 to 3:
1 = critical errors 1 = critical errors
2 = significant informations 2 = significant informations
3 = more verbose messages 3 = more verbose messages
Level 3 is useful for testing only, when only one device Level 3 is useful for testing only. It also shows some more
is used. It also shows some more informations about the informations about the hardware being detected.
hardware being detected. This parameter can be changed at This parameter can be changed at runtime thanks to the /sys
runtime thanks to the /sys filesystem interface. filesystem interface.
Default: 2 Default: 2
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
...@@ -235,7 +235,7 @@ created in the /sys/class/video4linux/videoX directory. You can set the green ...@@ -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 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, to 15 for the SN9C101 or SN9C102 bridges, from 0 to 127 for the SN9C103,
SN9C105 and SN9C120 bridges. 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 gain control files are available in the same directory, for which accepted
values may range from 0 to 127. values may range from 0 to 127.
...@@ -402,38 +402,49 @@ Vendor ID Product ID ...@@ -402,38 +402,49 @@ Vendor ID Product ID
0x0c45 0x60bc 0x0c45 0x60bc
0x0c45 0x60be 0x0c45 0x60be
0x0c45 0x60c0 0x0c45 0x60c0
0x0c45 0x60c2
0x0c45 0x60c8 0x0c45 0x60c8
0x0c45 0x60cc 0x0c45 0x60cc
0x0c45 0x60ea 0x0c45 0x60ea
0x0c45 0x60ec 0x0c45 0x60ec
0x0c45 0x60ef
0x0c45 0x60fa 0x0c45 0x60fa
0x0c45 0x60fb 0x0c45 0x60fb
0x0c45 0x60fc 0x0c45 0x60fc
0x0c45 0x60fe 0x0c45 0x60fe
0x0c45 0x6102
0x0c45 0x6108
0x0c45 0x610f
0x0c45 0x6130 0x0c45 0x6130
0x0c45 0x6138
0x0c45 0x613a 0x0c45 0x613a
0x0c45 0x613b 0x0c45 0x613b
0x0c45 0x613c 0x0c45 0x613c
0x0c45 0x613e 0x0c45 0x613e
The list above does not imply that all those devices work with this driver: up 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 until now only the ones that assemble the following pairs of SN9C1xx bridges
supported; kernel messages will always tell you whether this is the case (see and image sensors are supported; kernel messages will always tell you whether
"Module loading" paragraph): this is the case (see "Module loading" paragraph):
Model Manufacturer Image sensor / SN9C1xx bridge | SN9C10[12] SN9C103 SN9C105 SN9C120
----- ------------ -------------------------------------------------------------------------------
HV7131D Hynix Semiconductor, Inc. HV7131D Hynix Semiconductor | Yes No No No
MI-0343 Micron Technology, Inc. HV7131R Hynix Semiconductor | No Yes Yes Yes
OV7630 OmniVision Technologies, Inc. MI-0343 Micron Technology | Yes No No No
OV7660 OmniVision Technologies, Inc. MI-0360 Micron Technology | No Yes No No
PAS106B PixArt Imaging, Inc. OV7630 OmniVision Technologies | Yes Yes No No
PAS202BCA PixArt Imaging, Inc. OV7660 OmniVision Technologies | No No Yes Yes
PAS202BCB PixArt Imaging, Inc. PAS106B PixArt Imaging | Yes No No No
TAS5110C1B Taiwan Advanced Sensor Corporation PAS202B PixArt Imaging | Yes Yes No No
TAS5130D1B Taiwan Advanced Sensor Corporation TAS5110C1B Taiwan Advanced Sensor | Yes No No No
TAS5110D Taiwan Advanced Sensor | Yes No No No
Some of the available control settings of each image sensor are supported 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. through the V4L2 interface.
Donations of new models for further testing and support would be much Donations of new models for further testing and support would be much
...@@ -482,8 +493,8 @@ The SN9C1xx PC Camera Controllers can send images in two possible video ...@@ -482,8 +493,8 @@ The SN9C1xx PC Camera Controllers can send images in two possible video
formats over the USB: either native "Sequential RGB Bayer" or compressed. formats over the USB: either native "Sequential RGB Bayer" or compressed.
The compression is used to achieve high frame rates. With regard to the 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 SN9C101, SN9C102 and SN9C103, the compression is based on the Huffman encoding
algorithm described below, while the SN9C105 and SN9C120 the compression is algorithm described below, while with regard to the SN9C105 and SN9C120 the
based on the JPEG standard. compression is based on the JPEG standard.
The current video format may be selected or queried from the user application 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 by calling the VIDIOC_S_FMT or VIDIOC_G_FMT ioctl's, as described in the V4L2
API specifications. API specifications.
...@@ -573,4 +584,5 @@ order): ...@@ -573,4 +584,5 @@ order):
- Mizuno Takafumi for the donation of a webcam; - Mizuno Takafumi for the donation of a webcam;
- an "anonymous" donator (who didn't want his name to be revealed) for the - an "anonymous" donator (who didn't want his name to be revealed) for the
donation of a webcam. 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.
Zoran 364xx based USB webcam module version 0.72
site: http://royale.zerezo.com/zr364xx/
mail: royale@zerezo.com
introduction:
This brings support under Linux for the Aiptek PocketDV 3300 in webcam mode.
If you just want to get on your PC the pictures and movies on the camera, you should use the usb-storage module instead.
The driver works with several other cameras in webcam mode (see the list below).
Maybe this code can work for other JPEG/USB cams based on the Coach chips from Zoran?
Possible chipsets are : ZR36430 (ZR36430BGC) and maybe ZR36431, ZR36440, ZR36442...
You can try the experience changing the vendor/product ID values (look at the source code).
You can get these values by looking at /var/log/messages when you plug your camera, or by typing : cat /proc/bus/usb/devices.
If you manage to use your cam with this code, you can send me a mail (royale@zerezo.com) with the name of your cam and a patch if needed.
This is a beta release of the driver.
Since version 0.70, this driver is only compatible with V4L2 API and 2.6.x kernels.
If you need V4L1 or 2.4x kernels support, please use an older version, but the code is not maintained anymore.
Good luck!
install:
In order to use this driver, you must compile it with your kernel.
Location: Device Drivers -> Multimedia devices -> Video For Linux -> Video Capture Adapters -> V4L USB devices
usage:
modprobe zr364xx debug=X mode=Y
- debug : set to 1 to enable verbose debug messages
- mode : 0 = 320x240, 1 = 160x120, 2 = 640x480
You can then use the camera with V4L2 compatible applications, for example Ekiga.
To capture a single image, try this: dd if=/dev/video0 of=test.jpg bs=1 count=1
links :
http://mxhaard.free.fr/ (support for many others cams including some Aiptek PocketDV)
http://www.harmwal.nl/pccam880/ (this project also supports cameras based on this chipset)
supported devices:
------ ------- ----------- -----
Vendor Product Distributor Model
------ ------- ----------- -----
0x08ca 0x0109 Aiptek PocketDV 3300
0x08ca 0x0109 Maxell Maxcam PRO DV3
0x041e 0x4024 Creative PC-CAM 880
0x0d64 0x0108 Aiptek Fidelity 3200
0x0d64 0x0108 Praktica DCZ 1.3 S
0x0d64 0x0108 Genius Digital Camera (?)
0x0d64 0x0108 DXG Technology Fashion Cam
0x0546 0x3187 Polaroid iON 230
0x0d64 0x3108 Praktica Exakta DC 2200
0x0d64 0x3108 Genius G-Shot D211
0x0595 0x4343 Concord Eye-Q Duo 1300
0x0595 0x4343 Concord Eye-Q Duo 2000
0x0595 0x4343 Fujifilm EX-10
0x0595 0x4343 Ricoh RDC-6000
0x0595 0x4343 Digitrex DSC 1300
0x0595 0x4343 Firstline FDC 2000
0x0bb0 0x500d Concord EyeQ Go Wireless
0x0feb 0x2004 CRS Electronic 3.3 Digital Camera
0x0feb 0x2004 Packard Bell DSC-300
0x055f 0xb500 Mustek MDC 3000
0x08ca 0x2062 Aiptek PocketDV 5700
0x052b 0x1a18 Chiphead Megapix V12
0x04c8 0x0729 Konica Revio 2
0x04f2 0xa208 Creative PC-CAM 850
0x0784 0x0040 Traveler Slimline X5
0x06d6 0x0034 Trust Powerc@m 750
0x0a17 0x0062 Pentax Optio 50L
...@@ -55,7 +55,7 @@ trivial patch so apply some common sense. ...@@ -55,7 +55,7 @@ trivial patch so apply some common sense.
8. Happy hacking. 8. Happy hacking.
----------------------------------- -----------------------------------
Maintainers List (try to look for most precise areas first) Maintainers List (try to look for most precise areas first)
...@@ -873,6 +873,12 @@ W: http://linuxtv.org ...@@ -873,6 +873,12 @@ W: http://linuxtv.org
T: git kernel.org:/pub/scm/linux/kernel/git/mchehab/v4l-dvb.git T: git kernel.org:/pub/scm/linux/kernel/git/mchehab/v4l-dvb.git
S: Maintained S: Maintained
CAFE CMOS INTEGRATED CAMERA CONTROLLER DRIVER
P: Jonathan Corbet
M: corbet@lwn.net
L: video4linux-list@redhat.com
S: Maintained
CALGARY x86-64 IOMMU CALGARY x86-64 IOMMU
P: Muli Ben-Yehuda P: Muli Ben-Yehuda
M: muli@il.ibm.com M: muli@il.ibm.com
...@@ -907,7 +913,7 @@ L: linux-cifs-client@lists.samba.org ...@@ -907,7 +913,7 @@ L: linux-cifs-client@lists.samba.org
L: samba-technical@lists.samba.org L: samba-technical@lists.samba.org
W: http://us1.samba.org/samba/Linux_CIFS_client.html W: http://us1.samba.org/samba/Linux_CIFS_client.html
T: git kernel.org:/pub/scm/linux/kernel/git/sfrench/cifs-2.6.git T: git kernel.org:/pub/scm/linux/kernel/git/sfrench/cifs-2.6.git
S: Supported S: Supported
CONFIGFS CONFIGFS
P: Joel Becker P: Joel Becker
...@@ -1549,19 +1555,19 @@ P: Chirag Kantharia ...@@ -1549,19 +1555,19 @@ P: Chirag Kantharia
M: chirag.kantharia@hp.com M: chirag.kantharia@hp.com
L: iss_storagedev@hp.com L: iss_storagedev@hp.com
S: Maintained S: Maintained
HEWLETT-PACKARD SMART2 RAID DRIVER HEWLETT-PACKARD SMART2 RAID DRIVER
P: Chirag Kantharia P: Chirag Kantharia
M: chirag.kantharia@hp.com M: chirag.kantharia@hp.com
L: iss_storagedev@hp.com L: iss_storagedev@hp.com
S: Maintained S: Maintained
HEWLETT-PACKARD SMART CISS RAID DRIVER (cciss) HEWLETT-PACKARD SMART CISS RAID DRIVER (cciss)
P: Mike Miller P: Mike Miller
M: mike.miller@hp.com M: mike.miller@hp.com
L: iss_storagedev@hp.com L: iss_storagedev@hp.com
S: Supported S: Supported
HOST AP DRIVER HOST AP DRIVER
P: Jouni Malinen P: Jouni Malinen
M: jkmaline@cc.hut.fi M: jkmaline@cc.hut.fi
...@@ -1673,7 +1679,7 @@ P: Jack Hammer ...@@ -1673,7 +1679,7 @@ P: Jack Hammer
P: Dave Jeffery P: Dave Jeffery
M: ipslinux@adaptec.com M: ipslinux@adaptec.com
W: http://www.developer.ibm.com/welcome/netfinity/serveraid.html W: http://www.developer.ibm.com/welcome/netfinity/serveraid.html
S: Supported S: Supported
IDE SUBSYSTEM IDE SUBSYSTEM
P: Bartlomiej Zolnierkiewicz P: Bartlomiej Zolnierkiewicz
...@@ -1975,7 +1981,7 @@ M: kai@germaschewski.name ...@@ -1975,7 +1981,7 @@ M: kai@germaschewski.name
P: Sam Ravnborg P: Sam Ravnborg
M: sam@ravnborg.org M: sam@ravnborg.org
T: git kernel.org:/pub/scm/linux/kernel/git/sam/kbuild.git T: git kernel.org:/pub/scm/linux/kernel/git/sam/kbuild.git
S: Maintained S: Maintained
KERNEL JANITORS KERNEL JANITORS
P: Several P: Several
...@@ -2155,7 +2161,7 @@ S: Maintained ...@@ -2155,7 +2161,7 @@ S: Maintained
LOGICAL DISK MANAGER SUPPORT (LDM, Windows 2000/XP Dynamic Disks) LOGICAL DISK MANAGER SUPPORT (LDM, Windows 2000/XP Dynamic Disks)
P: Richard Russon (FlatCap) P: Richard Russon (FlatCap)
M: ldm@flatcap.org M: ldm@flatcap.org
L: ldm-devel@lists.sourceforge.net L: ldm-devel@lists.sourceforge.net
W: http://ldm.sourceforge.net W: http://ldm.sourceforge.net
S: Maintained S: Maintained
...@@ -2504,13 +2510,13 @@ P: Kurt Hackel ...@@ -2504,13 +2510,13 @@ P: Kurt Hackel
M: kurt.hackel@oracle.com M: kurt.hackel@oracle.com
L: ocfs2-devel@oss.oracle.com L: ocfs2-devel@oss.oracle.com
W: http://oss.oracle.com/projects/ocfs2/ W: http://oss.oracle.com/projects/ocfs2/
S: Supported S: Supported
OLYMPIC NETWORK DRIVER OLYMPIC NETWORK DRIVER
P: Peter De Shrijver P: Peter De Shrijver
M: p2@ace.ulyssis.student.kuleuven.ac.be M: p2@ace.ulyssis.student.kuleuven.ac.be
P: Mike Phillips P: Mike Phillips
M: mikep@linuxtr.net M: mikep@linuxtr.net
L: netdev@vger.kernel.org L: netdev@vger.kernel.org
L: linux-tr@linuxtr.net L: linux-tr@linuxtr.net
W: http://www.linuxtr.net W: http://www.linuxtr.net
...@@ -2526,6 +2532,12 @@ P: Harald Welte ...@@ -2526,6 +2532,12 @@ P: Harald Welte
M: laforge@gnumonks.org M: laforge@gnumonks.org
S: Maintained S: Maintained
OMNIVISION OV7670 SENSOR DRIVER
P: Jonathan Corbet
M: corbet@lwn.net
L: video4linux-list@redhat.com
S: Maintained
ONSTREAM SCSI TAPE DRIVER ONSTREAM SCSI TAPE DRIVER
P: Willem Riede P: Willem Riede
M: osst@riede.org M: osst@riede.org
...@@ -3045,7 +3057,7 @@ SIS FRAMEBUFFER DRIVER ...@@ -3045,7 +3057,7 @@ SIS FRAMEBUFFER DRIVER
P: Thomas Winischhofer P: Thomas Winischhofer
M: thomas@winischhofer.net M: thomas@winischhofer.net
W: http://www.winischhofer.net/linuxsisvga.shtml W: http://www.winischhofer.net/linuxsisvga.shtml
S: Maintained S: Maintained
SIS USB2VGA DRIVER SIS USB2VGA DRIVER
P: Thomas Winischhofer P: Thomas Winischhofer
...@@ -3594,7 +3606,7 @@ L: linux-usb-devel@lists.sourceforge.net ...@@ -3594,7 +3606,7 @@ L: linux-usb-devel@lists.sourceforge.net
W: http://www.connecttech.com W: http://www.connecttech.com
S: Supported S: Supported
USB SN9C10x DRIVER USB SN9C1xx DRIVER
P: Luca Risolia P: Luca Risolia
M: luca.risolia@studio.unibo.it M: luca.risolia@studio.unibo.it
L: linux-usb-devel@lists.sourceforge.net L: linux-usb-devel@lists.sourceforge.net
...@@ -3649,6 +3661,14 @@ L: linux-usb-devel@lists.sourceforge.net ...@@ -3649,6 +3661,14 @@ L: linux-usb-devel@lists.sourceforge.net
W: http://linux-lc100020.sourceforge.net W: http://linux-lc100020.sourceforge.net
S: Maintained S: Maintained
USB ZR364XX DRIVER
P: Antoine Jacquet
M: royale@zerezo.com
L: linux-usb-devel@lists.sourceforge.net
L: video4linux-list@redhat.com
W: http://royale.zerezo.com/zr364xx/
S: Maintained
USER-MODE LINUX USER-MODE LINUX
P: Jeff Dike P: Jeff Dike
M: jdike@karaya.com M: jdike@karaya.com
...@@ -3656,7 +3676,7 @@ L: user-mode-linux-devel@lists.sourceforge.net ...@@ -3656,7 +3676,7 @@ L: user-mode-linux-devel@lists.sourceforge.net
L: user-mode-linux-user@lists.sourceforge.net L: user-mode-linux-user@lists.sourceforge.net
W: http://user-mode-linux.sourceforge.net W: http://user-mode-linux.sourceforge.net
S: Maintained S: Maintained
FAT/VFAT/MSDOS FILESYSTEM: FAT/VFAT/MSDOS FILESYSTEM:
P: OGAWA Hirofumi P: OGAWA Hirofumi
M: hirofumi@mail.parknet.co.jp M: hirofumi@mail.parknet.co.jp
......
...@@ -667,7 +667,7 @@ IR_KEYTAB_TYPE ir_codes_pinnacle_grey[IR_KEYTAB_SIZE] = { ...@@ -667,7 +667,7 @@ IR_KEYTAB_TYPE ir_codes_pinnacle_grey[IR_KEYTAB_SIZE] = {
[ 0x1f ] = KEY_L, [ 0x1f ] = KEY_L,
[ 0x2b ] = KEY_I, [ 0x2b ] = KEY_I,
[ 0x2d ] = KEY_ZOOM, [ 0x2d ] = KEY_SCREEN,
[ 0x1e ] = KEY_ZOOM, [ 0x1e ] = KEY_ZOOM,
[ 0x1b ] = KEY_VOLUMEUP, [ 0x1b ] = KEY_VOLUMEUP,
[ 0x0f ] = KEY_VOLUMEDOWN, [ 0x0f ] = KEY_VOLUMEDOWN,
...@@ -682,12 +682,12 @@ IR_KEYTAB_TYPE ir_codes_pinnacle_grey[IR_KEYTAB_SIZE] = { ...@@ -682,12 +682,12 @@ IR_KEYTAB_TYPE ir_codes_pinnacle_grey[IR_KEYTAB_SIZE] = {
[ 0x3f ] = KEY_UP, [ 0x3f ] = KEY_UP,
[ 0x3e ] = KEY_DOWN, [ 0x3e ] = KEY_DOWN,
[ 0x1a ] = KEY_PAUSE, [ 0x1a ] = KEY_ENTER,
[ 0x1d ] = KEY_MENU, [ 0x1d ] = KEY_MENU,
[ 0x19 ] = KEY_PLAY, [ 0x19 ] = KEY_AGAIN,
[ 0x16 ] = KEY_REWIND, [ 0x16 ] = KEY_PREVIOUSSONG,
[ 0x13 ] = KEY_FORWARD, [ 0x13 ] = KEY_NEXTSONG,
[ 0x15 ] = KEY_PAUSE, [ 0x15 ] = KEY_PAUSE,
[ 0x0e ] = KEY_REWIND, [ 0x0e ] = KEY_REWIND,
[ 0x0d ] = KEY_PLAY, [ 0x0d ] = KEY_PLAY,
...@@ -1739,7 +1739,7 @@ IR_KEYTAB_TYPE ir_codes_encore_enltv[IR_KEYTAB_SIZE] = { ...@@ -1739,7 +1739,7 @@ IR_KEYTAB_TYPE ir_codes_encore_enltv[IR_KEYTAB_SIZE] = {
EXPORT_SYMBOL_GPL(ir_codes_encore_enltv); 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] = { IR_KEYTAB_TYPE ir_codes_tt_1500[IR_KEYTAB_SIZE] = {
[ 0x01 ] = KEY_POWER, [ 0x01 ] = KEY_POWER,
[ 0x02 ] = KEY_SHUFFLE, /* ? double-arrow key */ [ 0x02 ] = KEY_SHUFFLE, /* ? double-arrow key */
...@@ -1774,6 +1774,12 @@ IR_KEYTAB_TYPE ir_codes_tt_1500[IR_KEYTAB_SIZE] = { ...@@ -1774,6 +1774,12 @@ IR_KEYTAB_TYPE ir_codes_tt_1500[IR_KEYTAB_SIZE] = {
[ 0x25 ] = KEY_VOLUMEUP, [ 0x25 ] = KEY_VOLUMEUP,
[ 0x26 ] = KEY_VOLUMEDOWN, [ 0x26 ] = KEY_VOLUMEDOWN,
[ 0x27 ] = KEY_SETUP, [ 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); EXPORT_SYMBOL_GPL(ir_codes_tt_1500);
...@@ -1428,6 +1428,7 @@ static void video_close(struct saa7146_dev *dev, struct file *file) ...@@ -1428,6 +1428,7 @@ static void video_close(struct saa7146_dev *dev, struct file *file)
{ {
struct saa7146_fh *fh = (struct saa7146_fh *)file->private_data; struct saa7146_fh *fh = (struct saa7146_fh *)file->private_data;
struct saa7146_vv *vv = dev->vv_data; struct saa7146_vv *vv = dev->vv_data;
struct videobuf_queue *q = &fh->video_q;
int err; int err;
if (IS_CAPTURE_ACTIVE(fh) != 0) { if (IS_CAPTURE_ACTIVE(fh) != 0) {
...@@ -1436,6 +1437,11 @@ static void video_close(struct saa7146_dev *dev, struct file *file) ...@@ -1436,6 +1437,11 @@ static void video_close(struct saa7146_dev *dev, struct file *file)
err = saa7146_stop_preview(fh); 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? */ /* hmm, why is this function declared void? */
/* return err */ /* return err */
} }
......
...@@ -9,7 +9,6 @@ config DVB_B2C2_FLEXCOP ...@@ -9,7 +9,6 @@ config DVB_B2C2_FLEXCOP
select DVB_STV0297 if !DVB_FE_CUSTOMISE select DVB_STV0297 if !DVB_FE_CUSTOMISE
select DVB_BCM3510 if !DVB_FE_CUSTOMISE select DVB_BCM3510 if !DVB_FE_CUSTOMISE
select DVB_LGDT330X if !DVB_FE_CUSTOMISE select DVB_LGDT330X if !DVB_FE_CUSTOMISE
select DVB_TUNER_LGH06XF if !DVB_FE_CUSTOMISE
help help
Support for the digital TV receiver chip made by B2C2 Inc. included in Support for the digital TV receiver chip made by B2C2 Inc. included in
Technisats PCI cards and USB boxes. Technisats PCI cards and USB boxes.
......
...@@ -14,7 +14,6 @@ ...@@ -14,7 +14,6 @@
#include "stv0297.h" #include "stv0297.h"
#include "mt312.h" #include "mt312.h"
#include "lgdt330x.h" #include "lgdt330x.h"
#include "lgh06xf.h"
#include "dvb-pll.h" #include "dvb-pll.h"
/* lnb control */ /* lnb control */
...@@ -507,7 +506,7 @@ int flexcop_frontend_init(struct flexcop_device *fc) ...@@ -507,7 +506,7 @@ int flexcop_frontend_init(struct flexcop_device *fc)
/* try the air atsc 3nd generation (lgdt3303) */ /* try the air atsc 3nd generation (lgdt3303) */
if ((fc->fe = dvb_attach(lgdt330x_attach, &air2pc_atsc_hd5000_config, &fc->i2c_adap)) != NULL) { if ((fc->fe = dvb_attach(lgdt330x_attach, &air2pc_atsc_hd5000_config, &fc->i2c_adap)) != NULL) {
fc->dev_type = FC_AIR_ATSC3; fc->dev_type = FC_AIR_ATSC3;
dvb_attach(lgh06xf_attach, fc->fe, &fc->i2c_adap); dvb_attach(dvb_pll_attach, fc->fe, 0x61, &fc->i2c_adap, &dvb_pll_lg_tdvs_h06xf);
info("found the lgdt3303 at i2c address: 0x%02x",air2pc_atsc_hd5000_config.demod_address); info("found the lgdt3303 at i2c address: 0x%02x",air2pc_atsc_hd5000_config.demod_address);
} else } else
/* try the air atsc 1nd generation (bcm3510)/panasonic ct10s */ /* try the air atsc 1nd generation (bcm3510)/panasonic ct10s */
......
...@@ -127,10 +127,11 @@ static irqreturn_t flexcop_pci_isr(int irq, void *dev_id) ...@@ -127,10 +127,11 @@ static irqreturn_t flexcop_pci_isr(int irq, void *dev_id)
{ {
struct flexcop_pci *fc_pci = dev_id; struct flexcop_pci *fc_pci = dev_id;
struct flexcop_device *fc = fc_pci->fc_dev; struct flexcop_device *fc = fc_pci->fc_dev;
unsigned long flags;
flexcop_ibi_value v; flexcop_ibi_value v;
irqreturn_t ret = IRQ_HANDLED; 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); v = fc->read_ibi_reg(fc,irq_20c);
...@@ -194,7 +195,7 @@ static irqreturn_t flexcop_pci_isr(int irq, void *dev_id) ...@@ -194,7 +195,7 @@ static irqreturn_t flexcop_pci_isr(int irq, void *dev_id)
ret = IRQ_NONE; ret = IRQ_NONE;
} }
spin_unlock_irq(&fc_pci->irq_lock); spin_unlock_irqrestore(&fc_pci->irq_lock,flags);
return ret; return ret;
} }
...@@ -293,12 +294,12 @@ static int flexcop_pci_init(struct flexcop_pci *fc_pci) ...@@ -293,12 +294,12 @@ static int flexcop_pci_init(struct flexcop_pci *fc_pci)
} }
pci_set_drvdata(fc_pci->pdev, 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, if ((ret = request_irq(fc_pci->pdev->irq, flexcop_pci_isr,
IRQF_SHARED, DRIVER_NAME, fc_pci)) != 0) IRQF_SHARED, DRIVER_NAME, fc_pci)) != 0)
goto err_pci_iounmap; goto err_pci_iounmap;
spin_lock_init(&fc_pci->irq_lock);
fc_pci->init_state |= FC_PCI_INIT; fc_pci->init_state |= FC_PCI_INIT;
return ret; return ret;
......
...@@ -7,7 +7,7 @@ config DVB_BT8XX ...@@ -7,7 +7,7 @@ config DVB_BT8XX
select DVB_CX24110 if !DVB_FE_CUSTOMISE select DVB_CX24110 if !DVB_FE_CUSTOMISE
select DVB_OR51211 if !DVB_FE_CUSTOMISE select DVB_OR51211 if !DVB_FE_CUSTOMISE
select DVB_LGDT330X if !DVB_FE_CUSTOMISE select DVB_LGDT330X if !DVB_FE_CUSTOMISE
select DVB_TUNER_LGH06XF if !DVB_FE_CUSTOMISE select DVB_PLL
select DVB_ZL10353 if !DVB_FE_CUSTOMISE select DVB_ZL10353 if !DVB_FE_CUSTOMISE
select FW_LOADER select FW_LOADER
help help
......
...@@ -393,9 +393,7 @@ static struct cards card_list[] __devinitdata = { ...@@ -393,9 +393,7 @@ static struct cards card_list[] __devinitdata = {
{ 0xdb1118ac, BTTV_BOARD_DVICO_DVBT_LITE, "Ultraview DVB-T Lite" }, { 0xdb1118ac, BTTV_BOARD_DVICO_DVBT_LITE, "Ultraview DVB-T Lite" },
{ 0xd50018ac, BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE, "DViCO FusionHDTV 5 Lite" }, { 0xd50018ac, BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE, "DViCO FusionHDTV 5 Lite" },
{ 0x20007063, BTTV_BOARD_PC_HDTV, "pcHDTV HD-2000 TV" }, { 0x20007063, BTTV_BOARD_PC_HDTV, "pcHDTV HD-2000 TV" },
{ 0x00261822, BTTV_BOARD_TWINHAN_DST, "DNTV Live! Mini" }, { 0x00261822, BTTV_BOARD_TWINHAN_DST, "DNTV Live! Mini" }
{ 0, -1, NULL }
}; };
......
...@@ -610,7 +610,8 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type) ...@@ -610,7 +610,8 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type)
lgdt330x_reset(card); lgdt330x_reset(card);
card->fe = dvb_attach(lgdt330x_attach, &tdvs_tua6034_config, card->i2c_adapter); card->fe = dvb_attach(lgdt330x_attach, &tdvs_tua6034_config, card->i2c_adapter);
if (card->fe != NULL) { if (card->fe != NULL) {
dvb_attach(lgh06xf_attach, card->fe, card->i2c_adapter); dvb_attach(dvb_pll_attach, card->fe, 0x61,
card->i2c_adapter, &dvb_pll_lg_tdvs_h06xf);
dprintk ("dvb_bt8xx: lgdt330x detected\n"); dprintk ("dvb_bt8xx: lgdt330x detected\n");
} }
break; break;
......
...@@ -37,8 +37,8 @@ ...@@ -37,8 +37,8 @@
#include "cx24110.h" #include "cx24110.h"
#include "or51211.h" #include "or51211.h"
#include "lgdt330x.h" #include "lgdt330x.h"
#include "lgh06xf.h"
#include "zl10353.h" #include "zl10353.h"
#include "dvb-pll.h"
struct dvb_bt8xx_card { struct dvb_bt8xx_card {
struct mutex lock; struct mutex lock;
......
...@@ -132,6 +132,11 @@ static int dvb_dvr_open(struct inode *inode, struct file *file) ...@@ -132,6 +132,11 @@ static int dvb_dvr_open(struct inode *inode, struct file *file)
if (mutex_lock_interruptible(&dmxdev->mutex)) if (mutex_lock_interruptible(&dmxdev->mutex))
return -ERESTARTSYS; return -ERESTARTSYS;
if (dmxdev->exit) {
mutex_unlock(&dmxdev->mutex);
return -ENODEV;
}
if ((file->f_flags & O_ACCMODE) == O_RDWR) { if ((file->f_flags & O_ACCMODE) == O_RDWR) {
if (!(dmxdev->capabilities & DMXDEV_CAP_DUPLEX)) { if (!(dmxdev->capabilities & DMXDEV_CAP_DUPLEX)) {
mutex_unlock(&dmxdev->mutex); mutex_unlock(&dmxdev->mutex);
...@@ -171,6 +176,7 @@ static int dvb_dvr_open(struct inode *inode, struct file *file) ...@@ -171,6 +176,7 @@ static int dvb_dvr_open(struct inode *inode, struct file *file)
dmxdev->demux->disconnect_frontend(dmxdev->demux); dmxdev->demux->disconnect_frontend(dmxdev->demux);
dmxdev->demux->connect_frontend(dmxdev->demux, front); dmxdev->demux->connect_frontend(dmxdev->demux, front);
} }
dvbdev->users++;
mutex_unlock(&dmxdev->mutex); mutex_unlock(&dmxdev->mutex);
return 0; return 0;
} }
...@@ -198,7 +204,16 @@ static int dvb_dvr_release(struct inode *inode, struct file *file) ...@@ -198,7 +204,16 @@ static int dvb_dvr_release(struct inode *inode, struct file *file)
vfree(mem); 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; return 0;
} }
...@@ -215,6 +230,11 @@ static ssize_t dvb_dvr_write(struct file *file, const char __user *buf, ...@@ -215,6 +230,11 @@ static ssize_t dvb_dvr_write(struct file *file, const char __user *buf,
return -EINVAL; return -EINVAL;
if (mutex_lock_interruptible(&dmxdev->mutex)) if (mutex_lock_interruptible(&dmxdev->mutex))
return -ERESTARTSYS; return -ERESTARTSYS;
if (dmxdev->exit) {
mutex_unlock(&dmxdev->mutex);
return -ENODEV;
}
ret = dmxdev->demux->write(dmxdev->demux, buf, count); ret = dmxdev->demux->write(dmxdev->demux, buf, count);
mutex_unlock(&dmxdev->mutex); mutex_unlock(&dmxdev->mutex);
return ret; return ret;
...@@ -227,6 +247,11 @@ static ssize_t dvb_dvr_read(struct file *file, char __user *buf, size_t count, ...@@ -227,6 +247,11 @@ static ssize_t dvb_dvr_read(struct file *file, char __user *buf, size_t count,
struct dmxdev *dmxdev = dvbdev->priv; struct dmxdev *dmxdev = dvbdev->priv;
int ret; int ret;
if (dmxdev->exit) {
mutex_unlock(&dmxdev->mutex);
return -ENODEV;
}
//mutex_lock(&dmxdev->mutex); //mutex_lock(&dmxdev->mutex);
ret = dvb_dmxdev_buffer_read(&dmxdev->dvr_buffer, ret = dvb_dmxdev_buffer_read(&dmxdev->dvr_buffer,
file->f_flags & O_NONBLOCK, file->f_flags & O_NONBLOCK,
...@@ -665,6 +690,8 @@ static int dvb_demux_open(struct inode *inode, struct file *file) ...@@ -665,6 +690,8 @@ static int dvb_demux_open(struct inode *inode, struct file *file)
dmxdevfilter->feed.ts = NULL; dmxdevfilter->feed.ts = NULL;
init_timer(&dmxdevfilter->timer); init_timer(&dmxdevfilter->timer);
dvbdev->users++;
mutex_unlock(&dmxdev->mutex); mutex_unlock(&dmxdev->mutex);
return 0; return 0;
} }
...@@ -943,7 +970,21 @@ static int dvb_demux_release(struct inode *inode, struct file *file) ...@@ -943,7 +970,21 @@ static int dvb_demux_release(struct inode *inode, struct file *file)
struct dmxdev_filter *dmxdevfilter = file->private_data; struct dmxdev_filter *dmxdevfilter = file->private_data;
struct dmxdev *dmxdev = dmxdevfilter->dev; 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 = { static struct file_operations dvb_demux_fops = {
...@@ -1027,6 +1068,7 @@ static struct file_operations dvb_dvr_fops = { ...@@ -1027,6 +1068,7 @@ static struct file_operations dvb_dvr_fops = {
static struct dvb_device dvbdev_dvr = { static struct dvb_device dvbdev_dvr = {
.priv = NULL, .priv = NULL,
.readers = 1, .readers = 1,
.users = 1,
.fops = &dvb_dvr_fops .fops = &dvb_dvr_fops
}; };
...@@ -1064,6 +1106,16 @@ EXPORT_SYMBOL(dvb_dmxdev_init); ...@@ -1064,6 +1106,16 @@ EXPORT_SYMBOL(dvb_dmxdev_init);
void dvb_dmxdev_release(struct dmxdev *dmxdev) 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->dvbdev);
dvb_unregister_device(dmxdev->dvr_dvbdev); dvb_unregister_device(dmxdev->dvr_dvbdev);
......
...@@ -91,6 +91,8 @@ struct dmxdev { ...@@ -91,6 +91,8 @@ struct dmxdev {
int filternum; int filternum;
int capabilities; int capabilities;
unsigned int exit:1;
#define DMXDEV_CAP_DUPLEX 1 #define DMXDEV_CAP_DUPLEX 1
struct dmx_frontend *dvr_orig_fe; struct dmx_frontend *dvr_orig_fe;
......
...@@ -606,6 +606,7 @@ static void dvb_frontend_stop(struct dvb_frontend *fe) ...@@ -606,6 +606,7 @@ static void dvb_frontend_stop(struct dvb_frontend *fe)
return; return;
kthread_stop(fepriv->thread); kthread_stop(fepriv->thread);
init_MUTEX (&fepriv->sem); init_MUTEX (&fepriv->sem);
fepriv->state = FESTATE_IDLE; fepriv->state = FESTATE_IDLE;
...@@ -1023,6 +1024,7 @@ static int dvb_frontend_release(struct inode *inode, struct file *file) ...@@ -1023,6 +1024,7 @@ static int dvb_frontend_release(struct inode *inode, struct file *file)
struct dvb_device *dvbdev = file->private_data; struct dvb_device *dvbdev = file->private_data;
struct dvb_frontend *fe = dvbdev->priv; struct dvb_frontend *fe = dvbdev->priv;
struct dvb_frontend_private *fepriv = fe->frontend_priv; struct dvb_frontend_private *fepriv = fe->frontend_priv;
int ret;
dprintk ("%s\n", __FUNCTION__); dprintk ("%s\n", __FUNCTION__);
...@@ -1032,7 +1034,14 @@ static int dvb_frontend_release(struct inode *inode, struct file *file) ...@@ -1032,7 +1034,14 @@ static int dvb_frontend_release(struct inode *inode, struct file *file)
if (fe->ops.ts_bus_ctrl) if (fe->ops.ts_bus_ctrl)
fe->ops.ts_bus_ctrl (fe, 0); 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 = { static struct file_operations dvb_frontend_fops = {
...@@ -1092,8 +1101,15 @@ int dvb_unregister_frontend(struct dvb_frontend* fe) ...@@ -1092,8 +1101,15 @@ int dvb_unregister_frontend(struct dvb_frontend* fe)
dprintk ("%s\n", __FUNCTION__); dprintk ("%s\n", __FUNCTION__);
mutex_lock(&frontend_mutex); mutex_lock(&frontend_mutex);
dvb_unregister_device (fepriv->dvbdev);
dvb_frontend_stop (fe); 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 */ /* fe is invalid now */
kfree(fepriv); kfree(fepriv);
......
...@@ -1439,11 +1439,36 @@ static int dvb_net_ioctl(struct inode *inode, struct file *file, ...@@ -1439,11 +1439,36 @@ static int dvb_net_ioctl(struct inode *inode, struct file *file,
return dvb_usercopy(inode, file, cmd, arg, dvb_net_do_ioctl); 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 = { static struct file_operations dvb_net_fops = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.ioctl = dvb_net_ioctl, .ioctl = dvb_net_ioctl,
.open = dvb_generic_open, .open = dvb_generic_open,
.release = dvb_generic_release, .release = dvb_net_close,
}; };
static struct dvb_device dvbdev_net = { static struct dvb_device dvbdev_net = {
...@@ -1458,6 +1483,11 @@ void dvb_net_release (struct dvb_net *dvbnet) ...@@ -1458,6 +1483,11 @@ void dvb_net_release (struct dvb_net *dvbnet)
{ {
int i; 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); dvb_unregister_device(dvbnet->dvbdev);
for (i=0; i<DVB_NET_DEVICES_MAX; i++) { for (i=0; i<DVB_NET_DEVICES_MAX; i++) {
......
...@@ -36,6 +36,7 @@ struct dvb_net { ...@@ -36,6 +36,7 @@ struct dvb_net {
struct dvb_device *dvbdev; struct dvb_device *dvbdev;
struct net_device *device[DVB_NET_DEVICES_MAX]; struct net_device *device[DVB_NET_DEVICES_MAX];
int state[DVB_NET_DEVICES_MAX]; int state[DVB_NET_DEVICES_MAX];
unsigned int exit:1;
struct dmx_demux *demux; struct dmx_demux *demux;
}; };
......
...@@ -233,6 +233,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, ...@@ -233,6 +233,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
dvbdev->adapter = adap; dvbdev->adapter = adap;
dvbdev->priv = priv; dvbdev->priv = priv;
dvbdev->fops = dvbdevfops; dvbdev->fops = dvbdevfops;
init_waitqueue_head (&dvbdev->wait_queue);
memcpy(dvbdev->fops, template->fops, sizeof(struct file_operations)); memcpy(dvbdev->fops, template->fops, sizeof(struct file_operations));
dvbdev->fops->owner = adap->module; dvbdev->fops->owner = adap->module;
......
...@@ -69,6 +69,7 @@ struct dvb_device { ...@@ -69,6 +69,7 @@ struct dvb_device {
int writers; int writers;
int users; int users;
wait_queue_head_t wait_queue;
/* don't really need those !? -- FIXME: use video_usercopy */ /* don't really need those !? -- FIXME: use video_usercopy */
int (*kernel_ioctl)(struct inode *inode, struct file *file, int (*kernel_ioctl)(struct inode *inode, struct file *file,
unsigned int cmd, void *arg); unsigned int cmd, void *arg);
......
...@@ -33,6 +33,7 @@ config DVB_USB_A800 ...@@ -33,6 +33,7 @@ config DVB_USB_A800
config DVB_USB_DIBUSB_MB config DVB_USB_DIBUSB_MB
tristate "DiBcom USB DVB-T devices (based on the DiB3000M-B) (see help for device list)" tristate "DiBcom USB DVB-T devices (based on the DiB3000M-B) (see help for device list)"
depends on DVB_USB depends on DVB_USB
select DVB_PLL
select DVB_DIB3000MB select DVB_DIB3000MB
select DVB_TUNER_MT2060 if !DVB_FE_CUSTOMISE select DVB_TUNER_MT2060 if !DVB_FE_CUSTOMISE
help help
...@@ -88,6 +89,7 @@ config DVB_USB_DIB0700 ...@@ -88,6 +89,7 @@ config DVB_USB_DIB0700
config DVB_USB_UMT_010 config DVB_USB_UMT_010
tristate "HanfTek UMT-010 DVB-T USB2.0 support" tristate "HanfTek UMT-010 DVB-T USB2.0 support"
depends on DVB_USB depends on DVB_USB
select DVB_PLL
select DVB_DIB3000MC select DVB_DIB3000MC
select DVB_TUNER_MT2060 if !DVB_FE_CUSTOMISE select DVB_TUNER_MT2060 if !DVB_FE_CUSTOMISE
help help
...@@ -96,9 +98,9 @@ config DVB_USB_UMT_010 ...@@ -96,9 +98,9 @@ config DVB_USB_UMT_010
config DVB_USB_CXUSB config DVB_USB_CXUSB
tristate "Conexant USB2.0 hybrid reference design support" tristate "Conexant USB2.0 hybrid reference design support"
depends on DVB_USB depends on DVB_USB
select DVB_PLL
select DVB_CX22702 if !DVB_FE_CUSTOMISE select DVB_CX22702 if !DVB_FE_CUSTOMISE
select DVB_LGDT330X if !DVB_FE_CUSTOMISE select DVB_LGDT330X if !DVB_FE_CUSTOMISE
select DVB_TUNER_LGH06XF if !DVB_FE_CUSTOMISE
select DVB_MT352 if !DVB_FE_CUSTOMISE select DVB_MT352 if !DVB_FE_CUSTOMISE
select DVB_ZL10353 if !DVB_FE_CUSTOMISE select DVB_ZL10353 if !DVB_FE_CUSTOMISE
help help
...@@ -140,6 +142,7 @@ config DVB_USB_AU6610 ...@@ -140,6 +142,7 @@ config DVB_USB_AU6610
config DVB_USB_DIGITV config DVB_USB_DIGITV
tristate "Nebula Electronics uDigiTV DVB-T USB2.0 support" tristate "Nebula Electronics uDigiTV DVB-T USB2.0 support"
depends on DVB_USB depends on DVB_USB
select DVB_PLL
select DVB_NXT6000 if !DVB_FE_CUSTOMISE select DVB_NXT6000 if !DVB_FE_CUSTOMISE
select DVB_MT352 if !DVB_FE_CUSTOMISE select DVB_MT352 if !DVB_FE_CUSTOMISE
help help
...@@ -208,3 +211,10 @@ config DVB_USB_DTT200U ...@@ -208,3 +211,10 @@ config DVB_USB_DTT200U
The receivers are also known as DTT200U (Yakumo) and UB300 (Yuan). The receivers are also known as DTT200U (Yakumo) and UB300 (Yuan).
The WT-220U and its clones are pen-sized. 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.
...@@ -51,4 +51,8 @@ obj-$(CONFIG_DVB_USB_TTUSB2) += dvb-usb-ttusb2.o ...@@ -51,4 +51,8 @@ obj-$(CONFIG_DVB_USB_TTUSB2) += dvb-usb-ttusb2.o
dvb-usb-dib0700-objs = dib0700_core.o dib0700_devices.o dvb-usb-dib0700-objs = dib0700_core.o dib0700_devices.o
obj-$(CONFIG_DVB_USB_DIB0700) += dvb-usb-dib0700.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/ EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/
...@@ -40,7 +40,7 @@ static int au6610_usb_msg(struct dvb_usb_device *d, u8 operation, u8 addr, ...@@ -40,7 +40,7 @@ static int au6610_usb_msg(struct dvb_usb_device *d, u8 operation, u8 addr,
} }
ret = usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0), operation, ret = usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0), operation,
USB_TYPE_VENDOR|USB_DIR_IN, addr, index, usb_buf, USB_TYPE_VENDOR|USB_DIR_IN, addr << 1, index, usb_buf,
sizeof(usb_buf), AU6610_USB_TIMEOUT); sizeof(usb_buf), AU6610_USB_TIMEOUT);
if (ret < 0) if (ret < 0)
...@@ -124,7 +124,7 @@ static int au6610_identify_state(struct usb_device *udev, ...@@ -124,7 +124,7 @@ static int au6610_identify_state(struct usb_device *udev,
} }
static struct zl10353_config au6610_zl10353_config = { static struct zl10353_config au6610_zl10353_config = {
.demod_address = 0x1e, .demod_address = 0x0f,
.no_tuner = 1, .no_tuner = 1,
.parallel_ts = 1, .parallel_ts = 1,
}; };
...@@ -140,7 +140,7 @@ static int au6610_zl10353_frontend_attach(struct dvb_usb_adapter *adap) ...@@ -140,7 +140,7 @@ static int au6610_zl10353_frontend_attach(struct dvb_usb_adapter *adap)
} }
static struct qt1010_config au6610_qt1010_config = { static struct qt1010_config au6610_qt1010_config = {
.i2c_address = 0xc4 .i2c_address = 0x62
}; };
static int au6610_qt1010_tuner_attach(struct dvb_usb_adapter *adap) static int au6610_qt1010_tuner_attach(struct dvb_usb_adapter *adap)
......
...@@ -27,7 +27,6 @@ ...@@ -27,7 +27,6 @@
#include "cx22702.h" #include "cx22702.h"
#include "lgdt330x.h" #include "lgdt330x.h"
#include "lgh06xf.h"
#include "mt352.h" #include "mt352.h"
#include "mt352_priv.h" #include "mt352_priv.h"
#include "zl10353.h" #include "zl10353.h"
...@@ -388,7 +387,8 @@ static int cxusb_dtt7579_tuner_attach(struct dvb_usb_adapter *adap) ...@@ -388,7 +387,8 @@ static int cxusb_dtt7579_tuner_attach(struct dvb_usb_adapter *adap)
static int cxusb_lgh064f_tuner_attach(struct dvb_usb_adapter *adap) static int cxusb_lgh064f_tuner_attach(struct dvb_usb_adapter *adap)
{ {
dvb_attach(lgh06xf_attach, adap->fe, &adap->dev->i2c_adap); dvb_attach(dvb_pll_attach, adap->fe, 0x61, &adap->dev->i2c_adap,
&dvb_pll_lg_tdvs_h06xf);
return 0; return 0;
} }
......
...@@ -56,10 +56,6 @@ static int dib0700_ctrl_rd(struct dvb_usb_device *d, u8 *tx, u8 txlen, u8 *rx, u ...@@ -56,10 +56,6 @@ static int dib0700_ctrl_rd(struct dvb_usb_device *d, u8 *tx, u8 txlen, u8 *rx, u
if (txlen > 3) if (txlen > 3)
index |= tx[3]; index |= tx[3];
/* think about swapping here */
value = le16_to_cpu(value);
index = le16_to_cpu(index);
status = usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev,0), tx[0], status = usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev,0), tx[0],
USB_TYPE_VENDOR | USB_DIR_IN, value, index, rx, rxlen, USB_TYPE_VENDOR | USB_DIR_IN, value, index, rx, rxlen,
USB_CTRL_GET_TIMEOUT); USB_CTRL_GET_TIMEOUT);
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#define USB_VID_ADSTECH 0x06e1 #define USB_VID_ADSTECH 0x06e1
#define USB_VID_ALCOR_MICRO 0x058f #define USB_VID_ALCOR_MICRO 0x058f
#define USB_VID_ANCHOR 0x0547 #define USB_VID_ANCHOR 0x0547
#define USB_VID_ANUBIS_ELECTRONIC 0x10fd
#define USB_VID_AVERMEDIA 0x07ca #define USB_VID_AVERMEDIA 0x07ca
#define USB_VID_COMPRO 0x185b #define USB_VID_COMPRO 0x185b
#define USB_VID_COMPRO_UNK 0x145f #define USB_VID_COMPRO_UNK 0x145f
...@@ -31,6 +32,7 @@ ...@@ -31,6 +32,7 @@
#define USB_VID_LITEON 0x04ca #define USB_VID_LITEON 0x04ca
#define USB_VID_MEDION 0x1660 #define USB_VID_MEDION 0x1660
#define USB_VID_MSI 0x0db0 #define USB_VID_MSI 0x0db0
#define USB_VID_OPERA1 0x695c
#define USB_VID_PINNACLE 0x2304 #define USB_VID_PINNACLE 0x2304
#define USB_VID_VISIONPLUS 0x13d3 #define USB_VID_VISIONPLUS 0x13d3
#define USB_VID_TWINHAN 0x1822 #define USB_VID_TWINHAN 0x1822
...@@ -127,6 +129,7 @@ ...@@ -127,6 +129,7 @@
#define USB_PID_KYE_DVB_T_WARM 0x701f #define USB_PID_KYE_DVB_T_WARM 0x701f
#define USB_PID_PCTV_200E 0x020e #define USB_PID_PCTV_200E 0x020e
#define USB_PID_PCTV_400E 0x020f #define USB_PID_PCTV_400E 0x020f
#define USB_PID_PCTV_450E 0x0222
#define USB_PID_LITEON_DVB_T_COLD 0xf000 #define USB_PID_LITEON_DVB_T_COLD 0xf000
#define USB_PID_LITEON_DVB_T_WARM 0xf001 #define USB_PID_LITEON_DVB_T_WARM 0xf001
#define USB_PID_DIGIVOX_MINI_SL_COLD 0xe360 #define USB_PID_DIGIVOX_MINI_SL_COLD 0xe360
...@@ -139,6 +142,9 @@ ...@@ -139,6 +142,9 @@
#define USB_PID_GENPIX_8PSK_COLD 0x0200 #define USB_PID_GENPIX_8PSK_COLD 0x0200
#define USB_PID_GENPIX_8PSK_WARM 0x0201 #define USB_PID_GENPIX_8PSK_WARM 0x0201
#define USB_PID_SIGMATEK_DVB_110 0x6610 #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
#endif #endif
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
#include "qt1010.h" #include "qt1010.h"
/* debug */ /* debug */
int dvb_usb_gl861_debug; static int dvb_usb_gl861_debug;
module_param_named(debug,dvb_usb_gl861_debug, int, 0644); module_param_named(debug,dvb_usb_gl861_debug, int, 0644);
MODULE_PARM_DESC(debug, "set debugging level (1=rc (or-able))." DVB_USB_DEBUG_STATUS); MODULE_PARM_DESC(debug, "set debugging level (1=rc (or-able))." DVB_USB_DEBUG_STATUS);
...@@ -20,7 +20,7 @@ static int gl861_i2c_msg(struct dvb_usb_device *d, u8 addr, ...@@ -20,7 +20,7 @@ static int gl861_i2c_msg(struct dvb_usb_device *d, u8 addr,
u8 *wbuf, u16 wlen, u8 *rbuf, u16 rlen) u8 *wbuf, u16 wlen, u8 *rbuf, u16 rlen)
{ {
u16 index; u16 index;
u16 value = addr << 8; u16 value = addr << (8 + 1);
int wo = (rbuf == NULL || rlen == 0); /* write-only */ int wo = (rbuf == NULL || rlen == 0); /* write-only */
u8 req, type; u8 req, type;
...@@ -101,7 +101,7 @@ static int gl861_identify_state(struct usb_device *udev, ...@@ -101,7 +101,7 @@ static int gl861_identify_state(struct usb_device *udev,
} }
static struct zl10353_config gl861_zl10353_config = { static struct zl10353_config gl861_zl10353_config = {
.demod_address = 0x1e, .demod_address = 0x0f,
.no_tuner = 1, .no_tuner = 1,
.parallel_ts = 1, .parallel_ts = 1,
}; };
...@@ -117,7 +117,7 @@ static int gl861_frontend_attach(struct dvb_usb_adapter *adap) ...@@ -117,7 +117,7 @@ static int gl861_frontend_attach(struct dvb_usb_adapter *adap)
} }
static struct qt1010_config gl861_qt1010_config = { static struct qt1010_config gl861_qt1010_config = {
.i2c_address = 0xc4 .i2c_address = 0x62
}; };
static int gl861_tuner_attach(struct dvb_usb_adapter *adap) static int gl861_tuner_attach(struct dvb_usb_adapter *adap)
......
This diff is collapsed.
...@@ -19,17 +19,49 @@ ...@@ -19,17 +19,49 @@
#define M9206_MAX_FILTERS 8 #define M9206_MAX_FILTERS 8
#define M9206_I2C_TUNER 0 /*
#define M9206_I2C_DEMOD 1 sequences found in logs:
#define M9206_I2C_MAX 2 [index value]
0x80 write addr
(0x00 out byte)*
0x40 out byte
0x80 write addr
(0x00 out byte)*
0x80 read addr
(0x21 in byte)*
0x60 in byte
this sequence works:
0x80 read addr
(0x21 in byte)*
0x60 in byte
Guess at API of the I2C function:
I2C operation is done one byte at a time with USB control messages. The
index the messages is sent to is made up of a set of flags that control
the I2C bus state:
0x80: Send START condition. After a START condition, one would normally
always send the 7-bit slave I2C address as the 7 MSB, followed by
the read/write bit as the LSB.
0x40: Send STOP condition. This should be set on the last byte of an
I2C transaction.
0x20: Read a byte from the slave. As opposed to writing a byte to the
slave. The slave will normally not produce any data unless you
set the R/W bit to 1 when sending the slave's address after the
START condition.
0x01: Respond with ACK, as opposed to a NACK. For a multi-byte read,
the master should send an ACK, that is pull SDA low during the 9th
clock cycle, after every byte but the last. This flags only makes
sense when bit 0x20 is set, indicating a read.
What any other bits might mean, or how to get the slave's ACK/NACK
response to a write, is unknown.
*/
struct m9206_state { struct m9206_state {
u16 filters[M9206_MAX_FILTERS]; u16 filters[M9206_MAX_FILTERS];
int filtering_enabled; int filtering_enabled;
int rep_count; int rep_count;
struct {
unsigned char addr;
unsigned char magic;
}i2c_r[M9206_I2C_MAX];
}; };
#endif #endif
This diff is collapsed.
#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
...@@ -184,6 +184,7 @@ static int ttusb2_probe(struct usb_interface *intf, ...@@ -184,6 +184,7 @@ static int ttusb2_probe(struct usb_interface *intf,
static struct usb_device_id ttusb2_table [] = { static struct usb_device_id ttusb2_table [] = {
{ USB_DEVICE(USB_VID_PINNACLE, USB_PID_PCTV_400E) }, { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PCTV_400E) },
{ USB_DEVICE(USB_VID_PINNACLE, USB_PID_PCTV_450E) },
{} /* Terminating entry */ {} /* Terminating entry */
}; };
MODULE_DEVICE_TABLE (usb, ttusb2_table); MODULE_DEVICE_TABLE (usb, ttusb2_table);
...@@ -227,12 +228,16 @@ static struct dvb_usb_device_properties ttusb2_properties = { ...@@ -227,12 +228,16 @@ static struct dvb_usb_device_properties ttusb2_properties = {
.generic_bulk_ctrl_endpoint = 0x01, .generic_bulk_ctrl_endpoint = 0x01,
.num_device_descs = 1, .num_device_descs = 2,
.devices = { .devices = {
{ "Pinnacle 400e DVB-S USB2.0", { "Pinnacle 400e DVB-S USB2.0",
{ &ttusb2_table[0], NULL }, { &ttusb2_table[0], NULL },
{ NULL }, { NULL },
}, },
{ "Pinnacle 450e DVB-S USB2.0",
{ &ttusb2_table[1], NULL },
{ NULL },
},
} }
}; };
......
...@@ -205,6 +205,13 @@ config DVB_TDA10021 ...@@ -205,6 +205,13 @@ config DVB_TDA10021
help help
A DVB-C tuner module. Say Y when you want to support this frontend. 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 config DVB_STV0297
tristate "ST STV0297 based" tristate "ST STV0297 based"
depends on DVB_CORE && I2C depends on DVB_CORE && I2C
...@@ -280,8 +287,12 @@ comment "Tuners/PLL support" ...@@ -280,8 +287,12 @@ comment "Tuners/PLL support"
depends on DVB_CORE depends on DVB_CORE
config DVB_PLL config DVB_PLL
tristate tristate "Generic I2C PLL based tuners"
depends on DVB_CORE && I2C depends on DVB_CORE && I2C
default m if DVB_FE_CUSTOMISE
help
This module driver a number of tuners based on PLL chips with a
common I2C interface. Say Y when you want to support these tuners.
config DVB_TDA826X config DVB_TDA826X
tristate "Philips TDA826X silicon tuner" tristate "Philips TDA826X silicon tuner"
...@@ -290,6 +301,13 @@ config DVB_TDA826X ...@@ -290,6 +301,13 @@ config DVB_TDA826X
help help
A DVB-S silicon tuner module. Say Y when you want to support this tuner. A DVB-S silicon tuner module. Say Y when you want to support this tuner.
config DVB_TDA827X
tristate "Philips TDA827X silicon tuner"
depends on DVB_CORE && I2C
default m if DVB_FE_CUSTOMISE
help
A DVB-T silicon tuner module. Say Y when you want to support this tuner.
config DVB_TUNER_QT1010 config DVB_TUNER_QT1010
tristate "Quantek QT1010 silicon tuner" tristate "Quantek QT1010 silicon tuner"
depends on DVB_CORE && I2C depends on DVB_CORE && I2C
...@@ -304,14 +322,6 @@ config DVB_TUNER_MT2060 ...@@ -304,14 +322,6 @@ config DVB_TUNER_MT2060
help help
A driver for the silicon IF tuner MT2060 from Microtune. A driver for the silicon IF tuner MT2060 from Microtune.
config DVB_TUNER_LGH06XF
tristate "LG TDVS-H06xF ATSC tuner"
depends on DVB_CORE && I2C
select DVB_PLL
default m if DVB_FE_CUSTOMISE
help
A driver for the LG TDVS-H06xF ATSC tuner family.
comment "Miscellaneous devices" comment "Miscellaneous devices"
depends on DVB_CORE depends on DVB_CORE
......
...@@ -25,6 +25,7 @@ obj-$(CONFIG_DVB_MT352) += mt352.o ...@@ -25,6 +25,7 @@ obj-$(CONFIG_DVB_MT352) += mt352.o
obj-$(CONFIG_DVB_ZL10353) += zl10353.o obj-$(CONFIG_DVB_ZL10353) += zl10353.o
obj-$(CONFIG_DVB_CX22702) += cx22702.o obj-$(CONFIG_DVB_CX22702) += cx22702.o
obj-$(CONFIG_DVB_TDA10021) += tda10021.o obj-$(CONFIG_DVB_TDA10021) += tda10021.o
obj-$(CONFIG_DVB_TDA10023) += tda10023.o
obj-$(CONFIG_DVB_STV0297) += stv0297.o obj-$(CONFIG_DVB_STV0297) += stv0297.o
obj-$(CONFIG_DVB_NXT200X) += nxt200x.o obj-$(CONFIG_DVB_NXT200X) += nxt200x.o
obj-$(CONFIG_DVB_OR51211) += or51211.o obj-$(CONFIG_DVB_OR51211) += or51211.o
...@@ -37,7 +38,7 @@ obj-$(CONFIG_DVB_LNBP21) += lnbp21.o ...@@ -37,7 +38,7 @@ obj-$(CONFIG_DVB_LNBP21) += lnbp21.o
obj-$(CONFIG_DVB_ISL6421) += isl6421.o obj-$(CONFIG_DVB_ISL6421) += isl6421.o
obj-$(CONFIG_DVB_TDA10086) += tda10086.o obj-$(CONFIG_DVB_TDA10086) += tda10086.o
obj-$(CONFIG_DVB_TDA826X) += tda826x.o obj-$(CONFIG_DVB_TDA826X) += tda826x.o
obj-$(CONFIG_DVB_TDA827X) += tda827x.o
obj-$(CONFIG_DVB_TUNER_MT2060) += mt2060.o obj-$(CONFIG_DVB_TUNER_MT2060) += mt2060.o
obj-$(CONFIG_DVB_TUNER_QT1010) += qt1010.o obj-$(CONFIG_DVB_TUNER_QT1010) += qt1010.o
obj-$(CONFIG_DVB_TUA6100) += tua6100.o obj-$(CONFIG_DVB_TUA6100) += tua6100.o
obj-$(CONFIG_DVB_TUNER_LGH06XF) += lgh06xf.o
This diff is collapsed.
...@@ -12,11 +12,13 @@ struct dvb_pll_desc { ...@@ -12,11 +12,13 @@ struct dvb_pll_desc {
char *name; char *name;
u32 min; u32 min;
u32 max; u32 max;
u32 iffreq;
void (*setbw)(u8 *buf, u32 freq, int bandwidth); void (*setbw)(u8 *buf, u32 freq, int bandwidth);
u8 *initdata;
u8 *sleepdata;
int count; int count;
struct { struct {
u32 limit; u32 limit;
u32 offset;
u32 stepsize; u32 stepsize;
u8 config; u8 config;
u8 cb; u8 cb;
...@@ -46,6 +48,7 @@ extern struct dvb_pll_desc dvb_pll_philips_sd1878_tda8261; ...@@ -46,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_philips_td1316;
extern struct dvb_pll_desc dvb_pll_thomson_fe6600; 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, extern int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf,
u32 freq, int bandwidth); u32 freq, int bandwidth);
...@@ -59,9 +62,20 @@ extern int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf, ...@@ -59,9 +62,20 @@ extern int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf,
* @param desc dvb_pll_desc to use. * @param desc dvb_pll_desc to use.
* @return Frontend pointer on success, NULL on failure * @return Frontend pointer on success, NULL on failure
*/ */
#if defined(CONFIG_DVB_PLL) || (defined(CONFIG_DVB_PLL_MODULE) && defined(MODULE))
extern struct dvb_frontend *dvb_pll_attach(struct dvb_frontend *fe, extern struct dvb_frontend *dvb_pll_attach(struct dvb_frontend *fe,
int pll_addr, int pll_addr,
struct i2c_adapter *i2c, struct i2c_adapter *i2c,
struct dvb_pll_desc *desc); struct dvb_pll_desc *desc);
#else
static inline struct dvb_frontend *dvb_pll_attach(struct dvb_frontend *fe,
int pll_addr,
struct i2c_adapter *i2c,
struct dvb_pll_desc *desc)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
return NULL;
}
#endif
#endif #endif
...@@ -475,7 +475,7 @@ static int lgdt3302_read_status(struct dvb_frontend* fe, fe_status_t* status) ...@@ -475,7 +475,7 @@ static int lgdt3302_read_status(struct dvb_frontend* fe, fe_status_t* status)
*status |= FE_HAS_CARRIER; *status |= FE_HAS_CARRIER;
break; break;
default: 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; return 0;
...@@ -534,7 +534,7 @@ static int lgdt3303_read_status(struct dvb_frontend* fe, fe_status_t* status) ...@@ -534,7 +534,7 @@ static int lgdt3303_read_status(struct dvb_frontend* fe, fe_status_t* status)
} }
break; break;
default: 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; return 0;
} }
......
/*
* lgh06xf.c - ATSC Tuner support for LG TDVS-H06xF
*
* 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 "dvb-pll.h"
#include "lgh06xf.h"
#define LG_H06XF_PLL_I2C_ADDR 0x61
struct lgh06xf_priv {
struct i2c_adapter *i2c;
u32 frequency;
};
static int lgh06xf_release(struct dvb_frontend *fe)
{
kfree(fe->tuner_priv);
fe->tuner_priv = NULL;
return 0;
}
static int lgh06xf_set_params(struct dvb_frontend* fe,
struct dvb_frontend_parameters* params)
{
struct lgh06xf_priv *priv = fe->tuner_priv;
u8 buf[4];
struct i2c_msg msg = { .addr = LG_H06XF_PLL_I2C_ADDR, .flags = 0,
.buf = buf, .len = sizeof(buf) };
u32 frequency;
int result;
if ((result = dvb_pll_configure(&dvb_pll_lg_tdvs_h06xf, buf,
params->frequency, 0)) < 0)
return result;
else
frequency = result;
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 1);
if ((result = i2c_transfer(priv->i2c, &msg, 1)) != 1) {
printk(KERN_WARNING "lgh06xf: %s error "
"(addr %02x <- %02x, result = %i)\n",
__FUNCTION__, buf[0], buf[1], result);
if (result < 0)
return result;
else
return -EREMOTEIO;
}
/* Set the Auxiliary Byte. */
buf[0] = buf[2];
buf[0] &= ~0x20;
buf[0] |= 0x18;
buf[1] = 0x50;
msg.len = 2;
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 1);
if ((result = i2c_transfer(priv->i2c, &msg, 1)) != 1) {
printk(KERN_WARNING "lgh06xf: %s error "
"(addr %02x <- %02x, result = %i)\n",
__FUNCTION__, buf[0], buf[1], result);
if (result < 0)
return result;
else
return -EREMOTEIO;
}
priv->frequency = frequency;
return 0;
}
static int lgh06xf_get_frequency(struct dvb_frontend *fe, u32 *frequency)
{
struct lgh06xf_priv *priv = fe->tuner_priv;
*frequency = priv->frequency;
return 0;
}
static struct dvb_tuner_ops lgh06xf_tuner_ops = {
.release = lgh06xf_release,
.set_params = lgh06xf_set_params,
.get_frequency = lgh06xf_get_frequency,
};
struct dvb_frontend* lgh06xf_attach(struct dvb_frontend *fe,
struct i2c_adapter *i2c)
{
struct lgh06xf_priv *priv = NULL;
priv = kzalloc(sizeof(struct lgh06xf_priv), GFP_KERNEL);
if (priv == NULL)
return NULL;
priv->i2c = i2c;
memcpy(&fe->ops.tuner_ops, &lgh06xf_tuner_ops,
sizeof(struct dvb_tuner_ops));
strlcpy(fe->ops.tuner_ops.info.name, dvb_pll_lg_tdvs_h06xf.name,
sizeof(fe->ops.tuner_ops.info.name));
fe->ops.tuner_ops.info.frequency_min = dvb_pll_lg_tdvs_h06xf.min;
fe->ops.tuner_ops.info.frequency_max = dvb_pll_lg_tdvs_h06xf.max;
fe->tuner_priv = priv;
return fe;
}
EXPORT_SYMBOL(lgh06xf_attach);
MODULE_DESCRIPTION("LG TDVS-H06xF ATSC Tuner support");
MODULE_AUTHOR("Michael Krufky");
MODULE_LICENSE("GPL");
/*
* Local variables:
* c-basic-offset: 8
* End:
*/
/*
* lgh06xf.h - ATSC Tuner support for LG TDVS-H06xF
*
* 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.
*/
#ifndef _LGH06XF_H_
#define _LGH06XF_H_
#include "dvb_frontend.h"
#if defined(CONFIG_DVB_TUNER_LGH06XF) || (defined(CONFIG_DVB_TUNER_LGH06XF_MODULE) && defined(MODULE))
extern struct dvb_frontend* lgh06xf_attach(struct dvb_frontend* fe,
struct i2c_adapter *i2c);
#else
static inline struct dvb_frontend* lgh06xf_attach(struct dvb_frontend* fe,
struct i2c_adapter *i2c)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
return NULL;
}
#endif /* CONFIG_DVB_TUNER_LGH06XF */
#endif /* _LGH06XF_H_ */
This diff is collapsed.
...@@ -30,13 +30,13 @@ ...@@ -30,13 +30,13 @@
#include <linux/slab.h> #include <linux/slab.h>
#include "dvb_frontend.h" #include "dvb_frontend.h"
#include "tda10021.h" #include "tda1002x.h"
struct tda10021_state { struct tda10021_state {
struct i2c_adapter* i2c; struct i2c_adapter* i2c;
/* configuration settings */ /* configuration settings */
const struct tda10021_config* config; const struct tda1002x_config* config;
struct dvb_frontend frontend; struct dvb_frontend frontend;
u8 pwm; u8 pwm;
...@@ -53,9 +53,6 @@ struct tda10021_state { ...@@ -53,9 +53,6 @@ struct tda10021_state {
static int verbose; static int verbose;
#define XIN 57840000UL #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) #define FIN (XIN >> 4)
...@@ -64,7 +61,7 @@ static u8 tda10021_inittab[0x40]= ...@@ -64,7 +61,7 @@ static u8 tda10021_inittab[0x40]=
{ {
0x73, 0x6a, 0x23, 0x0a, 0x02, 0x37, 0x77, 0x1a, 0x73, 0x6a, 0x23, 0x0a, 0x02, 0x37, 0x77, 0x1a,
0x37, 0x6a, 0x17, 0x8a, 0x1e, 0x86, 0x43, 0x40, 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, 0x11, 0x00, 0x7c, 0x31, 0x30, 0x20, 0x00, 0x00,
0x02, 0x00, 0x00, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x7d, 0x00, 0x00, 0x00, 0x00,
0x07, 0x00, 0x33, 0x11, 0x0d, 0x95, 0x08, 0x58, 0x07, 0x00, 0x33, 0x11, 0x0d, 0x95, 0x08, 0x58,
...@@ -97,7 +94,8 @@ static u8 tda10021_readreg (struct tda10021_state* state, u8 reg) ...@@ -97,7 +94,8 @@ static u8 tda10021_readreg (struct tda10021_state* state, u8 reg)
int ret; int ret;
ret = i2c_transfer (state->i2c, msg, 2); 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", printk("DVB: TDA10021: %s: readreg error (ret == %i)\n",
__FUNCTION__, ret); __FUNCTION__, ret);
return b1[0]; return b1[0];
...@@ -136,10 +134,10 @@ static int tda10021_setup_reg0 (struct tda10021_state* state, u8 reg0, ...@@ -136,10 +134,10 @@ static int tda10021_setup_reg0 (struct tda10021_state* state, u8 reg0,
{ {
reg0 |= state->reg0 & 0x63; reg0 |= state->reg0 & 0x63;
if (INVERSION_ON == inversion) if ((INVERSION_ON == inversion) ^ (state->config->invert == 0))
ENABLE_INVERSION(reg0); reg0 &= ~0x20;
else if (INVERSION_OFF == inversion) else
DISABLE_INVERSION(reg0); reg0 |= 0x20;
_tda10021_writereg (state, 0x00, reg0 & 0xfe); _tda10021_writereg (state, 0x00, reg0 & 0xfe);
_tda10021_writereg (state, 0x00, reg0 | 0x01); _tda10021_writereg (state, 0x00, reg0 | 0x01);
...@@ -201,16 +199,6 @@ static int tda10021_set_symbolrate (struct tda10021_state* state, u32 symbolrate ...@@ -201,16 +199,6 @@ static int tda10021_set_symbolrate (struct tda10021_state* state, u32 symbolrate
return 0; 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) static int tda10021_init (struct dvb_frontend *fe)
{ {
struct tda10021_state* state = fe->demodulator_priv; struct tda10021_state* state = fe->demodulator_priv;
...@@ -258,6 +246,9 @@ static int tda10021_set_parameters (struct dvb_frontend *fe, ...@@ -258,6 +246,9 @@ static int tda10021_set_parameters (struct dvb_frontend *fe,
if (qam < 0 || qam > 5) if (qam < 0 || qam > 5)
return -EINVAL; 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); //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) { if (fe->ops.tuner_ops.set_params) {
...@@ -366,7 +357,7 @@ static int tda10021_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_pa ...@@ -366,7 +357,7 @@ static int tda10021_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_pa
-((s32)p->u.qam.symbol_rate * afc) >> 10); -((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.modulation = ((state->reg0 >> 2) & 7) + QAM_16;
p->u.qam.fec_inner = FEC_NONE; p->u.qam.fec_inner = FEC_NONE;
...@@ -408,11 +399,12 @@ static void tda10021_release(struct dvb_frontend* fe) ...@@ -408,11 +399,12 @@ static void tda10021_release(struct dvb_frontend* fe)
static struct dvb_frontend_ops tda10021_ops; 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, struct i2c_adapter* i2c,
u8 pwm) u8 pwm)
{ {
struct tda10021_state* state = NULL; struct tda10021_state* state = NULL;
u8 id;
/* allocate memory for the internal state */ /* allocate memory for the internal state */
state = kmalloc(sizeof(struct tda10021_state), GFP_KERNEL); state = kmalloc(sizeof(struct tda10021_state), GFP_KERNEL);
...@@ -425,7 +417,11 @@ struct dvb_frontend* tda10021_attach(const struct tda10021_config* config, ...@@ -425,7 +417,11 @@ struct dvb_frontend* tda10021_attach(const struct tda10021_config* config,
state->reg0 = tda10021_inittab[0]; state->reg0 = tda10021_inittab[0];
/* check if the demod is there */ /* 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 */ /* create dvb_frontend */
memcpy(&state->frontend.ops, &tda10021_ops, sizeof(struct dvb_frontend_ops)); memcpy(&state->frontend.ops, &tda10021_ops, sizeof(struct dvb_frontend_ops));
...@@ -447,7 +443,7 @@ static struct dvb_frontend_ops tda10021_ops = { ...@@ -447,7 +443,7 @@ static struct dvb_frontend_ops tda10021_ops = {
.frequency_max = 858000000, .frequency_max = 858000000,
.symbol_rate_min = (XIN/2)/64, /* SACLK/64 == (XIN/2)/64 */ .symbol_rate_min = (XIN/2)/64, /* SACLK/64 == (XIN/2)/64 */
.symbol_rate_max = (XIN/2)/4, /* SACLK/4 */ .symbol_rate_max = (XIN/2)/4, /* SACLK/4 */
#if 0 #if 0
.frequency_tolerance = ???, .frequency_tolerance = ???,
.symbol_rate_tolerance = ???, /* ppm */ /* == 8% (spec p. 5) */ .symbol_rate_tolerance = ???, /* ppm */ /* == 8% (spec p. 5) */
#endif #endif
...@@ -461,7 +457,6 @@ static struct dvb_frontend_ops tda10021_ops = { ...@@ -461,7 +457,6 @@ static struct dvb_frontend_ops tda10021_ops = {
.init = tda10021_init, .init = tda10021_init,
.sleep = tda10021_sleep, .sleep = tda10021_sleep,
.write = tda10021_write,
.i2c_gate_ctrl = tda10021_i2c_gate_ctrl, .i2c_gate_ctrl = tda10021_i2c_gate_ctrl,
.set_frontend = tda10021_set_parameters, .set_frontend = tda10021_set_parameters,
......
This diff is collapsed.
/* /*
TDA10021 - Single Chip Cable Channel Receiver driver module TDA10021/TDA10023 - Single Chip Cable Channel Receiver driver module
used on the the Siemens DVB-C cards used on the the Siemens DVB-C cards
Copyright (C) 1999 Convergence Integrated Media GmbH <ralph@convergence.de> Copyright (C) 1999 Convergence Integrated Media GmbH <ralph@convergence.de>
Copyright (C) 2004 Markus Schulz <msc@antzsystem.de> Copyright (C) 2004 Markus Schulz <msc@antzsystem.de>
...@@ -21,22 +21,23 @@ ...@@ -21,22 +21,23 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
#ifndef TDA10021_H #ifndef TDA1002x_H
#define TDA10021_H #define TDA1002x_H
#include <linux/dvb/frontend.h> #include <linux/dvb/frontend.h>
struct tda10021_config struct tda1002x_config
{ {
/* the demodulator's i2c address */ /* the demodulator's i2c address */
u8 demod_address; u8 demod_address;
u8 invert;
}; };
#if defined(CONFIG_DVB_TDA10021) || (defined(CONFIG_DVB_TDA10021_MODULE) && defined(MODULE)) #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); struct i2c_adapter* i2c, u8 pwm);
#else #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) struct i2c_adapter* i2c, u8 pwm)
{ {
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__); printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
...@@ -44,12 +45,16 @@ static inline struct dvb_frontend* tda10021_attach(const struct tda10021_config* ...@@ -44,12 +45,16 @@ static inline struct dvb_frontend* tda10021_attach(const struct tda10021_config*
} }
#endif // CONFIG_DVB_TDA10021 #endif // CONFIG_DVB_TDA10021
static inline int tda10021_writereg(struct dvb_frontend *fe, u8 reg, u8 val) { #if defined(CONFIG_DVB_TDA10023) || (defined(CONFIG_DVB_TDA10023_MODULE) && defined(MODULE))
int r = 0; extern struct dvb_frontend* tda10023_attach(const struct tda1002x_config* config,
u8 buf[] = {reg, val}; struct i2c_adapter* i2c, u8 pwm);
if (fe->ops.write) #else
r = fe->ops.write(fe, buf, 2); static inline struct dvb_frontend* tda10023_attach(const struct tda1002x_config* config,
return r; 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
...@@ -40,20 +40,6 @@ ...@@ -40,20 +40,6 @@
#include "dvb_frontend.h" #include "dvb_frontend.h"
#include "tda1004x.h" #include "tda1004x.h"
enum tda1004x_demod {
TDA1004X_DEMOD_TDA10045,
TDA1004X_DEMOD_TDA10046,
};
struct tda1004x_state {
struct i2c_adapter* i2c;
const struct tda1004x_config* config;
struct dvb_frontend frontend;
/* private demod data */
enum tda1004x_demod demod_type;
};
static int debug; static int debug;
#define dprintk(args...) \ #define dprintk(args...) \
do { \ do { \
...@@ -507,12 +493,25 @@ static int tda10046_fwupload(struct dvb_frontend* fe) ...@@ -507,12 +493,25 @@ static int tda10046_fwupload(struct dvb_frontend* fe)
tda1004x_write_byteI(state, TDA1004X_CONFC4, 0x80); tda1004x_write_byteI(state, TDA1004X_CONFC4, 0x80);
} }
tda1004x_write_mask(state, TDA10046H_CONF_TRISTATE1, 1, 0); tda1004x_write_mask(state, TDA10046H_CONF_TRISTATE1, 1, 0);
/* set GPIO 1 and 3 */
if (state->config->gpio_config != TDA10046_GPTRI) {
tda1004x_write_byteI(state, TDA10046H_CONF_TRISTATE2, 0x33);
tda1004x_write_mask(state, TDA10046H_CONF_POLARITY, 0x0f, state->config->gpio_config &0x0f);
}
/* let the clocks recover from sleep */ /* let the clocks recover from sleep */
msleep(5); msleep(10);
/* The PLLs need to be reprogrammed after sleep */ /* The PLLs need to be reprogrammed after sleep */
tda10046_init_plls(fe); tda10046_init_plls(fe);
tda1004x_write_mask(state, TDA1004X_CONFADC2, 0xc0, 0);
/* don't re-upload unless necessary */
if (tda1004x_check_upload_ok(state) == 0)
return 0;
printk(KERN_INFO "tda1004x: trying to boot from eeprom\n");
tda1004x_write_mask(state, TDA1004X_CONFC4, 4, 4);
msleep(300);
/* don't re-upload unless necessary */ /* don't re-upload unless necessary */
if (tda1004x_check_upload_ok(state) == 0) if (tda1004x_check_upload_ok(state) == 0)
return 0; return 0;
...@@ -522,20 +521,23 @@ static int tda10046_fwupload(struct dvb_frontend* fe) ...@@ -522,20 +521,23 @@ static int tda10046_fwupload(struct dvb_frontend* fe)
printk(KERN_INFO "tda1004x: waiting for firmware upload...\n"); printk(KERN_INFO "tda1004x: waiting for firmware upload...\n");
ret = state->config->request_firmware(fe, &fw, TDA10046_DEFAULT_FIRMWARE); ret = state->config->request_firmware(fe, &fw, TDA10046_DEFAULT_FIRMWARE);
if (ret) { if (ret) {
printk(KERN_ERR "tda1004x: no firmware upload (timeout or file not found?)\n"); /* remain compatible to old bug: try to load with tda10045 image name */
return ret; ret = state->config->request_firmware(fe, &fw, TDA10045_DEFAULT_FIRMWARE);
if (ret) {
printk(KERN_ERR "tda1004x: no firmware upload (timeout or file not found?)\n");
return ret;
} else {
printk(KERN_INFO "tda1004x: please rename the firmware file to %s\n",
TDA10046_DEFAULT_FIRMWARE);
}
} }
tda1004x_write_mask(state, TDA1004X_CONFC4, 8, 8); // going to boot from HOST
ret = tda1004x_do_upload(state, fw->data, fw->size, TDA10046H_CODE_CPT, TDA10046H_CODE_IN);
release_firmware(fw);
if (ret)
return ret;
} else { } else {
/* boot from firmware eeprom */ printk(KERN_ERR "tda1004x: no request function defined, can't upload from file\n");
printk(KERN_INFO "tda1004x: booting from eeprom\n"); return -EIO;
tda1004x_write_mask(state, TDA1004X_CONFC4, 4, 4);
msleep(300);
} }
tda1004x_write_mask(state, TDA1004X_CONFC4, 8, 8); // going to boot from HOST
ret = tda1004x_do_upload(state, fw->data, fw->size, TDA10046H_CODE_CPT, TDA10046H_CODE_IN);
release_firmware(fw);
return tda1004x_check_upload_ok(state); return tda1004x_check_upload_ok(state);
} }
...@@ -638,37 +640,33 @@ static int tda10046_init(struct dvb_frontend* fe) ...@@ -638,37 +640,33 @@ static int tda10046_init(struct dvb_frontend* fe)
switch (state->config->agc_config) { switch (state->config->agc_config) {
case TDA10046_AGC_DEFAULT: case TDA10046_AGC_DEFAULT:
tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x00); // AGC setup tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x00); // AGC setup
tda1004x_write_byteI(state, TDA10046H_CONF_POLARITY, 0x60); // set AGC polarities tda1004x_write_mask(state, TDA10046H_CONF_POLARITY, 0xf0, 0x60); // set AGC polarities
break; break;
case TDA10046_AGC_IFO_AUTO_NEG: case TDA10046_AGC_IFO_AUTO_NEG:
tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x0a); // AGC setup tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x0a); // AGC setup
tda1004x_write_byteI(state, TDA10046H_CONF_POLARITY, 0x60); // set AGC polarities tda1004x_write_mask(state, TDA10046H_CONF_POLARITY, 0xf0, 0x60); // set AGC polarities
break; break;
case TDA10046_AGC_IFO_AUTO_POS: case TDA10046_AGC_IFO_AUTO_POS:
tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x0a); // AGC setup tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x0a); // AGC setup
tda1004x_write_byteI(state, TDA10046H_CONF_POLARITY, 0x00); // set AGC polarities tda1004x_write_mask(state, TDA10046H_CONF_POLARITY, 0xf0, 0x00); // set AGC polarities
break;
case TDA10046_AGC_TDA827X_GP11:
tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x02); // AGC setup
tda1004x_write_byteI(state, TDA10046H_AGC_THR, 0x70); // AGC Threshold
tda1004x_write_byteI(state, TDA10046H_AGC_RENORM, 0x08); // Gain Renormalize
tda1004x_write_byteI(state, TDA10046H_CONF_POLARITY, 0x6a); // set AGC polarities
break;
case TDA10046_AGC_TDA827X_GP00:
tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x02); // AGC setup
tda1004x_write_byteI(state, TDA10046H_AGC_THR, 0x70); // AGC Threshold
tda1004x_write_byteI(state, TDA10046H_AGC_RENORM, 0x08); // Gain Renormalize
tda1004x_write_byteI(state, TDA10046H_CONF_POLARITY, 0x60); // set AGC polarities
break; break;
case TDA10046_AGC_TDA827X_GP01: case TDA10046_AGC_TDA827X:
tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x02); // AGC setup tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x02); // AGC setup
tda1004x_write_byteI(state, TDA10046H_AGC_THR, 0x70); // AGC Threshold tda1004x_write_byteI(state, TDA10046H_AGC_THR, 0x70); // AGC Threshold
tda1004x_write_byteI(state, TDA10046H_AGC_RENORM, 0x08); // Gain Renormalize tda1004x_write_byteI(state, TDA10046H_AGC_RENORM, 0x08); // Gain Renormalize
tda1004x_write_byteI(state, TDA10046H_CONF_POLARITY, 0x62); // set AGC polarities tda1004x_write_mask(state, TDA10046H_CONF_POLARITY, 0xf0, 0x60); // set AGC polarities
break; break;
} }
if (state->config->ts_mode == 0) {
tda1004x_write_mask(state, TDA10046H_CONF_TRISTATE1, 0xc0, 0x40);
tda1004x_write_mask(state, 0x3a, 0x80, state->config->invert_oclk << 7);
} else {
tda1004x_write_mask(state, TDA10046H_CONF_TRISTATE1, 0xc0, 0x80);
tda1004x_write_mask(state, TDA10046H_CONF_POLARITY, 0x10,
state->config->invert_oclk << 4);
}
tda1004x_write_byteI(state, TDA1004X_CONFADC2, 0x38); tda1004x_write_byteI(state, TDA1004X_CONFADC2, 0x38);
tda1004x_write_byteI(state, TDA10046H_CONF_TRISTATE1, 0x61); // Turn both AGC outputs on tda1004x_write_mask (state, TDA10046H_CONF_TRISTATE1, 0x3e, 0x38); // Turn IF AGC output on
tda1004x_write_byteI(state, TDA10046H_AGC_TUN_MIN, 0); // } tda1004x_write_byteI(state, TDA10046H_AGC_TUN_MIN, 0); // }
tda1004x_write_byteI(state, TDA10046H_AGC_TUN_MAX, 0xff); // } AGC min/max values tda1004x_write_byteI(state, TDA10046H_AGC_TUN_MAX, 0xff); // } AGC min/max values
tda1004x_write_byteI(state, TDA10046H_AGC_IF_MIN, 0); // } tda1004x_write_byteI(state, TDA10046H_AGC_IF_MIN, 0); // }
...@@ -678,7 +676,6 @@ static int tda10046_init(struct dvb_frontend* fe) ...@@ -678,7 +676,6 @@ static int tda10046_init(struct dvb_frontend* fe)
tda1004x_write_byteI(state, TDA1004X_CONF_TS1, 7); // MPEG2 interface config tda1004x_write_byteI(state, TDA1004X_CONF_TS1, 7); // MPEG2 interface config
tda1004x_write_byteI(state, TDA1004X_CONF_TS2, 0xc0); // MPEG2 interface config tda1004x_write_byteI(state, TDA1004X_CONF_TS2, 0xc0); // MPEG2 interface config
// tda1004x_write_mask(state, 0x50, 0x80, 0x80); // handle out of guard echoes // tda1004x_write_mask(state, 0x50, 0x80, 0x80); // handle out of guard echoes
tda1004x_write_mask(state, 0x3a, 0x80, state->config->invert_oclk << 7);
return 0; return 0;
} }
...@@ -705,7 +702,8 @@ static int tda1004x_set_fe(struct dvb_frontend* fe, ...@@ -705,7 +702,8 @@ static int tda1004x_set_fe(struct dvb_frontend* fe,
// set frequency // set frequency
if (fe->ops.tuner_ops.set_params) { if (fe->ops.tuner_ops.set_params) {
fe->ops.tuner_ops.set_params(fe, fe_params); fe->ops.tuner_ops.set_params(fe, fe_params);
if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 0);
} }
// Hardcoded to use auto as much as possible on the TDA10045 as it // Hardcoded to use auto as much as possible on the TDA10045 as it
...@@ -1165,6 +1163,7 @@ static int tda1004x_read_ber(struct dvb_frontend* fe, u32* ber) ...@@ -1165,6 +1163,7 @@ static int tda1004x_read_ber(struct dvb_frontend* fe, u32* ber)
static int tda1004x_sleep(struct dvb_frontend* fe) static int tda1004x_sleep(struct dvb_frontend* fe)
{ {
struct tda1004x_state* state = fe->demodulator_priv; struct tda1004x_state* state = fe->demodulator_priv;
int gpio_conf;
switch (state->demod_type) { switch (state->demod_type) {
case TDA1004X_DEMOD_TDA10045: case TDA1004X_DEMOD_TDA10045:
...@@ -1174,6 +1173,13 @@ static int tda1004x_sleep(struct dvb_frontend* fe) ...@@ -1174,6 +1173,13 @@ static int tda1004x_sleep(struct dvb_frontend* fe)
case TDA1004X_DEMOD_TDA10046: case TDA1004X_DEMOD_TDA10046:
/* set outputs to tristate */ /* set outputs to tristate */
tda1004x_write_byteI(state, TDA10046H_CONF_TRISTATE1, 0xff); tda1004x_write_byteI(state, TDA10046H_CONF_TRISTATE1, 0xff);
/* invert GPIO 1 and 3 if desired*/
gpio_conf = state->config->gpio_config;
if (gpio_conf >= TDA10046_GP00_I)
tda1004x_write_mask(state, TDA10046H_CONF_POLARITY, 0x0f,
(gpio_conf & 0x0f) ^ 0x0a);
tda1004x_write_mask(state, TDA1004X_CONFADC2, 0xc0, 0xc0);
tda1004x_write_mask(state, TDA1004X_CONFC4, 1, 1); tda1004x_write_mask(state, TDA1004X_CONFC4, 1, 1);
break; break;
} }
......
...@@ -35,9 +35,23 @@ enum tda10046_agc { ...@@ -35,9 +35,23 @@ enum tda10046_agc {
TDA10046_AGC_DEFAULT, /* original configuration */ TDA10046_AGC_DEFAULT, /* original configuration */
TDA10046_AGC_IFO_AUTO_NEG, /* IF AGC only, automatic, negtive */ TDA10046_AGC_IFO_AUTO_NEG, /* IF AGC only, automatic, negtive */
TDA10046_AGC_IFO_AUTO_POS, /* IF AGC only, automatic, positive */ TDA10046_AGC_IFO_AUTO_POS, /* IF AGC only, automatic, positive */
TDA10046_AGC_TDA827X_GP11, /* IF AGC only, special setup for tda827x */ TDA10046_AGC_TDA827X, /* IF AGC only, special setup for tda827x */
TDA10046_AGC_TDA827X_GP00, /* same as above, but GPIOs 0 */ };
TDA10046_AGC_TDA827X_GP01, /* same as above, but GPIO3=0 GPIO1=1*/
/* Many (hybrid) boards use GPIO 1 and 3
GPIO1 analog - dvb switch
GPIO3 firmware eeprom address switch
*/
enum tda10046_gpio {
TDA10046_GPTRI = 0x00, /* All GPIOs tristate */
TDA10046_GP00 = 0x40, /* GPIO3=0, GPIO1=0 */
TDA10046_GP01 = 0x42, /* GPIO3=0, GPIO1=1 */
TDA10046_GP10 = 0x48, /* GPIO3=1, GPIO1=0 */
TDA10046_GP11 = 0x4a, /* GPIO3=1, GPIO1=1 */
TDA10046_GP00_I = 0x80, /* GPIO3=0, GPIO1=0, invert in sleep mode*/
TDA10046_GP01_I = 0x82, /* GPIO3=0, GPIO1=1, invert in sleep mode */
TDA10046_GP10_I = 0x88, /* GPIO3=1, GPIO1=0, invert in sleep mode */
TDA10046_GP11_I = 0x8a, /* GPIO3=1, GPIO1=1, invert in sleep mode */
}; };
enum tda10046_if { enum tda10046_if {
...@@ -47,6 +61,11 @@ enum tda10046_if { ...@@ -47,6 +61,11 @@ enum tda10046_if {
TDA10046_FREQ_052, /* low IF, 5.1667 MHZ for tda9889 */ TDA10046_FREQ_052, /* low IF, 5.1667 MHZ for tda9889 */
}; };
enum tda10046_tsout {
TDA10046_TS_PARALLEL = 0x00, /* parallel transport stream, default */
TDA10046_TS_SERIAL = 0x01, /* serial transport stream */
};
struct tda1004x_config struct tda1004x_config
{ {
/* the demodulator's i2c address */ /* the demodulator's i2c address */
...@@ -58,6 +77,9 @@ struct tda1004x_config ...@@ -58,6 +77,9 @@ struct tda1004x_config
/* Does the OCLK signal need inverted? */ /* Does the OCLK signal need inverted? */
u8 invert_oclk; u8 invert_oclk;
/* parallel or serial transport stream */
enum tda10046_tsout ts_mode;
/* Xtal frequency, 4 or 16MHz*/ /* Xtal frequency, 4 or 16MHz*/
enum tda10046_xtal xtal_freq; enum tda10046_xtal xtal_freq;
...@@ -67,11 +89,35 @@ struct tda1004x_config ...@@ -67,11 +89,35 @@ struct tda1004x_config
/* AGC configuration */ /* AGC configuration */
enum tda10046_agc agc_config; enum tda10046_agc agc_config;
/* setting of GPIO1 and 3 */
enum tda10046_gpio gpio_config;
/* slave address and configuration of the tuner */
u8 tuner_address;
u8 tuner_config;
u8 antenna_switch;
/* if the board uses another I2c Bridge (tda8290), its address */
u8 i2c_gate;
/* request firmware for device */ /* request firmware for device */
/* set this to NULL if the card has a firmware EEPROM */
int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name); int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name);
}; };
enum tda1004x_demod {
TDA1004X_DEMOD_TDA10045,
TDA1004X_DEMOD_TDA10046,
};
struct tda1004x_state {
struct i2c_adapter* i2c;
const struct tda1004x_config* config;
struct dvb_frontend frontend;
/* private demod data */
enum tda1004x_demod demod_type;
};
#if defined(CONFIG_DVB_TDA1004X) || (defined(CONFIG_DVB_TDA1004X_MODULE) && defined(MODULE)) #if defined(CONFIG_DVB_TDA1004X) || (defined(CONFIG_DVB_TDA1004X_MODULE) && defined(MODULE))
extern struct dvb_frontend* tda10045_attach(const struct tda1004x_config* config, extern struct dvb_frontend* tda10045_attach(const struct tda1004x_config* config,
struct i2c_adapter* i2c); struct i2c_adapter* i2c);
......
This diff is collapsed.
/*
DVB Driver for Philips tda827x / tda827xa Silicon tuners
(c) 2005 Hartmut Hackmann
(c) 2007 Michael Krufky
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.
*/
#ifndef __DVB_TDA827X_H__
#define __DVB_TDA827X_H__
#include <linux/i2c.h>
#include "dvb_frontend.h"
struct tda827x_config
{
void (*lna_gain) (struct dvb_frontend *fe, int high);
int (*init) (struct dvb_frontend *fe);
int (*sleep) (struct dvb_frontend *fe);
};
/**
* Attach a tda827x tuner to the supplied frontend structure.
*
* @param fe Frontend to attach to.
* @param addr i2c address of the tuner.
* @param i2c i2c adapter to use.
* @param cfg optional callback function pointers.
* @return FE pointer on success, NULL on failure.
*/
#if defined(CONFIG_DVB_TDA827X) || (defined(CONFIG_DVB_TDA827X_MODULE) && defined(MODULE))
extern struct dvb_frontend* tda827x_attach(struct dvb_frontend *fe, int addr,
struct i2c_adapter *i2c,
struct tda827x_config *cfg);
#else
static inline struct dvb_frontend* tda827x_attach(struct dvb_frontend *fe,
int addr,
struct i2c_adapter *i2c,
struct tda827x_config *cfg)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
return NULL;
}
#endif // CONFIG_DVB_TDA827X
#endif // __DVB_TDA827X_H__
...@@ -2,7 +2,6 @@ config DVB_PLUTO2 ...@@ -2,7 +2,6 @@ config DVB_PLUTO2
tristate "Pluto2 cards" tristate "Pluto2 cards"
depends on DVB_CORE && PCI && I2C depends on DVB_CORE && PCI && I2C
select I2C_ALGOBIT select I2C_ALGOBIT
select DVB_PLL
select DVB_TDA1004X select DVB_TDA1004X
help help
Support for PCI cards based on the Pluto2 FPGA like the Satelco Support for PCI cards based on the Pluto2 FPGA like the Satelco
......
...@@ -3,7 +3,6 @@ config DVB_AV7110 ...@@ -3,7 +3,6 @@ config DVB_AV7110
depends on DVB_CORE && PCI && I2C && VIDEO_V4L1 depends on DVB_CORE && PCI && I2C && VIDEO_V4L1
select FW_LOADER if !DVB_AV7110_FIRMWARE select FW_LOADER if !DVB_AV7110_FIRMWARE
select VIDEO_SAA7146_VV select VIDEO_SAA7146_VV
select DVB_PLL
select DVB_VES1820 if !DVB_FE_CUSTOMISE select DVB_VES1820 if !DVB_FE_CUSTOMISE
select DVB_VES1X93 if !DVB_FE_CUSTOMISE select DVB_VES1X93 if !DVB_FE_CUSTOMISE
select DVB_STV0299 if !DVB_FE_CUSTOMISE select DVB_STV0299 if !DVB_FE_CUSTOMISE
...@@ -62,13 +61,13 @@ config DVB_BUDGET ...@@ -62,13 +61,13 @@ config DVB_BUDGET
tristate "Budget cards" tristate "Budget cards"
depends on DVB_CORE && PCI && I2C && VIDEO_V4L1 depends on DVB_CORE && PCI && I2C && VIDEO_V4L1
select VIDEO_SAA7146 select VIDEO_SAA7146
select DVB_PLL
select DVB_STV0299 if !DVB_FE_CUSTOMISE select DVB_STV0299 if !DVB_FE_CUSTOMISE
select DVB_VES1X93 if !DVB_FE_CUSTOMISE select DVB_VES1X93 if !DVB_FE_CUSTOMISE
select DVB_VES1820 if !DVB_FE_CUSTOMISE select DVB_VES1820 if !DVB_FE_CUSTOMISE
select DVB_L64781 if !DVB_FE_CUSTOMISE select DVB_L64781 if !DVB_FE_CUSTOMISE
select DVB_TDA8083 if !DVB_FE_CUSTOMISE select DVB_TDA8083 if !DVB_FE_CUSTOMISE
select DVB_TDA10021 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_S5H1420 if !DVB_FE_CUSTOMISE
select DVB_TDA10086 if !DVB_FE_CUSTOMISE select DVB_TDA10086 if !DVB_FE_CUSTOMISE
select DVB_TDA826X if !DVB_FE_CUSTOMISE select DVB_TDA826X if !DVB_FE_CUSTOMISE
...@@ -87,7 +86,6 @@ config DVB_BUDGET_CI ...@@ -87,7 +86,6 @@ config DVB_BUDGET_CI
tristate "Budget cards with onboard CI connector" tristate "Budget cards with onboard CI connector"
depends on DVB_CORE && PCI && I2C && VIDEO_V4L1 depends on DVB_CORE && PCI && I2C && VIDEO_V4L1
select VIDEO_SAA7146 select VIDEO_SAA7146
select DVB_PLL
select DVB_STV0297 if !DVB_FE_CUSTOMISE select DVB_STV0297 if !DVB_FE_CUSTOMISE
select DVB_STV0299 if !DVB_FE_CUSTOMISE select DVB_STV0299 if !DVB_FE_CUSTOMISE
select DVB_TDA1004X if !DVB_FE_CUSTOMISE select DVB_TDA1004X if !DVB_FE_CUSTOMISE
...@@ -114,6 +112,7 @@ config DVB_BUDGET_AV ...@@ -114,6 +112,7 @@ config DVB_BUDGET_AV
select DVB_STV0299 if !DVB_FE_CUSTOMISE select DVB_STV0299 if !DVB_FE_CUSTOMISE
select DVB_TDA1004X if !DVB_FE_CUSTOMISE select DVB_TDA1004X if !DVB_FE_CUSTOMISE
select DVB_TDA10021 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 DVB_TUA6100 if !DVB_FE_CUSTOMISE
select FW_LOADER select FW_LOADER
help help
...@@ -130,7 +129,6 @@ config DVB_BUDGET_PATCH ...@@ -130,7 +129,6 @@ config DVB_BUDGET_PATCH
tristate "AV7110 cards with Budget Patch" tristate "AV7110 cards with Budget Patch"
depends on DVB_CORE && DVB_BUDGET && VIDEO_V4L1 depends on DVB_CORE && DVB_BUDGET && VIDEO_V4L1
select DVB_AV7110 select DVB_AV7110
select DVB_PLL
select DVB_STV0299 if !DVB_FE_CUSTOMISE select DVB_STV0299 if !DVB_FE_CUSTOMISE
select DVB_VES1X93 if !DVB_FE_CUSTOMISE select DVB_VES1X93 if !DVB_FE_CUSTOMISE
select DVB_TDA8083 if !DVB_FE_CUSTOMISE select DVB_TDA8083 if !DVB_FE_CUSTOMISE
......
...@@ -219,7 +219,10 @@ static void recover_arm(struct av7110 *av7110) ...@@ -219,7 +219,10 @@ static void recover_arm(struct av7110 *av7110)
av7110->recover(av7110); av7110->recover(av7110);
restart_feeds(av7110); restart_feeds(av7110);
av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, SetIR, 1, av7110->ir_config);
#if defined(CONFIG_INPUT_EVDEV) || defined(CONFIG_INPUT_EVDEV_MODULE)
av7110_check_ir_config(av7110, true);
#endif
} }
static void av7110_arm_sync(struct av7110 *av7110) static void av7110_arm_sync(struct av7110 *av7110)
...@@ -250,6 +253,10 @@ static int arm_thread(void *data) ...@@ -250,6 +253,10 @@ static int arm_thread(void *data)
if (!av7110->arm_ready) if (!av7110->arm_ready)
continue; continue;
#if defined(CONFIG_INPUT_EVDEV) || defined(CONFIG_INPUT_EVDEV_MODULE)
av7110_check_ir_config(av7110, false);
#endif
if (mutex_lock_interruptible(&av7110->dcomlock)) if (mutex_lock_interruptible(&av7110->dcomlock))
break; break;
newloops = rdebi(av7110, DEBINOSWAP, STATUS_LOOPS, 0, 2); newloops = rdebi(av7110, DEBINOSWAP, STATUS_LOOPS, 0, 2);
...@@ -667,8 +674,8 @@ static void gpioirq(unsigned long data) ...@@ -667,8 +674,8 @@ static void gpioirq(unsigned long data)
return; return;
case DATA_IRCOMMAND: case DATA_IRCOMMAND:
if (av7110->ir_handler) if (av7110->ir.ir_handler)
av7110->ir_handler(av7110, av7110->ir.ir_handler(av7110,
swahw32(irdebi(av7110, DEBINOSWAP, Reserved, 0, 4))); swahw32(irdebi(av7110, DEBINOSWAP, Reserved, 0, 4)));
iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2); iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2);
break; break;
...@@ -1907,8 +1914,10 @@ static int av7110_fe_lock_fix(struct av7110* av7110, fe_status_t status) ...@@ -1907,8 +1914,10 @@ static int av7110_fe_lock_fix(struct av7110* av7110, fe_status_t status)
if (av7110->fe_synced == synced) if (av7110->fe_synced == synced)
return 0; return 0;
if (av7110->playing) if (av7110->playing) {
av7110->fe_synced = synced;
return 0; return 0;
}
if (mutex_lock_interruptible(&av7110->pid_mutex)) if (mutex_lock_interruptible(&av7110->pid_mutex))
return -ERESTARTSYS; return -ERESTARTSYS;
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include <linux/socket.h> #include <linux/socket.h>
#include <linux/netdevice.h> #include <linux/netdevice.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/input.h>
#include <linux/dvb/video.h> #include <linux/dvb/video.h>
#include <linux/dvb/audio.h> #include <linux/dvb/audio.h>
...@@ -66,6 +67,27 @@ struct dvb_video_events { ...@@ -66,6 +67,27 @@ struct dvb_video_events {
}; };
struct av7110;
/* infrared remote control */
struct infrared {
u16 key_map[256];
struct input_dev *input_dev;
char input_phys[32];
struct timer_list keyup_timer;
struct tasklet_struct ir_tasklet;
void (*ir_handler)(struct av7110 *av7110, u32 ircom);
u32 ir_command;
u32 ir_config;
u32 device_mask;
u8 protocol;
u8 inversion;
u16 last_key;
u16 last_toggle;
u8 delay_timer_finished;
};
/* place to store all the necessary device information */ /* place to store all the necessary device information */
struct av7110 { struct av7110 {
...@@ -227,10 +249,7 @@ struct av7110 { ...@@ -227,10 +249,7 @@ struct av7110 {
u16 wssMode; u16 wssMode;
u16 wssData; u16 wssData;
u32 ir_config; struct infrared ir;
u32 ir_command;
void (*ir_handler)(struct av7110 *av7110, u32 ircom);
struct tasklet_struct ir_tasklet;
/* firmware stuff */ /* firmware stuff */
unsigned char *bin_fw; unsigned char *bin_fw;
...@@ -268,6 +287,7 @@ struct av7110 { ...@@ -268,6 +287,7 @@ struct av7110 {
extern int ChangePIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid, extern int ChangePIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid,
u16 subpid, u16 pcrpid); u16 subpid, u16 pcrpid);
extern int av7110_check_ir_config(struct av7110 *av7110, int force);
extern int av7110_ir_init(struct av7110 *av7110); extern int av7110_ir_init(struct av7110 *av7110);
extern void av7110_ir_exit(struct av7110 *av7110); extern void av7110_ir_exit(struct av7110 *av7110);
......
...@@ -1009,7 +1009,7 @@ static int dvb_video_ioctl(struct inode *inode, struct file *file, ...@@ -1009,7 +1009,7 @@ static int dvb_video_ioctl(struct inode *inode, struct file *file,
if (av7110->videostate.stream_source == VIDEO_SOURCE_MEMORY) if (av7110->videostate.stream_source == VIDEO_SOURCE_MEMORY)
ret = av7110_av_stop(av7110, RP_VIDEO); ret = av7110_av_stop(av7110, RP_VIDEO);
else else
ret = vidcom(av7110, VIDEO_CMD_STOP, ret = vidcom(av7110, AV_VIDEO_CMD_STOP,
av7110->videostate.video_blank ? 0 : 1); av7110->videostate.video_blank ? 0 : 1);
if (!ret) if (!ret)
av7110->trickmode = TRICK_NONE; av7110->trickmode = TRICK_NONE;
...@@ -1019,7 +1019,7 @@ static int dvb_video_ioctl(struct inode *inode, struct file *file, ...@@ -1019,7 +1019,7 @@ static int dvb_video_ioctl(struct inode *inode, struct file *file,
av7110->trickmode = TRICK_NONE; av7110->trickmode = TRICK_NONE;
if (av7110->videostate.play_state == VIDEO_FREEZED) { if (av7110->videostate.play_state == VIDEO_FREEZED) {
av7110->videostate.play_state = VIDEO_PLAYING; av7110->videostate.play_state = VIDEO_PLAYING;
ret = vidcom(av7110, VIDEO_CMD_PLAY, 0); ret = vidcom(av7110, AV_VIDEO_CMD_PLAY, 0);
if (ret) if (ret)
break; break;
} }
...@@ -1034,7 +1034,7 @@ static int dvb_video_ioctl(struct inode *inode, struct file *file, ...@@ -1034,7 +1034,7 @@ static int dvb_video_ioctl(struct inode *inode, struct file *file,
ret = av7110_av_start_play(av7110, RP_VIDEO); ret = av7110_av_start_play(av7110, RP_VIDEO);
} }
if (!ret) if (!ret)
ret = vidcom(av7110, VIDEO_CMD_PLAY, 0); ret = vidcom(av7110, AV_VIDEO_CMD_PLAY, 0);
if (!ret) if (!ret)
av7110->videostate.play_state = VIDEO_PLAYING; av7110->videostate.play_state = VIDEO_PLAYING;
break; break;
...@@ -1044,7 +1044,7 @@ static int dvb_video_ioctl(struct inode *inode, struct file *file, ...@@ -1044,7 +1044,7 @@ static int dvb_video_ioctl(struct inode *inode, struct file *file,
if (av7110->playing & RP_VIDEO) if (av7110->playing & RP_VIDEO)
ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Pause, 0); ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Pause, 0);
else else
ret = vidcom(av7110, VIDEO_CMD_FREEZE, 1); ret = vidcom(av7110, AV_VIDEO_CMD_FREEZE, 1);
if (!ret) if (!ret)
av7110->trickmode = TRICK_FREEZE; av7110->trickmode = TRICK_FREEZE;
break; break;
...@@ -1053,7 +1053,7 @@ static int dvb_video_ioctl(struct inode *inode, struct file *file, ...@@ -1053,7 +1053,7 @@ static int dvb_video_ioctl(struct inode *inode, struct file *file,
if (av7110->playing & RP_VIDEO) if (av7110->playing & RP_VIDEO)
ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Continue, 0); ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Continue, 0);
if (!ret) if (!ret)
ret = vidcom(av7110, VIDEO_CMD_PLAY, 0); ret = vidcom(av7110, AV_VIDEO_CMD_PLAY, 0);
if (!ret) { if (!ret) {
av7110->videostate.play_state = VIDEO_PLAYING; av7110->videostate.play_state = VIDEO_PLAYING;
av7110->trickmode = TRICK_NONE; av7110->trickmode = TRICK_NONE;
...@@ -1136,7 +1136,7 @@ static int dvb_video_ioctl(struct inode *inode, struct file *file, ...@@ -1136,7 +1136,7 @@ static int dvb_video_ioctl(struct inode *inode, struct file *file,
ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY,
__Scan_I, 2, AV_PES, 0); __Scan_I, 2, AV_PES, 0);
else else
ret = vidcom(av7110, VIDEO_CMD_FFWD, arg); ret = vidcom(av7110, AV_VIDEO_CMD_FFWD, arg);
if (!ret) { if (!ret) {
av7110->trickmode = TRICK_FAST; av7110->trickmode = TRICK_FAST;
av7110->videostate.play_state = VIDEO_PLAYING; av7110->videostate.play_state = VIDEO_PLAYING;
...@@ -1147,13 +1147,13 @@ static int dvb_video_ioctl(struct inode *inode, struct file *file, ...@@ -1147,13 +1147,13 @@ static int dvb_video_ioctl(struct inode *inode, struct file *file,
if (av7110->playing&RP_VIDEO) { if (av7110->playing&RP_VIDEO) {
ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Slow, 2, 0, 0); ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Slow, 2, 0, 0);
if (!ret) if (!ret)
ret = vidcom(av7110, VIDEO_CMD_SLOW, arg); ret = vidcom(av7110, AV_VIDEO_CMD_SLOW, arg);
} else { } else {
ret = vidcom(av7110, VIDEO_CMD_PLAY, 0); ret = vidcom(av7110, AV_VIDEO_CMD_PLAY, 0);
if (!ret) if (!ret)
ret = vidcom(av7110, VIDEO_CMD_STOP, 0); ret = vidcom(av7110, AV_VIDEO_CMD_STOP, 0);
if (!ret) if (!ret)
ret = vidcom(av7110, VIDEO_CMD_SLOW, arg); ret = vidcom(av7110, AV_VIDEO_CMD_SLOW, arg);
} }
if (!ret) { if (!ret) {
av7110->trickmode = TRICK_SLOW; av7110->trickmode = TRICK_SLOW;
...@@ -1182,10 +1182,10 @@ static int dvb_video_ioctl(struct inode *inode, struct file *file, ...@@ -1182,10 +1182,10 @@ static int dvb_video_ioctl(struct inode *inode, struct file *file,
ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY,
__Slow, 2, 0, 0); __Slow, 2, 0, 0);
if (!ret) if (!ret)
ret = vidcom(av7110, VIDEO_CMD_SLOW, arg); ret = vidcom(av7110, AV_VIDEO_CMD_SLOW, arg);
} }
if (av7110->trickmode == TRICK_FREEZE) if (av7110->trickmode == TRICK_FREEZE)
ret = vidcom(av7110, VIDEO_CMD_STOP, 1); ret = vidcom(av7110, AV_VIDEO_CMD_STOP, 1);
} }
break; break;
......
...@@ -216,11 +216,11 @@ enum av7110_command_type { ...@@ -216,11 +216,11 @@ enum av7110_command_type {
#define VID_CENTRE_CUT_PREF 0x05 /* PanScan with zero vector */ #define VID_CENTRE_CUT_PREF 0x05 /* PanScan with zero vector */
/* MPEG video decoder commands */ /* MPEG video decoder commands */
#define VIDEO_CMD_STOP 0x000e #define AV_VIDEO_CMD_STOP 0x000e
#define VIDEO_CMD_PLAY 0x000d #define AV_VIDEO_CMD_PLAY 0x000d
#define VIDEO_CMD_FREEZE 0x0102 #define AV_VIDEO_CMD_FREEZE 0x0102
#define VIDEO_CMD_FFWD 0x0016 #define AV_VIDEO_CMD_FFWD 0x0016
#define VIDEO_CMD_SLOW 0x0022 #define AV_VIDEO_CMD_SLOW 0x0022
/* MPEG audio decoder commands */ /* MPEG audio decoder commands */
#define AUDIO_CMD_MUTE 0x0001 #define AUDIO_CMD_MUTE 0x0001
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -41,11 +41,14 @@ ...@@ -41,11 +41,14 @@
#define TS_WIDTH (2 * TS_SIZE) #define TS_WIDTH (2 * TS_SIZE)
#define TS_WIDTH_ACTIVY TS_SIZE #define TS_WIDTH_ACTIVY TS_SIZE
#define TS_WIDTH_DVBC TS_SIZE
#define TS_HEIGHT_MASK 0xf00 #define TS_HEIGHT_MASK 0xf00
#define TS_HEIGHT_MASK_ACTIVY 0xc00 #define TS_HEIGHT_MASK_ACTIVY 0xc00
#define TS_HEIGHT_MASK_DVBC 0xe00
#define TS_MIN_BUFSIZE_K 188 #define TS_MIN_BUFSIZE_K 188
#define TS_MAX_BUFSIZE_K 1410 #define TS_MAX_BUFSIZE_K 1410
#define TS_MAX_BUFSIZE_K_ACTIVY 564 #define TS_MAX_BUFSIZE_K_ACTIVY 564
#define TS_MAX_BUFSIZE_K_DVBC 1316
#define BUFFER_WARNING_WAIT (30*HZ) #define BUFFER_WARNING_WAIT (30*HZ)
int budget_debug; int budget_debug;
...@@ -106,6 +109,19 @@ static int start_ts_capture(struct budget *budget) ...@@ -106,6 +109,19 @@ static int start_ts_capture(struct budget *budget)
saa7146_write(dev, MC2, (MASK_10 | MASK_26)); saa7146_write(dev, MC2, (MASK_10 | MASK_26));
saa7146_write(dev, BRS_CTRL, 0x60000000); saa7146_write(dev, BRS_CTRL, 0x60000000);
break; 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: default:
if (budget->video_port == BUDGET_VIDEO_PORTA) { if (budget->video_port == BUDGET_VIDEO_PORTA) {
saa7146_write(dev, DD1_INIT, 0x06000200); saa7146_write(dev, DD1_INIT, 0x06000200);
...@@ -122,7 +138,13 @@ static int start_ts_capture(struct budget *budget) ...@@ -122,7 +138,13 @@ static int start_ts_capture(struct budget *budget)
mdelay(10); mdelay(10);
saa7146_write(dev, BASE_ODD3, 0); 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, PROT_ADDR3, budget->buffer_size);
saa7146_write(dev, BASE_PAGE3, budget->pt.dma | ME1 | 0x90); saa7146_write(dev, BASE_PAGE3, budget->pt.dma | ME1 | 0x90);
...@@ -399,11 +421,25 @@ int ttpci_budget_init(struct budget *budget, struct saa7146_dev *dev, ...@@ -399,11 +421,25 @@ int ttpci_budget_init(struct budget *budget, struct saa7146_dev *dev,
budget->card = bi; budget->card = bi;
budget->dev = (struct saa7146_dev *) dev; 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; budget->buffer_width = TS_WIDTH_ACTIVY;
max_bufsize = TS_MAX_BUFSIZE_K_ACTIVY; max_bufsize = TS_MAX_BUFSIZE_K_ACTIVY;
height_mask = TS_HEIGHT_MASK_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; budget->buffer_width = TS_WIDTH;
max_bufsize = TS_MAX_BUFSIZE_K; max_bufsize = TS_MAX_BUFSIZE_K;
height_mask = TS_HEIGHT_MASK; height_mask = TS_HEIGHT_MASK;
...@@ -415,14 +451,22 @@ int ttpci_budget_init(struct budget *budget, struct saa7146_dev *dev, ...@@ -415,14 +451,22 @@ int ttpci_budget_init(struct budget *budget, struct saa7146_dev *dev,
dma_buffer_size = max_bufsize; dma_buffer_size = max_bufsize;
budget->buffer_height = dma_buffer_size * 1024 / budget->buffer_width; budget->buffer_height = dma_buffer_size * 1024 / budget->buffer_width;
budget->buffer_height &= height_mask; if (budget->buffer_height > 0xfff) {
budget->buffer_size = budget->buffer_height * budget->buffer_width; 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_warning_threshold = budget->buffer_size * 80/100;
budget->buffer_warnings = 0; budget->buffer_warnings = 0;
budget->buffer_warning_time = jiffies; budget->buffer_warning_time = jiffies;
dprintk(2, "%s: width = %d, height = %d\n", dprintk(2, "%s: buffer type = %s, width = %d, height = %d\n",
budget->dev->name, budget->buffer_width, budget->buffer_height); 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); 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) { if ((ret = dvb_register_adapter(&budget->dvb_adapter, budget->card->name, owner, &budget->dev->pci->dev)) < 0) {
......
This diff is collapsed.
config DVB_TTUSB_BUDGET config DVB_TTUSB_BUDGET
tristate "Technotrend/Hauppauge Nova-USB devices" tristate "Technotrend/Hauppauge Nova-USB devices"
depends on DVB_CORE && USB && I2C depends on DVB_CORE && USB && I2C
select DVB_PLL
select DVB_CX22700 if !DVB_FE_CUSTOMISE select DVB_CX22700 if !DVB_FE_CUSTOMISE
select DVB_TDA1004X if !DVB_FE_CUSTOMISE select DVB_TDA1004X if !DVB_FE_CUSTOMISE
select DVB_VES1820 if !DVB_FE_CUSTOMISE select DVB_VES1820 if !DVB_FE_CUSTOMISE
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment