mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-01-16 09:56:46 +00:00
Merge git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/v4l-dvb
* git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/v4l-dvb: (509 commits) V4L/DVB (7078): radio: fix sf16fmi section mismatch V4L/DVB (7077): bt878: remove handcrafted PCI subsystem ID check V4L/DVB (7075): Make a local function static V4L/DVB (7074): DiB7000P: correct tuning problem for 7MHz channel V4L/DVB (7073): DiB7070: Reception quality improved V4L/DVB (7072): sets the MT2060 IF1 frequency according to EEPROM V4L/DVB (7071): DiB0700: Start streaming the right way V4L/DVB (7070): Fix some tuning problems V4L/DVB (7069): Support for myTV.t V4L/DVB (7068): Add support for WinTV Nova-T-CE driver V4L/DVB (7067): fix autoserach in the Hauppauge NOVA-T 500 V4L/DVB (7066): ASUS My Cinema U3000 Mini DVBT Tuner V4L/DVB (7065): Artec T14BR patches V4L/DVB (7063): xc5000: Fix OOPS caused by missing firmware V4L/DVB (7062): radio-si570x: Some fixes and new USB ID addition V4L/DVB (7061): radio-si470x: Some cleanups V4L/DVB (7060): em28xx: remove has_tuner V4L/DVB (7059): cx88: Ensure the tuner is reset correctly V4L/DVB (7058): IR corrections for the Pinnacle 800i V4L/DVB (7056): tuner: suppress obsolete tuner i2c address warning for XC5000 tuners ...
This commit is contained in:
commit
b31fde6db2
@ -96,7 +96,6 @@ static struct video_device my_radio
|
||||
{
|
||||
"My radio",
|
||||
VID_TYPE_TUNER,
|
||||
VID_HARDWARE_MYRADIO,
|
||||
radio_open.
|
||||
radio_close,
|
||||
NULL, /* no read */
|
||||
@ -118,13 +117,6 @@ static struct video_device my_radio
|
||||
indicates that the device can be tuned. Clearly our radio is going to have some
|
||||
way to change channel so it is tuneable.
|
||||
</para>
|
||||
<para>
|
||||
The VID_HARDWARE_ types are unique to each device. Numbers are assigned by
|
||||
<email>alan@redhat.com</email> when device drivers are going to be released. Until then you
|
||||
can pull a suitably large number out of your hat and use it. 10000 should be
|
||||
safe for a very long time even allowing for the huge number of vendors
|
||||
making new and different radio cards at the moment.
|
||||
</para>
|
||||
<para>
|
||||
We declare an open and close routine, but we do not need read or write,
|
||||
which are used to read and write video data to or from the card itself. As
|
||||
@ -844,7 +836,6 @@ static struct video_device my_camera
|
||||
"My Camera",
|
||||
VID_TYPE_OVERLAY|VID_TYPE_SCALES|\
|
||||
VID_TYPE_CAPTURE|VID_TYPE_CHROMAKEY,
|
||||
VID_HARDWARE_MYCAMERA,
|
||||
camera_open.
|
||||
camera_close,
|
||||
camera_read, /* no read */
|
||||
|
@ -78,6 +78,18 @@ Example:
|
||||
For a full list of card ID's please see Documentation/video4linux/CARDLIST.bttv.
|
||||
In case of further problems please subscribe and send questions to the mailing list: linux-dvb@linuxtv.org.
|
||||
|
||||
2c) Probing the cards with broken PCI subsystem ID
|
||||
--------------------------------------------------
|
||||
There are some TwinHan cards that the EEPROM has become corrupted for some
|
||||
reason. The cards do not have correct PCI subsystem ID. But we can force
|
||||
probing the cards with broken PCI subsystem ID
|
||||
|
||||
$ echo 109e 0878 $subvendor $subdevice > \
|
||||
/sys/bus/pci/drivers/bt878/new_id
|
||||
|
||||
109e: PCI_VENDOR_ID_BROOKTREE
|
||||
0878: PCI_DEVICE_ID_BROOKTREE_878
|
||||
|
||||
Authors: Richard Walker,
|
||||
Jamie Honan,
|
||||
Michael Hunold,
|
||||
|
@ -1,5 +1,7 @@
|
||||
0 -> UNKNOWN/GENERIC [0070:3400]
|
||||
1 -> Hauppauge WinTV-HVR1800lp [0070:7600]
|
||||
2 -> Hauppauge WinTV-HVR1800 [0070:7800,0070:7801]
|
||||
2 -> Hauppauge WinTV-HVR1800 [0070:7800,0070:7801,0070:7809]
|
||||
3 -> Hauppauge WinTV-HVR1250 [0070:7911]
|
||||
4 -> DViCO FusionHDTV5 Express [18ac:d500]
|
||||
5 -> Hauppauge WinTV-HVR1500Q [0070:7790,0070:7797]
|
||||
6 -> Hauppauge WinTV-HVR1500 [0070:7710,0070:7717]
|
||||
|
@ -56,3 +56,4 @@
|
||||
55 -> Shenzhen Tungsten Ages Tech TE-DTV-250 / Swann OEM [c180:c980]
|
||||
56 -> Hauppauge WinTV-HVR1300 DVB-T/Hybrid MPEG Encoder [0070:9600,0070:9601,0070:9602]
|
||||
57 -> ADS Tech Instant Video PCI [1421:0390]
|
||||
58 -> Pinnacle PCTV HD 800i [11bd:0051]
|
||||
|
@ -1,14 +1,17 @@
|
||||
0 -> Unknown EM2800 video grabber (em2800) [eb1a:2800]
|
||||
1 -> Unknown EM2820/2840 video grabber (em2820/em2840)
|
||||
1 -> Unknown EM2750/28xx video grabber (em2820/em2840) [eb1a:2750,eb1a:2820,eb1a:2821,eb1a:2860,eb1a:2861,eb1a:2870,eb1a:2881,eb1a:2883]
|
||||
2 -> Terratec Cinergy 250 USB (em2820/em2840) [0ccd:0036]
|
||||
3 -> Pinnacle PCTV USB 2 (em2820/em2840) [2304:0208]
|
||||
4 -> Hauppauge WinTV USB 2 (em2820/em2840) [2040:4200]
|
||||
5 -> MSI VOX USB 2.0 (em2820/em2840) [eb1a:2820]
|
||||
4 -> Hauppauge WinTV USB 2 (em2820/em2840) [2040:4200,2040:4201]
|
||||
5 -> MSI VOX USB 2.0 (em2820/em2840)
|
||||
6 -> Terratec Cinergy 200 USB (em2800)
|
||||
7 -> Leadtek Winfast USB II (em2800)
|
||||
8 -> Kworld USB2800 (em2800)
|
||||
9 -> Pinnacle Dazzle DVC 90 (em2820/em2840) [2304:0207]
|
||||
10 -> Hauppauge WinTV HVR 900 (em2880)
|
||||
11 -> Terratec Hybrid XS (em2880)
|
||||
9 -> Pinnacle Dazzle DVC 90/DVC 100 (em2820/em2840) [2304:0207,2304:021a]
|
||||
10 -> Hauppauge WinTV HVR 900 (em2880) [2040:6500]
|
||||
11 -> Terratec Hybrid XS (em2880) [0ccd:0042]
|
||||
12 -> Kworld PVR TV 2800 RF (em2820/em2840)
|
||||
13 -> Terratec Prodigy XS (em2880)
|
||||
13 -> Terratec Prodigy XS (em2880) [0ccd:0047]
|
||||
14 -> Pixelview Prolink PlayTV USB 2.0 (em2820/em2840)
|
||||
15 -> V-Gear PocketTV (em2800)
|
||||
16 -> Hauppauge WinTV HVR 950 (em2880) [2040:6513]
|
||||
|
@ -16,3 +16,9 @@
|
||||
16 -> GOTVIEW PCI DVD2 Deluxe [ffac:0600]
|
||||
17 -> Yuan MPC622 [ff01:d998]
|
||||
18 -> Digital Cowboy DCT-MTVP1 [1461:bfff]
|
||||
19 -> Yuan PG600V2/GotView PCI DVD Lite [ffab:0600,ffad:0600]
|
||||
20 -> Club3D ZAP-TV1x01 [ffab:0600]
|
||||
21 -> AverTV MCE 116 Plus [1461:c439]
|
||||
22 -> ASUS Falcon2 [1043:4b66,1043:462e,1043:4b2e]
|
||||
23 -> AverMedia PVR-150 Plus [1461:c035]
|
||||
24 -> AverMedia EZMaker PCI Deluxe [1461:c03f]
|
||||
|
@ -80,7 +80,7 @@
|
||||
79 -> Sedna/MuchTV PC TV Cardbus TV/Radio (ITO25 Rev:2B)
|
||||
80 -> ASUS Digimatrix TV [1043:0210]
|
||||
81 -> Philips Tiger reference design [1131:2018]
|
||||
82 -> MSI TV@Anywhere plus [1462:6231]
|
||||
82 -> MSI TV@Anywhere plus [1462:6231,1462:8624]
|
||||
83 -> Terratec Cinergy 250 PCI TV [153b:1160]
|
||||
84 -> LifeView FlyDVB Trio [5168:0319]
|
||||
85 -> AverTV DVB-T 777 [1461:2c05,1461:2c05]
|
||||
@ -102,7 +102,7 @@
|
||||
101 -> Pinnacle PCTV 310i [11bd:002f]
|
||||
102 -> Avermedia AVerTV Studio 507 [1461:9715]
|
||||
103 -> Compro Videomate DVB-T200A
|
||||
104 -> Hauppauge WinTV-HVR1110 DVB-T/Hybrid [0070:6701]
|
||||
104 -> Hauppauge WinTV-HVR1110 DVB-T/Hybrid [0070:6700,0070:6701,0070:6702,0070:6703,0070:6704,0070:6705]
|
||||
105 -> Terratec Cinergy HT PCMCIA [153b:1172]
|
||||
106 -> Encore ENLTV [1131:2342,1131:2341,3016:2344]
|
||||
107 -> Encore ENLTV-FM [1131:230f]
|
||||
@ -116,3 +116,16 @@
|
||||
115 -> Sabrent PCMCIA TV-PCB05 [0919:2003]
|
||||
116 -> 10MOONS TM300 TV Card [1131:2304]
|
||||
117 -> Avermedia Super 007 [1461:f01d]
|
||||
118 -> Beholder BeholdTV 401 [0000:4016]
|
||||
119 -> Beholder BeholdTV 403 [0000:4036]
|
||||
120 -> Beholder BeholdTV 403 FM [0000:4037]
|
||||
121 -> Beholder BeholdTV 405 [0000:4050]
|
||||
122 -> Beholder BeholdTV 405 FM [0000:4051]
|
||||
123 -> Beholder BeholdTV 407 [0000:4070]
|
||||
124 -> Beholder BeholdTV 407 FM [0000:4071]
|
||||
125 -> Beholder BeholdTV 409 [0000:4090]
|
||||
126 -> Beholder BeholdTV 505 FM/RDS [0000:5051,0000:505B,5ace:5050]
|
||||
127 -> Beholder BeholdTV 507 FM/RDS / BeholdTV 509 FM [0000:5071,0000:507B,5ace:5070,5ace:5090]
|
||||
128 -> Beholder BeholdTV Columbus TVFM [0000:5201]
|
||||
129 -> Beholder BeholdTV 607 / BeholdTV 609 [5ace:6070,5ace:6071,5ace:6072,5ace:6073,5ace:6090,5ace:6091,5ace:6092,5ace:6093]
|
||||
130 -> Beholder BeholdTV M6 / BeholdTV M6 Extra [5ace:6190,5ace:6193]
|
||||
|
@ -52,7 +52,7 @@ tuner=50 - TCL 2002N
|
||||
tuner=51 - Philips PAL/SECAM_D (FM 1256 I-H3)
|
||||
tuner=52 - Thomson DTT 7610 (ATSC/NTSC)
|
||||
tuner=53 - Philips FQ1286
|
||||
tuner=54 - tda8290+75
|
||||
tuner=54 - Philips/NXP TDA 8290/8295 + 8275/8275A/18271
|
||||
tuner=55 - TCL 2002MB
|
||||
tuner=56 - Philips PAL/SECAM multi (FQ1216AME MK4)
|
||||
tuner=57 - Philips FQ1236A MK4
|
||||
@ -69,7 +69,8 @@ tuner=67 - Philips TD1316 Hybrid Tuner
|
||||
tuner=68 - Philips TUV1236D ATSC/NTSC dual in
|
||||
tuner=69 - Tena TNF 5335 and similar models
|
||||
tuner=70 - Samsung TCPN 2121P30A
|
||||
tuner=71 - Xceive xc3028
|
||||
tuner=71 - Xceive xc2028/xc3028 tuner
|
||||
tuner=72 - Thomson FE6600
|
||||
tuner=73 - Samsung TCPG 6121P30A
|
||||
tuner=75 - Philips TEA5761 FM Radio
|
||||
tuner=76 - Xceive 5000 tuner
|
||||
|
@ -62,3 +62,4 @@
|
||||
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]
|
||||
64 -> Pinnacle Studio PCTV USB (NTSC) FM V3 [2304:0113]
|
||||
|
926
Documentation/video4linux/extract_xc3028.pl
Normal file
926
Documentation/video4linux/extract_xc3028.pl
Normal file
@ -0,0 +1,926 @@
|
||||
#!/usr/bin/perl
|
||||
|
||||
# Copyright (c) Mauro Carvalho Chehab <mchehab@infradead.org>
|
||||
# Released under GPLv2
|
||||
#
|
||||
# In order to use, you need to:
|
||||
# 1) Download the windows driver with something like:
|
||||
# wget http://www.steventoth.net/linux/xc5000/HVR-12x0-14x0-17x0_1_25_25271_WHQL.zip
|
||||
# 2) Extract the file hcw85bda.sys from the zip into the current dir:
|
||||
# unzip -j HVR-12x0-14x0-17x0_1_25_25271_WHQL.zip Driver85/hcw85bda.sys
|
||||
# 3) run the script:
|
||||
# ./extract_xc3028.pl
|
||||
# 4) copy the generated file:
|
||||
# cp xc3028-v27.fw /lib/firmware
|
||||
|
||||
#use strict;
|
||||
use IO::Handle;
|
||||
|
||||
my $debug=0;
|
||||
|
||||
sub verify ($$)
|
||||
{
|
||||
my ($filename, $hash) = @_;
|
||||
my ($testhash);
|
||||
|
||||
if (system("which md5sum > /dev/null 2>&1")) {
|
||||
die "This firmware requires the md5sum command - see http://www.gnu.org/software/coreutils/\n";
|
||||
}
|
||||
|
||||
open(CMD, "md5sum ".$filename."|");
|
||||
$testhash = <CMD>;
|
||||
$testhash =~ /([a-zA-Z0-9]*)/;
|
||||
$testhash = $1;
|
||||
close CMD;
|
||||
die "Hash of extracted file does not match (found $testhash, expected $hash!\n" if ($testhash ne $hash);
|
||||
}
|
||||
|
||||
sub get_hunk ($$)
|
||||
{
|
||||
my ($offset, $length) = @_;
|
||||
my ($chunklength, $buf, $rcount, $out);
|
||||
|
||||
sysseek(INFILE, $offset, SEEK_SET);
|
||||
while ($length > 0) {
|
||||
# Calc chunk size
|
||||
$chunklength = 2048;
|
||||
$chunklength = $length if ($chunklength > $length);
|
||||
|
||||
$rcount = sysread(INFILE, $buf, $chunklength);
|
||||
die "Ran out of data\n" if ($rcount != $chunklength);
|
||||
$out .= $buf;
|
||||
$length -= $rcount;
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
|
||||
sub write_le16($)
|
||||
{
|
||||
my $val = shift;
|
||||
my $msb = ($val >> 8) &0xff;
|
||||
my $lsb = $val & 0xff;
|
||||
|
||||
syswrite(OUTFILE, chr($lsb).chr($msb));
|
||||
}
|
||||
|
||||
sub write_le32($)
|
||||
{
|
||||
my $val = shift;
|
||||
my $l3 = ($val >> 24) & 0xff;
|
||||
my $l2 = ($val >> 16) & 0xff;
|
||||
my $l1 = ($val >> 8) & 0xff;
|
||||
my $l0 = $val & 0xff;
|
||||
|
||||
syswrite(OUTFILE, chr($l0).chr($l1).chr($l2).chr($l3));
|
||||
}
|
||||
|
||||
sub write_le64($$)
|
||||
{
|
||||
my $msb_val = shift;
|
||||
my $lsb_val = shift;
|
||||
my $l7 = ($msb_val >> 24) & 0xff;
|
||||
my $l6 = ($msb_val >> 16) & 0xff;
|
||||
my $l5 = ($msb_val >> 8) & 0xff;
|
||||
my $l4 = $msb_val & 0xff;
|
||||
|
||||
my $l3 = ($lsb_val >> 24) & 0xff;
|
||||
my $l2 = ($lsb_val >> 16) & 0xff;
|
||||
my $l1 = ($lsb_val >> 8) & 0xff;
|
||||
my $l0 = $lsb_val & 0xff;
|
||||
|
||||
syswrite(OUTFILE,
|
||||
chr($l0).chr($l1).chr($l2).chr($l3).
|
||||
chr($l4).chr($l5).chr($l6).chr($l7));
|
||||
}
|
||||
|
||||
sub write_hunk($$)
|
||||
{
|
||||
my ($offset, $length) = @_;
|
||||
my $out = get_hunk($offset, $length);
|
||||
|
||||
printf "(len %d) ",$length if ($debug);
|
||||
|
||||
for (my $i=0;$i<$length;$i++) {
|
||||
printf "%02x ",ord(substr($out,$i,1)) if ($debug);
|
||||
}
|
||||
printf "\n" if ($debug);
|
||||
|
||||
syswrite(OUTFILE, $out);
|
||||
}
|
||||
|
||||
sub write_hunk_fix_endian($$)
|
||||
{
|
||||
my ($offset, $length) = @_;
|
||||
my $out = get_hunk($offset, $length);
|
||||
|
||||
printf "(len_fix %d) ",$length if ($debug);
|
||||
|
||||
for (my $i=0;$i<$length;$i++) {
|
||||
printf "%02x ",ord(substr($out,$i,1)) if ($debug);
|
||||
}
|
||||
printf "\n" if ($debug);
|
||||
|
||||
my $i=0;
|
||||
while ($i<$length) {
|
||||
my $size = ord(substr($out,$i,1))*256+ord(substr($out,$i+1,1));
|
||||
syswrite(OUTFILE, substr($out,$i+1,1));
|
||||
syswrite(OUTFILE, substr($out,$i,1));
|
||||
$i+=2;
|
||||
if ($size>0 && $size <0x8000) {
|
||||
for (my $j=0;$j<$size;$j++) {
|
||||
syswrite(OUTFILE, substr($out,$j+$i,1));
|
||||
}
|
||||
$i+=$size;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sub main_firmware($$$$)
|
||||
{
|
||||
my $out;
|
||||
my $j=0;
|
||||
my $outfile = shift;
|
||||
my $name = shift;
|
||||
my $version = shift;
|
||||
my $nr_desc = shift;
|
||||
|
||||
for ($j = length($name); $j <32; $j++) {
|
||||
$name = $name.chr(0);
|
||||
}
|
||||
|
||||
open OUTFILE, ">$outfile";
|
||||
syswrite(OUTFILE, $name);
|
||||
write_le16($version);
|
||||
write_le16($nr_desc);
|
||||
|
||||
#
|
||||
# Firmware 0, type: BASE FW F8MHZ (0x00000003), id: (0000000000000000), size: 8718
|
||||
#
|
||||
|
||||
write_le32(0x00000003); # Type
|
||||
write_le64(0x00000000, 0x00000000); # ID
|
||||
write_le32(8718); # Size
|
||||
write_hunk_fix_endian(813432, 8718);
|
||||
|
||||
#
|
||||
# Firmware 1, type: BASE FW F8MHZ MTS (0x00000007), id: (0000000000000000), size: 8712
|
||||
#
|
||||
|
||||
write_le32(0x00000007); # Type
|
||||
write_le64(0x00000000, 0x00000000); # ID
|
||||
write_le32(8712); # Size
|
||||
write_hunk_fix_endian(822152, 8712);
|
||||
|
||||
#
|
||||
# Firmware 2, type: BASE FW FM (0x00000401), id: (0000000000000000), size: 8562
|
||||
#
|
||||
|
||||
write_le32(0x00000401); # Type
|
||||
write_le64(0x00000000, 0x00000000); # ID
|
||||
write_le32(8562); # Size
|
||||
write_hunk_fix_endian(830872, 8562);
|
||||
|
||||
#
|
||||
# Firmware 3, type: BASE FW FM INPUT1 (0x00000c01), id: (0000000000000000), size: 8576
|
||||
#
|
||||
|
||||
write_le32(0x00000c01); # Type
|
||||
write_le64(0x00000000, 0x00000000); # ID
|
||||
write_le32(8576); # Size
|
||||
write_hunk_fix_endian(839440, 8576);
|
||||
|
||||
#
|
||||
# Firmware 4, type: BASE FW (0x00000001), id: (0000000000000000), size: 8706
|
||||
#
|
||||
|
||||
write_le32(0x00000001); # Type
|
||||
write_le64(0x00000000, 0x00000000); # ID
|
||||
write_le32(8706); # Size
|
||||
write_hunk_fix_endian(848024, 8706);
|
||||
|
||||
#
|
||||
# Firmware 5, type: BASE FW MTS (0x00000005), id: (0000000000000000), size: 8682
|
||||
#
|
||||
|
||||
write_le32(0x00000005); # Type
|
||||
write_le64(0x00000000, 0x00000000); # ID
|
||||
write_le32(8682); # Size
|
||||
write_hunk_fix_endian(856736, 8682);
|
||||
|
||||
#
|
||||
# Firmware 6, type: STD FW (0x00000000), id: PAL/BG A2/A (0000000100000007), size: 161
|
||||
#
|
||||
|
||||
write_le32(0x00000000); # Type
|
||||
write_le64(0x00000001, 0x00000007); # ID
|
||||
write_le32(161); # Size
|
||||
write_hunk_fix_endian(865424, 161);
|
||||
|
||||
#
|
||||
# Firmware 7, type: STD FW MTS (0x00000004), id: PAL/BG A2/A (0000000100000007), size: 169
|
||||
#
|
||||
|
||||
write_le32(0x00000004); # Type
|
||||
write_le64(0x00000001, 0x00000007); # ID
|
||||
write_le32(169); # Size
|
||||
write_hunk_fix_endian(865592, 169);
|
||||
|
||||
#
|
||||
# Firmware 8, type: STD FW (0x00000000), id: PAL/BG A2/B (0000000200000007), size: 161
|
||||
#
|
||||
|
||||
write_le32(0x00000000); # Type
|
||||
write_le64(0x00000002, 0x00000007); # ID
|
||||
write_le32(161); # Size
|
||||
write_hunk_fix_endian(865424, 161);
|
||||
|
||||
#
|
||||
# Firmware 9, type: STD FW MTS (0x00000004), id: PAL/BG A2/B (0000000200000007), size: 169
|
||||
#
|
||||
|
||||
write_le32(0x00000004); # Type
|
||||
write_le64(0x00000002, 0x00000007); # ID
|
||||
write_le32(169); # Size
|
||||
write_hunk_fix_endian(865592, 169);
|
||||
|
||||
#
|
||||
# Firmware 10, type: STD FW (0x00000000), id: PAL/BG NICAM/A (0000000400000007), size: 161
|
||||
#
|
||||
|
||||
write_le32(0x00000000); # Type
|
||||
write_le64(0x00000004, 0x00000007); # ID
|
||||
write_le32(161); # Size
|
||||
write_hunk_fix_endian(866112, 161);
|
||||
|
||||
#
|
||||
# Firmware 11, type: STD FW MTS (0x00000004), id: PAL/BG NICAM/A (0000000400000007), size: 169
|
||||
#
|
||||
|
||||
write_le32(0x00000004); # Type
|
||||
write_le64(0x00000004, 0x00000007); # ID
|
||||
write_le32(169); # Size
|
||||
write_hunk_fix_endian(866280, 169);
|
||||
|
||||
#
|
||||
# Firmware 12, type: STD FW (0x00000000), id: PAL/BG NICAM/B (0000000800000007), size: 161
|
||||
#
|
||||
|
||||
write_le32(0x00000000); # Type
|
||||
write_le64(0x00000008, 0x00000007); # ID
|
||||
write_le32(161); # Size
|
||||
write_hunk_fix_endian(866112, 161);
|
||||
|
||||
#
|
||||
# Firmware 13, type: STD FW MTS (0x00000004), id: PAL/BG NICAM/B (0000000800000007), size: 169
|
||||
#
|
||||
|
||||
write_le32(0x00000004); # Type
|
||||
write_le64(0x00000008, 0x00000007); # ID
|
||||
write_le32(169); # Size
|
||||
write_hunk_fix_endian(866280, 169);
|
||||
|
||||
#
|
||||
# Firmware 14, type: STD FW (0x00000000), id: PAL/DK A2 (00000003000000e0), size: 161
|
||||
#
|
||||
|
||||
write_le32(0x00000000); # Type
|
||||
write_le64(0x00000003, 0x000000e0); # ID
|
||||
write_le32(161); # Size
|
||||
write_hunk_fix_endian(866800, 161);
|
||||
|
||||
#
|
||||
# Firmware 15, type: STD FW MTS (0x00000004), id: PAL/DK A2 (00000003000000e0), size: 169
|
||||
#
|
||||
|
||||
write_le32(0x00000004); # Type
|
||||
write_le64(0x00000003, 0x000000e0); # ID
|
||||
write_le32(169); # Size
|
||||
write_hunk_fix_endian(866968, 169);
|
||||
|
||||
#
|
||||
# Firmware 16, type: STD FW (0x00000000), id: PAL/DK NICAM (0000000c000000e0), size: 161
|
||||
#
|
||||
|
||||
write_le32(0x00000000); # Type
|
||||
write_le64(0x0000000c, 0x000000e0); # ID
|
||||
write_le32(161); # Size
|
||||
write_hunk_fix_endian(867144, 161);
|
||||
|
||||
#
|
||||
# Firmware 17, type: STD FW MTS (0x00000004), id: PAL/DK NICAM (0000000c000000e0), size: 169
|
||||
#
|
||||
|
||||
write_le32(0x00000004); # Type
|
||||
write_le64(0x0000000c, 0x000000e0); # ID
|
||||
write_le32(169); # Size
|
||||
write_hunk_fix_endian(867312, 169);
|
||||
|
||||
#
|
||||
# Firmware 18, type: STD FW (0x00000000), id: SECAM/K1 (0000000000200000), size: 161
|
||||
#
|
||||
|
||||
write_le32(0x00000000); # Type
|
||||
write_le64(0x00000000, 0x00200000); # ID
|
||||
write_le32(161); # Size
|
||||
write_hunk_fix_endian(867488, 161);
|
||||
|
||||
#
|
||||
# Firmware 19, type: STD FW MTS (0x00000004), id: SECAM/K1 (0000000000200000), size: 169
|
||||
#
|
||||
|
||||
write_le32(0x00000004); # Type
|
||||
write_le64(0x00000000, 0x00200000); # ID
|
||||
write_le32(169); # Size
|
||||
write_hunk_fix_endian(867656, 169);
|
||||
|
||||
#
|
||||
# Firmware 20, type: STD FW (0x00000000), id: SECAM/K3 (0000000004000000), size: 161
|
||||
#
|
||||
|
||||
write_le32(0x00000000); # Type
|
||||
write_le64(0x00000000, 0x04000000); # ID
|
||||
write_le32(161); # Size
|
||||
write_hunk_fix_endian(867832, 161);
|
||||
|
||||
#
|
||||
# Firmware 21, type: STD FW MTS (0x00000004), id: SECAM/K3 (0000000004000000), size: 169
|
||||
#
|
||||
|
||||
write_le32(0x00000004); # Type
|
||||
write_le64(0x00000000, 0x04000000); # ID
|
||||
write_le32(169); # Size
|
||||
write_hunk_fix_endian(868000, 169);
|
||||
|
||||
#
|
||||
# Firmware 22, type: STD FW D2633 DTV6 ATSC (0x00010030), id: (0000000000000000), size: 149
|
||||
#
|
||||
|
||||
write_le32(0x00010030); # Type
|
||||
write_le64(0x00000000, 0x00000000); # ID
|
||||
write_le32(149); # Size
|
||||
write_hunk_fix_endian(868176, 149);
|
||||
|
||||
#
|
||||
# Firmware 23, type: STD FW D2620 DTV6 QAM (0x00000068), id: (0000000000000000), size: 149
|
||||
#
|
||||
|
||||
write_le32(0x00000068); # Type
|
||||
write_le64(0x00000000, 0x00000000); # ID
|
||||
write_le32(149); # Size
|
||||
write_hunk_fix_endian(868336, 149);
|
||||
|
||||
#
|
||||
# Firmware 24, type: STD FW D2633 DTV6 QAM (0x00000070), id: (0000000000000000), size: 149
|
||||
#
|
||||
|
||||
write_le32(0x00000070); # Type
|
||||
write_le64(0x00000000, 0x00000000); # ID
|
||||
write_le32(149); # Size
|
||||
write_hunk_fix_endian(868488, 149);
|
||||
|
||||
#
|
||||
# Firmware 25, type: STD FW D2620 DTV7 (0x00000088), id: (0000000000000000), size: 149
|
||||
#
|
||||
|
||||
write_le32(0x00000088); # Type
|
||||
write_le64(0x00000000, 0x00000000); # ID
|
||||
write_le32(149); # Size
|
||||
write_hunk_fix_endian(868648, 149);
|
||||
|
||||
#
|
||||
# Firmware 26, type: STD FW D2633 DTV7 (0x00000090), id: (0000000000000000), size: 149
|
||||
#
|
||||
|
||||
write_le32(0x00000090); # Type
|
||||
write_le64(0x00000000, 0x00000000); # ID
|
||||
write_le32(149); # Size
|
||||
write_hunk_fix_endian(868800, 149);
|
||||
|
||||
#
|
||||
# Firmware 27, type: STD FW D2620 DTV78 (0x00000108), id: (0000000000000000), size: 149
|
||||
#
|
||||
|
||||
write_le32(0x00000108); # Type
|
||||
write_le64(0x00000000, 0x00000000); # ID
|
||||
write_le32(149); # Size
|
||||
write_hunk_fix_endian(868960, 149);
|
||||
|
||||
#
|
||||
# Firmware 28, type: STD FW D2633 DTV78 (0x00000110), id: (0000000000000000), size: 149
|
||||
#
|
||||
|
||||
write_le32(0x00000110); # Type
|
||||
write_le64(0x00000000, 0x00000000); # ID
|
||||
write_le32(149); # Size
|
||||
write_hunk_fix_endian(869112, 149);
|
||||
|
||||
#
|
||||
# Firmware 29, type: STD FW D2620 DTV8 (0x00000208), id: (0000000000000000), size: 149
|
||||
#
|
||||
|
||||
write_le32(0x00000208); # Type
|
||||
write_le64(0x00000000, 0x00000000); # ID
|
||||
write_le32(149); # Size
|
||||
write_hunk_fix_endian(868648, 149);
|
||||
|
||||
#
|
||||
# Firmware 30, type: STD FW D2633 DTV8 (0x00000210), id: (0000000000000000), size: 149
|
||||
#
|
||||
|
||||
write_le32(0x00000210); # Type
|
||||
write_le64(0x00000000, 0x00000000); # ID
|
||||
write_le32(149); # Size
|
||||
write_hunk_fix_endian(868800, 149);
|
||||
|
||||
#
|
||||
# Firmware 31, type: STD FW FM (0x00000400), id: (0000000000000000), size: 135
|
||||
#
|
||||
|
||||
write_le32(0x00000400); # Type
|
||||
write_le64(0x00000000, 0x00000000); # ID
|
||||
write_le32(135); # Size
|
||||
write_hunk_fix_endian(869584, 135);
|
||||
|
||||
#
|
||||
# Firmware 32, type: STD FW (0x00000000), id: PAL/I (0000000000000010), size: 161
|
||||
#
|
||||
|
||||
write_le32(0x00000000); # Type
|
||||
write_le64(0x00000000, 0x00000010); # ID
|
||||
write_le32(161); # Size
|
||||
write_hunk_fix_endian(869728, 161);
|
||||
|
||||
#
|
||||
# Firmware 33, type: STD FW MTS (0x00000004), id: PAL/I (0000000000000010), size: 169
|
||||
#
|
||||
|
||||
write_le32(0x00000004); # Type
|
||||
write_le64(0x00000000, 0x00000010); # ID
|
||||
write_le32(169); # Size
|
||||
write_hunk_fix_endian(869896, 169);
|
||||
|
||||
#
|
||||
# Firmware 34, type: STD FW (0x00000000), id: SECAM/L AM (0000001000400000), size: 169
|
||||
#
|
||||
|
||||
write_le32(0x00000000); # Type
|
||||
write_le64(0x00000010, 0x00400000); # ID
|
||||
write_le32(169); # Size
|
||||
write_hunk_fix_endian(870072, 169);
|
||||
|
||||
#
|
||||
# Firmware 35, type: STD FW (0x00000000), id: SECAM/L NICAM (0000000c00400000), size: 161
|
||||
#
|
||||
|
||||
write_le32(0x00000000); # Type
|
||||
write_le64(0x0000000c, 0x00400000); # ID
|
||||
write_le32(161); # Size
|
||||
write_hunk_fix_endian(870248, 161);
|
||||
|
||||
#
|
||||
# Firmware 36, type: STD FW (0x00000000), id: SECAM/Lc (0000000000800000), size: 161
|
||||
#
|
||||
|
||||
write_le32(0x00000000); # Type
|
||||
write_le64(0x00000000, 0x00800000); # ID
|
||||
write_le32(161); # Size
|
||||
write_hunk_fix_endian(870416, 161);
|
||||
|
||||
#
|
||||
# Firmware 37, type: STD FW (0x00000000), id: NTSC/M Kr (0000000000008000), size: 161
|
||||
#
|
||||
|
||||
write_le32(0x00000000); # Type
|
||||
write_le64(0x00000000, 0x00008000); # ID
|
||||
write_le32(161); # Size
|
||||
write_hunk_fix_endian(870584, 161);
|
||||
|
||||
#
|
||||
# Firmware 38, type: STD FW LCD (0x00001000), id: NTSC/M Kr (0000000000008000), size: 161
|
||||
#
|
||||
|
||||
write_le32(0x00001000); # Type
|
||||
write_le64(0x00000000, 0x00008000); # ID
|
||||
write_le32(161); # Size
|
||||
write_hunk_fix_endian(870752, 161);
|
||||
|
||||
#
|
||||
# Firmware 39, type: STD FW LCD NOGD (0x00003000), id: NTSC/M Kr (0000000000008000), size: 161
|
||||
#
|
||||
|
||||
write_le32(0x00003000); # Type
|
||||
write_le64(0x00000000, 0x00008000); # ID
|
||||
write_le32(161); # Size
|
||||
write_hunk_fix_endian(870920, 161);
|
||||
|
||||
#
|
||||
# Firmware 40, type: STD FW MTS (0x00000004), id: NTSC/M Kr (0000000000008000), size: 169
|
||||
#
|
||||
|
||||
write_le32(0x00000004); # Type
|
||||
write_le64(0x00000000, 0x00008000); # ID
|
||||
write_le32(169); # Size
|
||||
write_hunk_fix_endian(871088, 169);
|
||||
|
||||
#
|
||||
# Firmware 41, type: STD FW (0x00000000), id: NTSC PAL/M PAL/N (000000000000b700), size: 161
|
||||
#
|
||||
|
||||
write_le32(0x00000000); # Type
|
||||
write_le64(0x00000000, 0x0000b700); # ID
|
||||
write_le32(161); # Size
|
||||
write_hunk_fix_endian(871264, 161);
|
||||
|
||||
#
|
||||
# Firmware 42, type: STD FW LCD (0x00001000), id: NTSC PAL/M PAL/N (000000000000b700), size: 161
|
||||
#
|
||||
|
||||
write_le32(0x00001000); # Type
|
||||
write_le64(0x00000000, 0x0000b700); # ID
|
||||
write_le32(161); # Size
|
||||
write_hunk_fix_endian(871432, 161);
|
||||
|
||||
#
|
||||
# Firmware 43, type: STD FW LCD NOGD (0x00003000), id: NTSC PAL/M PAL/N (000000000000b700), size: 161
|
||||
#
|
||||
|
||||
write_le32(0x00003000); # Type
|
||||
write_le64(0x00000000, 0x0000b700); # ID
|
||||
write_le32(161); # Size
|
||||
write_hunk_fix_endian(871600, 161);
|
||||
|
||||
#
|
||||
# Firmware 44, type: STD FW (0x00000000), id: NTSC/M Jp (0000000000002000), size: 161
|
||||
#
|
||||
|
||||
write_le32(0x00000000); # Type
|
||||
write_le64(0x00000000, 0x00002000); # ID
|
||||
write_le32(161); # Size
|
||||
write_hunk_fix_endian(871264, 161);
|
||||
|
||||
#
|
||||
# Firmware 45, type: STD FW MTS (0x00000004), id: NTSC PAL/M PAL/N (000000000000b700), size: 169
|
||||
#
|
||||
|
||||
write_le32(0x00000004); # Type
|
||||
write_le64(0x00000000, 0x0000b700); # ID
|
||||
write_le32(169); # Size
|
||||
write_hunk_fix_endian(871936, 169);
|
||||
|
||||
#
|
||||
# Firmware 46, type: STD FW MTS LCD (0x00001004), id: NTSC PAL/M PAL/N (000000000000b700), size: 169
|
||||
#
|
||||
|
||||
write_le32(0x00001004); # Type
|
||||
write_le64(0x00000000, 0x0000b700); # ID
|
||||
write_le32(169); # Size
|
||||
write_hunk_fix_endian(872112, 169);
|
||||
|
||||
#
|
||||
# Firmware 47, type: STD FW MTS LCD NOGD (0x00003004), id: NTSC PAL/M PAL/N (000000000000b700), size: 169
|
||||
#
|
||||
|
||||
write_le32(0x00003004); # Type
|
||||
write_le64(0x00000000, 0x0000b700); # ID
|
||||
write_le32(169); # Size
|
||||
write_hunk_fix_endian(872288, 169);
|
||||
|
||||
#
|
||||
# Firmware 48, type: SCODE FW HAS IF (0x60000000), IF = 3.28 MHz id: (0000000000000000), size: 192
|
||||
#
|
||||
|
||||
write_le32(0x60000000); # Type
|
||||
write_le64(0x00000000, 0x00000000); # ID
|
||||
write_le16(3280); # IF
|
||||
write_le32(192); # Size
|
||||
write_hunk(811896, 192);
|
||||
|
||||
#
|
||||
# Firmware 49, type: SCODE FW HAS IF (0x60000000), IF = 3.30 MHz id: (0000000000000000), size: 192
|
||||
#
|
||||
|
||||
write_le32(0x60000000); # Type
|
||||
write_le64(0x00000000, 0x00000000); # ID
|
||||
write_le16(3300); # IF
|
||||
write_le32(192); # Size
|
||||
write_hunk(813048, 192);
|
||||
|
||||
#
|
||||
# Firmware 50, type: SCODE FW HAS IF (0x60000000), IF = 3.44 MHz id: (0000000000000000), size: 192
|
||||
#
|
||||
|
||||
write_le32(0x60000000); # Type
|
||||
write_le64(0x00000000, 0x00000000); # ID
|
||||
write_le16(3440); # IF
|
||||
write_le32(192); # Size
|
||||
write_hunk(812280, 192);
|
||||
|
||||
#
|
||||
# Firmware 51, type: SCODE FW HAS IF (0x60000000), IF = 3.46 MHz id: (0000000000000000), size: 192
|
||||
#
|
||||
|
||||
write_le32(0x60000000); # Type
|
||||
write_le64(0x00000000, 0x00000000); # ID
|
||||
write_le16(3460); # IF
|
||||
write_le32(192); # Size
|
||||
write_hunk(812472, 192);
|
||||
|
||||
#
|
||||
# Firmware 52, type: SCODE FW DTV6 ATSC OREN36 HAS IF (0x60210020), IF = 3.80 MHz id: (0000000000000000), size: 192
|
||||
#
|
||||
|
||||
write_le32(0x60210020); # Type
|
||||
write_le64(0x00000000, 0x00000000); # ID
|
||||
write_le16(3800); # IF
|
||||
write_le32(192); # Size
|
||||
write_hunk(809784, 192);
|
||||
|
||||
#
|
||||
# Firmware 53, type: SCODE FW HAS IF (0x60000000), IF = 4.00 MHz id: (0000000000000000), size: 192
|
||||
#
|
||||
|
||||
write_le32(0x60000000); # Type
|
||||
write_le64(0x00000000, 0x00000000); # ID
|
||||
write_le16(4000); # IF
|
||||
write_le32(192); # Size
|
||||
write_hunk(812088, 192);
|
||||
|
||||
#
|
||||
# Firmware 54, type: SCODE FW DTV6 ATSC TOYOTA388 HAS IF (0x60410020), IF = 4.08 MHz id: (0000000000000000), size: 192
|
||||
#
|
||||
|
||||
write_le32(0x60410020); # Type
|
||||
write_le64(0x00000000, 0x00000000); # ID
|
||||
write_le16(4080); # IF
|
||||
write_le32(192); # Size
|
||||
write_hunk(809976, 192);
|
||||
|
||||
#
|
||||
# Firmware 55, type: SCODE FW HAS IF (0x60000000), IF = 4.20 MHz id: (0000000000000000), size: 192
|
||||
#
|
||||
|
||||
write_le32(0x60000000); # Type
|
||||
write_le64(0x00000000, 0x00000000); # ID
|
||||
write_le16(4200); # IF
|
||||
write_le32(192); # Size
|
||||
write_hunk(811704, 192);
|
||||
|
||||
#
|
||||
# Firmware 56, type: SCODE FW MONO HAS IF (0x60008000), IF = 4.32 MHz id: NTSC/M Kr (0000000000008000), size: 192
|
||||
#
|
||||
|
||||
write_le32(0x60008000); # Type
|
||||
write_le64(0x00000000, 0x00008000); # ID
|
||||
write_le16(4320); # IF
|
||||
write_le32(192); # Size
|
||||
write_hunk(808056, 192);
|
||||
|
||||
#
|
||||
# Firmware 57, type: SCODE FW HAS IF (0x60000000), IF = 4.45 MHz id: (0000000000000000), size: 192
|
||||
#
|
||||
|
||||
write_le32(0x60000000); # Type
|
||||
write_le64(0x00000000, 0x00000000); # ID
|
||||
write_le16(4450); # IF
|
||||
write_le32(192); # Size
|
||||
write_hunk(812664, 192);
|
||||
|
||||
#
|
||||
# Firmware 58, type: SCODE FW HAS IF (0x60000000), IF = 4.50 MHz id: NTSC/M Jp (0000000000002000), size: 192
|
||||
#
|
||||
|
||||
write_le32(0x60000000); # Type
|
||||
write_le64(0x00000000, 0x00002000); # ID
|
||||
write_le16(4500); # IF
|
||||
write_le32(192); # Size
|
||||
write_hunk(807672, 192);
|
||||
|
||||
#
|
||||
# Firmware 59, type: SCODE FW LCD NOGD IF HAS IF (0x60023000), IF = 4.60 MHz id: NTSC/M Kr (0000000000008000), size: 192
|
||||
#
|
||||
|
||||
write_le32(0x60023000); # Type
|
||||
write_le64(0x00000000, 0x00008000); # ID
|
||||
write_le16(4600); # IF
|
||||
write_le32(192); # Size
|
||||
write_hunk(807864, 192);
|
||||
|
||||
#
|
||||
# Firmware 60, type: SCODE FW DTV78 ZARLINK456 HAS IF (0x62000100), IF = 4.76 MHz id: (0000000000000000), size: 192
|
||||
#
|
||||
|
||||
write_le32(0x62000100); # Type
|
||||
write_le64(0x00000000, 0x00000000); # ID
|
||||
write_le16(4760); # IF
|
||||
write_le32(192); # Size
|
||||
write_hunk(807288, 192);
|
||||
|
||||
#
|
||||
# Firmware 61, type: SCODE FW HAS IF (0x60000000), IF = 4.94 MHz id: (0000000000000000), size: 192
|
||||
#
|
||||
|
||||
write_le32(0x60000000); # Type
|
||||
write_le64(0x00000000, 0x00000000); # ID
|
||||
write_le16(4940); # IF
|
||||
write_le32(192); # Size
|
||||
write_hunk(811512, 192);
|
||||
|
||||
#
|
||||
# Firmware 62, type: SCODE FW DTV7 ZARLINK456 HAS IF (0x62000080), IF = 5.26 MHz id: (0000000000000000), size: 192
|
||||
#
|
||||
|
||||
write_le32(0x62000080); # Type
|
||||
write_le64(0x00000000, 0x00000000); # ID
|
||||
write_le16(5260); # IF
|
||||
write_le32(192); # Size
|
||||
write_hunk(810552, 192);
|
||||
|
||||
#
|
||||
# Firmware 63, type: SCODE FW MONO HAS IF (0x60008000), IF = 5.32 MHz id: PAL/BG NICAM/B (0000000800000007), size: 192
|
||||
#
|
||||
|
||||
write_le32(0x60008000); # Type
|
||||
write_le64(0x00000008, 0x00000007); # ID
|
||||
write_le16(5320); # IF
|
||||
write_le32(192); # Size
|
||||
write_hunk(810744, 192);
|
||||
|
||||
#
|
||||
# Firmware 64, type: SCODE FW DTV8 CHINA HAS IF (0x64000200), IF = 5.40 MHz id: (0000000000000000), size: 192
|
||||
#
|
||||
|
||||
write_le32(0x64000200); # Type
|
||||
write_le64(0x00000000, 0x00000000); # ID
|
||||
write_le16(5400); # IF
|
||||
write_le32(192); # Size
|
||||
write_hunk(807096, 192);
|
||||
|
||||
#
|
||||
# Firmware 65, type: SCODE FW DTV6 ATSC OREN538 HAS IF (0x60110020), IF = 5.58 MHz id: (0000000000000000), size: 192
|
||||
#
|
||||
|
||||
write_le32(0x60110020); # Type
|
||||
write_le64(0x00000000, 0x00000000); # ID
|
||||
write_le16(5580); # IF
|
||||
write_le32(192); # Size
|
||||
write_hunk(809592, 192);
|
||||
|
||||
#
|
||||
# Firmware 66, type: SCODE FW HAS IF (0x60000000), IF = 5.64 MHz id: PAL/BG A2/B (0000000200000007), size: 192
|
||||
#
|
||||
|
||||
write_le32(0x60000000); # Type
|
||||
write_le64(0x00000002, 0x00000007); # ID
|
||||
write_le16(5640); # IF
|
||||
write_le32(192); # Size
|
||||
write_hunk(808440, 192);
|
||||
|
||||
#
|
||||
# Firmware 67, type: SCODE FW HAS IF (0x60000000), IF = 5.74 MHz id: PAL/BG NICAM/B (0000000800000007), size: 192
|
||||
#
|
||||
|
||||
write_le32(0x60000000); # Type
|
||||
write_le64(0x00000008, 0x00000007); # ID
|
||||
write_le16(5740); # IF
|
||||
write_le32(192); # Size
|
||||
write_hunk(808632, 192);
|
||||
|
||||
#
|
||||
# Firmware 68, type: SCODE FW DTV7 DIBCOM52 HAS IF (0x61000080), IF = 5.90 MHz id: (0000000000000000), size: 192
|
||||
#
|
||||
|
||||
write_le32(0x61000080); # Type
|
||||
write_le64(0x00000000, 0x00000000); # ID
|
||||
write_le16(5900); # IF
|
||||
write_le32(192); # Size
|
||||
write_hunk(810360, 192);
|
||||
|
||||
#
|
||||
# Firmware 69, type: SCODE FW MONO HAS IF (0x60008000), IF = 6.00 MHz id: PAL/I (0000000000000010), size: 192
|
||||
#
|
||||
|
||||
write_le32(0x60008000); # Type
|
||||
write_le64(0x00000000, 0x00000010); # ID
|
||||
write_le16(6000); # IF
|
||||
write_le32(192); # Size
|
||||
write_hunk(808824, 192);
|
||||
|
||||
#
|
||||
# Firmware 70, type: SCODE FW DTV6 QAM F6MHZ HAS IF (0x68000060), IF = 6.20 MHz id: (0000000000000000), size: 192
|
||||
#
|
||||
|
||||
write_le32(0x68000060); # Type
|
||||
write_le64(0x00000000, 0x00000000); # ID
|
||||
write_le16(6200); # IF
|
||||
write_le32(192); # Size
|
||||
write_hunk(809400, 192);
|
||||
|
||||
#
|
||||
# Firmware 71, type: SCODE FW HAS IF (0x60000000), IF = 6.24 MHz id: PAL/I (0000000000000010), size: 192
|
||||
#
|
||||
|
||||
write_le32(0x60000000); # Type
|
||||
write_le64(0x00000000, 0x00000010); # ID
|
||||
write_le16(6240); # IF
|
||||
write_le32(192); # Size
|
||||
write_hunk(808248, 192);
|
||||
|
||||
#
|
||||
# Firmware 72, type: SCODE FW MONO HAS IF (0x60008000), IF = 6.32 MHz id: SECAM/K1 (0000000000200000), size: 192
|
||||
#
|
||||
|
||||
write_le32(0x60008000); # Type
|
||||
write_le64(0x00000000, 0x00200000); # ID
|
||||
write_le16(6320); # IF
|
||||
write_le32(192); # Size
|
||||
write_hunk(811320, 192);
|
||||
|
||||
#
|
||||
# Firmware 73, type: SCODE FW HAS IF (0x60000000), IF = 6.34 MHz id: SECAM/K1 (0000000000200000), size: 192
|
||||
#
|
||||
|
||||
write_le32(0x60000000); # Type
|
||||
write_le64(0x00000000, 0x00200000); # ID
|
||||
write_le16(6340); # IF
|
||||
write_le32(192); # Size
|
||||
write_hunk(809208, 192);
|
||||
|
||||
#
|
||||
# Firmware 74, type: SCODE FW MONO HAS IF (0x60008000), IF = 6.50 MHz id: SECAM/K3 (0000000004000000), size: 192
|
||||
#
|
||||
|
||||
write_le32(0x60008000); # Type
|
||||
write_le64(0x00000000, 0x04000000); # ID
|
||||
write_le16(6500); # IF
|
||||
write_le32(192); # Size
|
||||
write_hunk(811128, 192);
|
||||
|
||||
#
|
||||
# Firmware 75, type: SCODE FW DTV6 ATSC ATI638 HAS IF (0x60090020), IF = 6.58 MHz id: (0000000000000000), size: 192
|
||||
#
|
||||
|
||||
write_le32(0x60090020); # Type
|
||||
write_le64(0x00000000, 0x00000000); # ID
|
||||
write_le16(6580); # IF
|
||||
write_le32(192); # Size
|
||||
write_hunk(807480, 192);
|
||||
|
||||
#
|
||||
# Firmware 76, type: SCODE FW HAS IF (0x60000000), IF = 6.60 MHz id: PAL/DK A2 (00000003000000e0), size: 192
|
||||
#
|
||||
|
||||
write_le32(0x60000000); # Type
|
||||
write_le64(0x00000003, 0x000000e0); # ID
|
||||
write_le16(6600); # IF
|
||||
write_le32(192); # Size
|
||||
write_hunk(809016, 192);
|
||||
|
||||
#
|
||||
# Firmware 77, type: SCODE FW MONO HAS IF (0x60008000), IF = 6.68 MHz id: PAL/DK A2 (00000003000000e0), size: 192
|
||||
#
|
||||
|
||||
write_le32(0x60008000); # Type
|
||||
write_le64(0x00000003, 0x000000e0); # ID
|
||||
write_le16(6680); # IF
|
||||
write_le32(192); # Size
|
||||
write_hunk(810936, 192);
|
||||
|
||||
#
|
||||
# Firmware 78, type: SCODE FW DTV6 ATSC TOYOTA794 HAS IF (0x60810020), IF = 8.14 MHz id: (0000000000000000), size: 192
|
||||
#
|
||||
|
||||
write_le32(0x60810020); # Type
|
||||
write_le64(0x00000000, 0x00000000); # ID
|
||||
write_le16(8140); # IF
|
||||
write_le32(192); # Size
|
||||
write_hunk(810168, 192);
|
||||
|
||||
#
|
||||
# Firmware 79, type: SCODE FW HAS IF (0x60000000), IF = 8.20 MHz id: (0000000000000000), size: 192
|
||||
#
|
||||
|
||||
write_le32(0x60000000); # Type
|
||||
write_le64(0x00000000, 0x00000000); # ID
|
||||
write_le16(8200); # IF
|
||||
write_le32(192); # Size
|
||||
write_hunk(812856, 192);
|
||||
}
|
||||
|
||||
sub extract_firmware {
|
||||
my $sourcefile = "hcw85bda.sys";
|
||||
my $hash = "0e44dbf63bb0169d57446aec21881ff2";
|
||||
my $outfile = "xc3028-v27.fw";
|
||||
my $name = "xc2028 firmware";
|
||||
my $version = 519;
|
||||
my $nr_desc = 80;
|
||||
my $out;
|
||||
|
||||
verify($sourcefile, $hash);
|
||||
|
||||
open INFILE, "<$sourcefile";
|
||||
main_firmware($outfile, $name, $version, $nr_desc);
|
||||
close INFILE;
|
||||
}
|
||||
|
||||
extract_firmware;
|
||||
printf "Firmwares generated.\n";
|
@ -568,6 +568,7 @@ the fingerprint is: '88E8 F32F 7244 68BA 3958 5D40 99DA 5D2A FCE6 35A4'.
|
||||
Many thanks to following persons for their contribute (listed in alphabetical
|
||||
order):
|
||||
|
||||
- David Anderson for the donation of a webcam;
|
||||
- Luca Capello for the donation of a webcam;
|
||||
- Philippe Coval for having helped testing the PAS202BCA image sensor;
|
||||
- Joao Rodrigo Fuzaro, Joao Limirio, Claudio Filho and Caio Begotti for the
|
||||
|
@ -2141,6 +2141,15 @@ L: isdn4linux@listserv.isdn4linux.de
|
||||
W: http://www.melware.de
|
||||
S: Maintained
|
||||
|
||||
IVTV VIDEO4LINUX DRIVER
|
||||
P: Hans Verkuil
|
||||
M: hverkuil@xs4all.nl
|
||||
L: ivtv-devel@ivtvdriver.org
|
||||
L: ivtv-users@ivtvdriver.org
|
||||
L: video4linux-list@redhat.com
|
||||
W: http://www.ivtvdriver.org
|
||||
S: Maintained
|
||||
|
||||
JOURNALLING FLASH FILE SYSTEM V2 (JFFS2)
|
||||
P: David Woodhouse
|
||||
M: dwmw2@infradead.org
|
||||
|
@ -69,11 +69,13 @@ source "drivers/media/common/Kconfig"
|
||||
config VIDEO_TUNER
|
||||
tristate
|
||||
depends on I2C
|
||||
select TUNER_XC2028 if !VIDEO_TUNER_CUSTOMIZE
|
||||
select TUNER_MT20XX if !VIDEO_TUNER_CUSTOMIZE
|
||||
select TUNER_TDA8290 if !VIDEO_TUNER_CUSTOMIZE
|
||||
select TUNER_TEA5761 if !VIDEO_TUNER_CUSTOMIZE
|
||||
select TUNER_TEA5767 if !VIDEO_TUNER_CUSTOMIZE
|
||||
select TUNER_SIMPLE if !VIDEO_TUNER_CUSTOMIZE
|
||||
select TUNER_TDA9887 if !VIDEO_TUNER_CUSTOMIZE
|
||||
|
||||
menuconfig VIDEO_TUNER_CUSTOMIZE
|
||||
bool "Customize analog tuner modules to build"
|
||||
@ -89,6 +91,13 @@ menuconfig VIDEO_TUNER_CUSTOMIZE
|
||||
|
||||
if VIDEO_TUNER_CUSTOMIZE
|
||||
|
||||
config TUNER_XC2028
|
||||
tristate "XCeive xc2028/xc3028 tuners"
|
||||
depends on I2C
|
||||
default m if VIDEO_TUNER_CUSTOMIZE
|
||||
help
|
||||
Say Y here to include support for the xc2028/xc3028 tuners.
|
||||
|
||||
config TUNER_MT20XX
|
||||
tristate "Microtune 2032 / 2050 tuners"
|
||||
depends on I2C
|
||||
@ -97,8 +106,10 @@ config TUNER_MT20XX
|
||||
Say Y here to include support for the MT2032 / MT2050 tuner.
|
||||
|
||||
config TUNER_TDA8290
|
||||
tristate "TDA 8290+8275(a) tuner combo"
|
||||
tristate "TDA 8290/8295 + 8275(a)/18271 tuner combo"
|
||||
depends on I2C
|
||||
select DVB_TDA827X
|
||||
select DVB_TDA18271
|
||||
default m if VIDEO_TUNER_CUSTOMIZE
|
||||
help
|
||||
Say Y here to include support for Philips TDA8290+8275(a) tuner.
|
||||
@ -120,10 +131,19 @@ config TUNER_TEA5767
|
||||
config TUNER_SIMPLE
|
||||
tristate "Simple tuner support"
|
||||
depends on I2C
|
||||
select TUNER_TDA9887
|
||||
default m if VIDEO_TUNER_CUSTOMIZE
|
||||
help
|
||||
Say Y here to include support for various simple tuners.
|
||||
|
||||
config TUNER_TDA9887
|
||||
tristate "TDA 9885/6/7 analog IF demodulator"
|
||||
depends on I2C
|
||||
default m if VIDEO_TUNER_CUSTOMIZE
|
||||
help
|
||||
Say Y here to include support for Philips TDA9885/6/7
|
||||
analog IF demodulator.
|
||||
|
||||
endif # VIDEO_TUNER_CUSTOMIZE
|
||||
|
||||
config VIDEOBUF_GEN
|
||||
|
@ -1,6 +1,6 @@
|
||||
config VIDEO_SAA7146
|
||||
tristate
|
||||
depends on I2C
|
||||
depends on I2C && PCI
|
||||
|
||||
config VIDEO_SAA7146_VV
|
||||
tristate
|
||||
|
@ -258,7 +258,7 @@ int ir_decode_biphase(u32 *samples, int count, int low, int high)
|
||||
* saa7134 */
|
||||
|
||||
/* decode raw bit pattern to RC5 code */
|
||||
u32 ir_rc5_decode(unsigned int code)
|
||||
static u32 ir_rc5_decode(unsigned int code)
|
||||
{
|
||||
unsigned int org_code = code;
|
||||
unsigned int pair;
|
||||
@ -371,7 +371,6 @@ EXPORT_SYMBOL_GPL(ir_dump_samples);
|
||||
EXPORT_SYMBOL_GPL(ir_decode_biphase);
|
||||
EXPORT_SYMBOL_GPL(ir_decode_pulsedistance);
|
||||
|
||||
EXPORT_SYMBOL_GPL(ir_rc5_decode);
|
||||
EXPORT_SYMBOL_GPL(ir_rc5_timer_end);
|
||||
EXPORT_SYMBOL_GPL(ir_rc5_timer_keyup);
|
||||
|
||||
|
@ -1331,7 +1331,12 @@ IR_KEYTAB_TYPE ir_codes_winfast[IR_KEYTAB_SIZE] = {
|
||||
[ 0x35 ] = KEY_FASTFORWARD,
|
||||
[ 0x36 ] = KEY_TV,
|
||||
[ 0x37 ] = KEY_RADIO, /* FM */
|
||||
[ 0x38 ] = KEY_DVD
|
||||
[ 0x38 ] = KEY_DVD,
|
||||
|
||||
[ 0x3e ] = KEY_F21, /* MCE +VOL, on Y04G0033 */
|
||||
[ 0x3a ] = KEY_F22, /* MCE -VOL, on Y04G0033 */
|
||||
[ 0x3b ] = KEY_F23, /* MCE +CH, on Y04G0033 */
|
||||
[ 0x3f ] = KEY_F24 /* MCE -CH, on Y04G0033 */
|
||||
};
|
||||
|
||||
EXPORT_SYMBOL_GPL(ir_codes_winfast);
|
||||
@ -1843,3 +1848,142 @@ IR_KEYTAB_TYPE ir_codes_fusionhdtv_mce[IR_KEYTAB_SIZE] = {
|
||||
};
|
||||
|
||||
EXPORT_SYMBOL_GPL(ir_codes_fusionhdtv_mce);
|
||||
|
||||
/* Pinnacle PCTV HD 800i mini remote */
|
||||
IR_KEYTAB_TYPE ir_codes_pinnacle_pctv_hd[IR_KEYTAB_SIZE] = {
|
||||
|
||||
[0x0f] = KEY_1,
|
||||
[0x15] = KEY_2,
|
||||
[0x10] = KEY_3,
|
||||
[0x18] = KEY_4,
|
||||
[0x1b] = KEY_5,
|
||||
[0x1e] = KEY_6,
|
||||
[0x11] = KEY_7,
|
||||
[0x21] = KEY_8,
|
||||
[0x12] = KEY_9,
|
||||
[0x27] = KEY_0,
|
||||
|
||||
[0x24] = KEY_ZOOM,
|
||||
[0x2a] = KEY_SUBTITLE,
|
||||
|
||||
[0x00] = KEY_MUTE,
|
||||
[0x01] = KEY_ENTER, /* Pinnacle Logo */
|
||||
[0x39] = KEY_POWER,
|
||||
|
||||
[0x03] = KEY_VOLUMEUP,
|
||||
[0x09] = KEY_VOLUMEDOWN,
|
||||
[0x06] = KEY_CHANNELUP,
|
||||
[0x0c] = KEY_CHANNELDOWN,
|
||||
|
||||
[0x2d] = KEY_REWIND,
|
||||
[0x30] = KEY_PLAYPAUSE,
|
||||
[0x33] = KEY_FASTFORWARD,
|
||||
[0x3c] = KEY_STOP,
|
||||
[0x36] = KEY_RECORD,
|
||||
[0x3f] = KEY_EPG, /* Labeled "?" */
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(ir_codes_pinnacle_pctv_hd);
|
||||
|
||||
/*
|
||||
* Igor Kuznetsov <igk72@ya.ru>
|
||||
* Andrey J. Melnikov <temnota@kmv.ru>
|
||||
*
|
||||
* Keytable is used by BeholdTV 60x series, M6 series at
|
||||
* least, and probably other cards too.
|
||||
* The "ascii-art picture" below (in comments, first row
|
||||
* is the keycode in hex, and subsequent row(s) shows
|
||||
* the button labels (several variants when appropriate)
|
||||
* helps to descide which keycodes to assign to the buttons.
|
||||
*/
|
||||
IR_KEYTAB_TYPE ir_codes_behold[IR_KEYTAB_SIZE] = {
|
||||
|
||||
/* 0x1c 0x12 *
|
||||
* TV/FM POWER *
|
||||
* */
|
||||
[ 0x1c ] = KEY_TUNER, /*XXX KEY_TV KEY_RADIO */
|
||||
[ 0x12 ] = KEY_POWER,
|
||||
|
||||
/* 0x01 0x02 0x03 *
|
||||
* 1 2 3 *
|
||||
* *
|
||||
* 0x04 0x05 0x06 *
|
||||
* 4 5 6 *
|
||||
* *
|
||||
* 0x07 0x08 0x09 *
|
||||
* 7 8 9 *
|
||||
* */
|
||||
[ 0x01 ] = KEY_1,
|
||||
[ 0x02 ] = KEY_2,
|
||||
[ 0x03 ] = KEY_3,
|
||||
[ 0x04 ] = KEY_4,
|
||||
[ 0x05 ] = KEY_5,
|
||||
[ 0x06 ] = KEY_6,
|
||||
[ 0x07 ] = KEY_7,
|
||||
[ 0x08 ] = KEY_8,
|
||||
[ 0x09 ] = KEY_9,
|
||||
|
||||
/* 0x0a 0x00 0x17 *
|
||||
* RECALL 0 MODE *
|
||||
* */
|
||||
[ 0x0a ] = KEY_AGAIN,
|
||||
[ 0x00 ] = KEY_0,
|
||||
[ 0x17 ] = KEY_MODE,
|
||||
|
||||
/* 0x14 0x10 *
|
||||
* ASPECT FULLSCREEN *
|
||||
* */
|
||||
[ 0x14 ] = KEY_SCREEN,
|
||||
[ 0x10 ] = KEY_ZOOM,
|
||||
|
||||
/* 0x0b *
|
||||
* Up *
|
||||
* *
|
||||
* 0x18 0x16 0x0c *
|
||||
* Left Ok Right *
|
||||
* *
|
||||
* 0x015 *
|
||||
* Down *
|
||||
* */
|
||||
[ 0x0b ] = KEY_CHANNELUP, /*XXX KEY_UP */
|
||||
[ 0x18 ] = KEY_VOLUMEDOWN, /*XXX KEY_LEFT */
|
||||
[ 0x16 ] = KEY_OK, /*XXX KEY_ENTER */
|
||||
[ 0x0c ] = KEY_VOLUMEUP, /*XXX KEY_RIGHT */
|
||||
[ 0x15 ] = KEY_CHANNELDOWN, /*XXX KEY_DOWN */
|
||||
|
||||
/* 0x11 0x0d *
|
||||
* MUTE INFO *
|
||||
* */
|
||||
[ 0x11 ] = KEY_MUTE,
|
||||
[ 0x0d ] = KEY_INFO,
|
||||
|
||||
/* 0x0f 0x1b 0x1a *
|
||||
* RECORD PLAY/PAUSE STOP *
|
||||
* *
|
||||
* 0x0e 0x1f 0x1e *
|
||||
*TELETEXT AUDIO SOURCE *
|
||||
* RED YELLOW *
|
||||
* */
|
||||
[ 0x0f ] = KEY_RECORD,
|
||||
[ 0x1b ] = KEY_PLAYPAUSE,
|
||||
[ 0x1a ] = KEY_STOP,
|
||||
[ 0x0e ] = KEY_TEXT,
|
||||
[ 0x1f ] = KEY_RED, /*XXX KEY_AUDIO */
|
||||
[ 0x1e ] = KEY_YELLOW, /*XXX KEY_SOURCE */
|
||||
|
||||
/* 0x1d 0x13 0x19 *
|
||||
* SLEEP PREVIEW DVB *
|
||||
* GREEN BLUE *
|
||||
* */
|
||||
[ 0x1d ] = KEY_SLEEP,
|
||||
[ 0x13 ] = KEY_GREEN,
|
||||
[ 0x19 ] = KEY_BLUE, /*XXX KEY_SAT */
|
||||
|
||||
/* 0x58 0x5c *
|
||||
* FREEZE SNAPSHOT *
|
||||
* */
|
||||
[ 0x58 ] = KEY_SLOW,
|
||||
[ 0x5c ] = KEY_SAVE,
|
||||
|
||||
};
|
||||
|
||||
EXPORT_SYMBOL_GPL(ir_codes_behold);
|
||||
|
@ -61,7 +61,7 @@ void saa7146_dma_free(struct saa7146_dev *dev,struct videobuf_queue *q,
|
||||
videobuf_waiton(&buf->vb,0,0);
|
||||
videobuf_dma_unmap(q, dma);
|
||||
videobuf_dma_free(dma);
|
||||
buf->vb.state = STATE_NEEDS_INIT;
|
||||
buf->vb.state = VIDEOBUF_NEEDS_INIT;
|
||||
}
|
||||
|
||||
|
||||
@ -83,7 +83,7 @@ int saa7146_buffer_queue(struct saa7146_dev *dev,
|
||||
buf->activate(dev,buf,NULL);
|
||||
} else {
|
||||
list_add_tail(&buf->vb.queue,&q->queue);
|
||||
buf->vb.state = STATE_QUEUED;
|
||||
buf->vb.state = VIDEOBUF_QUEUED;
|
||||
DEB_D(("adding buffer %p to queue. (active buffer present)\n", buf));
|
||||
}
|
||||
return 0;
|
||||
@ -174,7 +174,7 @@ void saa7146_buffer_timeout(unsigned long data)
|
||||
spin_lock_irqsave(&dev->slock,flags);
|
||||
if (q->curr) {
|
||||
DEB_D(("timeout on %p\n", q->curr));
|
||||
saa7146_buffer_finish(dev,q,STATE_ERROR);
|
||||
saa7146_buffer_finish(dev,q,VIDEOBUF_ERROR);
|
||||
}
|
||||
|
||||
/* we don't restart the transfer here like other drivers do. when
|
||||
@ -366,7 +366,7 @@ static unsigned int fops_poll(struct file *file, struct poll_table_struct *wait)
|
||||
}
|
||||
|
||||
poll_wait(file, &buf->done, wait);
|
||||
if (buf->state == STATE_DONE || buf->state == STATE_ERROR) {
|
||||
if (buf->state == VIDEOBUF_DONE || buf->state == VIDEOBUF_ERROR) {
|
||||
DEB_D(("poll succeeded!\n"));
|
||||
return POLLIN|POLLRDNORM;
|
||||
}
|
||||
@ -538,6 +538,7 @@ int saa7146_register_device(struct video_device **vid, struct saa7146_dev* dev,
|
||||
// fixme: -1 should be an insmod parameter *for the extension* (like "video_nr");
|
||||
if (video_register_device(vfd, type, -1) < 0) {
|
||||
ERR(("cannot register v4l2 device. skipping.\n"));
|
||||
video_device_release(vfd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -205,7 +205,7 @@ static int buffer_activate(struct saa7146_dev *dev,
|
||||
struct saa7146_buf *next)
|
||||
{
|
||||
struct saa7146_vv *vv = dev->vv_data;
|
||||
buf->vb.state = STATE_ACTIVE;
|
||||
buf->vb.state = VIDEOBUF_ACTIVE;
|
||||
|
||||
DEB_VBI(("dev:%p, buf:%p, next:%p\n",dev,buf,next));
|
||||
saa7146_set_vbi_capture(dev,buf,next);
|
||||
@ -238,7 +238,7 @@ static int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,e
|
||||
if (buf->vb.size != size)
|
||||
saa7146_dma_free(dev,q,buf);
|
||||
|
||||
if (STATE_NEEDS_INIT == buf->vb.state) {
|
||||
if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
|
||||
struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
|
||||
|
||||
buf->vb.width = llength;
|
||||
@ -257,7 +257,7 @@ static int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,e
|
||||
if (0 != err)
|
||||
return err;
|
||||
}
|
||||
buf->vb.state = STATE_PREPARED;
|
||||
buf->vb.state = VIDEOBUF_PREPARED;
|
||||
buf->activate = buffer_activate;
|
||||
|
||||
return 0;
|
||||
@ -335,7 +335,7 @@ static void vbi_stop(struct saa7146_fh *fh, struct file *file)
|
||||
saa7146_write(dev, MC1, MASK_20);
|
||||
|
||||
if (vv->vbi_q.curr) {
|
||||
saa7146_buffer_finish(dev,&vv->vbi_q,STATE_DONE);
|
||||
saa7146_buffer_finish(dev,&vv->vbi_q,VIDEOBUF_DONE);
|
||||
}
|
||||
|
||||
videobuf_queue_cancel(&fh->vbi_q);
|
||||
@ -458,7 +458,7 @@ static void vbi_irq_done(struct saa7146_dev *dev, unsigned long status)
|
||||
/* this must be += 2, one count for each field */
|
||||
vv->vbi_fieldcount+=2;
|
||||
vv->vbi_q.curr->vb.field_count = vv->vbi_fieldcount;
|
||||
saa7146_buffer_finish(dev,&vv->vbi_q,STATE_DONE);
|
||||
saa7146_buffer_finish(dev,&vv->vbi_q,VIDEOBUF_DONE);
|
||||
} else {
|
||||
DEB_VBI(("dev:%p\n",dev));
|
||||
}
|
||||
|
@ -1235,7 +1235,7 @@ static int buffer_activate (struct saa7146_dev *dev,
|
||||
{
|
||||
struct saa7146_vv *vv = dev->vv_data;
|
||||
|
||||
buf->vb.state = STATE_ACTIVE;
|
||||
buf->vb.state = VIDEOBUF_ACTIVE;
|
||||
saa7146_set_capture(dev,buf,next);
|
||||
|
||||
mod_timer(&vv->video_q.timeout, jiffies+BUFFER_TIMEOUT);
|
||||
@ -1281,7 +1281,7 @@ static int buffer_prepare(struct videobuf_queue *q,
|
||||
saa7146_dma_free(dev,q,buf);
|
||||
}
|
||||
|
||||
if (STATE_NEEDS_INIT == buf->vb.state) {
|
||||
if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
|
||||
struct saa7146_format *sfmt;
|
||||
|
||||
buf->vb.bytesperline = fh->video_fmt.bytesperline;
|
||||
@ -1314,7 +1314,7 @@ static int buffer_prepare(struct videobuf_queue *q,
|
||||
if (err)
|
||||
goto oops;
|
||||
}
|
||||
buf->vb.state = STATE_PREPARED;
|
||||
buf->vb.state = VIDEOBUF_PREPARED;
|
||||
buf->activate = buffer_activate;
|
||||
|
||||
return 0;
|
||||
@ -1453,7 +1453,7 @@ static void video_irq_done(struct saa7146_dev *dev, unsigned long st)
|
||||
|
||||
/* only finish the buffer if we have one... */
|
||||
if( NULL != q->curr ) {
|
||||
saa7146_buffer_finish(dev,q,STATE_DONE);
|
||||
saa7146_buffer_finish(dev,q,VIDEOBUF_DONE);
|
||||
}
|
||||
saa7146_buffer_next(dev,q,0);
|
||||
|
||||
|
@ -212,7 +212,6 @@ void flexcop_reset_block_300(struct flexcop_device *fc)
|
||||
|
||||
fc->write_ibi_reg(fc,ctrl_208,v208_save);
|
||||
}
|
||||
EXPORT_SYMBOL(flexcop_reset_block_300);
|
||||
|
||||
struct flexcop_device *flexcop_device_kmalloc(size_t bus_specific_len)
|
||||
{
|
||||
|
@ -378,23 +378,37 @@ bt878_device_control(struct bt878 *bt, unsigned int cmd, union dst_gpio_packet *
|
||||
|
||||
EXPORT_SYMBOL(bt878_device_control);
|
||||
|
||||
#define BROOKTREE_878_DEVICE(vend, dev, name) \
|
||||
{ \
|
||||
.vendor = PCI_VENDOR_ID_BROOKTREE, \
|
||||
.device = PCI_DEVICE_ID_BROOKTREE_878, \
|
||||
.subvendor = (vend), .subdevice = (dev), \
|
||||
.driver_data = (unsigned long) name \
|
||||
}
|
||||
|
||||
static struct cards card_list[] __devinitdata = {
|
||||
|
||||
{ 0x01010071, BTTV_BOARD_NEBULA_DIGITV, "Nebula Electronics DigiTV" },
|
||||
{ 0x07611461, BTTV_BOARD_AVDVBT_761, "AverMedia AverTV DVB-T 761" },
|
||||
{ 0x001c11bd, BTTV_BOARD_PINNACLESAT, "Pinnacle PCTV Sat" },
|
||||
{ 0x002611bd, BTTV_BOARD_TWINHAN_DST, "Pinnacle PCTV SAT CI" },
|
||||
{ 0x00011822, BTTV_BOARD_TWINHAN_DST, "Twinhan VisionPlus DVB" },
|
||||
{ 0xfc00270f, BTTV_BOARD_TWINHAN_DST, "ChainTech digitop DST-1000 DVB-S" },
|
||||
{ 0x07711461, BTTV_BOARD_AVDVBT_771, "AVermedia AverTV DVB-T 771" },
|
||||
{ 0xdb1018ac, BTTV_BOARD_DVICO_DVBT_LITE, "DViCO FusionHDTV DVB-T Lite" },
|
||||
{ 0xdb1118ac, BTTV_BOARD_DVICO_DVBT_LITE, "Ultraview DVB-T Lite" },
|
||||
{ 0xd50018ac, BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE, "DViCO FusionHDTV 5 Lite" },
|
||||
{ 0x20007063, BTTV_BOARD_PC_HDTV, "pcHDTV HD-2000 TV" },
|
||||
{ 0x00261822, BTTV_BOARD_TWINHAN_DST, "DNTV Live! Mini" }
|
||||
static struct pci_device_id bt878_pci_tbl[] __devinitdata = {
|
||||
BROOKTREE_878_DEVICE(0x0071, 0x0101, "Nebula Electronics DigiTV"),
|
||||
BROOKTREE_878_DEVICE(0x1461, 0x0761, "AverMedia AverTV DVB-T 761"),
|
||||
BROOKTREE_878_DEVICE(0x11bd, 0x001c, "Pinnacle PCTV Sat"),
|
||||
BROOKTREE_878_DEVICE(0x11bd, 0x0026, "Pinnacle PCTV SAT CI"),
|
||||
BROOKTREE_878_DEVICE(0x1822, 0x0001, "Twinhan VisionPlus DVB"),
|
||||
BROOKTREE_878_DEVICE(0x270f, 0xfc00,
|
||||
"ChainTech digitop DST-1000 DVB-S"),
|
||||
BROOKTREE_878_DEVICE(0x1461, 0x0771, "AVermedia AverTV DVB-T 771"),
|
||||
BROOKTREE_878_DEVICE(0x18ac, 0xdb10, "DViCO FusionHDTV DVB-T Lite"),
|
||||
BROOKTREE_878_DEVICE(0x18ac, 0xdb11, "Ultraview DVB-T Lite"),
|
||||
BROOKTREE_878_DEVICE(0x18ac, 0xd500, "DViCO FusionHDTV 5 Lite"),
|
||||
BROOKTREE_878_DEVICE(0x7063, 0x2000, "pcHDTV HD-2000 TV"),
|
||||
BROOKTREE_878_DEVICE(0x1822, 0x0026, "DNTV Live! Mini"),
|
||||
{ }
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(pci, bt878_pci_tbl);
|
||||
|
||||
static const char * __devinit card_name(const struct pci_device_id *id)
|
||||
{
|
||||
return id->driver_data ? (const char *)id->driver_data : "Unknown";
|
||||
}
|
||||
|
||||
/***********************/
|
||||
/* PCI device handling */
|
||||
@ -403,15 +417,13 @@ static struct cards card_list[] __devinitdata = {
|
||||
static int __devinit bt878_probe(struct pci_dev *dev,
|
||||
const struct pci_device_id *pci_id)
|
||||
{
|
||||
int result = 0, has_dvb = 0, i;
|
||||
int result = 0;
|
||||
unsigned char lat;
|
||||
struct bt878 *bt;
|
||||
#if defined(__powerpc__)
|
||||
unsigned int cmd;
|
||||
#endif
|
||||
unsigned int cardid;
|
||||
unsigned short id;
|
||||
struct cards *dvb_cards;
|
||||
|
||||
printk(KERN_INFO "bt878: Bt878 AUDIO function found (%d).\n",
|
||||
bt878_num);
|
||||
@ -423,25 +435,11 @@ static int __devinit bt878_probe(struct pci_dev *dev,
|
||||
if (pci_enable_device(dev))
|
||||
return -EIO;
|
||||
|
||||
pci_read_config_word(dev, PCI_SUBSYSTEM_ID, &id);
|
||||
cardid = id << 16;
|
||||
pci_read_config_word(dev, PCI_SUBSYSTEM_VENDOR_ID, &id);
|
||||
cardid |= id;
|
||||
cardid = dev->subsystem_device << 16;
|
||||
cardid |= dev->subsystem_vendor;
|
||||
|
||||
for (i = 0, dvb_cards = card_list; i < ARRAY_SIZE(card_list); i++, dvb_cards++) {
|
||||
if (cardid == dvb_cards->pci_id) {
|
||||
printk("%s: card id=[0x%x],[ %s ] has DVB functions.\n",
|
||||
__func__, cardid, dvb_cards->name);
|
||||
has_dvb = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (!has_dvb) {
|
||||
printk("%s: card id=[0x%x], Unknown card.\nExiting..\n", __func__, cardid);
|
||||
result = -EINVAL;
|
||||
|
||||
goto fail0;
|
||||
}
|
||||
printk(KERN_INFO "%s: card id=[0x%x],[ %s ] has DVB functions.\n",
|
||||
__func__, cardid, card_name(pci_id));
|
||||
|
||||
bt = &bt878[bt878_num];
|
||||
bt->dev = dev;
|
||||
@ -572,14 +570,6 @@ static void __devexit bt878_remove(struct pci_dev *pci_dev)
|
||||
return;
|
||||
}
|
||||
|
||||
static struct pci_device_id bt878_pci_tbl[] __devinitdata = {
|
||||
{PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BROOKTREE_878,
|
||||
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
|
||||
{0,}
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(pci, bt878_pci_tbl);
|
||||
|
||||
static struct pci_driver bt878_pci_driver = {
|
||||
.name = "bt878",
|
||||
.id_table = bt878_pci_tbl,
|
||||
|
@ -101,12 +101,6 @@
|
||||
#define BTTV_BOARD_DVICO_DVBT_LITE 0x80
|
||||
#define BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE 0x87
|
||||
|
||||
struct cards {
|
||||
__u32 pci_id;
|
||||
__u16 card_id;
|
||||
char *name;
|
||||
};
|
||||
|
||||
extern int bt878_num;
|
||||
|
||||
struct bt878 {
|
||||
|
@ -71,6 +71,7 @@ MODULE_PARM_DESC(dst_algo, "tuning algo: default is 0=(SW), 1=(HW)");
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
static int dst_command(struct dst_state *state, u8 *data, u8 len);
|
||||
|
||||
static void dst_packsize(struct dst_state *state, int psize)
|
||||
{
|
||||
@ -80,7 +81,8 @@ static void dst_packsize(struct dst_state *state, int psize)
|
||||
bt878_device_control(state->bt, DST_IG_TS, &bits);
|
||||
}
|
||||
|
||||
int dst_gpio_outb(struct dst_state *state, u32 mask, u32 enbb, u32 outhigh, int delay)
|
||||
static int dst_gpio_outb(struct dst_state *state, u32 mask, u32 enbb,
|
||||
u32 outhigh, int delay)
|
||||
{
|
||||
union dst_gpio_packet enb;
|
||||
union dst_gpio_packet bits;
|
||||
@ -109,9 +111,8 @@ int dst_gpio_outb(struct dst_state *state, u32 mask, u32 enbb, u32 outhigh, int
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(dst_gpio_outb);
|
||||
|
||||
int dst_gpio_inb(struct dst_state *state, u8 *result)
|
||||
static int dst_gpio_inb(struct dst_state *state, u8 *result)
|
||||
{
|
||||
union dst_gpio_packet rd_packet;
|
||||
int err;
|
||||
@ -125,7 +126,6 @@ int dst_gpio_inb(struct dst_state *state, u8 *result)
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(dst_gpio_inb);
|
||||
|
||||
int rdc_reset_state(struct dst_state *state)
|
||||
{
|
||||
@ -145,7 +145,7 @@ int rdc_reset_state(struct dst_state *state)
|
||||
}
|
||||
EXPORT_SYMBOL(rdc_reset_state);
|
||||
|
||||
int rdc_8820_reset(struct dst_state *state)
|
||||
static int rdc_8820_reset(struct dst_state *state)
|
||||
{
|
||||
dprintk(verbose, DST_DEBUG, 1, "Resetting DST");
|
||||
if (dst_gpio_outb(state, RDC_8820_RESET, RDC_8820_RESET, 0, NO_DELAY) < 0) {
|
||||
@ -160,9 +160,8 @@ int rdc_8820_reset(struct dst_state *state)
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(rdc_8820_reset);
|
||||
|
||||
int dst_pio_enable(struct dst_state *state)
|
||||
static int dst_pio_enable(struct dst_state *state)
|
||||
{
|
||||
if (dst_gpio_outb(state, ~0, RDC_8820_PIO_0_ENABLE, 0, NO_DELAY) < 0) {
|
||||
dprintk(verbose, DST_ERROR, 1, "dst_gpio_outb ERROR !");
|
||||
@ -172,7 +171,6 @@ int dst_pio_enable(struct dst_state *state)
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(dst_pio_enable);
|
||||
|
||||
int dst_pio_disable(struct dst_state *state)
|
||||
{
|
||||
@ -611,7 +609,7 @@ static int dst_type_print(struct dst_state *state, u8 type)
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct tuner_types tuner_list[] = {
|
||||
static struct tuner_types tuner_list[] = {
|
||||
{
|
||||
.tuner_type = TUNER_TYPE_L64724,
|
||||
.tuner_name = "L 64724",
|
||||
@ -1224,7 +1222,7 @@ static int dst_probe(struct dst_state *state)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dst_command(struct dst_state *state, u8 *data, u8 len)
|
||||
static int dst_command(struct dst_state *state, u8 *data, u8 len)
|
||||
{
|
||||
u8 reply;
|
||||
|
||||
@ -1287,7 +1285,6 @@ error:
|
||||
return -EIO;
|
||||
|
||||
}
|
||||
EXPORT_SYMBOL(dst_command);
|
||||
|
||||
static int dst_get_signal(struct dst_state *state)
|
||||
{
|
||||
|
@ -165,10 +165,8 @@ struct dst_config
|
||||
};
|
||||
|
||||
int rdc_reset_state(struct dst_state *state);
|
||||
int rdc_8820_reset(struct dst_state *state);
|
||||
|
||||
int dst_wait_dst_ready(struct dst_state *state, u8 delay_mode);
|
||||
int dst_pio_enable(struct dst_state *state);
|
||||
int dst_pio_disable(struct dst_state *state);
|
||||
int dst_error_recovery(struct dst_state* state);
|
||||
int dst_error_bailout(struct dst_state *state);
|
||||
@ -179,9 +177,6 @@ int read_dst(struct dst_state *state, u8 * ret, u8 len);
|
||||
u8 dst_check_sum(u8 * buf, u32 len);
|
||||
struct dst_state* dst_attach(struct dst_state* state, struct dvb_adapter *dvb_adapter);
|
||||
struct dvb_device *dst_ca_attach(struct dst_state *state, struct dvb_adapter *dvb_adapter);
|
||||
int dst_gpio_outb(struct dst_state* state, u32 mask, u32 enbb, u32 outhigh, int delay);
|
||||
|
||||
int dst_command(struct dst_state* state, u8 * data, u8 len);
|
||||
|
||||
|
||||
#endif // DST_COMMON_H
|
||||
|
@ -1202,6 +1202,10 @@ void dvb_frontend_detach(struct dvb_frontend* fe)
|
||||
fe->ops.tuner_ops.release(fe);
|
||||
symbol_put_addr(fe->ops.tuner_ops.release);
|
||||
}
|
||||
if (fe->ops.analog_ops.release) {
|
||||
fe->ops.analog_ops.release(fe);
|
||||
symbol_put_addr(fe->ops.analog_ops.release);
|
||||
}
|
||||
ptr = (void*)fe->ops.release;
|
||||
if (ptr) {
|
||||
fe->ops.release(fe);
|
||||
@ -1215,6 +1219,8 @@ void dvb_frontend_detach(struct dvb_frontend* fe)
|
||||
fe->ops.release_sec(fe);
|
||||
if (fe->ops.tuner_ops.release)
|
||||
fe->ops.tuner_ops.release(fe);
|
||||
if (fe->ops.analog_ops.release)
|
||||
fe->ops.analog_ops.release(fe);
|
||||
if (fe->ops.release)
|
||||
fe->ops.release(fe);
|
||||
}
|
||||
|
@ -84,6 +84,9 @@ struct dvb_tuner_ops {
|
||||
/** This is support for demods like the mt352 - fills out the supplied buffer with what to write. */
|
||||
int (*calc_regs)(struct dvb_frontend *fe, struct dvb_frontend_parameters *p, u8 *buf, int buf_len);
|
||||
|
||||
/** This is to allow setting tuner-specific configs */
|
||||
int (*set_config)(struct dvb_frontend *fe, void *priv_cfg);
|
||||
|
||||
int (*get_frequency)(struct dvb_frontend *fe, u32 *frequency);
|
||||
int (*get_bandwidth)(struct dvb_frontend *fe, u32 *bandwidth);
|
||||
|
||||
@ -98,6 +101,28 @@ struct dvb_tuner_ops {
|
||||
int (*set_bandwidth)(struct dvb_frontend *fe, u32 bandwidth);
|
||||
};
|
||||
|
||||
struct analog_demod_info {
|
||||
char *name;
|
||||
};
|
||||
|
||||
struct analog_demod_ops {
|
||||
|
||||
struct analog_demod_info info;
|
||||
|
||||
void (*set_params)(struct dvb_frontend *fe,
|
||||
struct analog_parameters *params);
|
||||
int (*has_signal)(struct dvb_frontend *fe);
|
||||
int (*is_stereo)(struct dvb_frontend *fe);
|
||||
int (*get_afc)(struct dvb_frontend *fe);
|
||||
void (*tuner_status)(struct dvb_frontend *fe);
|
||||
void (*standby)(struct dvb_frontend *fe);
|
||||
void (*release)(struct dvb_frontend *fe);
|
||||
int (*i2c_gate_ctrl)(struct dvb_frontend *fe, int enable);
|
||||
|
||||
/** This is to allow setting tuner-specific configuration */
|
||||
int (*set_config)(struct dvb_frontend *fe, void *priv_cfg);
|
||||
};
|
||||
|
||||
struct dvb_frontend_ops {
|
||||
|
||||
struct dvb_frontend_info info;
|
||||
@ -143,6 +168,7 @@ struct dvb_frontend_ops {
|
||||
int (*ts_bus_ctrl)(struct dvb_frontend* fe, int acquire);
|
||||
|
||||
struct dvb_tuner_ops tuner_ops;
|
||||
struct analog_demod_ops analog_ops;
|
||||
};
|
||||
|
||||
#define MAX_EVENT 8
|
||||
@ -159,18 +185,19 @@ struct dvb_fe_events {
|
||||
struct dvb_frontend {
|
||||
struct dvb_frontend_ops ops;
|
||||
struct dvb_adapter *dvb;
|
||||
void* demodulator_priv;
|
||||
void* tuner_priv;
|
||||
void* frontend_priv;
|
||||
void* sec_priv;
|
||||
void *demodulator_priv;
|
||||
void *tuner_priv;
|
||||
void *frontend_priv;
|
||||
void *sec_priv;
|
||||
void *analog_demod_priv;
|
||||
};
|
||||
|
||||
extern int dvb_register_frontend(struct dvb_adapter* dvb,
|
||||
struct dvb_frontend* fe);
|
||||
extern int dvb_register_frontend(struct dvb_adapter *dvb,
|
||||
struct dvb_frontend *fe);
|
||||
|
||||
extern int dvb_unregister_frontend(struct dvb_frontend* fe);
|
||||
extern int dvb_unregister_frontend(struct dvb_frontend *fe);
|
||||
|
||||
extern void dvb_frontend_detach(struct dvb_frontend* fe);
|
||||
extern void dvb_frontend_detach(struct dvb_frontend *fe);
|
||||
|
||||
extern void dvb_frontend_reinitialise(struct dvb_frontend *fe);
|
||||
|
||||
|
@ -261,11 +261,6 @@ EXPORT_SYMBOL(dvb_ringbuffer_init);
|
||||
EXPORT_SYMBOL(dvb_ringbuffer_empty);
|
||||
EXPORT_SYMBOL(dvb_ringbuffer_free);
|
||||
EXPORT_SYMBOL(dvb_ringbuffer_avail);
|
||||
EXPORT_SYMBOL(dvb_ringbuffer_flush);
|
||||
EXPORT_SYMBOL(dvb_ringbuffer_flush_spinlock_wakeup);
|
||||
EXPORT_SYMBOL(dvb_ringbuffer_read);
|
||||
EXPORT_SYMBOL(dvb_ringbuffer_write);
|
||||
EXPORT_SYMBOL(dvb_ringbuffer_pkt_write);
|
||||
EXPORT_SYMBOL(dvb_ringbuffer_pkt_read);
|
||||
EXPORT_SYMBOL(dvb_ringbuffer_pkt_dispose);
|
||||
EXPORT_SYMBOL(dvb_ringbuffer_pkt_next);
|
||||
|
@ -1026,6 +1026,7 @@ static int af9005_usb_probe(struct usb_interface *intf,
|
||||
static struct usb_device_id af9005_usb_table[] = {
|
||||
{USB_DEVICE(USB_VID_AFATECH, USB_PID_AFATECH_AF9005)},
|
||||
{USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_USB_XE)},
|
||||
{USB_DEVICE(USB_VID_ANSONIC, USB_PID_ANSONIC_DVBT_USB)},
|
||||
{0},
|
||||
};
|
||||
|
||||
@ -1075,7 +1076,7 @@ static struct dvb_usb_device_properties af9005_properties = {
|
||||
.rc_key_map_size = 0,
|
||||
.rc_query = af9005_rc_query,
|
||||
|
||||
.num_device_descs = 2,
|
||||
.num_device_descs = 3,
|
||||
.devices = {
|
||||
{.name = "Afatech DVB-T USB1.1 stick",
|
||||
.cold_ids = {&af9005_usb_table[0], NULL},
|
||||
@ -1085,6 +1086,10 @@ static struct dvb_usb_device_properties af9005_properties = {
|
||||
.cold_ids = {&af9005_usb_table[1], NULL},
|
||||
.warm_ids = {NULL},
|
||||
},
|
||||
{.name = "Ansonic DVB-T USB1.1 stick",
|
||||
.cold_ids = {&af9005_usb_table[2], NULL},
|
||||
.warm_ids = {NULL},
|
||||
},
|
||||
{NULL},
|
||||
}
|
||||
};
|
||||
|
@ -79,12 +79,12 @@ static int au6610_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
|
||||
struct dvb_usb_device *d = i2c_get_adapdata(adap);
|
||||
int i;
|
||||
|
||||
if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
|
||||
return -EAGAIN;
|
||||
|
||||
if (num > 2)
|
||||
return -EINVAL;
|
||||
|
||||
if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
|
||||
return -EAGAIN;
|
||||
|
||||
for (i = 0; i < num; i++) {
|
||||
/* write/read request */
|
||||
if (i+1 < num && (msg[i+1].flags & I2C_M_RD)) {
|
||||
|
@ -15,7 +15,7 @@
|
||||
*
|
||||
* Copyright (C) 2005 Patrick Boettcher (patrick.boettcher@desy.de)
|
||||
* Copyright (C) 2006 Michael Krufky (mkrufky@linuxtv.org)
|
||||
* Copyright (C) 2006 Chris Pascoe (c.pascoe@itee.uq.edu.au)
|
||||
* Copyright (C) 2006, 2007 Chris Pascoe (c.pascoe@itee.uq.edu.au)
|
||||
*
|
||||
* 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
|
||||
@ -30,11 +30,16 @@
|
||||
#include "mt352.h"
|
||||
#include "mt352_priv.h"
|
||||
#include "zl10353.h"
|
||||
#include "tuner-xc2028.h"
|
||||
#include "tuner-xc2028-types.h"
|
||||
|
||||
/* debug */
|
||||
int dvb_usb_cxusb_debug;
|
||||
static int dvb_usb_cxusb_debug;
|
||||
module_param_named(debug, dvb_usb_cxusb_debug, int, 0644);
|
||||
MODULE_PARM_DESC(debug, "set debugging level (1=rc (or-able))." DVB_USB_DEBUG_STATUS);
|
||||
#define deb_info(args...) dprintk(dvb_usb_cxusb_debug,0x01,args)
|
||||
#define deb_i2c(args...) if (d->udev->descriptor.idVendor == USB_VID_MEDION) \
|
||||
dprintk(dvb_usb_cxusb_debug,0x01,args)
|
||||
|
||||
static int cxusb_ctrl_msg(struct dvb_usb_device *d,
|
||||
u8 cmd, u8 *wbuf, int wlen, u8 *rbuf, int rlen)
|
||||
@ -46,11 +51,9 @@ static int cxusb_ctrl_msg(struct dvb_usb_device *d,
|
||||
sndbuf[0] = cmd;
|
||||
memcpy(&sndbuf[1], wbuf, wlen);
|
||||
if (wo)
|
||||
dvb_usb_generic_write(d, sndbuf, 1+wlen);
|
||||
return dvb_usb_generic_write(d, sndbuf, 1+wlen);
|
||||
else
|
||||
dvb_usb_generic_rw(d, sndbuf, 1+wlen, rbuf, rlen, 0);
|
||||
|
||||
return 0;
|
||||
return dvb_usb_generic_rw(d, sndbuf, 1+wlen, rbuf, rlen, 0);
|
||||
}
|
||||
|
||||
/* GPIO */
|
||||
@ -72,6 +75,34 @@ static void cxusb_gpio_tuner(struct dvb_usb_device *d, int onoff)
|
||||
st->gpio_write_state[GPIO_TUNER] = onoff;
|
||||
}
|
||||
|
||||
static int cxusb_bluebird_gpio_rw(struct dvb_usb_device *d, u8 changemask,
|
||||
u8 newval)
|
||||
{
|
||||
u8 o[2], gpio_state;
|
||||
int rc;
|
||||
|
||||
o[0] = 0xff & ~changemask; /* mask of bits to keep */
|
||||
o[1] = newval & changemask; /* new values for bits */
|
||||
|
||||
rc = cxusb_ctrl_msg(d, CMD_BLUEBIRD_GPIO_RW, o, 2, &gpio_state, 1);
|
||||
if (rc < 0 || (gpio_state & changemask) != (newval & changemask))
|
||||
deb_info("bluebird_gpio_write failed.\n");
|
||||
|
||||
return rc < 0 ? rc : gpio_state;
|
||||
}
|
||||
|
||||
static void cxusb_bluebird_gpio_pulse(struct dvb_usb_device *d, u8 pin, int low)
|
||||
{
|
||||
cxusb_bluebird_gpio_rw(d, pin, low ? 0 : pin);
|
||||
msleep(5);
|
||||
cxusb_bluebird_gpio_rw(d, pin, low ? pin : 0);
|
||||
}
|
||||
|
||||
static void cxusb_nano2_led(struct dvb_usb_device *d, int onoff)
|
||||
{
|
||||
cxusb_bluebird_gpio_rw(d, 0x40, onoff ? 0 : 0x40);
|
||||
}
|
||||
|
||||
/* I2C */
|
||||
static int cxusb_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
|
||||
int num)
|
||||
@ -82,9 +113,6 @@ static int cxusb_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
|
||||
if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
|
||||
return -EAGAIN;
|
||||
|
||||
if (num > 2)
|
||||
warn("more than two i2c messages at a time is not handled yet. TODO.");
|
||||
|
||||
for (i = 0; i < num; i++) {
|
||||
|
||||
if (d->udev->descriptor.idVendor == USB_VID_MEDION)
|
||||
@ -97,8 +125,22 @@ static int cxusb_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
|
||||
break;
|
||||
}
|
||||
|
||||
/* read request */
|
||||
if (i+1 < num && (msg[i+1].flags & I2C_M_RD)) {
|
||||
if (msg[i].flags & I2C_M_RD) {
|
||||
/* read only */
|
||||
u8 obuf[3], ibuf[1+msg[i].len];
|
||||
obuf[0] = 0;
|
||||
obuf[1] = msg[i].len;
|
||||
obuf[2] = msg[i].addr;
|
||||
if (cxusb_ctrl_msg(d, CMD_I2C_READ,
|
||||
obuf, 3,
|
||||
ibuf, 1+msg[i].len) < 0) {
|
||||
warn("i2c read failed");
|
||||
break;
|
||||
}
|
||||
memcpy(msg[i].buf, &ibuf[1], msg[i].len);
|
||||
} else if (i+1 < num && (msg[i+1].flags & I2C_M_RD) &&
|
||||
msg[i].addr == msg[i+1].addr) {
|
||||
/* write to then read from same address */
|
||||
u8 obuf[3+msg[i].len], ibuf[1+msg[i+1].len];
|
||||
obuf[0] = msg[i].len;
|
||||
obuf[1] = msg[i+1].len;
|
||||
@ -116,7 +158,8 @@ static int cxusb_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
|
||||
memcpy(msg[i+1].buf, &ibuf[1], msg[i+1].len);
|
||||
|
||||
i++;
|
||||
} else { /* write */
|
||||
} else {
|
||||
/* write only */
|
||||
u8 obuf[2+msg[i].len], ibuf;
|
||||
obuf[0] = msg[i].addr;
|
||||
obuf[1] = msg[i].len;
|
||||
@ -131,7 +174,7 @@ static int cxusb_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
|
||||
}
|
||||
|
||||
mutex_unlock(&d->i2c_mutex);
|
||||
return i;
|
||||
return i == num ? num : -EREMOTEIO;
|
||||
}
|
||||
|
||||
static u32 cxusb_i2c_func(struct i2c_adapter *adapter)
|
||||
@ -162,6 +205,17 @@ static int cxusb_bluebird_power_ctrl(struct dvb_usb_device *d, int onoff)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cxusb_nano2_power_ctrl(struct dvb_usb_device *d, int onoff)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
rc = cxusb_power_ctrl(d, onoff);
|
||||
if (!onoff)
|
||||
cxusb_nano2_led(d, 0);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int cxusb_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
|
||||
{
|
||||
u8 buf[2] = { 0x03, 0x00 };
|
||||
@ -197,6 +251,34 @@ static int cxusb_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cxusb_bluebird2_rc_query(struct dvb_usb_device *d, u32 *event,
|
||||
int *state)
|
||||
{
|
||||
struct dvb_usb_rc_key *keymap = d->props.rc_key_map;
|
||||
u8 ircode[4];
|
||||
int i;
|
||||
struct i2c_msg msg = { .addr = 0x6b, .flags = I2C_M_RD,
|
||||
.buf = ircode, .len = 4 };
|
||||
|
||||
*event = 0;
|
||||
*state = REMOTE_NO_KEY_PRESSED;
|
||||
|
||||
if (cxusb_i2c_xfer(&d->i2c_adap, &msg, 1) != 1)
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < d->props.rc_key_map_size; i++) {
|
||||
if (keymap[i].custom == ircode[1] &&
|
||||
keymap[i].data == ircode[2]) {
|
||||
*event = keymap[i].event;
|
||||
*state = REMOTE_KEY_PRESSED;
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct dvb_usb_rc_key dvico_mce_rc_keys[] = {
|
||||
{ 0xfe, 0x02, KEY_TV },
|
||||
{ 0xfe, 0x0e, KEY_MP3 },
|
||||
@ -351,6 +433,20 @@ static struct mt352_config cxusb_mt352_config = {
|
||||
.demod_init = cxusb_mt352_demod_init,
|
||||
};
|
||||
|
||||
static struct zl10353_config cxusb_zl10353_xc3028_config = {
|
||||
.demod_address = 0x0f,
|
||||
.if2 = 45600,
|
||||
.no_tuner = 1,
|
||||
.parallel_ts = 1,
|
||||
};
|
||||
|
||||
static struct mt352_config cxusb_mt352_xc3028_config = {
|
||||
.demod_address = 0x0f,
|
||||
.if2 = 4560,
|
||||
.no_tuner = 1,
|
||||
.demod_init = cxusb_mt352_demod_init,
|
||||
};
|
||||
|
||||
/* Callbacks for DVB USB */
|
||||
static int cxusb_fmd1216me_tuner_attach(struct dvb_usb_adapter *adap)
|
||||
{
|
||||
@ -386,6 +482,51 @@ static int cxusb_lgh064f_tuner_attach(struct dvb_usb_adapter *adap)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dvico_bluebird_xc2028_callback(void *ptr, int command, int arg)
|
||||
{
|
||||
struct dvb_usb_device *d = ptr;
|
||||
|
||||
switch (command) {
|
||||
case XC2028_TUNER_RESET:
|
||||
deb_info("%s: XC2028_TUNER_RESET %d\n", __FUNCTION__, arg);
|
||||
cxusb_bluebird_gpio_pulse(d, 0x01, 1);
|
||||
break;
|
||||
case XC2028_RESET_CLK:
|
||||
deb_info("%s: XC2028_RESET_CLK %d\n", __FUNCTION__, arg);
|
||||
break;
|
||||
default:
|
||||
deb_info("%s: unknown command %d, arg %d\n", __FUNCTION__,
|
||||
command, arg);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cxusb_dvico_xc3028_tuner_attach(struct dvb_usb_adapter *adap)
|
||||
{
|
||||
struct dvb_frontend *fe;
|
||||
struct xc2028_config cfg = {
|
||||
.i2c_adap = &adap->dev->i2c_adap,
|
||||
.i2c_addr = 0x61,
|
||||
.video_dev = adap->dev,
|
||||
.callback = dvico_bluebird_xc2028_callback,
|
||||
};
|
||||
static struct xc2028_ctrl ctl = {
|
||||
.fname = "xc3028-dvico-au-01.fw",
|
||||
.max_len = 64,
|
||||
.scode_table = ZARLINK456,
|
||||
};
|
||||
|
||||
fe = dvb_attach(xc2028_attach, adap->fe, &cfg);
|
||||
if (fe == NULL || fe->ops.tuner_ops.set_config == NULL)
|
||||
return -EIO;
|
||||
|
||||
fe->ops.tuner_ops.set_config(fe, &ctl);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cxusb_cx22702_frontend_attach(struct dvb_usb_adapter *adap)
|
||||
{
|
||||
u8 b;
|
||||
@ -447,28 +588,121 @@ static int cxusb_dee1601_frontend_attach(struct dvb_usb_adapter *adap)
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
static int cxusb_dualdig4_frontend_attach(struct dvb_usb_adapter *adap)
|
||||
{
|
||||
u8 ircode[4];
|
||||
int i;
|
||||
struct i2c_msg msg = { .addr = 0x6b, .flags = I2C_M_RD,
|
||||
.buf = ircode, .len = 4 };
|
||||
|
||||
if (usb_set_interface(adap->dev->udev, 0, 1) < 0)
|
||||
err("set interface failed");
|
||||
|
||||
cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0);
|
||||
|
||||
/* reset the tuner and demodulator */
|
||||
cxusb_bluebird_gpio_rw(adap->dev, 0x04, 0);
|
||||
cxusb_bluebird_gpio_pulse(adap->dev, 0x01, 1);
|
||||
cxusb_bluebird_gpio_pulse(adap->dev, 0x02, 1);
|
||||
|
||||
if ((adap->fe = dvb_attach(zl10353_attach,
|
||||
&cxusb_zl10353_xc3028_config,
|
||||
&adap->dev->i2c_adap)) == NULL)
|
||||
return -EIO;
|
||||
|
||||
/* try to determine if there is no IR decoder on the I2C bus */
|
||||
for (i = 0; adap->dev->props.rc_key_map != NULL && i < 5; i++) {
|
||||
msleep(20);
|
||||
if (cxusb_i2c_xfer(&adap->dev->i2c_adap, &msg, 1) != 1)
|
||||
goto no_IR;
|
||||
if (ircode[0] == 0 && ircode[1] == 0)
|
||||
continue;
|
||||
if (ircode[2] + ircode[3] != 0xff) {
|
||||
no_IR:
|
||||
adap->dev->props.rc_key_map = NULL;
|
||||
info("No IR receiver detected on this device.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cxusb_nano2_frontend_attach(struct dvb_usb_adapter *adap)
|
||||
{
|
||||
if (usb_set_interface(adap->dev->udev, 0, 1) < 0)
|
||||
err("set interface failed");
|
||||
|
||||
cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0);
|
||||
|
||||
/* reset the tuner and demodulator */
|
||||
cxusb_bluebird_gpio_rw(adap->dev, 0x04, 0);
|
||||
cxusb_bluebird_gpio_pulse(adap->dev, 0x01, 1);
|
||||
cxusb_bluebird_gpio_pulse(adap->dev, 0x02, 1);
|
||||
|
||||
if ((adap->fe = dvb_attach(zl10353_attach,
|
||||
&cxusb_zl10353_xc3028_config,
|
||||
&adap->dev->i2c_adap)) != NULL)
|
||||
return 0;
|
||||
|
||||
if ((adap->fe = dvb_attach(mt352_attach,
|
||||
&cxusb_mt352_xc3028_config,
|
||||
&adap->dev->i2c_adap)) != NULL)
|
||||
return 0;
|
||||
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
/*
|
||||
* DViCO has shipped two devices with the same USB ID, but only one of them
|
||||
* needs a firmware download. Check the device class details to see if they
|
||||
* have non-default values to decide whether the device is actually cold or
|
||||
* not, and forget a match if it turns out we selected the wrong device.
|
||||
*/
|
||||
static int bluebird_fx2_identify_state(struct usb_device *udev,
|
||||
struct dvb_usb_device_properties *props,
|
||||
struct dvb_usb_device_description **desc,
|
||||
int *cold)
|
||||
{
|
||||
int wascold = *cold;
|
||||
|
||||
*cold = udev->descriptor.bDeviceClass == 0xff &&
|
||||
udev->descriptor.bDeviceSubClass == 0xff &&
|
||||
udev->descriptor.bDeviceProtocol == 0xff;
|
||||
|
||||
if (*cold && !wascold)
|
||||
*desc = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* DViCO bluebird firmware needs the "warm" product ID to be patched into the
|
||||
* firmware file before download.
|
||||
*/
|
||||
|
||||
#define BLUEBIRD_01_ID_OFFSET 6638
|
||||
static const int dvico_firmware_id_offsets[] = { 6638, 3204 };
|
||||
static int bluebird_patch_dvico_firmware_download(struct usb_device *udev,
|
||||
const struct firmware *fw)
|
||||
{
|
||||
if (fw->size < BLUEBIRD_01_ID_OFFSET + 4)
|
||||
return -EINVAL;
|
||||
int pos;
|
||||
|
||||
if (fw->data[BLUEBIRD_01_ID_OFFSET] == (USB_VID_DVICO & 0xff) &&
|
||||
fw->data[BLUEBIRD_01_ID_OFFSET + 1] == USB_VID_DVICO >> 8) {
|
||||
for (pos = 0; pos < ARRAY_SIZE(dvico_firmware_id_offsets); pos++) {
|
||||
int idoff = dvico_firmware_id_offsets[pos];
|
||||
|
||||
fw->data[BLUEBIRD_01_ID_OFFSET + 2] =
|
||||
if (fw->size < idoff + 4)
|
||||
continue;
|
||||
|
||||
if (fw->data[idoff] == (USB_VID_DVICO & 0xff) &&
|
||||
fw->data[idoff + 1] == USB_VID_DVICO >> 8) {
|
||||
fw->data[idoff + 2] =
|
||||
le16_to_cpu(udev->descriptor.idProduct) + 1;
|
||||
fw->data[BLUEBIRD_01_ID_OFFSET + 3] =
|
||||
fw->data[idoff + 3] =
|
||||
le16_to_cpu(udev->descriptor.idProduct) >> 8;
|
||||
|
||||
return usb_cypress_load_firmware(udev, fw, CYPRESS_FX2);
|
||||
}
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -479,6 +713,9 @@ static struct dvb_usb_device_properties cxusb_bluebird_lgh064f_properties;
|
||||
static struct dvb_usb_device_properties cxusb_bluebird_dee1601_properties;
|
||||
static struct dvb_usb_device_properties cxusb_bluebird_lgz201_properties;
|
||||
static struct dvb_usb_device_properties cxusb_bluebird_dtt7579_properties;
|
||||
static struct dvb_usb_device_properties cxusb_bluebird_dualdig4_properties;
|
||||
static struct dvb_usb_device_properties cxusb_bluebird_nano2_properties;
|
||||
static struct dvb_usb_device_properties cxusb_bluebird_nano2_needsfirmware_properties;
|
||||
|
||||
static int cxusb_probe(struct usb_interface *intf,
|
||||
const struct usb_device_id *id)
|
||||
@ -487,7 +724,10 @@ static int cxusb_probe(struct usb_interface *intf,
|
||||
dvb_usb_device_init(intf,&cxusb_bluebird_lgh064f_properties,THIS_MODULE,NULL) == 0 ||
|
||||
dvb_usb_device_init(intf,&cxusb_bluebird_dee1601_properties,THIS_MODULE,NULL) == 0 ||
|
||||
dvb_usb_device_init(intf,&cxusb_bluebird_lgz201_properties,THIS_MODULE,NULL) == 0 ||
|
||||
dvb_usb_device_init(intf,&cxusb_bluebird_dtt7579_properties,THIS_MODULE,NULL) == 0) {
|
||||
dvb_usb_device_init(intf,&cxusb_bluebird_dtt7579_properties,THIS_MODULE,NULL) == 0 ||
|
||||
dvb_usb_device_init(intf,&cxusb_bluebird_dualdig4_properties,THIS_MODULE,NULL) == 0 ||
|
||||
dvb_usb_device_init(intf,&cxusb_bluebird_nano2_properties,THIS_MODULE,NULL) == 0 ||
|
||||
dvb_usb_device_init(intf,&cxusb_bluebird_nano2_needsfirmware_properties,THIS_MODULE,NULL) == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -508,6 +748,9 @@ static struct usb_device_id cxusb_table [] = {
|
||||
{ USB_DEVICE(USB_VID_DVICO, USB_PID_DIGITALNOW_BLUEBIRD_DUAL_1_WARM) },
|
||||
{ USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_2_COLD) },
|
||||
{ USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_2_WARM) },
|
||||
{ USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_4) },
|
||||
{ USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DVB_T_NANO_2) },
|
||||
{ USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DVB_T_NANO_2_NFW_WARM) },
|
||||
{} /* Terminating entry */
|
||||
};
|
||||
MODULE_DEVICE_TABLE (usb, cxusb_table);
|
||||
@ -766,6 +1009,151 @@ static struct dvb_usb_device_properties cxusb_bluebird_dtt7579_properties = {
|
||||
}
|
||||
};
|
||||
|
||||
static struct dvb_usb_device_properties cxusb_bluebird_dualdig4_properties = {
|
||||
.caps = DVB_USB_IS_AN_I2C_ADAPTER,
|
||||
|
||||
.usb_ctrl = CYPRESS_FX2,
|
||||
|
||||
.size_of_priv = sizeof(struct cxusb_state),
|
||||
|
||||
.num_adapters = 1,
|
||||
.adapter = {
|
||||
{
|
||||
.streaming_ctrl = cxusb_streaming_ctrl,
|
||||
.frontend_attach = cxusb_dualdig4_frontend_attach,
|
||||
.tuner_attach = cxusb_dvico_xc3028_tuner_attach,
|
||||
/* parameter for the MPEG2-data transfer */
|
||||
.stream = {
|
||||
.type = USB_BULK,
|
||||
.count = 5,
|
||||
.endpoint = 0x02,
|
||||
.u = {
|
||||
.bulk = {
|
||||
.buffersize = 8192,
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
.power_ctrl = cxusb_power_ctrl,
|
||||
|
||||
.i2c_algo = &cxusb_i2c_algo,
|
||||
|
||||
.generic_bulk_ctrl_endpoint = 0x01,
|
||||
|
||||
.rc_interval = 100,
|
||||
.rc_key_map = dvico_mce_rc_keys,
|
||||
.rc_key_map_size = ARRAY_SIZE(dvico_mce_rc_keys),
|
||||
.rc_query = cxusb_bluebird2_rc_query,
|
||||
|
||||
.num_device_descs = 1,
|
||||
.devices = {
|
||||
{ "DViCO FusionHDTV DVB-T Dual Digital 4",
|
||||
{ NULL },
|
||||
{ &cxusb_table[13], NULL },
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
static struct dvb_usb_device_properties cxusb_bluebird_nano2_properties = {
|
||||
.caps = DVB_USB_IS_AN_I2C_ADAPTER,
|
||||
|
||||
.usb_ctrl = CYPRESS_FX2,
|
||||
.identify_state = bluebird_fx2_identify_state,
|
||||
|
||||
.size_of_priv = sizeof(struct cxusb_state),
|
||||
|
||||
.num_adapters = 1,
|
||||
.adapter = {
|
||||
{
|
||||
.streaming_ctrl = cxusb_streaming_ctrl,
|
||||
.frontend_attach = cxusb_nano2_frontend_attach,
|
||||
.tuner_attach = cxusb_dvico_xc3028_tuner_attach,
|
||||
/* parameter for the MPEG2-data transfer */
|
||||
.stream = {
|
||||
.type = USB_BULK,
|
||||
.count = 5,
|
||||
.endpoint = 0x02,
|
||||
.u = {
|
||||
.bulk = {
|
||||
.buffersize = 8192,
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
.power_ctrl = cxusb_nano2_power_ctrl,
|
||||
|
||||
.i2c_algo = &cxusb_i2c_algo,
|
||||
|
||||
.generic_bulk_ctrl_endpoint = 0x01,
|
||||
|
||||
.rc_interval = 100,
|
||||
.rc_key_map = dvico_portable_rc_keys,
|
||||
.rc_key_map_size = ARRAY_SIZE(dvico_portable_rc_keys),
|
||||
.rc_query = cxusb_bluebird2_rc_query,
|
||||
|
||||
.num_device_descs = 1,
|
||||
.devices = {
|
||||
{ "DViCO FusionHDTV DVB-T NANO2",
|
||||
{ NULL },
|
||||
{ &cxusb_table[14], NULL },
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
static struct dvb_usb_device_properties cxusb_bluebird_nano2_needsfirmware_properties = {
|
||||
.caps = DVB_USB_IS_AN_I2C_ADAPTER,
|
||||
|
||||
.usb_ctrl = DEVICE_SPECIFIC,
|
||||
.firmware = "dvb-usb-bluebird-02.fw",
|
||||
.download_firmware = bluebird_patch_dvico_firmware_download,
|
||||
.identify_state = bluebird_fx2_identify_state,
|
||||
|
||||
.size_of_priv = sizeof(struct cxusb_state),
|
||||
|
||||
.num_adapters = 1,
|
||||
.adapter = {
|
||||
{
|
||||
.streaming_ctrl = cxusb_streaming_ctrl,
|
||||
.frontend_attach = cxusb_nano2_frontend_attach,
|
||||
.tuner_attach = cxusb_dvico_xc3028_tuner_attach,
|
||||
/* parameter for the MPEG2-data transfer */
|
||||
.stream = {
|
||||
.type = USB_BULK,
|
||||
.count = 5,
|
||||
.endpoint = 0x02,
|
||||
.u = {
|
||||
.bulk = {
|
||||
.buffersize = 8192,
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
.power_ctrl = cxusb_nano2_power_ctrl,
|
||||
|
||||
.i2c_algo = &cxusb_i2c_algo,
|
||||
|
||||
.generic_bulk_ctrl_endpoint = 0x01,
|
||||
|
||||
.rc_interval = 100,
|
||||
.rc_key_map = dvico_portable_rc_keys,
|
||||
.rc_key_map_size = ARRAY_SIZE(dvico_portable_rc_keys),
|
||||
.rc_query = cxusb_rc_query,
|
||||
|
||||
.num_device_descs = 1,
|
||||
.devices = {
|
||||
{ "DViCO FusionHDTV DVB-T NANO2 w/o firmware",
|
||||
{ &cxusb_table[14], NULL },
|
||||
{ &cxusb_table[15], NULL },
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
static struct usb_driver cxusb_driver = {
|
||||
.name = "dvb_usb_cxusb",
|
||||
.probe = cxusb_probe,
|
||||
|
@ -4,12 +4,9 @@
|
||||
#define DVB_USB_LOG_PREFIX "cxusb"
|
||||
#include "dvb-usb.h"
|
||||
|
||||
extern int dvb_usb_cxusb_debug;
|
||||
#define deb_info(args...) dprintk(dvb_usb_cxusb_debug,0x01,args)
|
||||
#define deb_i2c(args...) if (d->udev->descriptor.idVendor == USB_VID_MEDION) \
|
||||
dprintk(dvb_usb_cxusb_debug,0x01,args)
|
||||
|
||||
/* usb commands - some of it are guesses, don't have a reference yet */
|
||||
#define CMD_BLUEBIRD_GPIO_RW 0x05
|
||||
|
||||
#define CMD_I2C_WRITE 0x08
|
||||
#define CMD_I2C_READ 0x09
|
||||
|
||||
|
@ -243,7 +243,7 @@ int dib0700_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
|
||||
u8 b[4];
|
||||
|
||||
b[0] = REQUEST_ENABLE_VIDEO;
|
||||
b[1] = 0x00;
|
||||
b[1] = (onoff << 4) | 0x00; /* this bit gives a kind of command, rather than enabling something or not */
|
||||
b[2] = (0x01 << 4); /* Master mode */
|
||||
b[3] = 0x00;
|
||||
|
||||
@ -256,9 +256,6 @@ int dib0700_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
|
||||
|
||||
b[2] |= st->channel_state;
|
||||
|
||||
if (st->channel_state) /* if at least one channel is active */
|
||||
b[1] = (0x01 << 4) | 0x00;
|
||||
|
||||
deb_info("data for streaming: %x %x\n",b[1],b[2]);
|
||||
|
||||
return dib0700_ctrl_wr(adap->dev, b, 4);
|
||||
|
@ -94,12 +94,28 @@ static int bristol_frontend_attach(struct dvb_usb_adapter *adap)
|
||||
(10 + adap->id) << 1, &bristol_dib3000mc_config[adap->id])) == NULL ? -ENODEV : 0;
|
||||
}
|
||||
|
||||
static int eeprom_read(struct i2c_adapter *adap,u8 adrs,u8 *pval)
|
||||
{
|
||||
struct i2c_msg msg[2] = {
|
||||
{ .addr = 0x50, .flags = 0, .buf = &adrs, .len = 1 },
|
||||
{ .addr = 0x50, .flags = I2C_M_RD, .buf = pval, .len = 1 },
|
||||
};
|
||||
if (i2c_transfer(adap, msg, 2) != 2) return -EREMOTEIO;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bristol_tuner_attach(struct dvb_usb_adapter *adap)
|
||||
{
|
||||
struct dib0700_state *st = adap->dev->priv;
|
||||
struct i2c_adapter *prim_i2c = &adap->dev->i2c_adap;
|
||||
struct i2c_adapter *tun_i2c = dib3000mc_get_tuner_i2c_master(adap->fe, 1);
|
||||
return dvb_attach(mt2060_attach,adap->fe, tun_i2c, &bristol_mt2060_config[adap->id],
|
||||
st->mt2060_if1[adap->id]) == NULL ? -ENODEV : 0;
|
||||
s8 a;
|
||||
int if1=1220;
|
||||
if (adap->dev->udev->descriptor.idVendor == USB_VID_HAUPPAUGE &&
|
||||
adap->dev->udev->descriptor.idProduct == USB_PID_HAUPPAUGE_NOVA_T_500_2) {
|
||||
if (!eeprom_read(prim_i2c,0x59 + adap->id,&a)) if1=1220+a;
|
||||
}
|
||||
return dvb_attach(mt2060_attach,adap->fe, tun_i2c,&bristol_mt2060_config[adap->id],
|
||||
if1) == NULL ? -ENODEV : 0;
|
||||
}
|
||||
|
||||
/* STK7700D: Pinnacle/Terratec/Hauppauge Dual DVB-T Diversity */
|
||||
@ -230,6 +246,27 @@ static struct mt2266_config stk7700d_mt2266_config[2] = {
|
||||
}
|
||||
};
|
||||
|
||||
static int stk7700P2_frontend_attach(struct dvb_usb_adapter *adap)
|
||||
{
|
||||
if (adap->id == 0) {
|
||||
dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
|
||||
msleep(10);
|
||||
dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
|
||||
dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
|
||||
dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
|
||||
dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
|
||||
msleep(10);
|
||||
dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
|
||||
msleep(10);
|
||||
dib7000p_i2c_enumeration(&adap->dev->i2c_adap,1,18,stk7700d_dib7000p_mt2266_config);
|
||||
}
|
||||
|
||||
adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap,0x80+(adap->id << 1),
|
||||
&stk7700d_dib7000p_mt2266_config[adap->id]);
|
||||
|
||||
return adap->fe == NULL ? -ENODEV : 0;
|
||||
}
|
||||
|
||||
static int stk7700d_frontend_attach(struct dvb_usb_adapter *adap)
|
||||
{
|
||||
if (adap->id == 0) {
|
||||
@ -415,6 +452,35 @@ static struct dvb_usb_rc_key dib0700_rc_keys[] = {
|
||||
{ 0x1e, 0x38, KEY_YELLOW },
|
||||
{ 0x1e, 0x3b, KEY_GOTO },
|
||||
{ 0x1e, 0x3d, KEY_POWER },
|
||||
|
||||
/* Key codes for the Leadtek Winfast DTV Dongle */
|
||||
{ 0x00, 0x42, KEY_POWER },
|
||||
{ 0x07, 0x7c, KEY_TUNER },
|
||||
{ 0x0f, 0x4e, KEY_PRINT }, /* PREVIEW */
|
||||
{ 0x08, 0x40, KEY_SCREEN }, /* full screen toggle*/
|
||||
{ 0x0f, 0x71, KEY_DOT }, /* frequency */
|
||||
{ 0x07, 0x43, KEY_0 },
|
||||
{ 0x0c, 0x41, KEY_1 },
|
||||
{ 0x04, 0x43, KEY_2 },
|
||||
{ 0x0b, 0x7f, KEY_3 },
|
||||
{ 0x0e, 0x41, KEY_4 },
|
||||
{ 0x06, 0x43, KEY_5 },
|
||||
{ 0x09, 0x7f, KEY_6 },
|
||||
{ 0x0d, 0x7e, KEY_7 },
|
||||
{ 0x05, 0x7c, KEY_8 },
|
||||
{ 0x0a, 0x40, KEY_9 },
|
||||
{ 0x0e, 0x4e, KEY_CLEAR },
|
||||
{ 0x04, 0x7c, KEY_CHANNEL }, /* show channel number */
|
||||
{ 0x0f, 0x41, KEY_LAST }, /* recall */
|
||||
{ 0x03, 0x42, KEY_MUTE },
|
||||
{ 0x06, 0x4c, KEY_RESERVED }, /* PIP button*/
|
||||
{ 0x01, 0x72, KEY_SHUFFLE }, /* SNAPSHOT */
|
||||
{ 0x0c, 0x4e, KEY_PLAYPAUSE }, /* TIMESHIFT */
|
||||
{ 0x0b, 0x70, KEY_RECORD },
|
||||
{ 0x03, 0x7d, KEY_VOLUMEUP },
|
||||
{ 0x01, 0x7d, KEY_VOLUMEDOWN },
|
||||
{ 0x02, 0x42, KEY_CHANNELUP },
|
||||
{ 0x00, 0x7d, KEY_CHANNELDOWN },
|
||||
};
|
||||
|
||||
/* STK7700P: Hauppauge Nova-T Stick, AVerMedia Volar */
|
||||
@ -578,16 +644,22 @@ static struct mt2060_config stk7700p_mt2060_config = {
|
||||
|
||||
static int stk7700p_tuner_attach(struct dvb_usb_adapter *adap)
|
||||
{
|
||||
struct i2c_adapter *prim_i2c = &adap->dev->i2c_adap;
|
||||
struct dib0700_state *st = adap->dev->priv;
|
||||
struct i2c_adapter *tun_i2c;
|
||||
|
||||
s8 a;
|
||||
int if1=1220;
|
||||
if (adap->dev->udev->descriptor.idVendor == USB_VID_HAUPPAUGE &&
|
||||
adap->dev->udev->descriptor.idProduct == USB_PID_HAUPPAUGE_NOVA_T_STICK) {
|
||||
if (!eeprom_read(prim_i2c,0x58,&a)) if1=1220+a;
|
||||
}
|
||||
if (st->is_dib7000pc)
|
||||
tun_i2c = dib7000p_get_i2c_master(adap->fe, DIBX000_I2C_INTERFACE_TUNER, 1);
|
||||
else
|
||||
tun_i2c = dib7000m_get_i2c_master(adap->fe, DIBX000_I2C_INTERFACE_TUNER, 1);
|
||||
|
||||
return dvb_attach(mt2060_attach, adap->fe, tun_i2c, &stk7700p_mt2060_config,
|
||||
st->mt2060_if1[0]) == NULL ? -ENODEV : 0;
|
||||
if1) == NULL ? -ENODEV : 0;
|
||||
}
|
||||
|
||||
/* DIB7070 generic */
|
||||
@ -709,6 +781,8 @@ static struct dib7000p_config dib7070p_dib7000p_config = {
|
||||
.agc_config_count = 1,
|
||||
.agc = &dib7070_agc_config,
|
||||
.bw = &dib7070_bw_config_12_mhz,
|
||||
.tuner_is_baseband = 1,
|
||||
.spur_protect = 1,
|
||||
|
||||
.gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
|
||||
.gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
|
||||
@ -748,6 +822,8 @@ static struct dib7000p_config stk7070pd_dib7000p_config[2] = {
|
||||
.agc_config_count = 1,
|
||||
.agc = &dib7070_agc_config,
|
||||
.bw = &dib7070_bw_config_12_mhz,
|
||||
.tuner_is_baseband = 1,
|
||||
.spur_protect = 1,
|
||||
|
||||
.gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
|
||||
.gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
|
||||
@ -760,6 +836,8 @@ static struct dib7000p_config stk7070pd_dib7000p_config[2] = {
|
||||
.agc_config_count = 1,
|
||||
.agc = &dib7070_agc_config,
|
||||
.bw = &dib7070_bw_config_12_mhz,
|
||||
.tuner_is_baseband = 1,
|
||||
.spur_protect = 1,
|
||||
|
||||
.gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
|
||||
.gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
|
||||
@ -821,6 +899,12 @@ struct usb_device_id dib0700_usb_id_table[] = {
|
||||
{ USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV_DUAL_DIVERSITY_DVB_T) },
|
||||
{ USB_DEVICE(USB_VID_COMPRO, USB_PID_COMPRO_VIDEOMATE_U500_PC) },
|
||||
/* 20 */{ USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_EXPRESS) },
|
||||
{ USB_DEVICE(USB_VID_GIGABYTE, USB_PID_GIGABYTE_U7000) },
|
||||
{ USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ARTEC_T14BR) },
|
||||
{ USB_DEVICE(USB_VID_ASUS, USB_PID_ASUS_U3000) },
|
||||
{ USB_DEVICE(USB_VID_ASUS, USB_PID_ASUS_U3100) },
|
||||
/* 25 */ { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_STICK_3) },
|
||||
{ USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_MYTV_T) },
|
||||
{ 0 } /* Terminating entry */
|
||||
};
|
||||
MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table);
|
||||
@ -862,7 +946,7 @@ struct dvb_usb_device_properties dib0700_devices[] = {
|
||||
},
|
||||
},
|
||||
|
||||
.num_device_descs = 7,
|
||||
.num_device_descs = 8,
|
||||
.devices = {
|
||||
{ "DiBcom STK7700P reference design",
|
||||
{ &dib0700_usb_id_table[0], &dib0700_usb_id_table[1] },
|
||||
@ -891,6 +975,10 @@ struct dvb_usb_device_properties dib0700_devices[] = {
|
||||
{ "AVerMedia AVerTV DVB-T Express",
|
||||
{ &dib0700_usb_id_table[20] },
|
||||
{ NULL },
|
||||
},
|
||||
{ "Gigabyte U7000",
|
||||
{ &dib0700_usb_id_table[21], NULL },
|
||||
{ NULL },
|
||||
}
|
||||
},
|
||||
|
||||
@ -961,7 +1049,7 @@ struct dvb_usb_device_properties dib0700_devices[] = {
|
||||
{ "DiBcom STK7700D reference design",
|
||||
{ &dib0700_usb_id_table[14], NULL },
|
||||
{ NULL },
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
.rc_interval = DEFAULT_RC_INTERVAL,
|
||||
@ -969,6 +1057,25 @@ struct dvb_usb_device_properties dib0700_devices[] = {
|
||||
.rc_key_map_size = ARRAY_SIZE(dib0700_rc_keys),
|
||||
.rc_query = dib0700_rc_query
|
||||
|
||||
}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
|
||||
|
||||
.num_adapters = 1,
|
||||
.adapter = {
|
||||
{
|
||||
.frontend_attach = stk7700P2_frontend_attach,
|
||||
.tuner_attach = stk7700d_tuner_attach,
|
||||
|
||||
DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
|
||||
},
|
||||
},
|
||||
|
||||
.num_device_descs = 1,
|
||||
.devices = {
|
||||
{ "ASUS My Cinema U3000 Mini DVBT Tuner",
|
||||
{ &dib0700_usb_id_table[23], NULL },
|
||||
{ NULL },
|
||||
},
|
||||
}
|
||||
}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
|
||||
|
||||
.num_adapters = 1,
|
||||
@ -983,7 +1090,7 @@ struct dvb_usb_device_properties dib0700_devices[] = {
|
||||
},
|
||||
},
|
||||
|
||||
.num_device_descs = 2,
|
||||
.num_device_descs = 6,
|
||||
.devices = {
|
||||
{ "DiBcom STK7070P reference design",
|
||||
{ &dib0700_usb_id_table[15], NULL },
|
||||
@ -993,7 +1100,29 @@ struct dvb_usb_device_properties dib0700_devices[] = {
|
||||
{ &dib0700_usb_id_table[16], NULL },
|
||||
{ NULL },
|
||||
},
|
||||
}
|
||||
{ "Artec T14BR DVB-T",
|
||||
{ &dib0700_usb_id_table[22], NULL },
|
||||
{ NULL },
|
||||
},
|
||||
{ "ASUS My Cinema U3100 Mini DVBT Tuner",
|
||||
{ &dib0700_usb_id_table[24], NULL },
|
||||
{ NULL },
|
||||
},
|
||||
{ "Hauppauge Nova-T Stick",
|
||||
{ &dib0700_usb_id_table[25], NULL },
|
||||
{ NULL },
|
||||
},
|
||||
{ "Hauppauge Nova-T MyTV.t",
|
||||
{ &dib0700_usb_id_table[26], NULL },
|
||||
{ NULL },
|
||||
},
|
||||
},
|
||||
|
||||
.rc_interval = DEFAULT_RC_INTERVAL,
|
||||
.rc_key_map = dib0700_rc_keys,
|
||||
.rc_key_map_size = ARRAY_SIZE(dib0700_rc_keys),
|
||||
.rc_query = dib0700_rc_query
|
||||
|
||||
}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
|
||||
|
||||
.num_adapters = 2,
|
||||
@ -1024,7 +1153,7 @@ struct dvb_usb_device_properties dib0700_devices[] = {
|
||||
{ "Pinnacle PCTV Dual DVB-T Diversity Stick",
|
||||
{ &dib0700_usb_id_table[18], NULL },
|
||||
{ NULL },
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
@ -17,9 +17,10 @@
|
||||
#include "nxt6000.h"
|
||||
|
||||
/* debug */
|
||||
int dvb_usb_digitv_debug;
|
||||
static int dvb_usb_digitv_debug;
|
||||
module_param_named(debug,dvb_usb_digitv_debug, int, 0644);
|
||||
MODULE_PARM_DESC(debug, "set debugging level (1=rc (or-able))." DVB_USB_DEBUG_STATUS);
|
||||
#define deb_rc(args...) dprintk(dvb_usb_digitv_debug,0x01,args)
|
||||
|
||||
static int digitv_ctrl_msg(struct dvb_usb_device *d,
|
||||
u8 cmd, u8 vv, u8 *wbuf, int wlen, u8 *rbuf, int rlen)
|
||||
|
@ -8,9 +8,6 @@ struct digitv_state {
|
||||
int is_nxt6000;
|
||||
};
|
||||
|
||||
extern int dvb_usb_digitv_debug;
|
||||
#define deb_rc(args...) dprintk(dvb_usb_digitv_debug,0x01,args)
|
||||
|
||||
/* protocol (from usblogging and the SDK:
|
||||
*
|
||||
* Always 7 bytes bulk message(s) for controlling
|
||||
|
@ -15,7 +15,9 @@
|
||||
#define USB_VID_ALCOR_MICRO 0x058f
|
||||
#define USB_VID_ALINK 0x05e3
|
||||
#define USB_VID_ANCHOR 0x0547
|
||||
#define USB_VID_ANSONIC 0x10b9
|
||||
#define USB_VID_ANUBIS_ELECTRONIC 0x10fd
|
||||
#define USB_VID_ASUS 0x0b05
|
||||
#define USB_VID_AVERMEDIA 0x07ca
|
||||
#define USB_VID_COMPRO 0x185b
|
||||
#define USB_VID_COMPRO_UNK 0x145f
|
||||
@ -44,12 +46,16 @@
|
||||
#define USB_VID_ULTIMA_ELECTRONIC 0x05d8
|
||||
#define USB_VID_UNIWILL 0x1584
|
||||
#define USB_VID_WIDEVIEW 0x14aa
|
||||
/* dom : pour gigabyte u7000 */
|
||||
#define USB_VID_GIGABYTE 0x1044
|
||||
|
||||
|
||||
/* Product IDs */
|
||||
#define USB_PID_ADSTECH_USB2_COLD 0xa333
|
||||
#define USB_PID_ADSTECH_USB2_WARM 0xa334
|
||||
#define USB_PID_AFATECH_AF9005 0x9020
|
||||
#define USB_VID_ALINK_DTU 0xf170
|
||||
#define USB_PID_ANSONIC_DVBT_USB 0x6000
|
||||
#define USB_PID_AVERMEDIA_DVBT_USB_COLD 0x0001
|
||||
#define USB_PID_AVERMEDIA_DVBT_USB_WARM 0x0002
|
||||
#define USB_PID_AVERMEDIA_DVBT_USB2_COLD 0xa800
|
||||
@ -69,6 +75,7 @@
|
||||
#define USB_PID_DIBCOM_STK7700P 0x1e14
|
||||
#define USB_PID_DIBCOM_STK7700P_PC 0x1e78
|
||||
#define USB_PID_DIBCOM_STK7700D 0x1ef0
|
||||
#define USB_PID_DIBCOM_STK7700_U7000 0x7001
|
||||
#define USB_PID_DIBCOM_STK7070P 0x1ebc
|
||||
#define USB_PID_DIBCOM_STK7070PD 0x1ebe
|
||||
#define USB_PID_DIBCOM_ANCHOR_2135_COLD 0x2131
|
||||
@ -99,6 +106,7 @@
|
||||
#define USB_PID_ULTIMA_TVBOX_USB2_WARM 0x810a
|
||||
#define USB_PID_ARTEC_T14_COLD 0x810b
|
||||
#define USB_PID_ARTEC_T14_WARM 0x810c
|
||||
#define USB_PID_ARTEC_T14BR 0x810f
|
||||
#define USB_PID_ULTIMA_TVBOX_USB2_FX_COLD 0x8613
|
||||
#define USB_PID_ULTIMA_TVBOX_USB2_FX_WARM 0x1002
|
||||
#define USB_PID_UNK_HYPER_PALTEK_COLD 0x005e
|
||||
@ -120,6 +128,8 @@
|
||||
#define USB_PID_HAUPPAUGE_NOVA_T_500_2 0x9950
|
||||
#define USB_PID_HAUPPAUGE_NOVA_T_STICK 0x7050
|
||||
#define USB_PID_HAUPPAUGE_NOVA_T_STICK_2 0x7060
|
||||
#define USB_PID_HAUPPAUGE_NOVA_T_STICK_3 0x7070
|
||||
#define USB_PID_HAUPPAUGE_MYTV_T 0x7080
|
||||
#define USB_PID_HAUPPAUGE_NOVA_TD_STICK 0x9580
|
||||
#define USB_PID_AVERMEDIA_EXPRESS 0xb568
|
||||
#define USB_PID_AVERMEDIA_VOLAR 0xa807
|
||||
@ -143,6 +153,9 @@
|
||||
#define USB_PID_DVICO_BLUEBIRD_DUAL_1_WARM 0xdb51
|
||||
#define USB_PID_DVICO_BLUEBIRD_DUAL_2_COLD 0xdb58
|
||||
#define USB_PID_DVICO_BLUEBIRD_DUAL_2_WARM 0xdb59
|
||||
#define USB_PID_DVICO_BLUEBIRD_DUAL_4 0xdb78
|
||||
#define USB_PID_DVICO_BLUEBIRD_DVB_T_NANO_2 0xdb70
|
||||
#define USB_PID_DVICO_BLUEBIRD_DVB_T_NANO_2_NFW_WARM 0xdb71
|
||||
#define USB_PID_DIGITALNOW_BLUEBIRD_DUAL_1_COLD 0xdb54
|
||||
#define USB_PID_DIGITALNOW_BLUEBIRD_DUAL_1_WARM 0xdb55
|
||||
#define USB_PID_MEDION_MD95700 0x0932
|
||||
@ -170,6 +183,9 @@
|
||||
#define USB_PID_OPERA1_WARM 0x3829
|
||||
#define USB_PID_LIFEVIEW_TV_WALKER_TWIN_COLD 0x0514
|
||||
#define USB_PID_LIFEVIEW_TV_WALKER_TWIN_WARM 0x0513
|
||||
|
||||
/* dom pour gigabyte u7000 */
|
||||
#define USB_PID_GIGABYTE_U7000 0x7001
|
||||
#define USB_PID_ASUS_U3000 0x171f
|
||||
#define USB_PID_ASUS_U3100 0x173f
|
||||
|
||||
#endif
|
||||
|
@ -56,12 +56,12 @@ static int gl861_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
|
||||
struct dvb_usb_device *d = i2c_get_adapdata(adap);
|
||||
int i;
|
||||
|
||||
if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
|
||||
return -EAGAIN;
|
||||
|
||||
if (num > 2)
|
||||
return -EINVAL;
|
||||
|
||||
if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
|
||||
return -EAGAIN;
|
||||
|
||||
for (i = 0; i < num; i++) {
|
||||
/* write/read request */
|
||||
if (i+1 < num && (msg[i+1].flags & I2C_M_RD)) {
|
||||
|
@ -171,22 +171,6 @@ static int gp8psk_power_ctrl(struct dvb_usb_device *d, int onoff)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int gp8psk_bcm4500_reload(struct dvb_usb_device *d)
|
||||
{
|
||||
u8 buf;
|
||||
int gp_product_id = le16_to_cpu(d->udev->descriptor.idProduct);
|
||||
/* Turn off 8psk power */
|
||||
if (gp8psk_usb_in_op(d, BOOT_8PSK, 0, 0, &buf, 1))
|
||||
return -EINVAL;
|
||||
/* Turn On 8psk power */
|
||||
if (gp8psk_usb_in_op(d, BOOT_8PSK, 1, 0, &buf, 1))
|
||||
return -EINVAL;
|
||||
/* load BCM4500 firmware */
|
||||
if (gp_product_id == USB_PID_GENPIX_8PSK_REV_1_WARM)
|
||||
if (gp8psk_load_bcm4500fw(d))
|
||||
return EINVAL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gp8psk_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
|
||||
{
|
||||
|
@ -92,6 +92,5 @@ extern struct dvb_frontend * gp8psk_fe_attach(struct dvb_usb_device *d);
|
||||
extern int gp8psk_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen);
|
||||
extern int gp8psk_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value,
|
||||
u16 index, u8 *b, int blen);
|
||||
extern int gp8psk_bcm4500_reload(struct dvb_usb_device *d);
|
||||
|
||||
#endif
|
||||
|
@ -10,7 +10,9 @@
|
||||
* see Documentation/dvb/README.dvb-usb for more information
|
||||
*/
|
||||
|
||||
#include "opera1.h"
|
||||
#define DVB_USB_LOG_PREFIX "opera"
|
||||
|
||||
#include "dvb-usb.h"
|
||||
#include "stv0299.h"
|
||||
|
||||
#define OPERA_READ_MSG 0
|
||||
@ -38,7 +40,7 @@ struct opera_rc_keys {
|
||||
u32 event;
|
||||
};
|
||||
|
||||
int dvb_usb_opera1_debug;
|
||||
static int dvb_usb_opera1_debug;
|
||||
module_param_named(debug, dvb_usb_opera1_debug, int, 0644);
|
||||
MODULE_PARM_DESC(debug,
|
||||
"set debugging level (1=info,xfer=2,pll=4,ts=8,err=16,rc=32,fw=64 (or-able))."
|
||||
|
@ -1,9 +0,0 @@
|
||||
#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
|
@ -56,7 +56,7 @@ int vp702x_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8
|
||||
return ret;
|
||||
}
|
||||
|
||||
int vp702x_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value,
|
||||
static int vp702x_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value,
|
||||
u16 index, u8 *b, int blen)
|
||||
{
|
||||
int ret;
|
||||
@ -204,19 +204,6 @@ static int vp702x_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int vp702x_power_ctrl(struct dvb_usb_device *d, int onoff)
|
||||
{
|
||||
struct vp702x_device_state *st = d->priv;
|
||||
|
||||
if (st->power_state == 0 && onoff)
|
||||
vp702x_usb_out_op(d, SET_TUNER_POWER_REQ, 1, 7, NULL, 0);
|
||||
else if (st->power_state == 1 && onoff == 0)
|
||||
vp702x_usb_out_op(d, SET_TUNER_POWER_REQ, 0, 7, NULL, 0);
|
||||
|
||||
st->power_state = onoff;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int vp702x_read_mac_addr(struct dvb_usb_device *d,u8 mac[6])
|
||||
{
|
||||
|
@ -102,7 +102,5 @@ extern struct dvb_frontend * vp702x_fe_attach(struct dvb_usb_device *d);
|
||||
|
||||
extern int vp702x_usb_inout_op(struct dvb_usb_device *d, u8 *o, int olen, u8 *i, int ilen, int msec);
|
||||
extern int vp702x_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen);
|
||||
extern int vp702x_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen);
|
||||
extern int vp702x_power_ctrl(struct dvb_usb_device *d, int onoff);
|
||||
|
||||
#endif
|
||||
|
@ -15,9 +15,12 @@
|
||||
#include "vp7045.h"
|
||||
|
||||
/* debug */
|
||||
int dvb_usb_vp7045_debug;
|
||||
static int dvb_usb_vp7045_debug;
|
||||
module_param_named(debug,dvb_usb_vp7045_debug, int, 0644);
|
||||
MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2,rc=4 (or-able))." DVB_USB_DEBUG_STATUS);
|
||||
#define deb_info(args...) dprintk(dvb_usb_vp7045_debug,0x01,args)
|
||||
#define deb_xfer(args...) dprintk(dvb_usb_vp7045_debug,0x02,args)
|
||||
#define deb_rc(args...) dprintk(dvb_usb_vp7045_debug,0x04,args)
|
||||
|
||||
int vp7045_usb_op(struct dvb_usb_device *d, u8 cmd, u8 *out, int outlen, u8 *in, int inlen, int msec)
|
||||
{
|
||||
|
@ -17,11 +17,6 @@
|
||||
#define DVB_USB_LOG_PREFIX "vp7045"
|
||||
#include "dvb-usb.h"
|
||||
|
||||
extern int dvb_usb_vp7045_debug;
|
||||
#define deb_info(args...) dprintk(dvb_usb_vp7045_debug,0x01,args)
|
||||
#define deb_xfer(args...) dprintk(dvb_usb_vp7045_debug,0x02,args)
|
||||
#define deb_rc(args...) dprintk(dvb_usb_vp7045_debug,0x04,args)
|
||||
|
||||
/* vp7045 commands */
|
||||
|
||||
/* Twinhan Vendor requests */
|
||||
|
@ -316,6 +316,13 @@ config DVB_TDA827X
|
||||
help
|
||||
A DVB-T silicon tuner module. Say Y when you want to support this tuner.
|
||||
|
||||
config DVB_TDA18271
|
||||
tristate "NXP TDA18271 silicon tuner"
|
||||
depends on I2C
|
||||
default m if DVB_FE_CUSTOMISE
|
||||
help
|
||||
A silicon tuner module. Say Y when you want to support this tuner.
|
||||
|
||||
config DVB_TUNER_QT1010
|
||||
tristate "Quantek QT1010 silicon tuner"
|
||||
depends on DVB_CORE && I2C
|
||||
@ -353,6 +360,15 @@ config DVB_TUNER_DIB0070
|
||||
This device is only used inside a SiP called togther with a
|
||||
demodulator for now.
|
||||
|
||||
config DVB_TUNER_XC5000
|
||||
tristate "Xceive XC5000 silicon tuner"
|
||||
depends on I2C
|
||||
default m if DVB_FE_CUSTOMISE
|
||||
help
|
||||
A driver for the silicon tuner XC5000 from Xceive.
|
||||
This device is only used inside a SiP called togther with a
|
||||
demodulator for now.
|
||||
|
||||
comment "Miscellaneous devices"
|
||||
depends on DVB_CORE
|
||||
|
||||
|
@ -3,6 +3,9 @@
|
||||
#
|
||||
|
||||
EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/
|
||||
EXTRA_CFLAGS += -Idrivers/media/video/
|
||||
|
||||
tda18271-objs := tda18271-tables.o tda18271-common.o tda18271-fe.o
|
||||
|
||||
obj-$(CONFIG_DVB_PLL) += dvb-pll.o
|
||||
obj-$(CONFIG_DVB_STV0299) += stv0299.o
|
||||
@ -39,6 +42,7 @@ obj-$(CONFIG_DVB_ISL6421) += isl6421.o
|
||||
obj-$(CONFIG_DVB_TDA10086) += tda10086.o
|
||||
obj-$(CONFIG_DVB_TDA826X) += tda826x.o
|
||||
obj-$(CONFIG_DVB_TDA827X) += tda827x.o
|
||||
obj-$(CONFIG_DVB_TDA18271) += tda18271.o
|
||||
obj-$(CONFIG_DVB_TUNER_MT2060) += mt2060.o
|
||||
obj-$(CONFIG_DVB_TUNER_MT2266) += mt2266.o
|
||||
obj-$(CONFIG_DVB_TUNER_DIB0070) += dib0070.o
|
||||
@ -46,3 +50,4 @@ obj-$(CONFIG_DVB_TUNER_QT1010) += qt1010.o
|
||||
obj-$(CONFIG_DVB_TUA6100) += tua6100.o
|
||||
obj-$(CONFIG_DVB_TUNER_MT2131) += mt2131.o
|
||||
obj-$(CONFIG_DVB_S5H1409) += s5h1409.o
|
||||
obj-$(CONFIG_DVB_TUNER_XC5000) += xc5000.o
|
||||
|
@ -434,9 +434,14 @@ static u16 dib0070_p1f_defaults[] =
|
||||
0,
|
||||
};
|
||||
|
||||
static void dib0070_wbd_calibration(struct dib0070_state *state)
|
||||
static void dib0070_wbd_calibration(struct dvb_frontend *fe)
|
||||
{
|
||||
u16 wbd_offs;
|
||||
struct dib0070_state *state = fe->tuner_priv;
|
||||
|
||||
if (state->cfg->sleep)
|
||||
state->cfg->sleep(fe, 0);
|
||||
|
||||
dib0070_write_reg(state, 0x0f, 0x6d81);
|
||||
dib0070_write_reg(state, 0x20, 0x0040 | 0x0020 | 0x0010 | 0x0008 | 0x0002 | 0x0001);
|
||||
msleep(9);
|
||||
@ -444,6 +449,10 @@ static void dib0070_wbd_calibration(struct dib0070_state *state)
|
||||
dib0070_write_reg(state, 0x20, 0);
|
||||
state->wbd_ff_offset = ((wbd_offs * 8 * 18 / 33 + 1) / 2);
|
||||
dprintk( "WBDStart = %d (Vargen) - FF = %hd", (u32) wbd_offs * 1800/1024, state->wbd_ff_offset);
|
||||
|
||||
if (state->cfg->sleep)
|
||||
state->cfg->sleep(fe, 1);
|
||||
|
||||
}
|
||||
|
||||
u16 dib0070_wbd_offset(struct dvb_frontend *fe)
|
||||
@ -560,7 +569,7 @@ struct dvb_frontend * dib0070_attach(struct dvb_frontend *fe, struct i2c_adapter
|
||||
if (dib0070_reset(state) != 0)
|
||||
goto free_mem;
|
||||
|
||||
dib0070_wbd_calibration(state);
|
||||
dib0070_wbd_calibration(fe);
|
||||
|
||||
printk(KERN_INFO "DiB0070: successfully identified\n");
|
||||
memcpy(&fe->ops.tuner_ops, &dib0070_ops, sizeof(struct dvb_tuner_ops));
|
||||
|
@ -684,6 +684,9 @@ static int dib3000mc_set_frontend(struct dvb_frontend* fe,
|
||||
struct dvb_frontend_parameters *fep)
|
||||
{
|
||||
struct dib3000mc_state *state = fe->demodulator_priv;
|
||||
int ret;
|
||||
|
||||
dib3000mc_set_output_mode(state, OUTMODE_HIGH_Z);
|
||||
|
||||
state->current_bandwidth = fep->u.ofdm.bandwidth;
|
||||
dib3000mc_set_bandwidth(state, BANDWIDTH_TO_KHZ(fep->u.ofdm.bandwidth));
|
||||
@ -700,7 +703,7 @@ static int dib3000mc_set_frontend(struct dvb_frontend* fe,
|
||||
fep->u.ofdm.guard_interval == GUARD_INTERVAL_AUTO ||
|
||||
fep->u.ofdm.constellation == QAM_AUTO ||
|
||||
fep->u.ofdm.code_rate_HP == FEC_AUTO) {
|
||||
int i = 100, found;
|
||||
int i = 1000, found;
|
||||
|
||||
dib3000mc_autosearch_start(fe, fep);
|
||||
do {
|
||||
@ -715,10 +718,11 @@ static int dib3000mc_set_frontend(struct dvb_frontend* fe,
|
||||
dib3000mc_get_frontend(fe, fep);
|
||||
}
|
||||
|
||||
ret = dib3000mc_tune(fe, fep);
|
||||
|
||||
/* make this a config parameter */
|
||||
dib3000mc_set_output_mode(state, OUTMODE_MPEG2_FIFO);
|
||||
|
||||
return dib3000mc_tune(fe, fep);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int dib3000mc_read_status(struct dvb_frontend *fe, fe_status_t *stat)
|
||||
|
@ -1171,7 +1171,9 @@ static int dib7000m_set_frontend(struct dvb_frontend* fe,
|
||||
struct dvb_frontend_parameters *fep)
|
||||
{
|
||||
struct dib7000m_state *state = fe->demodulator_priv;
|
||||
int time;
|
||||
int time, ret;
|
||||
|
||||
dib7000m_set_output_mode(state, OUTMODE_HIGH_Z);
|
||||
|
||||
state->current_bandwidth = fep->u.ofdm.bandwidth;
|
||||
dib7000m_set_bandwidth(state, BANDWIDTH_TO_KHZ(fep->u.ofdm.bandwidth));
|
||||
@ -1206,10 +1208,11 @@ static int dib7000m_set_frontend(struct dvb_frontend* fe,
|
||||
dib7000m_get_frontend(fe, fep);
|
||||
}
|
||||
|
||||
ret = dib7000m_tune(fe, fep);
|
||||
|
||||
/* make this a config parameter */
|
||||
dib7000m_set_output_mode(state, OUTMODE_MPEG2_FIFO);
|
||||
|
||||
return dib7000m_tune(fe, fep);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int dib7000m_read_status(struct dvb_frontend *fe, fe_status_t *stat)
|
||||
|
@ -36,7 +36,7 @@ struct dib7000p_state {
|
||||
u16 wbd_ref;
|
||||
|
||||
u8 current_band;
|
||||
fe_bandwidth_t current_bandwidth;
|
||||
u32 current_bandwidth;
|
||||
struct dibx000_agc_config *current_agc;
|
||||
u32 timf;
|
||||
|
||||
@ -1074,7 +1074,7 @@ static int dib7000p_get_frontend(struct dvb_frontend* fe,
|
||||
|
||||
fep->inversion = INVERSION_AUTO;
|
||||
|
||||
fep->u.ofdm.bandwidth = state->current_bandwidth;
|
||||
fep->u.ofdm.bandwidth = BANDWIDTH_TO_INDEX(state->current_bandwidth);
|
||||
|
||||
switch ((tps >> 8) & 0x3) {
|
||||
case 0: fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_2K; break;
|
||||
@ -1128,10 +1128,9 @@ static int dib7000p_set_frontend(struct dvb_frontend* fe,
|
||||
struct dvb_frontend_parameters *fep)
|
||||
{
|
||||
struct dib7000p_state *state = fe->demodulator_priv;
|
||||
int time;
|
||||
int time, ret;
|
||||
|
||||
state->current_bandwidth = fep->u.ofdm.bandwidth;
|
||||
dib7000p_set_bandwidth(state, BANDWIDTH_TO_KHZ(fep->u.ofdm.bandwidth));
|
||||
dib7000p_set_output_mode(state, OUTMODE_HIGH_Z);
|
||||
|
||||
/* maybe the parameter has been changed */
|
||||
state->sfn_workaround_active = buggy_sfn_workaround;
|
||||
@ -1166,10 +1165,11 @@ static int dib7000p_set_frontend(struct dvb_frontend* fe,
|
||||
dib7000p_get_frontend(fe, fep);
|
||||
}
|
||||
|
||||
ret = dib7000p_tune(fe, fep);
|
||||
|
||||
/* make this a config parameter */
|
||||
dib7000p_set_output_mode(state, OUTMODE_MPEG2_FIFO);
|
||||
|
||||
return dib7000p_tune(fe, fep);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int dib7000p_read_status(struct dvb_frontend *fe, fe_status_t *stat)
|
||||
|
@ -128,6 +128,11 @@ enum dibx000_adc_states {
|
||||
(v) == BANDWIDTH_7_MHZ ? 7000 : \
|
||||
(v) == BANDWIDTH_6_MHZ ? 6000 : 8000 )
|
||||
|
||||
#define BANDWIDTH_TO_INDEX(v) ( \
|
||||
(v) == 8000 ? BANDWIDTH_8_MHZ : \
|
||||
(v) == 7000 ? BANDWIDTH_7_MHZ : \
|
||||
(v) == 6000 ? BANDWIDTH_6_MHZ : BANDWIDTH_8_MHZ )
|
||||
|
||||
/* Chip output mode. */
|
||||
#define OUTMODE_HIGH_Z 0
|
||||
#define OUTMODE_MPEG2_PAR_GATED_CLK 1
|
||||
|
@ -38,8 +38,12 @@ struct mt2266_priv {
|
||||
|
||||
u32 frequency;
|
||||
u32 bandwidth;
|
||||
u8 band;
|
||||
};
|
||||
|
||||
#define MT2266_VHF 1
|
||||
#define MT2266_UHF 0
|
||||
|
||||
/* Here, frequencies are expressed in kiloHertz to avoid 32 bits overflows */
|
||||
|
||||
static int debug;
|
||||
@ -90,26 +94,30 @@ static int mt2266_writeregs(struct mt2266_priv *priv,u8 *buf, u8 len)
|
||||
}
|
||||
|
||||
// Initialisation sequences
|
||||
static u8 mt2266_init1[] = {
|
||||
REG_TUNE,
|
||||
0x00, 0x00, 0x28, 0x00, 0x52, 0x99, 0x3f };
|
||||
static u8 mt2266_init1[] = { REG_TUNE, 0x00, 0x00, 0x28,
|
||||
0x00, 0x52, 0x99, 0x3f };
|
||||
|
||||
static u8 mt2266_init2[] = {
|
||||
0x17, 0x6d, 0x71, 0x61, 0xc0, 0xbf, 0xff, 0xdc, 0x00, 0x0a,
|
||||
0xd4, 0x03, 0x64, 0x64, 0x64, 0x64, 0x22, 0xaa, 0xf2, 0x1e, 0x80, 0x14, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x7f, 0x5e, 0x3f, 0xff, 0xff, 0xff, 0x00, 0x77, 0x0f, 0x2d };
|
||||
0x17, 0x6d, 0x71, 0x61, 0xc0, 0xbf, 0xff, 0xdc, 0x00, 0x0a, 0xd4,
|
||||
0x03, 0x64, 0x64, 0x64, 0x64, 0x22, 0xaa, 0xf2, 0x1e, 0x80, 0x14,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x7f, 0x5e, 0x3f, 0xff, 0xff,
|
||||
0xff, 0x00, 0x77, 0x0f, 0x2d
|
||||
};
|
||||
|
||||
static u8 mt2266_init_8mhz[] = {
|
||||
REG_BANDWIDTH,
|
||||
0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 };
|
||||
static u8 mt2266_init_8mhz[] = { REG_BANDWIDTH, 0x22, 0x22, 0x22, 0x22,
|
||||
0x22, 0x22, 0x22, 0x22 };
|
||||
|
||||
static u8 mt2266_init_7mhz[] = {
|
||||
REG_BANDWIDTH,
|
||||
0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32 };
|
||||
static u8 mt2266_init_7mhz[] = { REG_BANDWIDTH, 0x32, 0x32, 0x32, 0x32,
|
||||
0x32, 0x32, 0x32, 0x32 };
|
||||
|
||||
static u8 mt2266_init_6mhz[] = {
|
||||
REG_BANDWIDTH,
|
||||
0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7 };
|
||||
static u8 mt2266_init_6mhz[] = { REG_BANDWIDTH, 0xa7, 0xa7, 0xa7, 0xa7,
|
||||
0xa7, 0xa7, 0xa7, 0xa7 };
|
||||
|
||||
static u8 mt2266_uhf[] = { 0x1d, 0xdc, 0x00, 0x0a, 0xd4, 0x03, 0x64, 0x64,
|
||||
0x64, 0x64, 0x22, 0xaa, 0xf2, 0x1e, 0x80, 0x14 };
|
||||
|
||||
static u8 mt2266_vhf[] = { 0x1d, 0xfe, 0x00, 0x00, 0xb4, 0x03, 0xa5, 0xa5,
|
||||
0xa5, 0xa5, 0x82, 0xaa, 0xf1, 0x17, 0x80, 0x1f };
|
||||
|
||||
#define FREF 30000 // Quartz oscillator 30 MHz
|
||||
|
||||
@ -122,35 +130,78 @@ static int mt2266_set_params(struct dvb_frontend *fe, struct dvb_frontend_parame
|
||||
u8 lnaband;
|
||||
u8 b[10];
|
||||
int i;
|
||||
u8 band;
|
||||
|
||||
priv = fe->tuner_priv;
|
||||
|
||||
mt2266_writereg(priv,0x17,0x6d);
|
||||
mt2266_writereg(priv,0x1c,0xff);
|
||||
|
||||
freq = params->frequency / 1000; // Hz -> kHz
|
||||
if (freq < 470000 && freq > 230000)
|
||||
return -EINVAL; /* Gap between VHF and UHF bands */
|
||||
priv->bandwidth = (fe->ops.info.type == FE_OFDM) ? params->u.ofdm.bandwidth : 0;
|
||||
priv->frequency = freq * 1000;
|
||||
tune=2 * freq * (8192/16) / (FREF/16);
|
||||
|
||||
if (freq <= 495000) lnaband = 0xEE; else
|
||||
if (freq <= 525000) lnaband = 0xDD; else
|
||||
if (freq <= 550000) lnaband = 0xCC; else
|
||||
if (freq <= 580000) lnaband = 0xBB; else
|
||||
if (freq <= 605000) lnaband = 0xAA; else
|
||||
if (freq <= 630000) lnaband = 0x99; else
|
||||
if (freq <= 655000) lnaband = 0x88; else
|
||||
if (freq <= 685000) lnaband = 0x77; else
|
||||
if (freq <= 710000) lnaband = 0x66; else
|
||||
if (freq <= 735000) lnaband = 0x55; else
|
||||
if (freq <= 765000) lnaband = 0x44; else
|
||||
if (freq <= 802000) lnaband = 0x33; else
|
||||
if (freq <= 840000) lnaband = 0x22; else lnaband = 0x11;
|
||||
tune = 2 * freq * (8192/16) / (FREF/16);
|
||||
band = (freq < 300000) ? MT2266_VHF : MT2266_UHF;
|
||||
if (band == MT2266_VHF)
|
||||
tune *= 2;
|
||||
|
||||
msleep(100);
|
||||
mt2266_writeregs(priv,(params->u.ofdm.bandwidth==BANDWIDTH_6_MHZ)?mt2266_init_6mhz:
|
||||
(params->u.ofdm.bandwidth==BANDWIDTH_7_MHZ)?mt2266_init_7mhz:
|
||||
mt2266_init_8mhz,sizeof(mt2266_init_8mhz));
|
||||
switch (params->u.ofdm.bandwidth) {
|
||||
case BANDWIDTH_6_MHZ:
|
||||
mt2266_writeregs(priv, mt2266_init_6mhz,
|
||||
sizeof(mt2266_init_6mhz));
|
||||
break;
|
||||
case BANDWIDTH_7_MHZ:
|
||||
mt2266_writeregs(priv, mt2266_init_7mhz,
|
||||
sizeof(mt2266_init_7mhz));
|
||||
break;
|
||||
case BANDWIDTH_8_MHZ:
|
||||
default:
|
||||
mt2266_writeregs(priv, mt2266_init_8mhz,
|
||||
sizeof(mt2266_init_8mhz));
|
||||
break;
|
||||
}
|
||||
|
||||
if (band == MT2266_VHF && priv->band == MT2266_UHF) {
|
||||
dprintk("Switch from UHF to VHF");
|
||||
mt2266_writereg(priv, 0x05, 0x04);
|
||||
mt2266_writereg(priv, 0x19, 0x61);
|
||||
mt2266_writeregs(priv, mt2266_vhf, sizeof(mt2266_vhf));
|
||||
} else if (band == MT2266_UHF && priv->band == MT2266_VHF) {
|
||||
dprintk("Switch from VHF to UHF");
|
||||
mt2266_writereg(priv, 0x05, 0x52);
|
||||
mt2266_writereg(priv, 0x19, 0x61);
|
||||
mt2266_writeregs(priv, mt2266_uhf, sizeof(mt2266_uhf));
|
||||
}
|
||||
msleep(10);
|
||||
|
||||
if (freq <= 495000)
|
||||
lnaband = 0xEE;
|
||||
else if (freq <= 525000)
|
||||
lnaband = 0xDD;
|
||||
else if (freq <= 550000)
|
||||
lnaband = 0xCC;
|
||||
else if (freq <= 580000)
|
||||
lnaband = 0xBB;
|
||||
else if (freq <= 605000)
|
||||
lnaband = 0xAA;
|
||||
else if (freq <= 630000)
|
||||
lnaband = 0x99;
|
||||
else if (freq <= 655000)
|
||||
lnaband = 0x88;
|
||||
else if (freq <= 685000)
|
||||
lnaband = 0x77;
|
||||
else if (freq <= 710000)
|
||||
lnaband = 0x66;
|
||||
else if (freq <= 735000)
|
||||
lnaband = 0x55;
|
||||
else if (freq <= 765000)
|
||||
lnaband = 0x44;
|
||||
else if (freq <= 802000)
|
||||
lnaband = 0x33;
|
||||
else if (freq <= 840000)
|
||||
lnaband = 0x22;
|
||||
else
|
||||
lnaband = 0x11;
|
||||
|
||||
b[0] = REG_TUNE;
|
||||
b[1] = (tune >> 8) & 0x1F;
|
||||
@ -158,47 +209,54 @@ static int mt2266_set_params(struct dvb_frontend *fe, struct dvb_frontend_parame
|
||||
b[3] = tune >> 13;
|
||||
mt2266_writeregs(priv,b,4);
|
||||
|
||||
dprintk("set_parms: tune=%d band=%d",(int)tune,(int)lnaband);
|
||||
dprintk("set_parms: [1..3]: %2x %2x %2x",(int)b[1],(int)b[2],(int)b[3]);
|
||||
dprintk("set_parms: tune=%d band=%d %s",
|
||||
(int) tune, (int) lnaband,
|
||||
(band == MT2266_UHF) ? "UHF" : "VHF");
|
||||
dprintk("set_parms: [1..3]: %2x %2x %2x",
|
||||
(int) b[1], (int) b[2], (int)b[3]);
|
||||
|
||||
if (band == MT2266_UHF) {
|
||||
b[0] = 0x05;
|
||||
b[1] = 0x62;
|
||||
b[1] = (priv->band == MT2266_VHF) ? 0x52 : 0x62;
|
||||
b[2] = lnaband;
|
||||
mt2266_writeregs(priv,b,3);
|
||||
mt2266_writeregs(priv, b, 3);
|
||||
}
|
||||
|
||||
//Waits for pll lock or timeout
|
||||
/* Wait for pll lock or timeout */
|
||||
i = 0;
|
||||
do {
|
||||
mt2266_readreg(priv,REG_LOCK,b);
|
||||
if ((b[0] & 0x40)==0x40)
|
||||
if (b[0] & 0x40)
|
||||
break;
|
||||
msleep(10);
|
||||
i++;
|
||||
} while (i<10);
|
||||
dprintk("Lock when i=%i",(int)i);
|
||||
|
||||
if (band == MT2266_UHF && priv->band == MT2266_VHF)
|
||||
mt2266_writereg(priv, 0x05, 0x62);
|
||||
|
||||
priv->band = band;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void mt2266_calibrate(struct mt2266_priv *priv)
|
||||
{
|
||||
mt2266_writereg(priv,0x11,0x03);
|
||||
mt2266_writereg(priv,0x11,0x01);
|
||||
|
||||
mt2266_writeregs(priv,mt2266_init1,sizeof(mt2266_init1));
|
||||
mt2266_writeregs(priv,mt2266_init2,sizeof(mt2266_init2));
|
||||
|
||||
mt2266_writereg(priv,0x33,0x5e);
|
||||
mt2266_writereg(priv,0x10,0x10);
|
||||
mt2266_writereg(priv,0x10,0x00);
|
||||
|
||||
mt2266_writeregs(priv,mt2266_init_8mhz,sizeof(mt2266_init_8mhz));
|
||||
|
||||
mt2266_writereg(priv, 0x11, 0x03);
|
||||
mt2266_writereg(priv, 0x11, 0x01);
|
||||
mt2266_writeregs(priv, mt2266_init1, sizeof(mt2266_init1));
|
||||
mt2266_writeregs(priv, mt2266_init2, sizeof(mt2266_init2));
|
||||
mt2266_writereg(priv, 0x33, 0x5e);
|
||||
mt2266_writereg(priv, 0x10, 0x10);
|
||||
mt2266_writereg(priv, 0x10, 0x00);
|
||||
mt2266_writeregs(priv, mt2266_init_8mhz, sizeof(mt2266_init_8mhz));
|
||||
msleep(25);
|
||||
mt2266_writereg(priv,0x17,0x6d);
|
||||
mt2266_writereg(priv,0x1c,0x00);
|
||||
mt2266_writereg(priv, 0x17, 0x6d);
|
||||
mt2266_writereg(priv, 0x1c, 0x00);
|
||||
msleep(75);
|
||||
mt2266_writereg(priv,0x17,0x6d);
|
||||
mt2266_writereg(priv,0x1c,0xff);
|
||||
mt2266_writereg(priv, 0x17, 0x6d);
|
||||
mt2266_writereg(priv, 0x1c, 0xff);
|
||||
}
|
||||
|
||||
static int mt2266_get_frequency(struct dvb_frontend *fe, u32 *frequency)
|
||||
@ -217,17 +275,22 @@ static int mt2266_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
|
||||
|
||||
static int mt2266_init(struct dvb_frontend *fe)
|
||||
{
|
||||
int ret;
|
||||
struct mt2266_priv *priv = fe->tuner_priv;
|
||||
mt2266_writereg(priv,0x17,0x6d);
|
||||
mt2266_writereg(priv,0x1c,0xff);
|
||||
ret = mt2266_writereg(priv, 0x17, 0x6d);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
ret = mt2266_writereg(priv, 0x1c, 0xff);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mt2266_sleep(struct dvb_frontend *fe)
|
||||
{
|
||||
struct mt2266_priv *priv = fe->tuner_priv;
|
||||
mt2266_writereg(priv,0x17,0x6d);
|
||||
mt2266_writereg(priv,0x1c,0x00);
|
||||
mt2266_writereg(priv, 0x17, 0x6d);
|
||||
mt2266_writereg(priv, 0x1c, 0x00);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -241,8 +304,8 @@ static int mt2266_release(struct dvb_frontend *fe)
|
||||
static const struct dvb_tuner_ops mt2266_tuner_ops = {
|
||||
.info = {
|
||||
.name = "Microtune MT2266",
|
||||
.frequency_min = 470000000,
|
||||
.frequency_max = 860000000,
|
||||
.frequency_min = 174000000,
|
||||
.frequency_max = 862000000,
|
||||
.frequency_step = 50000,
|
||||
},
|
||||
.release = mt2266_release,
|
||||
@ -264,8 +327,9 @@ struct dvb_frontend * mt2266_attach(struct dvb_frontend *fe, struct i2c_adapter
|
||||
|
||||
priv->cfg = cfg;
|
||||
priv->i2c = i2c;
|
||||
priv->band = MT2266_UHF;
|
||||
|
||||
if (mt2266_readreg(priv,0,&id) != 0) {
|
||||
if (mt2266_readreg(priv, 0, &id)) {
|
||||
kfree(priv);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -37,9 +37,9 @@
|
||||
|
||||
|
||||
struct mt312_state {
|
||||
struct i2c_adapter* i2c;
|
||||
struct i2c_adapter *i2c;
|
||||
/* configuration settings */
|
||||
const struct mt312_config* config;
|
||||
const struct mt312_config *config;
|
||||
struct dvb_frontend frontend;
|
||||
|
||||
u8 id;
|
||||
@ -49,14 +49,15 @@ struct mt312_state {
|
||||
static int debug;
|
||||
#define dprintk(args...) \
|
||||
do { \
|
||||
if (debug) printk(KERN_DEBUG "mt312: " args); \
|
||||
if (debug) \
|
||||
printk(KERN_DEBUG "mt312: " args); \
|
||||
} while (0)
|
||||
|
||||
#define MT312_SYS_CLK 90000000UL /* 90 MHz */
|
||||
#define MT312_LPOWER_SYS_CLK 60000000UL /* 60 MHz */
|
||||
#define MT312_PLL_CLK 10000000UL /* 10 MHz */
|
||||
|
||||
static int mt312_read(struct mt312_state* state, const enum mt312_reg_addr reg,
|
||||
static int mt312_read(struct mt312_state *state, const enum mt312_reg_addr reg,
|
||||
void *buf, const size_t count)
|
||||
{
|
||||
int ret;
|
||||
@ -79,7 +80,7 @@ static int mt312_read(struct mt312_state* state, const enum mt312_reg_addr reg,
|
||||
return -EREMOTEIO;
|
||||
}
|
||||
|
||||
if(debug) {
|
||||
if (debug) {
|
||||
int i;
|
||||
dprintk("R(%d):", reg & 0x7f);
|
||||
for (i = 0; i < count; i++)
|
||||
@ -90,14 +91,14 @@ static int mt312_read(struct mt312_state* state, const enum mt312_reg_addr reg,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mt312_write(struct mt312_state* state, const enum mt312_reg_addr reg,
|
||||
static int mt312_write(struct mt312_state *state, const enum mt312_reg_addr reg,
|
||||
const void *src, const size_t count)
|
||||
{
|
||||
int ret;
|
||||
u8 buf[count + 1];
|
||||
struct i2c_msg msg;
|
||||
|
||||
if(debug) {
|
||||
if (debug) {
|
||||
int i;
|
||||
dprintk("W(%d):", reg & 0x7f);
|
||||
for (i = 0; i < count; i++)
|
||||
@ -123,13 +124,13 @@ static int mt312_write(struct mt312_state* state, const enum mt312_reg_addr reg,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int mt312_readreg(struct mt312_state* state,
|
||||
static inline int mt312_readreg(struct mt312_state *state,
|
||||
const enum mt312_reg_addr reg, u8 *val)
|
||||
{
|
||||
return mt312_read(state, reg, val, 1);
|
||||
}
|
||||
|
||||
static inline int mt312_writereg(struct mt312_state* state,
|
||||
static inline int mt312_writereg(struct mt312_state *state,
|
||||
const enum mt312_reg_addr reg, const u8 val)
|
||||
{
|
||||
return mt312_write(state, reg, &val, 1);
|
||||
@ -140,18 +141,19 @@ static inline u32 mt312_div(u32 a, u32 b)
|
||||
return (a + (b / 2)) / b;
|
||||
}
|
||||
|
||||
static int mt312_reset(struct mt312_state* state, const u8 full)
|
||||
static int mt312_reset(struct mt312_state *state, const u8 full)
|
||||
{
|
||||
return mt312_writereg(state, RESET, full ? 0x80 : 0x40);
|
||||
}
|
||||
|
||||
static int mt312_get_inversion(struct mt312_state* state,
|
||||
static int mt312_get_inversion(struct mt312_state *state,
|
||||
fe_spectral_inversion_t *i)
|
||||
{
|
||||
int ret;
|
||||
u8 vit_mode;
|
||||
|
||||
if ((ret = mt312_readreg(state, VIT_MODE, &vit_mode)) < 0)
|
||||
ret = mt312_readreg(state, VIT_MODE, &vit_mode);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (vit_mode & 0x80) /* auto inversion was used */
|
||||
@ -160,7 +162,7 @@ static int mt312_get_inversion(struct mt312_state* state,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mt312_get_symbol_rate(struct mt312_state* state, u32 *sr)
|
||||
static int mt312_get_symbol_rate(struct mt312_state *state, u32 *sr)
|
||||
{
|
||||
int ret;
|
||||
u8 sym_rate_h;
|
||||
@ -169,37 +171,44 @@ static int mt312_get_symbol_rate(struct mt312_state* state, u32 *sr)
|
||||
u16 monitor;
|
||||
u8 buf[2];
|
||||
|
||||
if ((ret = mt312_readreg(state, SYM_RATE_H, &sym_rate_h)) < 0)
|
||||
ret = mt312_readreg(state, SYM_RATE_H, &sym_rate_h);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (sym_rate_h & 0x80) { /* symbol rate search was used */
|
||||
if ((ret = mt312_writereg(state, MON_CTRL, 0x03)) < 0)
|
||||
if (sym_rate_h & 0x80) {
|
||||
/* symbol rate search was used */
|
||||
ret = mt312_writereg(state, MON_CTRL, 0x03);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if ((ret = mt312_read(state, MONITOR_H, buf, sizeof(buf))) < 0)
|
||||
ret = mt312_read(state, MONITOR_H, buf, sizeof(buf));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
monitor = (buf[0] << 8) | buf[1];
|
||||
|
||||
dprintk(KERN_DEBUG "sr(auto) = %u\n",
|
||||
dprintk("sr(auto) = %u\n",
|
||||
mt312_div(monitor * 15625, 4));
|
||||
} else {
|
||||
if ((ret = mt312_writereg(state, MON_CTRL, 0x05)) < 0)
|
||||
ret = mt312_writereg(state, MON_CTRL, 0x05);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if ((ret = mt312_read(state, MONITOR_H, buf, sizeof(buf))) < 0)
|
||||
ret = mt312_read(state, MONITOR_H, buf, sizeof(buf));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
dec_ratio = ((buf[0] >> 5) & 0x07) * 32;
|
||||
|
||||
if ((ret = mt312_read(state, SYM_RAT_OP_H, buf, sizeof(buf))) < 0)
|
||||
ret = mt312_read(state, SYM_RAT_OP_H, buf, sizeof(buf));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
sym_rat_op = (buf[0] << 8) | buf[1];
|
||||
|
||||
dprintk(KERN_DEBUG "sym_rat_op=%d dec_ratio=%d\n",
|
||||
dprintk("sym_rat_op=%d dec_ratio=%d\n",
|
||||
sym_rat_op, dec_ratio);
|
||||
dprintk(KERN_DEBUG "*sr(manual) = %lu\n",
|
||||
dprintk("*sr(manual) = %lu\n",
|
||||
(((MT312_PLL_CLK * 8192) / (sym_rat_op + 8192)) *
|
||||
2) - dec_ratio);
|
||||
}
|
||||
@ -207,7 +216,7 @@ static int mt312_get_symbol_rate(struct mt312_state* state, u32 *sr)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mt312_get_code_rate(struct mt312_state* state, fe_code_rate_t *cr)
|
||||
static int mt312_get_code_rate(struct mt312_state *state, fe_code_rate_t *cr)
|
||||
{
|
||||
const fe_code_rate_t fec_tab[8] =
|
||||
{ FEC_1_2, FEC_2_3, FEC_3_4, FEC_5_6, FEC_6_7, FEC_7_8,
|
||||
@ -216,7 +225,8 @@ static int mt312_get_code_rate(struct mt312_state* state, fe_code_rate_t *cr)
|
||||
int ret;
|
||||
u8 fec_status;
|
||||
|
||||
if ((ret = mt312_readreg(state, FEC_STATUS, &fec_status)) < 0)
|
||||
ret = mt312_readreg(state, FEC_STATUS, &fec_status);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
*cr = fec_tab[(fec_status >> 4) & 0x07];
|
||||
@ -224,61 +234,72 @@ static int mt312_get_code_rate(struct mt312_state* state, fe_code_rate_t *cr)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mt312_initfe(struct dvb_frontend* fe)
|
||||
static int mt312_initfe(struct dvb_frontend *fe)
|
||||
{
|
||||
struct mt312_state *state = fe->demodulator_priv;
|
||||
int ret;
|
||||
u8 buf[2];
|
||||
|
||||
/* wake up */
|
||||
if ((ret = mt312_writereg(state, CONFIG, (state->frequency == 60 ? 0x88 : 0x8c))) < 0)
|
||||
ret = mt312_writereg(state, CONFIG,
|
||||
(state->frequency == 60 ? 0x88 : 0x8c));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* wait at least 150 usec */
|
||||
udelay(150);
|
||||
|
||||
/* full reset */
|
||||
if ((ret = mt312_reset(state, 1)) < 0)
|
||||
ret = mt312_reset(state, 1);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
// Per datasheet, write correct values. 09/28/03 ACCJr.
|
||||
// If we don't do this, we won't get FE_HAS_VITERBI in the VP310.
|
||||
/* Per datasheet, write correct values. 09/28/03 ACCJr.
|
||||
* If we don't do this, we won't get FE_HAS_VITERBI in the VP310. */
|
||||
{
|
||||
u8 buf_def[8]={0x14, 0x12, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00};
|
||||
u8 buf_def[8] = { 0x14, 0x12, 0x03, 0x02,
|
||||
0x01, 0x00, 0x00, 0x00 };
|
||||
|
||||
if ((ret = mt312_write(state, VIT_SETUP, buf_def, sizeof(buf_def))) < 0)
|
||||
ret = mt312_write(state, VIT_SETUP, buf_def, sizeof(buf_def));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* SYS_CLK */
|
||||
buf[0] = mt312_div((state->frequency == 60 ? MT312_LPOWER_SYS_CLK : MT312_SYS_CLK) * 2, 1000000);
|
||||
buf[0] = mt312_div((state->frequency == 60 ? MT312_LPOWER_SYS_CLK :
|
||||
MT312_SYS_CLK) * 2, 1000000);
|
||||
|
||||
/* DISEQC_RATIO */
|
||||
buf[1] = mt312_div(MT312_PLL_CLK, 15000 * 4);
|
||||
|
||||
if ((ret = mt312_write(state, SYS_CLK, buf, sizeof(buf))) < 0)
|
||||
ret = mt312_write(state, SYS_CLK, buf, sizeof(buf));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if ((ret = mt312_writereg(state, SNR_THS_HIGH, 0x32)) < 0)
|
||||
ret = mt312_writereg(state, SNR_THS_HIGH, 0x32);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if ((ret = mt312_writereg(state, OP_CTRL, 0x53)) < 0)
|
||||
ret = mt312_writereg(state, OP_CTRL, 0x53);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* TS_SW_LIM */
|
||||
buf[0] = 0x8c;
|
||||
buf[1] = 0x98;
|
||||
|
||||
if ((ret = mt312_write(state, TS_SW_LIM_L, buf, sizeof(buf))) < 0)
|
||||
ret = mt312_write(state, TS_SW_LIM_L, buf, sizeof(buf));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if ((ret = mt312_writereg(state, CS_SW_LIM, 0x69)) < 0)
|
||||
ret = mt312_writereg(state, CS_SW_LIM, 0x69);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mt312_send_master_cmd(struct dvb_frontend* fe,
|
||||
static int mt312_send_master_cmd(struct dvb_frontend *fe,
|
||||
struct dvb_diseqc_master_cmd *c)
|
||||
{
|
||||
struct mt312_state *state = fe->demodulator_priv;
|
||||
@ -288,29 +309,31 @@ static int mt312_send_master_cmd(struct dvb_frontend* fe,
|
||||
if ((c->msg_len == 0) || (c->msg_len > sizeof(c->msg)))
|
||||
return -EINVAL;
|
||||
|
||||
if ((ret = mt312_readreg(state, DISEQC_MODE, &diseqc_mode)) < 0)
|
||||
ret = mt312_readreg(state, DISEQC_MODE, &diseqc_mode);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if ((ret =
|
||||
mt312_write(state, (0x80 | DISEQC_INSTR), c->msg, c->msg_len)) < 0)
|
||||
ret = mt312_write(state, (0x80 | DISEQC_INSTR), c->msg, c->msg_len);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if ((ret =
|
||||
mt312_writereg(state, DISEQC_MODE,
|
||||
ret = mt312_writereg(state, DISEQC_MODE,
|
||||
(diseqc_mode & 0x40) | ((c->msg_len - 1) << 3)
|
||||
| 0x04)) < 0)
|
||||
| 0x04);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* set DISEQC_MODE[2:0] to zero if a return message is expected */
|
||||
if (c->msg[0] & 0x02)
|
||||
if ((ret =
|
||||
mt312_writereg(state, DISEQC_MODE, (diseqc_mode & 0x40))) < 0)
|
||||
if (c->msg[0] & 0x02) {
|
||||
ret = mt312_writereg(state, DISEQC_MODE, (diseqc_mode & 0x40));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mt312_send_burst(struct dvb_frontend* fe, const fe_sec_mini_cmd_t c)
|
||||
static int mt312_send_burst(struct dvb_frontend *fe, const fe_sec_mini_cmd_t c)
|
||||
{
|
||||
struct mt312_state *state = fe->demodulator_priv;
|
||||
const u8 mini_tab[2] = { 0x02, 0x03 };
|
||||
@ -321,18 +344,19 @@ static int mt312_send_burst(struct dvb_frontend* fe, const fe_sec_mini_cmd_t c)
|
||||
if (c > SEC_MINI_B)
|
||||
return -EINVAL;
|
||||
|
||||
if ((ret = mt312_readreg(state, DISEQC_MODE, &diseqc_mode)) < 0)
|
||||
ret = mt312_readreg(state, DISEQC_MODE, &diseqc_mode);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if ((ret =
|
||||
mt312_writereg(state, DISEQC_MODE,
|
||||
(diseqc_mode & 0x40) | mini_tab[c])) < 0)
|
||||
ret = mt312_writereg(state, DISEQC_MODE,
|
||||
(diseqc_mode & 0x40) | mini_tab[c]);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mt312_set_tone(struct dvb_frontend* fe, const fe_sec_tone_mode_t t)
|
||||
static int mt312_set_tone(struct dvb_frontend *fe, const fe_sec_tone_mode_t t)
|
||||
{
|
||||
struct mt312_state *state = fe->demodulator_priv;
|
||||
const u8 tone_tab[2] = { 0x01, 0x00 };
|
||||
@ -343,18 +367,19 @@ static int mt312_set_tone(struct dvb_frontend* fe, const fe_sec_tone_mode_t t)
|
||||
if (t > SEC_TONE_OFF)
|
||||
return -EINVAL;
|
||||
|
||||
if ((ret = mt312_readreg(state, DISEQC_MODE, &diseqc_mode)) < 0)
|
||||
ret = mt312_readreg(state, DISEQC_MODE, &diseqc_mode);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if ((ret =
|
||||
mt312_writereg(state, DISEQC_MODE,
|
||||
(diseqc_mode & 0x40) | tone_tab[t])) < 0)
|
||||
ret = mt312_writereg(state, DISEQC_MODE,
|
||||
(diseqc_mode & 0x40) | tone_tab[t]);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mt312_set_voltage(struct dvb_frontend* fe, const fe_sec_voltage_t v)
|
||||
static int mt312_set_voltage(struct dvb_frontend *fe, const fe_sec_voltage_t v)
|
||||
{
|
||||
struct mt312_state *state = fe->demodulator_priv;
|
||||
const u8 volt_tab[3] = { 0x00, 0x40, 0x00 };
|
||||
@ -365,7 +390,7 @@ static int mt312_set_voltage(struct dvb_frontend* fe, const fe_sec_voltage_t v)
|
||||
return mt312_writereg(state, DISEQC_MODE, volt_tab[v]);
|
||||
}
|
||||
|
||||
static int mt312_read_status(struct dvb_frontend* fe, fe_status_t *s)
|
||||
static int mt312_read_status(struct dvb_frontend *fe, fe_status_t *s)
|
||||
{
|
||||
struct mt312_state *state = fe->demodulator_priv;
|
||||
int ret;
|
||||
@ -373,10 +398,12 @@ static int mt312_read_status(struct dvb_frontend* fe, fe_status_t *s)
|
||||
|
||||
*s = 0;
|
||||
|
||||
if ((ret = mt312_read(state, QPSK_STAT_H, status, sizeof(status))) < 0)
|
||||
ret = mt312_read(state, QPSK_STAT_H, status, sizeof(status));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
dprintk(KERN_DEBUG "QPSK_STAT_H: 0x%02x, QPSK_STAT_L: 0x%02x, FEC_STATUS: 0x%02x\n", status[0], status[1], status[2]);
|
||||
dprintk("QPSK_STAT_H: 0x%02x, QPSK_STAT_L: 0x%02x,"
|
||||
" FEC_STATUS: 0x%02x\n", status[0], status[1], status[2]);
|
||||
|
||||
if (status[0] & 0xc0)
|
||||
*s |= FE_HAS_SIGNAL; /* signal noise ratio */
|
||||
@ -392,13 +419,14 @@ static int mt312_read_status(struct dvb_frontend* fe, fe_status_t *s)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mt312_read_ber(struct dvb_frontend* fe, u32 *ber)
|
||||
static int mt312_read_ber(struct dvb_frontend *fe, u32 *ber)
|
||||
{
|
||||
struct mt312_state *state = fe->demodulator_priv;
|
||||
int ret;
|
||||
u8 buf[3];
|
||||
|
||||
if ((ret = mt312_read(state, RS_BERCNT_H, buf, 3)) < 0)
|
||||
ret = mt312_read(state, RS_BERCNT_H, buf, 3);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
*ber = ((buf[0] << 16) | (buf[1] << 8) | buf[2]) * 64;
|
||||
@ -406,7 +434,8 @@ static int mt312_read_ber(struct dvb_frontend* fe, u32 *ber)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mt312_read_signal_strength(struct dvb_frontend* fe, u16 *signal_strength)
|
||||
static int mt312_read_signal_strength(struct dvb_frontend *fe,
|
||||
u16 *signal_strength)
|
||||
{
|
||||
struct mt312_state *state = fe->demodulator_priv;
|
||||
int ret;
|
||||
@ -414,7 +443,8 @@ static int mt312_read_signal_strength(struct dvb_frontend* fe, u16 *signal_stren
|
||||
u16 agc;
|
||||
s16 err_db;
|
||||
|
||||
if ((ret = mt312_read(state, AGC_H, buf, sizeof(buf))) < 0)
|
||||
ret = mt312_read(state, AGC_H, buf, sizeof(buf));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
agc = (buf[0] << 6) | (buf[1] >> 2);
|
||||
@ -422,18 +452,19 @@ static int mt312_read_signal_strength(struct dvb_frontend* fe, u16 *signal_stren
|
||||
|
||||
*signal_strength = agc;
|
||||
|
||||
dprintk(KERN_DEBUG "agc=%08x err_db=%hd\n", agc, err_db);
|
||||
dprintk("agc=%08x err_db=%hd\n", agc, err_db);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mt312_read_snr(struct dvb_frontend* fe, u16 *snr)
|
||||
static int mt312_read_snr(struct dvb_frontend *fe, u16 *snr)
|
||||
{
|
||||
struct mt312_state *state = fe->demodulator_priv;
|
||||
int ret;
|
||||
u8 buf[2];
|
||||
|
||||
if ((ret = mt312_read(state, M_SNR_H, &buf, sizeof(buf))) < 0)
|
||||
ret = mt312_read(state, M_SNR_H, &buf, sizeof(buf));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
*snr = 0xFFFF - ((((buf[0] & 0x7f) << 8) | buf[1]) << 1);
|
||||
@ -441,13 +472,14 @@ static int mt312_read_snr(struct dvb_frontend* fe, u16 *snr)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mt312_read_ucblocks(struct dvb_frontend* fe, u32 *ubc)
|
||||
static int mt312_read_ucblocks(struct dvb_frontend *fe, u32 *ubc)
|
||||
{
|
||||
struct mt312_state *state = fe->demodulator_priv;
|
||||
int ret;
|
||||
u8 buf[2];
|
||||
|
||||
if ((ret = mt312_read(state, RS_UBC_H, &buf, sizeof(buf))) < 0)
|
||||
ret = mt312_read(state, RS_UBC_H, &buf, sizeof(buf));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
*ubc = (buf[0] << 8) | buf[1];
|
||||
@ -455,7 +487,7 @@ static int mt312_read_ucblocks(struct dvb_frontend* fe, u32 *ubc)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mt312_set_frontend(struct dvb_frontend* fe,
|
||||
static int mt312_set_frontend(struct dvb_frontend *fe,
|
||||
struct dvb_frontend_parameters *p)
|
||||
{
|
||||
struct mt312_state *state = fe->demodulator_priv;
|
||||
@ -491,24 +523,28 @@ static int mt312_set_frontend(struct dvb_frontend* fe,
|
||||
|
||||
switch (state->id) {
|
||||
case ID_VP310:
|
||||
// For now we will do this only for the VP310.
|
||||
// It should be better for the mt312 as well, but tunning will be slower. ACCJr 09/29/03
|
||||
/* For now we will do this only for the VP310.
|
||||
* It should be better for the mt312 as well,
|
||||
* but tuning will be slower. ACCJr 09/29/03
|
||||
*/
|
||||
ret = mt312_readreg(state, CONFIG, &config_val);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
if (p->u.qpsk.symbol_rate >= 30000000) //Note that 30MS/s should use 90MHz
|
||||
{
|
||||
if ((config_val & 0x0c) == 0x08) { //We are running 60MHz
|
||||
if (p->u.qpsk.symbol_rate >= 30000000) {
|
||||
/* Note that 30MS/s should use 90MHz */
|
||||
if ((config_val & 0x0c) == 0x08) {
|
||||
/* We are running 60MHz */
|
||||
state->frequency = 90;
|
||||
if ((ret = mt312_initfe(fe)) < 0)
|
||||
ret = mt312_initfe(fe);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((config_val & 0x0c) == 0x0C) { //We are running 90MHz
|
||||
} else {
|
||||
if ((config_val & 0x0c) == 0x0C) {
|
||||
/* We are running 90MHz */
|
||||
state->frequency = 60;
|
||||
if ((ret = mt312_initfe(fe)) < 0)
|
||||
ret = mt312_initfe(fe);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
@ -523,7 +559,8 @@ static int mt312_set_frontend(struct dvb_frontend* fe,
|
||||
|
||||
if (fe->ops.tuner_ops.set_params) {
|
||||
fe->ops.tuner_ops.set_params(fe, p);
|
||||
if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
|
||||
if (fe->ops.i2c_gate_ctrl)
|
||||
fe->ops.i2c_gate_ctrl(fe, 0);
|
||||
}
|
||||
|
||||
/* sr = (u16)(sr * 256.0 / 1000000.0) */
|
||||
@ -545,7 +582,8 @@ static int mt312_set_frontend(struct dvb_frontend* fe,
|
||||
/* GO */
|
||||
buf[4] = 0x01;
|
||||
|
||||
if ((ret = mt312_write(state, SYM_RATE_H, buf, sizeof(buf))) < 0)
|
||||
ret = mt312_write(state, SYM_RATE_H, buf, sizeof(buf));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
mt312_reset(state, 0);
|
||||
@ -553,27 +591,30 @@ static int mt312_set_frontend(struct dvb_frontend* fe,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mt312_get_frontend(struct dvb_frontend* fe,
|
||||
static int mt312_get_frontend(struct dvb_frontend *fe,
|
||||
struct dvb_frontend_parameters *p)
|
||||
{
|
||||
struct mt312_state *state = fe->demodulator_priv;
|
||||
int ret;
|
||||
|
||||
if ((ret = mt312_get_inversion(state, &p->inversion)) < 0)
|
||||
ret = mt312_get_inversion(state, &p->inversion);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if ((ret = mt312_get_symbol_rate(state, &p->u.qpsk.symbol_rate)) < 0)
|
||||
ret = mt312_get_symbol_rate(state, &p->u.qpsk.symbol_rate);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if ((ret = mt312_get_code_rate(state, &p->u.qpsk.fec_inner)) < 0)
|
||||
ret = mt312_get_code_rate(state, &p->u.qpsk.fec_inner);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mt312_i2c_gate_ctrl(struct dvb_frontend* fe, int enable)
|
||||
static int mt312_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
|
||||
{
|
||||
struct mt312_state* state = fe->demodulator_priv;
|
||||
struct mt312_state *state = fe->demodulator_priv;
|
||||
|
||||
if (enable) {
|
||||
return mt312_writereg(state, GPP_CTRL, 0x40);
|
||||
@ -582,27 +623,31 @@ static int mt312_i2c_gate_ctrl(struct dvb_frontend* fe, int enable)
|
||||
}
|
||||
}
|
||||
|
||||
static int mt312_sleep(struct dvb_frontend* fe)
|
||||
static int mt312_sleep(struct dvb_frontend *fe)
|
||||
{
|
||||
struct mt312_state *state = fe->demodulator_priv;
|
||||
int ret;
|
||||
u8 config;
|
||||
|
||||
/* reset all registers to defaults */
|
||||
if ((ret = mt312_reset(state, 1)) < 0)
|
||||
ret = mt312_reset(state, 1);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if ((ret = mt312_readreg(state, CONFIG, &config)) < 0)
|
||||
ret = mt312_readreg(state, CONFIG, &config);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* enter standby */
|
||||
if ((ret = mt312_writereg(state, CONFIG, config & 0x7f)) < 0)
|
||||
ret = mt312_writereg(state, CONFIG, config & 0x7f);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mt312_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings)
|
||||
static int mt312_get_tune_settings(struct dvb_frontend *fe,
|
||||
struct dvb_frontend_tune_settings *fesettings)
|
||||
{
|
||||
fesettings->min_delay_ms = 50;
|
||||
fesettings->step_size = 0;
|
||||
@ -610,9 +655,9 @@ static int mt312_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void mt312_release(struct dvb_frontend* fe)
|
||||
static void mt312_release(struct dvb_frontend *fe)
|
||||
{
|
||||
struct mt312_state* state = fe->demodulator_priv;
|
||||
struct mt312_state *state = fe->demodulator_priv;
|
||||
kfree(state);
|
||||
}
|
||||
|
||||
@ -655,10 +700,10 @@ static struct dvb_frontend_ops vp310_mt312_ops = {
|
||||
.set_voltage = mt312_set_voltage,
|
||||
};
|
||||
|
||||
struct dvb_frontend* vp310_mt312_attach(const struct mt312_config* config,
|
||||
struct i2c_adapter* i2c)
|
||||
struct dvb_frontend *vp310_mt312_attach(const struct mt312_config *config,
|
||||
struct i2c_adapter *i2c)
|
||||
{
|
||||
struct mt312_state* state = NULL;
|
||||
struct mt312_state *state = NULL;
|
||||
|
||||
/* allocate memory for the internal state */
|
||||
state = kmalloc(sizeof(struct mt312_state), GFP_KERNEL);
|
||||
@ -674,7 +719,8 @@ struct dvb_frontend* vp310_mt312_attach(const struct mt312_config* config,
|
||||
goto error;
|
||||
|
||||
/* create dvb_frontend */
|
||||
memcpy(&state->frontend.ops, &vp310_mt312_ops, sizeof(struct dvb_frontend_ops));
|
||||
memcpy(&state->frontend.ops, &vp310_mt312_ops,
|
||||
sizeof(struct dvb_frontend_ops));
|
||||
state->frontend.demodulator_priv = state;
|
||||
|
||||
switch (state->id) {
|
||||
@ -687,7 +733,8 @@ struct dvb_frontend* vp310_mt312_attach(const struct mt312_config* config,
|
||||
state->frequency = 60;
|
||||
break;
|
||||
default:
|
||||
printk (KERN_WARNING "Only Zarlink VP310/MT312 are supported chips.\n");
|
||||
printk(KERN_WARNING "Only Zarlink VP310/MT312"
|
||||
" are supported chips.\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
@ -697,6 +744,7 @@ error:
|
||||
kfree(state);
|
||||
return NULL;
|
||||
}
|
||||
EXPORT_SYMBOL(vp310_mt312_attach);
|
||||
|
||||
module_param(debug, int, 0644);
|
||||
MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
|
||||
@ -705,4 +753,3 @@ MODULE_DESCRIPTION("Zarlink VP310/MT312 DVB-S Demodulator driver");
|
||||
MODULE_AUTHOR("Andreas Oberritter <obi@linuxtv.org>");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
EXPORT_SYMBOL(vp310_mt312_attach);
|
||||
|
@ -28,22 +28,21 @@
|
||||
|
||||
#include <linux/dvb/frontend.h>
|
||||
|
||||
struct mt312_config
|
||||
{
|
||||
struct mt312_config {
|
||||
/* the demodulator's i2c address */
|
||||
u8 demod_address;
|
||||
};
|
||||
|
||||
#if defined(CONFIG_DVB_MT312) || (defined(CONFIG_DVB_MT312_MODULE) && defined(MODULE))
|
||||
struct dvb_frontend* vp310_mt312_attach(const struct mt312_config* config,
|
||||
struct i2c_adapter* i2c);
|
||||
struct dvb_frontend *vp310_mt312_attach(const struct mt312_config *config,
|
||||
struct i2c_adapter *i2c);
|
||||
#else
|
||||
static inline struct dvb_frontend* vp310_mt312_attach(const struct mt312_config* config,
|
||||
struct i2c_adapter* i2c)
|
||||
static inline struct dvb_frontend *vp310_mt312_attach(
|
||||
const struct mt312_config *config, struct i2c_adapter *i2c)
|
||||
{
|
||||
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
|
||||
return NULL;
|
||||
}
|
||||
#endif // CONFIG_DVB_MT312
|
||||
#endif /* CONFIG_DVB_MT312 */
|
||||
|
||||
#endif // MT312_H
|
||||
#endif /* MT312_H */
|
||||
|
@ -152,7 +152,13 @@ static void mt352_calc_input_freq(struct mt352_state* state,
|
||||
if (state->config.if2)
|
||||
if2 = state->config.if2;
|
||||
|
||||
ife = (2*adc_clock - if2);
|
||||
if (adc_clock >= if2 * 2)
|
||||
ife = if2;
|
||||
else {
|
||||
ife = adc_clock - (if2 % adc_clock);
|
||||
if (ife > adc_clock / 2)
|
||||
ife = adc_clock - ife;
|
||||
}
|
||||
value = -16374 * ife / adc_clock;
|
||||
dprintk("%s: if2 %d, ife %d, adc_clock %d => %d / 0x%x\n",
|
||||
__FUNCTION__, if2, ife, adc_clock, value, value & 0x3fff);
|
||||
|
@ -564,7 +564,7 @@ struct dvb_frontend* or51132_attach(const struct or51132_config* config,
|
||||
/* Allocate memory for the internal state */
|
||||
state = kmalloc(sizeof(struct or51132_state), GFP_KERNEL);
|
||||
if (state == NULL)
|
||||
goto error;
|
||||
return NULL;
|
||||
|
||||
/* Setup the state */
|
||||
state->config = config;
|
||||
@ -576,10 +576,6 @@ struct dvb_frontend* or51132_attach(const struct or51132_config* config,
|
||||
memcpy(&state->frontend.ops, &or51132_ops, sizeof(struct dvb_frontend_ops));
|
||||
state->frontend.demodulator_priv = state;
|
||||
return &state->frontend;
|
||||
|
||||
error:
|
||||
kfree(state);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct dvb_frontend_ops or51132_ops = {
|
||||
|
@ -529,7 +529,7 @@ struct dvb_frontend* or51211_attach(const struct or51211_config* config,
|
||||
/* Allocate memory for the internal state */
|
||||
state = kmalloc(sizeof(struct or51211_state), GFP_KERNEL);
|
||||
if (state == NULL)
|
||||
goto error;
|
||||
return NULL;
|
||||
|
||||
/* Setup the state */
|
||||
state->config = config;
|
||||
@ -541,10 +541,6 @@ struct dvb_frontend* or51211_attach(const struct or51211_config* config,
|
||||
memcpy(&state->frontend.ops, &or51211_ops, sizeof(struct dvb_frontend_ops));
|
||||
state->frontend.demodulator_priv = state;
|
||||
return &state->frontend;
|
||||
|
||||
error:
|
||||
kfree(state);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct dvb_frontend_ops or51211_ops = {
|
||||
|
@ -42,6 +42,7 @@ struct s5h1409_state {
|
||||
fe_modulation_t current_modulation;
|
||||
|
||||
u32 current_frequency;
|
||||
int if_freq;
|
||||
|
||||
u32 is_qam_locked;
|
||||
u32 qam_state;
|
||||
@ -97,7 +98,7 @@ static struct init_tab {
|
||||
{ 0xac, 0x1003, },
|
||||
{ 0xad, 0x103f, },
|
||||
{ 0xe2, 0x0100, },
|
||||
{ 0xe3, 0x0000, },
|
||||
{ 0xe3, 0x1000, },
|
||||
{ 0x28, 0x1010, },
|
||||
{ 0xb1, 0x000e, },
|
||||
};
|
||||
@ -348,28 +349,32 @@ static int s5h1409_softreset(struct dvb_frontend* fe)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define S5H1409_VSB_IF_FREQ 5380
|
||||
#define S5H1409_QAM_IF_FREQ state->config->qam_if
|
||||
|
||||
static int s5h1409_set_if_freq(struct dvb_frontend* fe, int KHz)
|
||||
{
|
||||
struct s5h1409_state* state = fe->demodulator_priv;
|
||||
int ret = 0;
|
||||
|
||||
dprintk("%s(%d KHz)\n", __FUNCTION__, KHz);
|
||||
|
||||
if( (KHz == 44000) || (KHz == 5380) ) {
|
||||
s5h1409_writereg(state, 0x87, 0x01be);
|
||||
s5h1409_writereg(state, 0x88, 0x0436);
|
||||
s5h1409_writereg(state, 0x89, 0x054d);
|
||||
} else
|
||||
if (KHz == 4000) {
|
||||
switch (KHz) {
|
||||
case 4000:
|
||||
s5h1409_writereg(state, 0x87, 0x014b);
|
||||
s5h1409_writereg(state, 0x88, 0x0cb5);
|
||||
s5h1409_writereg(state, 0x89, 0x03e2);
|
||||
} else {
|
||||
printk("%s() Invalid arg = %d KHz\n", __FUNCTION__, KHz);
|
||||
ret = -1;
|
||||
break;
|
||||
case 5380:
|
||||
case 44000:
|
||||
default:
|
||||
s5h1409_writereg(state, 0x87, 0x01be);
|
||||
s5h1409_writereg(state, 0x88, 0x0436);
|
||||
s5h1409_writereg(state, 0x89, 0x054d);
|
||||
break;
|
||||
}
|
||||
state->if_freq = KHz;
|
||||
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int s5h1409_set_spectralinversion(struct dvb_frontend* fe, int inverted)
|
||||
@ -394,11 +399,15 @@ static int s5h1409_enable_modulation(struct dvb_frontend* fe,
|
||||
switch(m) {
|
||||
case VSB_8:
|
||||
dprintk("%s() VSB_8\n", __FUNCTION__);
|
||||
if (state->if_freq != S5H1409_VSB_IF_FREQ)
|
||||
s5h1409_set_if_freq(fe, S5H1409_VSB_IF_FREQ);
|
||||
s5h1409_writereg(state, 0xf4, 0);
|
||||
break;
|
||||
case QAM_64:
|
||||
case QAM_256:
|
||||
dprintk("%s() QAM_AUTO (64/256)\n", __FUNCTION__);
|
||||
if (state->if_freq != S5H1409_QAM_IF_FREQ)
|
||||
s5h1409_set_if_freq(fe, S5H1409_QAM_IF_FREQ);
|
||||
s5h1409_writereg(state, 0xf4, 1);
|
||||
s5h1409_writereg(state, 0x85, 0x110);
|
||||
break;
|
||||
@ -432,9 +441,11 @@ static int s5h1409_set_gpio(struct dvb_frontend* fe, int enable)
|
||||
dprintk("%s(%d)\n", __FUNCTION__, enable);
|
||||
|
||||
if (enable)
|
||||
return s5h1409_writereg(state, 0xe3, 0x1100);
|
||||
return s5h1409_writereg(state, 0xe3,
|
||||
s5h1409_readreg(state, 0xe3) | 0x1100);
|
||||
else
|
||||
return s5h1409_writereg(state, 0xe3, 0x1000);
|
||||
return s5h1409_writereg(state, 0xe3,
|
||||
s5h1409_readreg(state, 0xe3) & 0xeeff);
|
||||
}
|
||||
|
||||
static int s5h1409_sleep(struct dvb_frontend* fe, int enable)
|
||||
@ -504,13 +515,15 @@ static void s5h1409_set_qam_interleave_mode(struct dvb_frontend *fe)
|
||||
s5h1409_writereg(state, 0x96, 0x20);
|
||||
s5h1409_writereg(state, 0xad,
|
||||
( ((reg1 & 0xf000) >> 4) | (reg2 & 0xf0ff)) );
|
||||
s5h1409_writereg(state, 0xab, 0x1100);
|
||||
s5h1409_writereg(state, 0xab,
|
||||
s5h1409_readreg(state, 0xab) & 0xeffe);
|
||||
}
|
||||
} else {
|
||||
if (state->qam_state != 1) {
|
||||
state->qam_state = 1;
|
||||
s5h1409_writereg(state, 0x96, 0x08);
|
||||
s5h1409_writereg(state, 0xab, 0x1101);
|
||||
s5h1409_writereg(state, 0xab,
|
||||
s5h1409_readreg(state, 0xab) | 0x1001);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -547,6 +560,36 @@ static int s5h1409_set_frontend (struct dvb_frontend* fe,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int s5h1409_set_mpeg_timing(struct dvb_frontend *fe, int mode)
|
||||
{
|
||||
struct s5h1409_state *state = fe->demodulator_priv;
|
||||
u16 val;
|
||||
|
||||
dprintk("%s(%d)\n", __FUNCTION__, mode);
|
||||
|
||||
val = s5h1409_readreg(state, 0xac) & 0xcfff;
|
||||
switch (mode) {
|
||||
case S5H1409_MPEGTIMING_CONTINOUS_INVERTING_CLOCK:
|
||||
val |= 0x0000;
|
||||
break;
|
||||
case S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK:
|
||||
dprintk("%s(%d) Mode1 or Defaulting\n", __FUNCTION__, mode);
|
||||
val |= 0x1000;
|
||||
break;
|
||||
case S5H1409_MPEGTIMING_NONCONTINOUS_INVERTING_CLOCK:
|
||||
val |= 0x2000;
|
||||
break;
|
||||
case S5H1409_MPEGTIMING_NONCONTINOUS_NONINVERTING_CLOCK:
|
||||
val |= 0x3000;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Configure MPEG Signal Timing charactistics */
|
||||
return s5h1409_writereg(state, 0xac, val);
|
||||
}
|
||||
|
||||
/* Reset the demod hardware and reset all of the configuration registers
|
||||
to a default state. */
|
||||
static int s5h1409_init (struct dvb_frontend* fe)
|
||||
@ -566,13 +609,16 @@ static int s5h1409_init (struct dvb_frontend* fe)
|
||||
state->current_modulation = VSB_8;
|
||||
|
||||
if (state->config->output_mode == S5H1409_SERIAL_OUTPUT)
|
||||
s5h1409_writereg(state, 0xab, 0x100); /* Serial */
|
||||
s5h1409_writereg(state, 0xab,
|
||||
s5h1409_readreg(state, 0xab) | 0x100); /* Serial */
|
||||
else
|
||||
s5h1409_writereg(state, 0xab, 0x0); /* Parallel */
|
||||
s5h1409_writereg(state, 0xab,
|
||||
s5h1409_readreg(state, 0xab) & 0xfeff); /* Parallel */
|
||||
|
||||
s5h1409_set_spectralinversion(fe, state->config->inversion);
|
||||
s5h1409_set_if_freq(fe, state->config->if_freq);
|
||||
s5h1409_set_if_freq(fe, state->if_freq);
|
||||
s5h1409_set_gpio(fe, state->config->gpio);
|
||||
s5h1409_set_mpeg_timing(fe, state->config->mpeg_timing);
|
||||
s5h1409_softreset(fe);
|
||||
|
||||
/* Note: Leaving the I2C gate closed. */
|
||||
@ -741,6 +787,7 @@ struct dvb_frontend* s5h1409_attach(const struct s5h1409_config* config,
|
||||
struct i2c_adapter* i2c)
|
||||
{
|
||||
struct s5h1409_state* state = NULL;
|
||||
u16 reg;
|
||||
|
||||
/* allocate memory for the internal state */
|
||||
state = kmalloc(sizeof(struct s5h1409_state), GFP_KERNEL);
|
||||
@ -751,9 +798,11 @@ struct dvb_frontend* s5h1409_attach(const struct s5h1409_config* config,
|
||||
state->config = config;
|
||||
state->i2c = i2c;
|
||||
state->current_modulation = 0;
|
||||
state->if_freq = S5H1409_VSB_IF_FREQ;
|
||||
|
||||
/* check if the demod exists */
|
||||
if (s5h1409_readreg(state, 0x04) != 0x0066)
|
||||
reg = s5h1409_readreg(state, 0x04);
|
||||
if ((reg != 0x0066) && (reg != 0x007f))
|
||||
goto error;
|
||||
|
||||
/* create dvb_frontend */
|
||||
@ -761,8 +810,14 @@ struct dvb_frontend* s5h1409_attach(const struct s5h1409_config* config,
|
||||
sizeof(struct dvb_frontend_ops));
|
||||
state->frontend.demodulator_priv = state;
|
||||
|
||||
if (s5h1409_init(&state->frontend) != 0) {
|
||||
printk(KERN_ERR "%s: Failed to initialize correctly\n",
|
||||
__FUNCTION__);
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Note: Leaving the I2C gate open here. */
|
||||
s5h1409_writereg(state, 0xf3, 1);
|
||||
s5h1409_i2c_gate_ctrl(&state->frontend, 1);
|
||||
|
||||
return &state->frontend;
|
||||
|
||||
|
@ -39,8 +39,8 @@ struct s5h1409_config
|
||||
#define S5H1409_GPIO_ON 1
|
||||
u8 gpio;
|
||||
|
||||
/* IF Freq in KHz */
|
||||
u16 if_freq;
|
||||
/* IF Freq for QAM in KHz, VSB is hardcoded to 5380 */
|
||||
u16 qam_if;
|
||||
|
||||
/* Spectral Inversion */
|
||||
#define S5H1409_INVERSION_OFF 0
|
||||
@ -51,6 +51,13 @@ struct s5h1409_config
|
||||
#define S5H1409_TUNERLOCKING 0
|
||||
#define S5H1409_DEMODLOCKING 1
|
||||
u8 status_mode;
|
||||
|
||||
/* MPEG signal timing */
|
||||
#define S5H1409_MPEGTIMING_CONTINOUS_INVERTING_CLOCK 0
|
||||
#define S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK 1
|
||||
#define S5H1409_MPEGTIMING_NONCONTINOUS_INVERTING_CLOCK 2
|
||||
#define S5H1409_MPEGTIMING_NONCONTINOUS_NONINVERTING_CLOCK 3
|
||||
u16 mpeg_timing;
|
||||
};
|
||||
|
||||
#if defined(CONFIG_DVB_S5H1409) || (defined(CONFIG_DVB_S5H1409_MODULE) && defined(MODULE))
|
||||
|
653
drivers/media/dvb/frontends/tda18271-common.c
Normal file
653
drivers/media/dvb/frontends/tda18271-common.c
Normal file
@ -0,0 +1,653 @@
|
||||
/*
|
||||
tda18271-common.c - driver for the Philips / NXP TDA18271 silicon tuner
|
||||
|
||||
Copyright (C) 2007, 2008 Michael Krufky <mkrufky@linuxtv.org>
|
||||
|
||||
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 "tda18271-priv.h"
|
||||
|
||||
static int tda18271_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
|
||||
{
|
||||
struct tda18271_priv *priv = fe->tuner_priv;
|
||||
enum tda18271_i2c_gate gate;
|
||||
int ret = 0;
|
||||
|
||||
switch (priv->gate) {
|
||||
case TDA18271_GATE_DIGITAL:
|
||||
case TDA18271_GATE_ANALOG:
|
||||
gate = priv->gate;
|
||||
break;
|
||||
case TDA18271_GATE_AUTO:
|
||||
default:
|
||||
switch (priv->mode) {
|
||||
case TDA18271_DIGITAL:
|
||||
gate = TDA18271_GATE_DIGITAL;
|
||||
break;
|
||||
case TDA18271_ANALOG:
|
||||
default:
|
||||
gate = TDA18271_GATE_ANALOG;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch (gate) {
|
||||
case TDA18271_GATE_ANALOG:
|
||||
if (fe->ops.analog_ops.i2c_gate_ctrl)
|
||||
ret = fe->ops.analog_ops.i2c_gate_ctrl(fe, enable);
|
||||
break;
|
||||
case TDA18271_GATE_DIGITAL:
|
||||
if (fe->ops.i2c_gate_ctrl)
|
||||
ret = fe->ops.i2c_gate_ctrl(fe, enable);
|
||||
break;
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
};
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
|
||||
static void tda18271_dump_regs(struct dvb_frontend *fe, int extended)
|
||||
{
|
||||
struct tda18271_priv *priv = fe->tuner_priv;
|
||||
unsigned char *regs = priv->tda18271_regs;
|
||||
|
||||
tda_reg("=== TDA18271 REG DUMP ===\n");
|
||||
tda_reg("ID_BYTE = 0x%02x\n", 0xff & regs[R_ID]);
|
||||
tda_reg("THERMO_BYTE = 0x%02x\n", 0xff & regs[R_TM]);
|
||||
tda_reg("POWER_LEVEL_BYTE = 0x%02x\n", 0xff & regs[R_PL]);
|
||||
tda_reg("EASY_PROG_BYTE_1 = 0x%02x\n", 0xff & regs[R_EP1]);
|
||||
tda_reg("EASY_PROG_BYTE_2 = 0x%02x\n", 0xff & regs[R_EP2]);
|
||||
tda_reg("EASY_PROG_BYTE_3 = 0x%02x\n", 0xff & regs[R_EP3]);
|
||||
tda_reg("EASY_PROG_BYTE_4 = 0x%02x\n", 0xff & regs[R_EP4]);
|
||||
tda_reg("EASY_PROG_BYTE_5 = 0x%02x\n", 0xff & regs[R_EP5]);
|
||||
tda_reg("CAL_POST_DIV_BYTE = 0x%02x\n", 0xff & regs[R_CPD]);
|
||||
tda_reg("CAL_DIV_BYTE_1 = 0x%02x\n", 0xff & regs[R_CD1]);
|
||||
tda_reg("CAL_DIV_BYTE_2 = 0x%02x\n", 0xff & regs[R_CD2]);
|
||||
tda_reg("CAL_DIV_BYTE_3 = 0x%02x\n", 0xff & regs[R_CD3]);
|
||||
tda_reg("MAIN_POST_DIV_BYTE = 0x%02x\n", 0xff & regs[R_MPD]);
|
||||
tda_reg("MAIN_DIV_BYTE_1 = 0x%02x\n", 0xff & regs[R_MD1]);
|
||||
tda_reg("MAIN_DIV_BYTE_2 = 0x%02x\n", 0xff & regs[R_MD2]);
|
||||
tda_reg("MAIN_DIV_BYTE_3 = 0x%02x\n", 0xff & regs[R_MD3]);
|
||||
|
||||
/* only dump extended regs if DBG_ADV is set */
|
||||
if (!(tda18271_debug & DBG_ADV))
|
||||
return;
|
||||
|
||||
/* W indicates write-only registers.
|
||||
* Register dump for write-only registers shows last value written. */
|
||||
|
||||
tda_reg("EXTENDED_BYTE_1 = 0x%02x\n", 0xff & regs[R_EB1]);
|
||||
tda_reg("EXTENDED_BYTE_2 = 0x%02x\n", 0xff & regs[R_EB2]);
|
||||
tda_reg("EXTENDED_BYTE_3 = 0x%02x\n", 0xff & regs[R_EB3]);
|
||||
tda_reg("EXTENDED_BYTE_4 = 0x%02x\n", 0xff & regs[R_EB4]);
|
||||
tda_reg("EXTENDED_BYTE_5 = 0x%02x\n", 0xff & regs[R_EB5]);
|
||||
tda_reg("EXTENDED_BYTE_6 = 0x%02x\n", 0xff & regs[R_EB6]);
|
||||
tda_reg("EXTENDED_BYTE_7 = 0x%02x\n", 0xff & regs[R_EB7]);
|
||||
tda_reg("EXTENDED_BYTE_8 = 0x%02x\n", 0xff & regs[R_EB8]);
|
||||
tda_reg("EXTENDED_BYTE_9 W = 0x%02x\n", 0xff & regs[R_EB9]);
|
||||
tda_reg("EXTENDED_BYTE_10 = 0x%02x\n", 0xff & regs[R_EB10]);
|
||||
tda_reg("EXTENDED_BYTE_11 = 0x%02x\n", 0xff & regs[R_EB11]);
|
||||
tda_reg("EXTENDED_BYTE_12 = 0x%02x\n", 0xff & regs[R_EB12]);
|
||||
tda_reg("EXTENDED_BYTE_13 = 0x%02x\n", 0xff & regs[R_EB13]);
|
||||
tda_reg("EXTENDED_BYTE_14 = 0x%02x\n", 0xff & regs[R_EB14]);
|
||||
tda_reg("EXTENDED_BYTE_15 = 0x%02x\n", 0xff & regs[R_EB15]);
|
||||
tda_reg("EXTENDED_BYTE_16 W = 0x%02x\n", 0xff & regs[R_EB16]);
|
||||
tda_reg("EXTENDED_BYTE_17 W = 0x%02x\n", 0xff & regs[R_EB17]);
|
||||
tda_reg("EXTENDED_BYTE_18 = 0x%02x\n", 0xff & regs[R_EB18]);
|
||||
tda_reg("EXTENDED_BYTE_19 W = 0x%02x\n", 0xff & regs[R_EB19]);
|
||||
tda_reg("EXTENDED_BYTE_20 W = 0x%02x\n", 0xff & regs[R_EB20]);
|
||||
tda_reg("EXTENDED_BYTE_21 = 0x%02x\n", 0xff & regs[R_EB21]);
|
||||
tda_reg("EXTENDED_BYTE_22 = 0x%02x\n", 0xff & regs[R_EB22]);
|
||||
tda_reg("EXTENDED_BYTE_23 = 0x%02x\n", 0xff & regs[R_EB23]);
|
||||
}
|
||||
|
||||
int tda18271_read_regs(struct dvb_frontend *fe)
|
||||
{
|
||||
struct tda18271_priv *priv = fe->tuner_priv;
|
||||
unsigned char *regs = priv->tda18271_regs;
|
||||
unsigned char buf = 0x00;
|
||||
int ret;
|
||||
struct i2c_msg msg[] = {
|
||||
{ .addr = priv->i2c_addr, .flags = 0,
|
||||
.buf = &buf, .len = 1 },
|
||||
{ .addr = priv->i2c_addr, .flags = I2C_M_RD,
|
||||
.buf = regs, .len = 16 }
|
||||
};
|
||||
|
||||
tda18271_i2c_gate_ctrl(fe, 1);
|
||||
|
||||
/* read all registers */
|
||||
ret = i2c_transfer(priv->i2c_adap, msg, 2);
|
||||
|
||||
tda18271_i2c_gate_ctrl(fe, 0);
|
||||
|
||||
if (ret != 2)
|
||||
tda_err("ERROR: i2c_transfer returned: %d\n", ret);
|
||||
|
||||
if (tda18271_debug & DBG_REG)
|
||||
tda18271_dump_regs(fe, 0);
|
||||
|
||||
return (ret == 2 ? 0 : ret);
|
||||
}
|
||||
|
||||
int tda18271_read_extended(struct dvb_frontend *fe)
|
||||
{
|
||||
struct tda18271_priv *priv = fe->tuner_priv;
|
||||
unsigned char *regs = priv->tda18271_regs;
|
||||
unsigned char regdump[TDA18271_NUM_REGS];
|
||||
unsigned char buf = 0x00;
|
||||
int ret, i;
|
||||
struct i2c_msg msg[] = {
|
||||
{ .addr = priv->i2c_addr, .flags = 0,
|
||||
.buf = &buf, .len = 1 },
|
||||
{ .addr = priv->i2c_addr, .flags = I2C_M_RD,
|
||||
.buf = regdump, .len = TDA18271_NUM_REGS }
|
||||
};
|
||||
|
||||
tda18271_i2c_gate_ctrl(fe, 1);
|
||||
|
||||
/* read all registers */
|
||||
ret = i2c_transfer(priv->i2c_adap, msg, 2);
|
||||
|
||||
tda18271_i2c_gate_ctrl(fe, 0);
|
||||
|
||||
if (ret != 2)
|
||||
tda_err("ERROR: i2c_transfer returned: %d\n", ret);
|
||||
|
||||
for (i = 0; i <= TDA18271_NUM_REGS; i++) {
|
||||
/* don't update write-only registers */
|
||||
if ((i != R_EB9) &&
|
||||
(i != R_EB16) &&
|
||||
(i != R_EB17) &&
|
||||
(i != R_EB19) &&
|
||||
(i != R_EB20))
|
||||
regs[i] = regdump[i];
|
||||
}
|
||||
|
||||
if (tda18271_debug & DBG_REG)
|
||||
tda18271_dump_regs(fe, 1);
|
||||
|
||||
return (ret == 2 ? 0 : ret);
|
||||
}
|
||||
|
||||
int tda18271_write_regs(struct dvb_frontend *fe, int idx, int len)
|
||||
{
|
||||
struct tda18271_priv *priv = fe->tuner_priv;
|
||||
unsigned char *regs = priv->tda18271_regs;
|
||||
unsigned char buf[TDA18271_NUM_REGS + 1];
|
||||
struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0,
|
||||
.buf = buf, .len = len + 1 };
|
||||
int i, ret;
|
||||
|
||||
BUG_ON((len == 0) || (idx + len > sizeof(buf)));
|
||||
|
||||
buf[0] = idx;
|
||||
for (i = 1; i <= len; i++)
|
||||
buf[i] = regs[idx - 1 + i];
|
||||
|
||||
tda18271_i2c_gate_ctrl(fe, 1);
|
||||
|
||||
/* write registers */
|
||||
ret = i2c_transfer(priv->i2c_adap, &msg, 1);
|
||||
|
||||
tda18271_i2c_gate_ctrl(fe, 0);
|
||||
|
||||
if (ret != 1)
|
||||
tda_err("ERROR: i2c_transfer returned: %d\n", ret);
|
||||
|
||||
return (ret == 1 ? 0 : ret);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
|
||||
int tda18271_init_regs(struct dvb_frontend *fe)
|
||||
{
|
||||
struct tda18271_priv *priv = fe->tuner_priv;
|
||||
unsigned char *regs = priv->tda18271_regs;
|
||||
|
||||
tda_dbg("initializing registers for device @ %d-%04x\n",
|
||||
i2c_adapter_id(priv->i2c_adap), priv->i2c_addr);
|
||||
|
||||
/* initialize registers */
|
||||
switch (priv->id) {
|
||||
case TDA18271HDC1:
|
||||
regs[R_ID] = 0x83;
|
||||
break;
|
||||
case TDA18271HDC2:
|
||||
regs[R_ID] = 0x84;
|
||||
break;
|
||||
};
|
||||
|
||||
regs[R_TM] = 0x08;
|
||||
regs[R_PL] = 0x80;
|
||||
regs[R_EP1] = 0xc6;
|
||||
regs[R_EP2] = 0xdf;
|
||||
regs[R_EP3] = 0x16;
|
||||
regs[R_EP4] = 0x60;
|
||||
regs[R_EP5] = 0x80;
|
||||
regs[R_CPD] = 0x80;
|
||||
regs[R_CD1] = 0x00;
|
||||
regs[R_CD2] = 0x00;
|
||||
regs[R_CD3] = 0x00;
|
||||
regs[R_MPD] = 0x00;
|
||||
regs[R_MD1] = 0x00;
|
||||
regs[R_MD2] = 0x00;
|
||||
regs[R_MD3] = 0x00;
|
||||
|
||||
switch (priv->id) {
|
||||
case TDA18271HDC1:
|
||||
regs[R_EB1] = 0xff;
|
||||
break;
|
||||
case TDA18271HDC2:
|
||||
regs[R_EB1] = 0xfc;
|
||||
break;
|
||||
};
|
||||
|
||||
regs[R_EB2] = 0x01;
|
||||
regs[R_EB3] = 0x84;
|
||||
regs[R_EB4] = 0x41;
|
||||
regs[R_EB5] = 0x01;
|
||||
regs[R_EB6] = 0x84;
|
||||
regs[R_EB7] = 0x40;
|
||||
regs[R_EB8] = 0x07;
|
||||
regs[R_EB9] = 0x00;
|
||||
regs[R_EB10] = 0x00;
|
||||
regs[R_EB11] = 0x96;
|
||||
|
||||
switch (priv->id) {
|
||||
case TDA18271HDC1:
|
||||
regs[R_EB12] = 0x0f;
|
||||
break;
|
||||
case TDA18271HDC2:
|
||||
regs[R_EB12] = 0x33;
|
||||
break;
|
||||
};
|
||||
|
||||
regs[R_EB13] = 0xc1;
|
||||
regs[R_EB14] = 0x00;
|
||||
regs[R_EB15] = 0x8f;
|
||||
regs[R_EB16] = 0x00;
|
||||
regs[R_EB17] = 0x00;
|
||||
|
||||
switch (priv->id) {
|
||||
case TDA18271HDC1:
|
||||
regs[R_EB18] = 0x00;
|
||||
break;
|
||||
case TDA18271HDC2:
|
||||
regs[R_EB18] = 0x8c;
|
||||
break;
|
||||
};
|
||||
|
||||
regs[R_EB19] = 0x00;
|
||||
regs[R_EB20] = 0x20;
|
||||
|
||||
switch (priv->id) {
|
||||
case TDA18271HDC1:
|
||||
regs[R_EB21] = 0x33;
|
||||
break;
|
||||
case TDA18271HDC2:
|
||||
regs[R_EB21] = 0xb3;
|
||||
break;
|
||||
};
|
||||
|
||||
regs[R_EB22] = 0x48;
|
||||
regs[R_EB23] = 0xb0;
|
||||
|
||||
tda18271_write_regs(fe, 0x00, TDA18271_NUM_REGS);
|
||||
|
||||
/* setup agc1 gain */
|
||||
regs[R_EB17] = 0x00;
|
||||
tda18271_write_regs(fe, R_EB17, 1);
|
||||
regs[R_EB17] = 0x03;
|
||||
tda18271_write_regs(fe, R_EB17, 1);
|
||||
regs[R_EB17] = 0x43;
|
||||
tda18271_write_regs(fe, R_EB17, 1);
|
||||
regs[R_EB17] = 0x4c;
|
||||
tda18271_write_regs(fe, R_EB17, 1);
|
||||
|
||||
/* setup agc2 gain */
|
||||
if ((priv->id) == TDA18271HDC1) {
|
||||
regs[R_EB20] = 0xa0;
|
||||
tda18271_write_regs(fe, R_EB20, 1);
|
||||
regs[R_EB20] = 0xa7;
|
||||
tda18271_write_regs(fe, R_EB20, 1);
|
||||
regs[R_EB20] = 0xe7;
|
||||
tda18271_write_regs(fe, R_EB20, 1);
|
||||
regs[R_EB20] = 0xec;
|
||||
tda18271_write_regs(fe, R_EB20, 1);
|
||||
}
|
||||
|
||||
/* image rejection calibration */
|
||||
|
||||
/* low-band */
|
||||
regs[R_EP3] = 0x1f;
|
||||
regs[R_EP4] = 0x66;
|
||||
regs[R_EP5] = 0x81;
|
||||
regs[R_CPD] = 0xcc;
|
||||
regs[R_CD1] = 0x6c;
|
||||
regs[R_CD2] = 0x00;
|
||||
regs[R_CD3] = 0x00;
|
||||
regs[R_MPD] = 0xcd;
|
||||
regs[R_MD1] = 0x77;
|
||||
regs[R_MD2] = 0x08;
|
||||
regs[R_MD3] = 0x00;
|
||||
|
||||
switch (priv->id) {
|
||||
case TDA18271HDC1:
|
||||
tda18271_write_regs(fe, R_EP3, 11);
|
||||
break;
|
||||
case TDA18271HDC2:
|
||||
tda18271_write_regs(fe, R_EP3, 12);
|
||||
break;
|
||||
};
|
||||
|
||||
if ((priv->id) == TDA18271HDC2) {
|
||||
/* main pll cp source on */
|
||||
regs[R_EB4] = 0x61;
|
||||
tda18271_write_regs(fe, R_EB4, 1);
|
||||
msleep(1);
|
||||
|
||||
/* main pll cp source off */
|
||||
regs[R_EB4] = 0x41;
|
||||
tda18271_write_regs(fe, R_EB4, 1);
|
||||
}
|
||||
|
||||
msleep(5); /* pll locking */
|
||||
|
||||
/* launch detector */
|
||||
tda18271_write_regs(fe, R_EP1, 1);
|
||||
msleep(5); /* wanted low measurement */
|
||||
|
||||
regs[R_EP5] = 0x85;
|
||||
regs[R_CPD] = 0xcb;
|
||||
regs[R_CD1] = 0x66;
|
||||
regs[R_CD2] = 0x70;
|
||||
|
||||
tda18271_write_regs(fe, R_EP3, 7);
|
||||
msleep(5); /* pll locking */
|
||||
|
||||
/* launch optimization algorithm */
|
||||
tda18271_write_regs(fe, R_EP2, 1);
|
||||
msleep(30); /* image low optimization completion */
|
||||
|
||||
/* mid-band */
|
||||
regs[R_EP5] = 0x82;
|
||||
regs[R_CPD] = 0xa8;
|
||||
regs[R_CD2] = 0x00;
|
||||
regs[R_MPD] = 0xa9;
|
||||
regs[R_MD1] = 0x73;
|
||||
regs[R_MD2] = 0x1a;
|
||||
|
||||
tda18271_write_regs(fe, R_EP3, 11);
|
||||
msleep(5); /* pll locking */
|
||||
|
||||
tda18271_write_regs(fe, R_EP1, 1);
|
||||
msleep(5); /* wanted mid measurement */
|
||||
|
||||
regs[R_EP5] = 0x86;
|
||||
regs[R_CPD] = 0xa8;
|
||||
regs[R_CD1] = 0x66;
|
||||
regs[R_CD2] = 0xa0;
|
||||
|
||||
tda18271_write_regs(fe, R_EP3, 7);
|
||||
msleep(5); /* pll locking */
|
||||
|
||||
/* launch optimization algorithm */
|
||||
tda18271_write_regs(fe, R_EP2, 1);
|
||||
msleep(30); /* image mid optimization completion */
|
||||
|
||||
/* high-band */
|
||||
regs[R_EP5] = 0x83;
|
||||
regs[R_CPD] = 0x98;
|
||||
regs[R_CD1] = 0x65;
|
||||
regs[R_CD2] = 0x00;
|
||||
regs[R_MPD] = 0x99;
|
||||
regs[R_MD1] = 0x71;
|
||||
regs[R_MD2] = 0xcd;
|
||||
|
||||
tda18271_write_regs(fe, R_EP3, 11);
|
||||
msleep(5); /* pll locking */
|
||||
|
||||
/* launch detector */
|
||||
tda18271_write_regs(fe, R_EP1, 1);
|
||||
msleep(5); /* wanted high measurement */
|
||||
|
||||
regs[R_EP5] = 0x87;
|
||||
regs[R_CD1] = 0x65;
|
||||
regs[R_CD2] = 0x50;
|
||||
|
||||
tda18271_write_regs(fe, R_EP3, 7);
|
||||
msleep(5); /* pll locking */
|
||||
|
||||
/* launch optimization algorithm */
|
||||
tda18271_write_regs(fe, R_EP2, 1);
|
||||
msleep(30); /* image high optimization completion */
|
||||
|
||||
/* return to normal mode */
|
||||
regs[R_EP4] = 0x64;
|
||||
tda18271_write_regs(fe, R_EP4, 1);
|
||||
|
||||
/* synchronize */
|
||||
tda18271_write_regs(fe, R_EP1, 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* Standby modes, EP3 [7:5]
|
||||
*
|
||||
* | SM || SM_LT || SM_XT || mode description
|
||||
* |=====\\=======\\=======\\===================================
|
||||
* | 0 || 0 || 0 || normal mode
|
||||
* |-----||-------||-------||-----------------------------------
|
||||
* | || || || standby mode w/ slave tuner output
|
||||
* | 1 || 0 || 0 || & loop thru & xtal oscillator on
|
||||
* |-----||-------||-------||-----------------------------------
|
||||
* | 1 || 1 || 0 || standby mode w/ xtal oscillator on
|
||||
* |-----||-------||-------||-----------------------------------
|
||||
* | 1 || 1 || 1 || power off
|
||||
*
|
||||
*/
|
||||
|
||||
int tda18271_set_standby_mode(struct dvb_frontend *fe,
|
||||
int sm, int sm_lt, int sm_xt)
|
||||
{
|
||||
struct tda18271_priv *priv = fe->tuner_priv;
|
||||
unsigned char *regs = priv->tda18271_regs;
|
||||
|
||||
tda_dbg("sm = %d, sm_lt = %d, sm_xt = %d\n", sm, sm_lt, sm_xt);
|
||||
|
||||
regs[R_EP3] &= ~0xe0; /* clear sm, sm_lt, sm_xt */
|
||||
regs[R_EP3] |= sm ? (1 << 7) : 0 |
|
||||
sm_lt ? (1 << 6) : 0 |
|
||||
sm_xt ? (1 << 5) : 0;
|
||||
|
||||
tda18271_write_regs(fe, R_EP3, 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
|
||||
int tda18271_calc_main_pll(struct dvb_frontend *fe, u32 freq)
|
||||
{
|
||||
/* sets main post divider & divider bytes, but does not write them */
|
||||
struct tda18271_priv *priv = fe->tuner_priv;
|
||||
unsigned char *regs = priv->tda18271_regs;
|
||||
u8 d, pd;
|
||||
u32 div;
|
||||
|
||||
int ret = tda18271_lookup_pll_map(fe, MAIN_PLL, &freq, &pd, &d);
|
||||
if (ret < 0)
|
||||
goto fail;
|
||||
|
||||
regs[R_MPD] = (0x77 & pd);
|
||||
|
||||
switch (priv->mode) {
|
||||
case TDA18271_ANALOG:
|
||||
regs[R_MPD] &= ~0x08;
|
||||
break;
|
||||
case TDA18271_DIGITAL:
|
||||
regs[R_MPD] |= 0x08;
|
||||
break;
|
||||
}
|
||||
|
||||
div = ((d * (freq / 1000)) << 7) / 125;
|
||||
|
||||
regs[R_MD1] = 0x7f & (div >> 16);
|
||||
regs[R_MD2] = 0xff & (div >> 8);
|
||||
regs[R_MD3] = 0xff & div;
|
||||
fail:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int tda18271_calc_cal_pll(struct dvb_frontend *fe, u32 freq)
|
||||
{
|
||||
/* sets cal post divider & divider bytes, but does not write them */
|
||||
struct tda18271_priv *priv = fe->tuner_priv;
|
||||
unsigned char *regs = priv->tda18271_regs;
|
||||
u8 d, pd;
|
||||
u32 div;
|
||||
|
||||
int ret = tda18271_lookup_pll_map(fe, CAL_PLL, &freq, &pd, &d);
|
||||
if (ret < 0)
|
||||
goto fail;
|
||||
|
||||
regs[R_CPD] = pd;
|
||||
|
||||
div = ((d * (freq / 1000)) << 7) / 125;
|
||||
|
||||
regs[R_CD1] = 0x7f & (div >> 16);
|
||||
regs[R_CD2] = 0xff & (div >> 8);
|
||||
regs[R_CD3] = 0xff & div;
|
||||
fail:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
|
||||
int tda18271_calc_bp_filter(struct dvb_frontend *fe, u32 *freq)
|
||||
{
|
||||
/* sets bp filter bits, but does not write them */
|
||||
struct tda18271_priv *priv = fe->tuner_priv;
|
||||
unsigned char *regs = priv->tda18271_regs;
|
||||
u8 val;
|
||||
|
||||
int ret = tda18271_lookup_map(fe, BP_FILTER, freq, &val);
|
||||
if (ret < 0)
|
||||
goto fail;
|
||||
|
||||
regs[R_EP1] &= ~0x07; /* clear bp filter bits */
|
||||
regs[R_EP1] |= (0x07 & val);
|
||||
fail:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int tda18271_calc_km(struct dvb_frontend *fe, u32 *freq)
|
||||
{
|
||||
/* sets K & M bits, but does not write them */
|
||||
struct tda18271_priv *priv = fe->tuner_priv;
|
||||
unsigned char *regs = priv->tda18271_regs;
|
||||
u8 val;
|
||||
|
||||
int ret = tda18271_lookup_map(fe, RF_CAL_KMCO, freq, &val);
|
||||
if (ret < 0)
|
||||
goto fail;
|
||||
|
||||
regs[R_EB13] &= ~0x7c; /* clear k & m bits */
|
||||
regs[R_EB13] |= (0x7c & val);
|
||||
fail:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int tda18271_calc_rf_band(struct dvb_frontend *fe, u32 *freq)
|
||||
{
|
||||
/* sets rf band bits, but does not write them */
|
||||
struct tda18271_priv *priv = fe->tuner_priv;
|
||||
unsigned char *regs = priv->tda18271_regs;
|
||||
u8 val;
|
||||
|
||||
int ret = tda18271_lookup_map(fe, RF_BAND, freq, &val);
|
||||
if (ret < 0)
|
||||
goto fail;
|
||||
|
||||
regs[R_EP2] &= ~0xe0; /* clear rf band bits */
|
||||
regs[R_EP2] |= (0xe0 & (val << 5));
|
||||
fail:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int tda18271_calc_gain_taper(struct dvb_frontend *fe, u32 *freq)
|
||||
{
|
||||
/* sets gain taper bits, but does not write them */
|
||||
struct tda18271_priv *priv = fe->tuner_priv;
|
||||
unsigned char *regs = priv->tda18271_regs;
|
||||
u8 val;
|
||||
|
||||
int ret = tda18271_lookup_map(fe, GAIN_TAPER, freq, &val);
|
||||
if (ret < 0)
|
||||
goto fail;
|
||||
|
||||
regs[R_EP2] &= ~0x1f; /* clear gain taper bits */
|
||||
regs[R_EP2] |= (0x1f & val);
|
||||
fail:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int tda18271_calc_ir_measure(struct dvb_frontend *fe, u32 *freq)
|
||||
{
|
||||
/* sets IR Meas bits, but does not write them */
|
||||
struct tda18271_priv *priv = fe->tuner_priv;
|
||||
unsigned char *regs = priv->tda18271_regs;
|
||||
u8 val;
|
||||
|
||||
int ret = tda18271_lookup_map(fe, IR_MEASURE, freq, &val);
|
||||
if (ret < 0)
|
||||
goto fail;
|
||||
|
||||
regs[R_EP5] &= ~0x07;
|
||||
regs[R_EP5] |= (0x07 & val);
|
||||
fail:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int tda18271_calc_rf_cal(struct dvb_frontend *fe, u32 *freq)
|
||||
{
|
||||
/* sets rf cal byte (RFC_Cprog), but does not write it */
|
||||
struct tda18271_priv *priv = fe->tuner_priv;
|
||||
unsigned char *regs = priv->tda18271_regs;
|
||||
u8 val;
|
||||
|
||||
tda18271_lookup_map(fe, RF_CAL, freq, &val);
|
||||
|
||||
regs[R_EB14] = val;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Overrides for Emacs so that we follow Linus's tabbing style.
|
||||
* ---------------------------------------------------------------------------
|
||||
* Local variables:
|
||||
* c-basic-offset: 8
|
||||
* End:
|
||||
*/
|
1225
drivers/media/dvb/frontends/tda18271-fe.c
Normal file
1225
drivers/media/dvb/frontends/tda18271-fe.c
Normal file
File diff suppressed because it is too large
Load Diff
212
drivers/media/dvb/frontends/tda18271-priv.h
Normal file
212
drivers/media/dvb/frontends/tda18271-priv.h
Normal file
@ -0,0 +1,212 @@
|
||||
/*
|
||||
tda18271-priv.h - private header for the NXP TDA18271 silicon tuner
|
||||
|
||||
Copyright (C) 2007, 2008 Michael Krufky <mkrufky@linuxtv.org>
|
||||
|
||||
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 __TDA18271_PRIV_H__
|
||||
#define __TDA18271_PRIV_H__
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/mutex.h>
|
||||
#include "tda18271.h"
|
||||
|
||||
#define R_ID 0x00 /* ID byte */
|
||||
#define R_TM 0x01 /* Thermo byte */
|
||||
#define R_PL 0x02 /* Power level byte */
|
||||
#define R_EP1 0x03 /* Easy Prog byte 1 */
|
||||
#define R_EP2 0x04 /* Easy Prog byte 2 */
|
||||
#define R_EP3 0x05 /* Easy Prog byte 3 */
|
||||
#define R_EP4 0x06 /* Easy Prog byte 4 */
|
||||
#define R_EP5 0x07 /* Easy Prog byte 5 */
|
||||
#define R_CPD 0x08 /* Cal Post-Divider byte */
|
||||
#define R_CD1 0x09 /* Cal Divider byte 1 */
|
||||
#define R_CD2 0x0a /* Cal Divider byte 2 */
|
||||
#define R_CD3 0x0b /* Cal Divider byte 3 */
|
||||
#define R_MPD 0x0c /* Main Post-Divider byte */
|
||||
#define R_MD1 0x0d /* Main Divider byte 1 */
|
||||
#define R_MD2 0x0e /* Main Divider byte 2 */
|
||||
#define R_MD3 0x0f /* Main Divider byte 3 */
|
||||
#define R_EB1 0x10 /* Extended byte 1 */
|
||||
#define R_EB2 0x11 /* Extended byte 2 */
|
||||
#define R_EB3 0x12 /* Extended byte 3 */
|
||||
#define R_EB4 0x13 /* Extended byte 4 */
|
||||
#define R_EB5 0x14 /* Extended byte 5 */
|
||||
#define R_EB6 0x15 /* Extended byte 6 */
|
||||
#define R_EB7 0x16 /* Extended byte 7 */
|
||||
#define R_EB8 0x17 /* Extended byte 8 */
|
||||
#define R_EB9 0x18 /* Extended byte 9 */
|
||||
#define R_EB10 0x19 /* Extended byte 10 */
|
||||
#define R_EB11 0x1a /* Extended byte 11 */
|
||||
#define R_EB12 0x1b /* Extended byte 12 */
|
||||
#define R_EB13 0x1c /* Extended byte 13 */
|
||||
#define R_EB14 0x1d /* Extended byte 14 */
|
||||
#define R_EB15 0x1e /* Extended byte 15 */
|
||||
#define R_EB16 0x1f /* Extended byte 16 */
|
||||
#define R_EB17 0x20 /* Extended byte 17 */
|
||||
#define R_EB18 0x21 /* Extended byte 18 */
|
||||
#define R_EB19 0x22 /* Extended byte 19 */
|
||||
#define R_EB20 0x23 /* Extended byte 20 */
|
||||
#define R_EB21 0x24 /* Extended byte 21 */
|
||||
#define R_EB22 0x25 /* Extended byte 22 */
|
||||
#define R_EB23 0x26 /* Extended byte 23 */
|
||||
|
||||
#define TDA18271_NUM_REGS 39
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
|
||||
struct tda18271_rf_tracking_filter_cal {
|
||||
u32 rfmax;
|
||||
u8 rfband;
|
||||
u32 rf1_def;
|
||||
u32 rf2_def;
|
||||
u32 rf3_def;
|
||||
u32 rf1;
|
||||
u32 rf2;
|
||||
u32 rf3;
|
||||
int rf_a1;
|
||||
int rf_b1;
|
||||
int rf_a2;
|
||||
int rf_b2;
|
||||
};
|
||||
|
||||
enum tda18271_mode {
|
||||
TDA18271_ANALOG,
|
||||
TDA18271_DIGITAL,
|
||||
};
|
||||
|
||||
struct tda18271_map_layout;
|
||||
|
||||
enum tda18271_ver {
|
||||
TDA18271HDC1,
|
||||
TDA18271HDC2,
|
||||
};
|
||||
|
||||
struct tda18271_priv {
|
||||
u8 i2c_addr;
|
||||
struct i2c_adapter *i2c_adap;
|
||||
unsigned char tda18271_regs[TDA18271_NUM_REGS];
|
||||
|
||||
struct list_head tda18271_list;
|
||||
|
||||
enum tda18271_mode mode;
|
||||
enum tda18271_i2c_gate gate;
|
||||
enum tda18271_ver id;
|
||||
|
||||
unsigned int count;
|
||||
unsigned int tm_rfcal;
|
||||
unsigned int cal_initialized:1;
|
||||
|
||||
struct tda18271_map_layout *maps;
|
||||
struct tda18271_std_map std;
|
||||
struct tda18271_rf_tracking_filter_cal rf_cal_state[8];
|
||||
|
||||
struct mutex lock;
|
||||
|
||||
u32 frequency;
|
||||
u32 bandwidth;
|
||||
};
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
|
||||
extern int tda18271_debug;
|
||||
|
||||
#define DBG_INFO 1
|
||||
#define DBG_MAP 2
|
||||
#define DBG_REG 4
|
||||
#define DBG_ADV 8
|
||||
#define DBG_CAL 16
|
||||
|
||||
#define tda_printk(kern, fmt, arg...) \
|
||||
printk(kern "%s: " fmt, __FUNCTION__, ##arg)
|
||||
|
||||
#define dprintk(kern, lvl, fmt, arg...) do {\
|
||||
if (tda18271_debug & lvl) \
|
||||
tda_printk(kern, fmt, ##arg); } while (0)
|
||||
|
||||
#define tda_info(fmt, arg...) printk(KERN_INFO fmt, ##arg)
|
||||
#define tda_warn(fmt, arg...) tda_printk(KERN_WARNING, fmt, ##arg)
|
||||
#define tda_err(fmt, arg...) tda_printk(KERN_ERR, fmt, ##arg)
|
||||
#define tda_dbg(fmt, arg...) dprintk(KERN_DEBUG, DBG_INFO, fmt, ##arg)
|
||||
#define tda_map(fmt, arg...) dprintk(KERN_DEBUG, DBG_MAP, fmt, ##arg)
|
||||
#define tda_reg(fmt, arg...) dprintk(KERN_DEBUG, DBG_REG, fmt, ##arg)
|
||||
#define tda_cal(fmt, arg...) dprintk(KERN_DEBUG, DBG_CAL, fmt, ##arg)
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
|
||||
enum tda18271_map_type {
|
||||
/* tda18271_pll_map */
|
||||
MAIN_PLL,
|
||||
CAL_PLL,
|
||||
/* tda18271_map */
|
||||
RF_CAL,
|
||||
RF_CAL_KMCO,
|
||||
RF_CAL_DC_OVER_DT,
|
||||
BP_FILTER,
|
||||
RF_BAND,
|
||||
GAIN_TAPER,
|
||||
IR_MEASURE,
|
||||
};
|
||||
|
||||
extern int tda18271_lookup_pll_map(struct dvb_frontend *fe,
|
||||
enum tda18271_map_type map_type,
|
||||
u32 *freq, u8 *post_div, u8 *div);
|
||||
extern int tda18271_lookup_map(struct dvb_frontend *fe,
|
||||
enum tda18271_map_type map_type,
|
||||
u32 *freq, u8 *val);
|
||||
|
||||
extern int tda18271_lookup_thermometer(struct dvb_frontend *fe);
|
||||
|
||||
extern int tda18271_lookup_rf_band(struct dvb_frontend *fe,
|
||||
u32 *freq, u8 *rf_band);
|
||||
|
||||
extern int tda18271_lookup_cid_target(struct dvb_frontend *fe,
|
||||
u32 *freq, u8 *cid_target,
|
||||
u16 *count_limit);
|
||||
|
||||
extern int tda18271_assign_map_layout(struct dvb_frontend *fe);
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
|
||||
extern int tda18271_read_regs(struct dvb_frontend *fe);
|
||||
extern int tda18271_read_extended(struct dvb_frontend *fe);
|
||||
extern int tda18271_write_regs(struct dvb_frontend *fe, int idx, int len);
|
||||
extern int tda18271_init_regs(struct dvb_frontend *fe);
|
||||
|
||||
extern int tda18271_set_standby_mode(struct dvb_frontend *fe,
|
||||
int sm, int sm_lt, int sm_xt);
|
||||
|
||||
extern int tda18271_calc_main_pll(struct dvb_frontend *fe, u32 freq);
|
||||
extern int tda18271_calc_cal_pll(struct dvb_frontend *fe, u32 freq);
|
||||
|
||||
extern int tda18271_calc_bp_filter(struct dvb_frontend *fe, u32 *freq);
|
||||
extern int tda18271_calc_km(struct dvb_frontend *fe, u32 *freq);
|
||||
extern int tda18271_calc_rf_band(struct dvb_frontend *fe, u32 *freq);
|
||||
extern int tda18271_calc_gain_taper(struct dvb_frontend *fe, u32 *freq);
|
||||
extern int tda18271_calc_ir_measure(struct dvb_frontend *fe, u32 *freq);
|
||||
extern int tda18271_calc_rf_cal(struct dvb_frontend *fe, u32 *freq);
|
||||
|
||||
#endif /* __TDA18271_PRIV_H__ */
|
||||
|
||||
/*
|
||||
* Overrides for Emacs so that we follow Linus's tabbing style.
|
||||
* ---------------------------------------------------------------------------
|
||||
* Local variables:
|
||||
* c-basic-offset: 8
|
||||
* End:
|
||||
*/
|
1285
drivers/media/dvb/frontends/tda18271-tables.c
Normal file
1285
drivers/media/dvb/frontends/tda18271-tables.c
Normal file
File diff suppressed because it is too large
Load Diff
78
drivers/media/dvb/frontends/tda18271.h
Normal file
78
drivers/media/dvb/frontends/tda18271.h
Normal file
@ -0,0 +1,78 @@
|
||||
/*
|
||||
tda18271.h - header for the Philips / NXP TDA18271 silicon tuner
|
||||
|
||||
Copyright (C) 2007, 2008 Michael Krufky <mkrufky@linuxtv.org>
|
||||
|
||||
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 __TDA18271_H__
|
||||
#define __TDA18271_H__
|
||||
|
||||
#include <linux/i2c.h>
|
||||
#include "dvb_frontend.h"
|
||||
|
||||
struct tda18271_std_map_item {
|
||||
u16 if_freq;
|
||||
u8 std_bits;
|
||||
};
|
||||
|
||||
struct tda18271_std_map {
|
||||
struct tda18271_std_map_item fm_radio;
|
||||
struct tda18271_std_map_item atv_b;
|
||||
struct tda18271_std_map_item atv_dk;
|
||||
struct tda18271_std_map_item atv_gh;
|
||||
struct tda18271_std_map_item atv_i;
|
||||
struct tda18271_std_map_item atv_l;
|
||||
struct tda18271_std_map_item atv_lc;
|
||||
struct tda18271_std_map_item atv_mn;
|
||||
struct tda18271_std_map_item atsc_6;
|
||||
struct tda18271_std_map_item dvbt_6;
|
||||
struct tda18271_std_map_item dvbt_7;
|
||||
struct tda18271_std_map_item dvbt_8;
|
||||
struct tda18271_std_map_item qam_6;
|
||||
struct tda18271_std_map_item qam_8;
|
||||
};
|
||||
|
||||
enum tda18271_i2c_gate {
|
||||
TDA18271_GATE_AUTO = 0,
|
||||
TDA18271_GATE_ANALOG,
|
||||
TDA18271_GATE_DIGITAL,
|
||||
};
|
||||
|
||||
struct tda18271_config {
|
||||
/* override default if freq / std settings (optional) */
|
||||
struct tda18271_std_map *std_map;
|
||||
|
||||
/* use i2c gate provided by analog or digital demod */
|
||||
enum tda18271_i2c_gate gate;
|
||||
};
|
||||
|
||||
#if defined(CONFIG_DVB_TDA18271) || (defined(CONFIG_DVB_TDA18271_MODULE) && defined(MODULE))
|
||||
extern struct dvb_frontend *tda18271_attach(struct dvb_frontend *fe, u8 addr,
|
||||
struct i2c_adapter *i2c,
|
||||
struct tda18271_config *cfg);
|
||||
#else
|
||||
static inline struct dvb_frontend *tda18271_attach(struct dvb_frontend *fe,
|
||||
u8 addr,
|
||||
struct i2c_adapter *i2c,
|
||||
struct tda18271_config *cfg)
|
||||
{
|
||||
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __TDA18271_H__ */
|
@ -19,12 +19,16 @@
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/dvb/frontend.h>
|
||||
#include <asm/types.h>
|
||||
#include <linux/dvb/frontend.h>
|
||||
#include <linux/videodev2.h>
|
||||
|
||||
#include "tda827x.h"
|
||||
|
||||
static int debug = 0;
|
||||
module_param(debug, int, 0644);
|
||||
MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
|
||||
|
||||
#define dprintk(args...) \
|
||||
do { \
|
||||
if (debug) printk(KERN_DEBUG "tda827x: " args); \
|
||||
@ -34,10 +38,57 @@ struct tda827x_priv {
|
||||
int i2c_addr;
|
||||
struct i2c_adapter *i2c_adap;
|
||||
struct tda827x_config *cfg;
|
||||
|
||||
unsigned int sgIF;
|
||||
unsigned char lpsel;
|
||||
|
||||
u32 frequency;
|
||||
u32 bandwidth;
|
||||
};
|
||||
|
||||
static void tda827x_set_std(struct dvb_frontend *fe,
|
||||
struct analog_parameters *params)
|
||||
{
|
||||
struct tda827x_priv *priv = fe->tuner_priv;
|
||||
char *mode;
|
||||
|
||||
priv->lpsel = 0;
|
||||
if (params->std & V4L2_STD_MN) {
|
||||
priv->sgIF = 92;
|
||||
priv->lpsel = 1;
|
||||
mode = "MN";
|
||||
} else if (params->std & V4L2_STD_B) {
|
||||
priv->sgIF = 108;
|
||||
mode = "B";
|
||||
} else if (params->std & V4L2_STD_GH) {
|
||||
priv->sgIF = 124;
|
||||
mode = "GH";
|
||||
} else if (params->std & V4L2_STD_PAL_I) {
|
||||
priv->sgIF = 124;
|
||||
mode = "I";
|
||||
} else if (params->std & V4L2_STD_DK) {
|
||||
priv->sgIF = 124;
|
||||
mode = "DK";
|
||||
} else if (params->std & V4L2_STD_SECAM_L) {
|
||||
priv->sgIF = 124;
|
||||
mode = "L";
|
||||
} else if (params->std & V4L2_STD_SECAM_LC) {
|
||||
priv->sgIF = 20;
|
||||
mode = "LC";
|
||||
} else {
|
||||
priv->sgIF = 124;
|
||||
mode = "xx";
|
||||
}
|
||||
|
||||
if (params->mode == V4L2_TUNER_RADIO)
|
||||
priv->sgIF = 88; /* if frequency is 5.5 MHz */
|
||||
|
||||
dprintk("setting tda827x to system %s\n", mode);
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
||||
struct tda827x_data {
|
||||
u32 lomax;
|
||||
u8 spd;
|
||||
@ -48,7 +99,7 @@ struct tda827x_data {
|
||||
u8 div1p5;
|
||||
};
|
||||
|
||||
static const struct tda827x_data tda827x_dvbt[] = {
|
||||
static const struct tda827x_data tda827x_table[] = {
|
||||
{ .lomax = 62000000, .spd = 3, .bs = 2, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 1},
|
||||
{ .lomax = 66000000, .spd = 3, .bs = 3, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 1},
|
||||
{ .lomax = 76000000, .spd = 3, .bs = 1, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 0},
|
||||
@ -106,21 +157,22 @@ static int tda827xo_set_params(struct dvb_frontend *fe,
|
||||
tuner_freq = params->frequency + if_freq;
|
||||
|
||||
i = 0;
|
||||
while (tda827x_dvbt[i].lomax < tuner_freq) {
|
||||
if(tda827x_dvbt[i + 1].lomax == 0)
|
||||
while (tda827x_table[i].lomax < tuner_freq) {
|
||||
if (tda827x_table[i + 1].lomax == 0)
|
||||
break;
|
||||
i++;
|
||||
}
|
||||
|
||||
N = ((tuner_freq + 125000) / 250000) << (tda827x_dvbt[i].spd + 2);
|
||||
N = ((tuner_freq + 125000) / 250000) << (tda827x_table[i].spd + 2);
|
||||
buf[0] = 0;
|
||||
buf[1] = (N>>8) | 0x40;
|
||||
buf[2] = N & 0xff;
|
||||
buf[3] = 0;
|
||||
buf[4] = 0x52;
|
||||
buf[5] = (tda827x_dvbt[i].spd << 6) + (tda827x_dvbt[i].div1p5 << 5) +
|
||||
(tda827x_dvbt[i].bs << 3) + tda827x_dvbt[i].bp;
|
||||
buf[6] = (tda827x_dvbt[i].gc3 << 4) + 0x8f;
|
||||
buf[5] = (tda827x_table[i].spd << 6) + (tda827x_table[i].div1p5 << 5) +
|
||||
(tda827x_table[i].bs << 3) +
|
||||
tda827x_table[i].bp;
|
||||
buf[6] = (tda827x_table[i].gc3 << 4) + 0x8f;
|
||||
buf[7] = 0xbf;
|
||||
buf[8] = 0x2a;
|
||||
buf[9] = 0x05;
|
||||
@ -140,7 +192,7 @@ static int tda827xo_set_params(struct dvb_frontend *fe,
|
||||
msleep(500);
|
||||
/* correct CP value */
|
||||
buf[0] = 0x30;
|
||||
buf[1] = 0x50 + tda827x_dvbt[i].cp;
|
||||
buf[1] = 0x50 + tda827x_table[i].cp;
|
||||
msg.len = 2;
|
||||
|
||||
if (fe->ops.i2c_gate_ctrl)
|
||||
@ -173,6 +225,102 @@ static int tda827xo_sleep(struct dvb_frontend *fe)
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
||||
static int tda827xo_set_analog_params(struct dvb_frontend *fe,
|
||||
struct analog_parameters *params)
|
||||
{
|
||||
unsigned char tuner_reg[8];
|
||||
unsigned char reg2[2];
|
||||
u32 N;
|
||||
int i;
|
||||
struct tda827x_priv *priv = fe->tuner_priv;
|
||||
struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0 };
|
||||
unsigned int freq = params->frequency;
|
||||
|
||||
tda827x_set_std(fe, params);
|
||||
|
||||
if (params->mode == V4L2_TUNER_RADIO)
|
||||
freq = freq / 1000;
|
||||
|
||||
N = freq + priv->sgIF;
|
||||
|
||||
i = 0;
|
||||
while (tda827x_table[i].lomax < N * 62500) {
|
||||
if (tda827x_table[i + 1].lomax == 0)
|
||||
break;
|
||||
i++;
|
||||
}
|
||||
|
||||
N = N << tda827x_table[i].spd;
|
||||
|
||||
tuner_reg[0] = 0;
|
||||
tuner_reg[1] = (unsigned char)(N>>8);
|
||||
tuner_reg[2] = (unsigned char) N;
|
||||
tuner_reg[3] = 0x40;
|
||||
tuner_reg[4] = 0x52 + (priv->lpsel << 5);
|
||||
tuner_reg[5] = (tda827x_table[i].spd << 6) +
|
||||
(tda827x_table[i].div1p5 << 5) +
|
||||
(tda827x_table[i].bs << 3) + tda827x_table[i].bp;
|
||||
tuner_reg[6] = 0x8f + (tda827x_table[i].gc3 << 4);
|
||||
tuner_reg[7] = 0x8f;
|
||||
|
||||
msg.buf = tuner_reg;
|
||||
msg.len = 8;
|
||||
i2c_transfer(priv->i2c_adap, &msg, 1);
|
||||
|
||||
msg.buf = reg2;
|
||||
msg.len = 2;
|
||||
reg2[0] = 0x80;
|
||||
reg2[1] = 0;
|
||||
i2c_transfer(priv->i2c_adap, &msg, 1);
|
||||
|
||||
reg2[0] = 0x60;
|
||||
reg2[1] = 0xbf;
|
||||
i2c_transfer(priv->i2c_adap, &msg, 1);
|
||||
|
||||
reg2[0] = 0x30;
|
||||
reg2[1] = tuner_reg[4] + 0x80;
|
||||
i2c_transfer(priv->i2c_adap, &msg, 1);
|
||||
|
||||
msleep(1);
|
||||
reg2[0] = 0x30;
|
||||
reg2[1] = tuner_reg[4] + 4;
|
||||
i2c_transfer(priv->i2c_adap, &msg, 1);
|
||||
|
||||
msleep(1);
|
||||
reg2[0] = 0x30;
|
||||
reg2[1] = tuner_reg[4];
|
||||
i2c_transfer(priv->i2c_adap, &msg, 1);
|
||||
|
||||
msleep(550);
|
||||
reg2[0] = 0x30;
|
||||
reg2[1] = (tuner_reg[4] & 0xfc) + tda827x_table[i].cp;
|
||||
i2c_transfer(priv->i2c_adap, &msg, 1);
|
||||
|
||||
reg2[0] = 0x60;
|
||||
reg2[1] = 0x3f;
|
||||
i2c_transfer(priv->i2c_adap, &msg, 1);
|
||||
|
||||
reg2[0] = 0x80;
|
||||
reg2[1] = 0x08; /* Vsync en */
|
||||
i2c_transfer(priv->i2c_adap, &msg, 1);
|
||||
|
||||
priv->frequency = freq * 62500;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void tda827xo_agcf(struct dvb_frontend *fe)
|
||||
{
|
||||
struct tda827x_priv *priv = fe->tuner_priv;
|
||||
unsigned char data[] = { 0x80, 0x0c };
|
||||
struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0,
|
||||
.buf = data, .len = 2};
|
||||
|
||||
i2c_transfer(priv->i2c_adap, &msg, 1);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
||||
struct tda827xa_data {
|
||||
u32 lomax;
|
||||
u8 svco;
|
||||
@ -212,6 +360,35 @@ static const struct tda827xa_data tda827xa_dvbt[] = {
|
||||
{ .lomax = 0, .svco = 0, .spd = 0, .scr = 0, .sbs = 0, .gc3 = 0}
|
||||
};
|
||||
|
||||
static struct tda827xa_data tda827xa_analog[] = {
|
||||
{ .lomax = 56875000, .svco = 3, .spd = 4, .scr = 0, .sbs = 0, .gc3 = 3},
|
||||
{ .lomax = 67250000, .svco = 0, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 3},
|
||||
{ .lomax = 81250000, .svco = 1, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 3},
|
||||
{ .lomax = 97500000, .svco = 2, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 3},
|
||||
{ .lomax = 113750000, .svco = 3, .spd = 3, .scr = 0, .sbs = 1, .gc3 = 1},
|
||||
{ .lomax = 134500000, .svco = 0, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1},
|
||||
{ .lomax = 154000000, .svco = 1, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1},
|
||||
{ .lomax = 162500000, .svco = 1, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1},
|
||||
{ .lomax = 183000000, .svco = 2, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1},
|
||||
{ .lomax = 195000000, .svco = 2, .spd = 2, .scr = 0, .sbs = 2, .gc3 = 1},
|
||||
{ .lomax = 227500000, .svco = 3, .spd = 2, .scr = 0, .sbs = 2, .gc3 = 3},
|
||||
{ .lomax = 269000000, .svco = 0, .spd = 1, .scr = 0, .sbs = 2, .gc3 = 3},
|
||||
{ .lomax = 325000000, .svco = 1, .spd = 1, .scr = 0, .sbs = 2, .gc3 = 1},
|
||||
{ .lomax = 390000000, .svco = 2, .spd = 1, .scr = 0, .sbs = 3, .gc3 = 3},
|
||||
{ .lomax = 455000000, .svco = 3, .spd = 1, .scr = 0, .sbs = 3, .gc3 = 3},
|
||||
{ .lomax = 520000000, .svco = 0, .spd = 0, .scr = 0, .sbs = 3, .gc3 = 1},
|
||||
{ .lomax = 538000000, .svco = 0, .spd = 0, .scr = 1, .sbs = 3, .gc3 = 1},
|
||||
{ .lomax = 554000000, .svco = 1, .spd = 0, .scr = 0, .sbs = 3, .gc3 = 1},
|
||||
{ .lomax = 620000000, .svco = 1, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0},
|
||||
{ .lomax = 650000000, .svco = 1, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0},
|
||||
{ .lomax = 700000000, .svco = 2, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0},
|
||||
{ .lomax = 780000000, .svco = 2, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0},
|
||||
{ .lomax = 820000000, .svco = 3, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0},
|
||||
{ .lomax = 870000000, .svco = 3, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0},
|
||||
{ .lomax = 911000000, .svco = 3, .spd = 0, .scr = 2, .sbs = 4, .gc3 = 0},
|
||||
{ .lomax = 0, .svco = 0, .spd = 0, .scr = 0, .sbs = 0, .gc3 = 0}
|
||||
};
|
||||
|
||||
static int tda827xa_set_params(struct dvb_frontend *fe,
|
||||
struct dvb_frontend_parameters *params)
|
||||
{
|
||||
@ -368,6 +545,163 @@ static int tda827xa_sleep(struct dvb_frontend *fe)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
||||
static void tda827xa_lna_gain(struct dvb_frontend *fe, int high,
|
||||
struct analog_parameters *params)
|
||||
{
|
||||
struct tda827x_priv *priv = fe->tuner_priv;
|
||||
unsigned char buf[] = {0x22, 0x01};
|
||||
int arg;
|
||||
struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0,
|
||||
.buf = buf, .len = sizeof(buf) };
|
||||
|
||||
if (NULL == priv->cfg) {
|
||||
dprintk("tda827x_config not defined, cannot set LNA gain!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (priv->cfg->config) {
|
||||
if (high)
|
||||
dprintk("setting LNA to high gain\n");
|
||||
else
|
||||
dprintk("setting LNA to low gain\n");
|
||||
}
|
||||
switch (*priv->cfg->config) {
|
||||
case 0: /* no LNA */
|
||||
break;
|
||||
case 1: /* switch is GPIO 0 of tda8290 */
|
||||
case 2:
|
||||
/* turn Vsync on */
|
||||
if (params->std & V4L2_STD_MN)
|
||||
arg = 1;
|
||||
else
|
||||
arg = 0;
|
||||
if (priv->cfg->tuner_callback)
|
||||
priv->cfg->tuner_callback(priv->i2c_adap->algo_data,
|
||||
1, arg);
|
||||
buf[1] = high ? 0 : 1;
|
||||
if (*priv->cfg->config == 2)
|
||||
buf[1] = high ? 1 : 0;
|
||||
i2c_transfer(priv->i2c_adap, &msg, 1);
|
||||
break;
|
||||
case 3: /* switch with GPIO of saa713x */
|
||||
if (priv->cfg->tuner_callback)
|
||||
priv->cfg->tuner_callback(priv->i2c_adap->algo_data,
|
||||
0, high);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int tda827xa_set_analog_params(struct dvb_frontend *fe,
|
||||
struct analog_parameters *params)
|
||||
{
|
||||
unsigned char tuner_reg[11];
|
||||
u32 N;
|
||||
int i;
|
||||
struct tda827x_priv *priv = fe->tuner_priv;
|
||||
struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0,
|
||||
.buf = tuner_reg, .len = sizeof(tuner_reg) };
|
||||
unsigned int freq = params->frequency;
|
||||
|
||||
tda827x_set_std(fe, params);
|
||||
|
||||
tda827xa_lna_gain(fe, 1, params);
|
||||
msleep(10);
|
||||
|
||||
if (params->mode == V4L2_TUNER_RADIO)
|
||||
freq = freq / 1000;
|
||||
|
||||
N = freq + priv->sgIF;
|
||||
|
||||
i = 0;
|
||||
while (tda827xa_analog[i].lomax < N * 62500) {
|
||||
if (tda827xa_analog[i + 1].lomax == 0)
|
||||
break;
|
||||
i++;
|
||||
}
|
||||
|
||||
N = N << tda827xa_analog[i].spd;
|
||||
|
||||
tuner_reg[0] = 0;
|
||||
tuner_reg[1] = (unsigned char)(N>>8);
|
||||
tuner_reg[2] = (unsigned char) N;
|
||||
tuner_reg[3] = 0;
|
||||
tuner_reg[4] = 0x16;
|
||||
tuner_reg[5] = (tda827xa_analog[i].spd << 5) +
|
||||
(tda827xa_analog[i].svco << 3) +
|
||||
tda827xa_analog[i].sbs;
|
||||
tuner_reg[6] = 0x8b + (tda827xa_analog[i].gc3 << 4);
|
||||
tuner_reg[7] = 0x1c;
|
||||
tuner_reg[8] = 4;
|
||||
tuner_reg[9] = 0x20;
|
||||
tuner_reg[10] = 0x00;
|
||||
msg.len = 11;
|
||||
i2c_transfer(priv->i2c_adap, &msg, 1);
|
||||
|
||||
tuner_reg[0] = 0x90;
|
||||
tuner_reg[1] = 0xff;
|
||||
tuner_reg[2] = 0xe0;
|
||||
tuner_reg[3] = 0;
|
||||
tuner_reg[4] = 0x99 + (priv->lpsel << 1);
|
||||
msg.len = 5;
|
||||
i2c_transfer(priv->i2c_adap, &msg, 1);
|
||||
|
||||
tuner_reg[0] = 0xa0;
|
||||
tuner_reg[1] = 0xc0;
|
||||
msg.len = 2;
|
||||
i2c_transfer(priv->i2c_adap, &msg, 1);
|
||||
|
||||
tuner_reg[0] = 0x30;
|
||||
tuner_reg[1] = 0x10 + tda827xa_analog[i].scr;
|
||||
i2c_transfer(priv->i2c_adap, &msg, 1);
|
||||
|
||||
msg.flags = I2C_M_RD;
|
||||
i2c_transfer(priv->i2c_adap, &msg, 1);
|
||||
msg.flags = 0;
|
||||
tuner_reg[1] >>= 4;
|
||||
dprintk("AGC2 gain is: %d\n", tuner_reg[1]);
|
||||
if (tuner_reg[1] < 1)
|
||||
tda827xa_lna_gain(fe, 0, params);
|
||||
|
||||
msleep(100);
|
||||
tuner_reg[0] = 0x60;
|
||||
tuner_reg[1] = 0x3c;
|
||||
i2c_transfer(priv->i2c_adap, &msg, 1);
|
||||
|
||||
msleep(163);
|
||||
tuner_reg[0] = 0x50;
|
||||
tuner_reg[1] = 0x8f + (tda827xa_analog[i].gc3 << 4);
|
||||
i2c_transfer(priv->i2c_adap, &msg, 1);
|
||||
|
||||
tuner_reg[0] = 0x80;
|
||||
tuner_reg[1] = 0x28;
|
||||
i2c_transfer(priv->i2c_adap, &msg, 1);
|
||||
|
||||
tuner_reg[0] = 0xb0;
|
||||
tuner_reg[1] = 0x01;
|
||||
i2c_transfer(priv->i2c_adap, &msg, 1);
|
||||
|
||||
tuner_reg[0] = 0xc0;
|
||||
tuner_reg[1] = 0x19 + (priv->lpsel << 1);
|
||||
i2c_transfer(priv->i2c_adap, &msg, 1);
|
||||
|
||||
priv->frequency = freq * 62500;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void tda827xa_agcf(struct dvb_frontend *fe)
|
||||
{
|
||||
struct tda827x_priv *priv = fe->tuner_priv;
|
||||
unsigned char data[] = {0x80, 0x2c};
|
||||
struct i2c_msg msg = {.addr = priv->i2c_addr, .flags = 0,
|
||||
.buf = data, .len = 2};
|
||||
i2c_transfer(priv->i2c_adap, &msg, 1);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
||||
static int tda827x_release(struct dvb_frontend *fe)
|
||||
{
|
||||
kfree(fe->tuner_priv);
|
||||
@ -430,6 +764,7 @@ static struct dvb_tuner_ops tda827xo_tuner_ops = {
|
||||
.init = tda827x_initial_init,
|
||||
.sleep = tda827x_initial_sleep,
|
||||
.set_params = tda827xo_set_params,
|
||||
.set_analog_params = tda827xo_set_analog_params,
|
||||
.get_frequency = tda827x_get_frequency,
|
||||
.get_bandwidth = tda827x_get_bandwidth,
|
||||
};
|
||||
@ -445,6 +780,7 @@ static struct dvb_tuner_ops tda827xa_tuner_ops = {
|
||||
.init = tda827x_init,
|
||||
.sleep = tda827xa_sleep,
|
||||
.set_params = tda827xa_set_params,
|
||||
.set_analog_params = tda827xa_set_analog_params,
|
||||
.get_frequency = tda827x_get_frequency,
|
||||
.get_bandwidth = tda827x_get_bandwidth,
|
||||
};
|
||||
@ -465,9 +801,13 @@ static int tda827x_probe_version(struct dvb_frontend *fe)
|
||||
dprintk("tda827x tuner found\n");
|
||||
fe->ops.tuner_ops.init = tda827x_init;
|
||||
fe->ops.tuner_ops.sleep = tda827xo_sleep;
|
||||
if (priv->cfg)
|
||||
priv->cfg->agcf = tda827xo_agcf;
|
||||
} else {
|
||||
dprintk("tda827xa tuner found\n");
|
||||
memcpy(&fe->ops.tuner_ops, &tda827xa_tuner_ops, sizeof(struct dvb_tuner_ops));
|
||||
if (priv->cfg)
|
||||
priv->cfg->agcf = tda827xa_agcf;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -487,16 +827,13 @@ struct dvb_frontend *tda827x_attach(struct dvb_frontend *fe, int addr,
|
||||
priv->i2c_adap = i2c;
|
||||
priv->cfg = cfg;
|
||||
memcpy(&fe->ops.tuner_ops, &tda827xo_tuner_ops, sizeof(struct dvb_tuner_ops));
|
||||
|
||||
fe->tuner_priv = priv;
|
||||
|
||||
dprintk("type set to %s\n", fe->ops.tuner_ops.info.name);
|
||||
|
||||
return fe;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(tda827x_attach);
|
||||
|
||||
module_param(debug, int, 0644);
|
||||
MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
|
||||
EXPORT_SYMBOL_GPL(tda827x_attach);
|
||||
|
||||
MODULE_DESCRIPTION("DVB TDA827x driver");
|
||||
MODULE_AUTHOR("Hartmut Hackmann <hartmut.hackmann@t-online.de>");
|
||||
|
@ -29,9 +29,16 @@
|
||||
|
||||
struct tda827x_config
|
||||
{
|
||||
/* saa7134 - provided callbacks */
|
||||
void (*lna_gain) (struct dvb_frontend *fe, int high);
|
||||
int (*init) (struct dvb_frontend *fe);
|
||||
int (*sleep) (struct dvb_frontend *fe);
|
||||
|
||||
/* interface to tda829x driver */
|
||||
unsigned int *config;
|
||||
int (*tuner_callback) (void *dev, int command, int arg);
|
||||
|
||||
void (*agcf)(struct dvb_frontend *fe);
|
||||
};
|
||||
|
||||
|
||||
|
@ -65,7 +65,7 @@ static int ves1820_writereg(struct ves1820_state *state, u8 reg, u8 data)
|
||||
ret = i2c_transfer(state->i2c, &msg, 1);
|
||||
|
||||
if (ret != 1)
|
||||
printk("ves1820: %s(): writereg error (reg == 0x%02x,"
|
||||
printk("ves1820: %s(): writereg error (reg == 0x%02x, "
|
||||
"val == 0x%02x, ret == %i)\n", __FUNCTION__, reg, data, ret);
|
||||
|
||||
return (ret != 1) ? -EREMOTEIO : 0;
|
||||
@ -84,7 +84,7 @@ static u8 ves1820_readreg(struct ves1820_state *state, u8 reg)
|
||||
ret = i2c_transfer(state->i2c, msg, 2);
|
||||
|
||||
if (ret != 2)
|
||||
printk("ves1820: %s(): readreg error (reg == 0x%02x,"
|
||||
printk("ves1820: %s(): readreg error (reg == 0x%02x, "
|
||||
"ret == %i)\n", __FUNCTION__, reg, ret);
|
||||
|
||||
return b1[0];
|
||||
|
964
drivers/media/dvb/frontends/xc5000.c
Normal file
964
drivers/media/dvb/frontends/xc5000.c
Normal file
@ -0,0 +1,964 @@
|
||||
/*
|
||||
* Driver for Xceive XC5000 "QAM/8VSB single chip tuner"
|
||||
*
|
||||
* Copyright (c) 2007 Xceive Corporation
|
||||
* Copyright (c) 2007 Steven Toth <stoth@hauppauge.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
*
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/moduleparam.h>
|
||||
#include <linux/videodev2.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/dvb/frontend.h>
|
||||
#include <linux/i2c.h>
|
||||
|
||||
#include "dvb_frontend.h"
|
||||
|
||||
#include "xc5000.h"
|
||||
#include "xc5000_priv.h"
|
||||
|
||||
static int debug;
|
||||
module_param(debug, int, 0644);
|
||||
MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
|
||||
|
||||
#define dprintk(level,fmt, arg...) if (debug >= level) \
|
||||
printk(KERN_INFO "%s: " fmt, "xc5000", ## arg)
|
||||
|
||||
#define XC5000_DEFAULT_FIRMWARE "dvb-fe-xc5000-1.1.fw"
|
||||
#define XC5000_DEFAULT_FIRMWARE_SIZE 12332
|
||||
|
||||
/* Misc Defines */
|
||||
#define MAX_TV_STANDARD 23
|
||||
#define XC_MAX_I2C_WRITE_LENGTH 64
|
||||
|
||||
/* Signal Types */
|
||||
#define XC_RF_MODE_AIR 0
|
||||
#define XC_RF_MODE_CABLE 1
|
||||
|
||||
/* Result codes */
|
||||
#define XC_RESULT_SUCCESS 0
|
||||
#define XC_RESULT_RESET_FAILURE 1
|
||||
#define XC_RESULT_I2C_WRITE_FAILURE 2
|
||||
#define XC_RESULT_I2C_READ_FAILURE 3
|
||||
#define XC_RESULT_OUT_OF_RANGE 5
|
||||
|
||||
/* Product id */
|
||||
#define XC_PRODUCT_ID_FW_NOT_LOADED 0x2000
|
||||
#define XC_PRODUCT_ID_FW_LOADED 0x1388
|
||||
|
||||
/* Registers */
|
||||
#define XREG_INIT 0x00
|
||||
#define XREG_VIDEO_MODE 0x01
|
||||
#define XREG_AUDIO_MODE 0x02
|
||||
#define XREG_RF_FREQ 0x03
|
||||
#define XREG_D_CODE 0x04
|
||||
#define XREG_IF_OUT 0x05
|
||||
#define XREG_SEEK_MODE 0x07
|
||||
#define XREG_POWER_DOWN 0x0A
|
||||
#define XREG_SIGNALSOURCE 0x0D /* 0=Air, 1=Cable */
|
||||
#define XREG_SMOOTHEDCVBS 0x0E
|
||||
#define XREG_XTALFREQ 0x0F
|
||||
#define XREG_FINERFFREQ 0x10
|
||||
#define XREG_DDIMODE 0x11
|
||||
|
||||
#define XREG_ADC_ENV 0x00
|
||||
#define XREG_QUALITY 0x01
|
||||
#define XREG_FRAME_LINES 0x02
|
||||
#define XREG_HSYNC_FREQ 0x03
|
||||
#define XREG_LOCK 0x04
|
||||
#define XREG_FREQ_ERROR 0x05
|
||||
#define XREG_SNR 0x06
|
||||
#define XREG_VERSION 0x07
|
||||
#define XREG_PRODUCT_ID 0x08
|
||||
#define XREG_BUSY 0x09
|
||||
|
||||
/*
|
||||
Basic firmware description. This will remain with
|
||||
the driver for documentation purposes.
|
||||
|
||||
This represents an I2C firmware file encoded as a
|
||||
string of unsigned char. Format is as follows:
|
||||
|
||||
char[0 ]=len0_MSB -> len = len_MSB * 256 + len_LSB
|
||||
char[1 ]=len0_LSB -> length of first write transaction
|
||||
char[2 ]=data0 -> first byte to be sent
|
||||
char[3 ]=data1
|
||||
char[4 ]=data2
|
||||
char[ ]=...
|
||||
char[M ]=dataN -> last byte to be sent
|
||||
char[M+1]=len1_MSB -> len = len_MSB * 256 + len_LSB
|
||||
char[M+2]=len1_LSB -> length of second write transaction
|
||||
char[M+3]=data0
|
||||
char[M+4]=data1
|
||||
...
|
||||
etc.
|
||||
|
||||
The [len] value should be interpreted as follows:
|
||||
|
||||
len= len_MSB _ len_LSB
|
||||
len=1111_1111_1111_1111 : End of I2C_SEQUENCE
|
||||
len=0000_0000_0000_0000 : Reset command: Do hardware reset
|
||||
len=0NNN_NNNN_NNNN_NNNN : Normal transaction: number of bytes = {1:32767)
|
||||
len=1WWW_WWWW_WWWW_WWWW : Wait command: wait for {1:32767} ms
|
||||
|
||||
For the RESET and WAIT commands, the two following bytes will contain
|
||||
immediately the length of the following transaction.
|
||||
|
||||
*/
|
||||
typedef struct {
|
||||
char *Name;
|
||||
u16 AudioMode;
|
||||
u16 VideoMode;
|
||||
} XC_TV_STANDARD;
|
||||
|
||||
/* Tuner standards */
|
||||
#define MN_NTSC_PAL_BTSC 0
|
||||
#define MN_NTSC_PAL_A2 1
|
||||
#define MN_NTSC_PAL_EIAJ 2
|
||||
#define MN_NTSC_PAL_Mono 3
|
||||
#define BG_PAL_A2 4
|
||||
#define BG_PAL_NICAM 5
|
||||
#define BG_PAL_MONO 6
|
||||
#define I_PAL_NICAM 7
|
||||
#define I_PAL_NICAM_MONO 8
|
||||
#define DK_PAL_A2 9
|
||||
#define DK_PAL_NICAM 10
|
||||
#define DK_PAL_MONO 11
|
||||
#define DK_SECAM_A2DK1 12
|
||||
#define DK_SECAM_A2LDK3 13
|
||||
#define DK_SECAM_A2MONO 14
|
||||
#define L_SECAM_NICAM 15
|
||||
#define LC_SECAM_NICAM 16
|
||||
#define DTV6 17
|
||||
#define DTV8 18
|
||||
#define DTV7_8 19
|
||||
#define DTV7 20
|
||||
#define FM_Radio_INPUT2 21
|
||||
#define FM_Radio_INPUT1 22
|
||||
|
||||
XC_TV_STANDARD XC5000_Standard[MAX_TV_STANDARD] = {
|
||||
{"M/N-NTSC/PAL-BTSC", 0x0400, 0x8020},
|
||||
{"M/N-NTSC/PAL-A2", 0x0600, 0x8020},
|
||||
{"M/N-NTSC/PAL-EIAJ", 0x0440, 0x8020},
|
||||
{"M/N-NTSC/PAL-Mono", 0x0478, 0x8020},
|
||||
{"B/G-PAL-A2", 0x0A00, 0x8049},
|
||||
{"B/G-PAL-NICAM", 0x0C04, 0x8049},
|
||||
{"B/G-PAL-MONO", 0x0878, 0x8059},
|
||||
{"I-PAL-NICAM", 0x1080, 0x8009},
|
||||
{"I-PAL-NICAM-MONO", 0x0E78, 0x8009},
|
||||
{"D/K-PAL-A2", 0x1600, 0x8009},
|
||||
{"D/K-PAL-NICAM", 0x0E80, 0x8009},
|
||||
{"D/K-PAL-MONO", 0x1478, 0x8009},
|
||||
{"D/K-SECAM-A2 DK1", 0x1200, 0x8009},
|
||||
{"D/K-SECAM-A2 L/DK3",0x0E00, 0x8009},
|
||||
{"D/K-SECAM-A2 MONO", 0x1478, 0x8009},
|
||||
{"L-SECAM-NICAM", 0x8E82, 0x0009},
|
||||
{"L'-SECAM-NICAM", 0x8E82, 0x4009},
|
||||
{"DTV6", 0x00C0, 0x8002},
|
||||
{"DTV8", 0x00C0, 0x800B},
|
||||
{"DTV7/8", 0x00C0, 0x801B},
|
||||
{"DTV7", 0x00C0, 0x8007},
|
||||
{"FM Radio-INPUT2", 0x9802, 0x9002},
|
||||
{"FM Radio-INPUT1", 0x0208, 0x9002}
|
||||
};
|
||||
|
||||
static int xc5000_writeregs(struct xc5000_priv *priv, u8 *buf, u8 len);
|
||||
static int xc5000_readregs(struct xc5000_priv *priv, u8 *buf, u8 len);
|
||||
static void xc5000_TunerReset(struct dvb_frontend *fe);
|
||||
|
||||
static int xc_send_i2c_data(struct xc5000_priv *priv, u8 *buf, int len)
|
||||
{
|
||||
return xc5000_writeregs(priv, buf, len)
|
||||
? XC_RESULT_I2C_WRITE_FAILURE : XC_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
static int xc_read_i2c_data(struct xc5000_priv *priv, u8 *buf, int len)
|
||||
{
|
||||
return xc5000_readregs(priv, buf, len)
|
||||
? XC_RESULT_I2C_READ_FAILURE : XC_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
static int xc_reset(struct dvb_frontend *fe)
|
||||
{
|
||||
xc5000_TunerReset(fe);
|
||||
return XC_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
static void xc_wait(int wait_ms)
|
||||
{
|
||||
msleep(wait_ms);
|
||||
}
|
||||
|
||||
static void xc5000_TunerReset(struct dvb_frontend *fe)
|
||||
{
|
||||
struct xc5000_priv *priv = fe->tuner_priv;
|
||||
int ret;
|
||||
|
||||
dprintk(1, "%s()\n", __FUNCTION__);
|
||||
|
||||
if (priv->cfg->tuner_callback) {
|
||||
ret = priv->cfg->tuner_callback(priv->cfg->priv,
|
||||
XC5000_TUNER_RESET, 0);
|
||||
if (ret)
|
||||
printk(KERN_ERR "xc5000: reset failed\n");
|
||||
} else
|
||||
printk(KERN_ERR "xc5000: no tuner reset callback function, fatal\n");
|
||||
}
|
||||
|
||||
static int xc_write_reg(struct xc5000_priv *priv, u16 regAddr, u16 i2cData)
|
||||
{
|
||||
u8 buf[4];
|
||||
int WatchDogTimer = 5;
|
||||
int result;
|
||||
|
||||
buf[0] = (regAddr >> 8) & 0xFF;
|
||||
buf[1] = regAddr & 0xFF;
|
||||
buf[2] = (i2cData >> 8) & 0xFF;
|
||||
buf[3] = i2cData & 0xFF;
|
||||
result = xc_send_i2c_data(priv, buf, 4);
|
||||
if (result == XC_RESULT_SUCCESS) {
|
||||
/* wait for busy flag to clear */
|
||||
while ((WatchDogTimer > 0) && (result == XC_RESULT_SUCCESS)) {
|
||||
buf[0] = 0;
|
||||
buf[1] = XREG_BUSY;
|
||||
|
||||
result = xc_send_i2c_data(priv, buf, 2);
|
||||
if (result == XC_RESULT_SUCCESS) {
|
||||
result = xc_read_i2c_data(priv, buf, 2);
|
||||
if (result == XC_RESULT_SUCCESS) {
|
||||
if ((buf[0] == 0) && (buf[1] == 0)) {
|
||||
/* busy flag cleared */
|
||||
break;
|
||||
} else {
|
||||
xc_wait(100); /* wait 5 ms */
|
||||
WatchDogTimer--;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (WatchDogTimer < 0)
|
||||
result = XC_RESULT_I2C_WRITE_FAILURE;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static int xc_read_reg(struct xc5000_priv *priv, u16 regAddr, u16 *i2cData)
|
||||
{
|
||||
u8 buf[2];
|
||||
int result;
|
||||
|
||||
buf[0] = (regAddr >> 8) & 0xFF;
|
||||
buf[1] = regAddr & 0xFF;
|
||||
result = xc_send_i2c_data(priv, buf, 2);
|
||||
if (result != XC_RESULT_SUCCESS)
|
||||
return result;
|
||||
|
||||
result = xc_read_i2c_data(priv, buf, 2);
|
||||
if (result != XC_RESULT_SUCCESS)
|
||||
return result;
|
||||
|
||||
*i2cData = buf[0] * 256 + buf[1];
|
||||
return result;
|
||||
}
|
||||
|
||||
static int xc_load_i2c_sequence(struct dvb_frontend *fe, u8 i2c_sequence[])
|
||||
{
|
||||
struct xc5000_priv *priv = fe->tuner_priv;
|
||||
|
||||
int i, nbytes_to_send, result;
|
||||
unsigned int len, pos, index;
|
||||
u8 buf[XC_MAX_I2C_WRITE_LENGTH];
|
||||
|
||||
index=0;
|
||||
while ((i2c_sequence[index]!=0xFF) || (i2c_sequence[index+1]!=0xFF)) {
|
||||
len = i2c_sequence[index]* 256 + i2c_sequence[index+1];
|
||||
if (len == 0x0000) {
|
||||
/* RESET command */
|
||||
result = xc_reset(fe);
|
||||
index += 2;
|
||||
if (result != XC_RESULT_SUCCESS)
|
||||
return result;
|
||||
} else if (len & 0x8000) {
|
||||
/* WAIT command */
|
||||
xc_wait(len & 0x7FFF);
|
||||
index += 2;
|
||||
} else {
|
||||
/* Send i2c data whilst ensuring individual transactions
|
||||
* do not exceed XC_MAX_I2C_WRITE_LENGTH bytes.
|
||||
*/
|
||||
index += 2;
|
||||
buf[0] = i2c_sequence[index];
|
||||
buf[1] = i2c_sequence[index + 1];
|
||||
pos = 2;
|
||||
while (pos < len) {
|
||||
if ((len - pos) > XC_MAX_I2C_WRITE_LENGTH - 2) {
|
||||
nbytes_to_send = XC_MAX_I2C_WRITE_LENGTH;
|
||||
} else {
|
||||
nbytes_to_send = (len - pos + 2);
|
||||
}
|
||||
for (i=2; i<nbytes_to_send; i++) {
|
||||
buf[i] = i2c_sequence[index + pos + i - 2];
|
||||
}
|
||||
result = xc_send_i2c_data(priv, buf, nbytes_to_send);
|
||||
|
||||
if (result != XC_RESULT_SUCCESS)
|
||||
return result;
|
||||
|
||||
pos += nbytes_to_send - 2;
|
||||
}
|
||||
index += len;
|
||||
}
|
||||
}
|
||||
return XC_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
static int xc_initialize(struct xc5000_priv *priv)
|
||||
{
|
||||
dprintk(1, "%s()\n", __FUNCTION__);
|
||||
return xc_write_reg(priv, XREG_INIT, 0);
|
||||
}
|
||||
|
||||
static int xc_SetTVStandard(struct xc5000_priv *priv,
|
||||
u16 VideoMode, u16 AudioMode)
|
||||
{
|
||||
int ret;
|
||||
dprintk(1, "%s(0x%04x,0x%04x)\n", __FUNCTION__, VideoMode, AudioMode);
|
||||
dprintk(1, "%s() Standard = %s\n",
|
||||
__FUNCTION__,
|
||||
XC5000_Standard[priv->video_standard].Name);
|
||||
|
||||
ret = xc_write_reg(priv, XREG_VIDEO_MODE, VideoMode);
|
||||
if (ret == XC_RESULT_SUCCESS)
|
||||
ret = xc_write_reg(priv, XREG_AUDIO_MODE, AudioMode);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int xc_shutdown(struct xc5000_priv *priv)
|
||||
{
|
||||
return 0;
|
||||
/* Fixme: cannot bring tuner back alive once shutdown
|
||||
* without reloading the driver modules.
|
||||
* return xc_write_reg(priv, XREG_POWER_DOWN, 0);
|
||||
*/
|
||||
}
|
||||
|
||||
static int xc_SetSignalSource(struct xc5000_priv *priv, u16 rf_mode)
|
||||
{
|
||||
dprintk(1, "%s(%d) Source = %s\n", __FUNCTION__, rf_mode,
|
||||
rf_mode == XC_RF_MODE_AIR ? "ANTENNA" : "CABLE");
|
||||
|
||||
if ((rf_mode != XC_RF_MODE_AIR) && (rf_mode != XC_RF_MODE_CABLE))
|
||||
{
|
||||
rf_mode = XC_RF_MODE_CABLE;
|
||||
printk(KERN_ERR
|
||||
"%s(), Invalid mode, defaulting to CABLE",
|
||||
__FUNCTION__);
|
||||
}
|
||||
return xc_write_reg(priv, XREG_SIGNALSOURCE, rf_mode);
|
||||
}
|
||||
|
||||
static const struct dvb_tuner_ops xc5000_tuner_ops;
|
||||
|
||||
static int xc_set_RF_frequency(struct xc5000_priv *priv, u32 freq_hz)
|
||||
{
|
||||
u16 freq_code;
|
||||
|
||||
dprintk(1, "%s(%u)\n", __FUNCTION__, freq_hz);
|
||||
|
||||
if ((freq_hz > xc5000_tuner_ops.info.frequency_max) ||
|
||||
(freq_hz < xc5000_tuner_ops.info.frequency_min))
|
||||
return XC_RESULT_OUT_OF_RANGE;
|
||||
|
||||
freq_code = (u16)(freq_hz / 15625);
|
||||
|
||||
return xc_write_reg(priv, XREG_RF_FREQ, freq_code);
|
||||
}
|
||||
|
||||
|
||||
static int xc_set_IF_frequency(struct xc5000_priv *priv, u32 freq_khz)
|
||||
{
|
||||
u32 freq_code = (freq_khz * 1024)/1000;
|
||||
dprintk(1, "%s(freq_khz = %d) freq_code = 0x%x\n",
|
||||
__FUNCTION__, freq_khz, freq_code);
|
||||
|
||||
return xc_write_reg(priv, XREG_IF_OUT, freq_code);
|
||||
}
|
||||
|
||||
|
||||
static int xc_get_ADC_Envelope(struct xc5000_priv *priv, u16 *adc_envelope)
|
||||
{
|
||||
return xc_read_reg(priv, XREG_ADC_ENV, adc_envelope);
|
||||
}
|
||||
|
||||
static int xc_get_frequency_error(struct xc5000_priv *priv, u32 *freq_error_hz)
|
||||
{
|
||||
int result;
|
||||
u16 regData;
|
||||
u32 tmp;
|
||||
|
||||
result = xc_read_reg(priv, XREG_FREQ_ERROR, ®Data);
|
||||
if (result)
|
||||
return result;
|
||||
|
||||
tmp = (u32)regData;
|
||||
(*freq_error_hz) = (tmp * 15625) / 1000;
|
||||
return result;
|
||||
}
|
||||
|
||||
static int xc_get_lock_status(struct xc5000_priv *priv, u16 *lock_status)
|
||||
{
|
||||
return xc_read_reg(priv, XREG_LOCK, lock_status);
|
||||
}
|
||||
|
||||
static int xc_get_version(struct xc5000_priv *priv,
|
||||
u8 *hw_majorversion, u8 *hw_minorversion,
|
||||
u8 *fw_majorversion, u8 *fw_minorversion)
|
||||
{
|
||||
u16 data;
|
||||
int result;
|
||||
|
||||
result = xc_read_reg(priv, XREG_VERSION, &data);
|
||||
if (result)
|
||||
return result;
|
||||
|
||||
(*hw_majorversion) = (data >> 12) & 0x0F;
|
||||
(*hw_minorversion) = (data >> 8) & 0x0F;
|
||||
(*fw_majorversion) = (data >> 4) & 0x0F;
|
||||
(*fw_minorversion) = data & 0x0F;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int xc_get_hsync_freq(struct xc5000_priv *priv, u32 *hsync_freq_hz)
|
||||
{
|
||||
u16 regData;
|
||||
int result;
|
||||
|
||||
result = xc_read_reg(priv, XREG_HSYNC_FREQ, ®Data);
|
||||
if (result)
|
||||
return result;
|
||||
|
||||
(*hsync_freq_hz) = ((regData & 0x0fff) * 763)/100;
|
||||
return result;
|
||||
}
|
||||
|
||||
static int xc_get_frame_lines(struct xc5000_priv *priv, u16 *frame_lines)
|
||||
{
|
||||
return xc_read_reg(priv, XREG_FRAME_LINES, frame_lines);
|
||||
}
|
||||
|
||||
static int xc_get_quality(struct xc5000_priv *priv, u16 *quality)
|
||||
{
|
||||
return xc_read_reg(priv, XREG_QUALITY, quality);
|
||||
}
|
||||
|
||||
static u16 WaitForLock(struct xc5000_priv *priv)
|
||||
{
|
||||
u16 lockState = 0;
|
||||
int watchDogCount = 40;
|
||||
|
||||
while ((lockState == 0) && (watchDogCount > 0)) {
|
||||
xc_get_lock_status(priv, &lockState);
|
||||
if (lockState != 1) {
|
||||
xc_wait(5);
|
||||
watchDogCount--;
|
||||
}
|
||||
}
|
||||
return lockState;
|
||||
}
|
||||
|
||||
static int xc_tune_channel(struct xc5000_priv *priv, u32 freq_hz)
|
||||
{
|
||||
int found = 0;
|
||||
|
||||
dprintk(1, "%s(%u)\n", __FUNCTION__, freq_hz);
|
||||
|
||||
if (xc_set_RF_frequency(priv, freq_hz) != XC_RESULT_SUCCESS)
|
||||
return 0;
|
||||
|
||||
if (WaitForLock(priv) == 1)
|
||||
found = 1;
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
static int xc5000_readreg(struct xc5000_priv *priv, u16 reg, u16 *val)
|
||||
{
|
||||
u8 buf[2] = { reg >> 8, reg & 0xff };
|
||||
u8 bval[2] = { 0, 0 };
|
||||
struct i2c_msg msg[2] = {
|
||||
{ .addr = priv->cfg->i2c_address,
|
||||
.flags = 0, .buf = &buf[0], .len = 2 },
|
||||
{ .addr = priv->cfg->i2c_address,
|
||||
.flags = I2C_M_RD, .buf = &bval[0], .len = 2 },
|
||||
};
|
||||
|
||||
if (i2c_transfer(priv->i2c, msg, 2) != 2) {
|
||||
printk(KERN_WARNING "xc5000: I2C read failed\n");
|
||||
return -EREMOTEIO;
|
||||
}
|
||||
|
||||
*val = (bval[0] << 8) | bval[1];
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int xc5000_writeregs(struct xc5000_priv *priv, u8 *buf, u8 len)
|
||||
{
|
||||
struct i2c_msg msg = { .addr = priv->cfg->i2c_address,
|
||||
.flags = 0, .buf = buf, .len = len };
|
||||
|
||||
if (i2c_transfer(priv->i2c, &msg, 1) != 1) {
|
||||
printk(KERN_ERR "xc5000: I2C write failed (len=%i)\n",
|
||||
(int)len);
|
||||
return -EREMOTEIO;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int xc5000_readregs(struct xc5000_priv *priv, u8 *buf, u8 len)
|
||||
{
|
||||
struct i2c_msg msg = { .addr = priv->cfg->i2c_address,
|
||||
.flags = I2C_M_RD, .buf = buf, .len = len };
|
||||
|
||||
if (i2c_transfer(priv->i2c, &msg, 1) != 1) {
|
||||
printk(KERN_ERR "xc5000 I2C read failed (len=%i)\n",(int)len);
|
||||
return -EREMOTEIO;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int xc5000_fwupload(struct dvb_frontend* fe)
|
||||
{
|
||||
struct xc5000_priv *priv = fe->tuner_priv;
|
||||
const struct firmware *fw;
|
||||
int ret;
|
||||
|
||||
/* request the firmware, this will block and timeout */
|
||||
printk(KERN_INFO "xc5000: waiting for firmware upload (%s)...\n",
|
||||
XC5000_DEFAULT_FIRMWARE);
|
||||
|
||||
ret = request_firmware(&fw, XC5000_DEFAULT_FIRMWARE, &priv->i2c->dev);
|
||||
if (ret) {
|
||||
printk(KERN_ERR "xc5000: Upload failed. (file not found?)\n");
|
||||
ret = XC_RESULT_RESET_FAILURE;
|
||||
goto out;
|
||||
} else {
|
||||
printk(KERN_INFO "xc5000: firmware read %Zu bytes.\n",
|
||||
fw->size);
|
||||
ret = XC_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
if (fw->size != XC5000_DEFAULT_FIRMWARE_SIZE) {
|
||||
printk(KERN_ERR "xc5000: firmware incorrect size\n");
|
||||
ret = XC_RESULT_RESET_FAILURE;
|
||||
} else {
|
||||
printk(KERN_INFO "xc5000: firmware upload\n");
|
||||
ret = xc_load_i2c_sequence(fe, fw->data );
|
||||
}
|
||||
|
||||
out:
|
||||
release_firmware(fw);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void xc_debug_dump(struct xc5000_priv *priv)
|
||||
{
|
||||
u16 adc_envelope;
|
||||
u32 freq_error_hz = 0;
|
||||
u16 lock_status;
|
||||
u32 hsync_freq_hz = 0;
|
||||
u16 frame_lines;
|
||||
u16 quality;
|
||||
u8 hw_majorversion = 0, hw_minorversion = 0;
|
||||
u8 fw_majorversion = 0, fw_minorversion = 0;
|
||||
|
||||
/* Wait for stats to stabilize.
|
||||
* Frame Lines needs two frame times after initial lock
|
||||
* before it is valid.
|
||||
*/
|
||||
xc_wait(100);
|
||||
|
||||
xc_get_ADC_Envelope(priv, &adc_envelope);
|
||||
dprintk(1, "*** ADC envelope (0-1023) = %d\n", adc_envelope);
|
||||
|
||||
xc_get_frequency_error(priv, &freq_error_hz);
|
||||
dprintk(1, "*** Frequency error = %d Hz\n", freq_error_hz);
|
||||
|
||||
xc_get_lock_status(priv, &lock_status);
|
||||
dprintk(1, "*** Lock status (0-Wait, 1-Locked, 2-No-signal) = %d\n",
|
||||
lock_status);
|
||||
|
||||
xc_get_version(priv, &hw_majorversion, &hw_minorversion,
|
||||
&fw_majorversion, &fw_minorversion);
|
||||
dprintk(1, "*** HW: V%02x.%02x, FW: V%02x.%02x\n",
|
||||
hw_majorversion, hw_minorversion,
|
||||
fw_majorversion, fw_minorversion);
|
||||
|
||||
xc_get_hsync_freq(priv, &hsync_freq_hz);
|
||||
dprintk(1, "*** Horizontal sync frequency = %d Hz\n", hsync_freq_hz);
|
||||
|
||||
xc_get_frame_lines(priv, &frame_lines);
|
||||
dprintk(1, "*** Frame lines = %d\n", frame_lines);
|
||||
|
||||
xc_get_quality(priv, &quality);
|
||||
dprintk(1, "*** Quality (0:<8dB, 7:>56dB) = %d\n", quality);
|
||||
}
|
||||
|
||||
static int xc5000_set_params(struct dvb_frontend *fe,
|
||||
struct dvb_frontend_parameters *params)
|
||||
{
|
||||
struct xc5000_priv *priv = fe->tuner_priv;
|
||||
int ret;
|
||||
|
||||
dprintk(1, "%s() frequency=%d (Hz)\n", __FUNCTION__, params->frequency);
|
||||
|
||||
switch(params->u.vsb.modulation) {
|
||||
case VSB_8:
|
||||
case VSB_16:
|
||||
dprintk(1, "%s() VSB modulation\n", __FUNCTION__);
|
||||
priv->rf_mode = XC_RF_MODE_AIR;
|
||||
priv->freq_hz = params->frequency - 1750000;
|
||||
priv->bandwidth = BANDWIDTH_6_MHZ;
|
||||
priv->video_standard = DTV6;
|
||||
break;
|
||||
case QAM_64:
|
||||
case QAM_256:
|
||||
case QAM_AUTO:
|
||||
dprintk(1, "%s() QAM modulation\n", __FUNCTION__);
|
||||
priv->rf_mode = XC_RF_MODE_CABLE;
|
||||
priv->freq_hz = params->frequency - 1750000;
|
||||
priv->bandwidth = BANDWIDTH_6_MHZ;
|
||||
priv->video_standard = DTV6;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
dprintk(1, "%s() frequency=%d (compensated)\n",
|
||||
__FUNCTION__, priv->freq_hz);
|
||||
|
||||
ret = xc_SetSignalSource(priv, priv->rf_mode);
|
||||
if (ret != XC_RESULT_SUCCESS) {
|
||||
printk(KERN_ERR
|
||||
"xc5000: xc_SetSignalSource(%d) failed\n",
|
||||
priv->rf_mode);
|
||||
return -EREMOTEIO;
|
||||
}
|
||||
|
||||
ret = xc_SetTVStandard(priv,
|
||||
XC5000_Standard[priv->video_standard].VideoMode,
|
||||
XC5000_Standard[priv->video_standard].AudioMode);
|
||||
if (ret != XC_RESULT_SUCCESS) {
|
||||
printk(KERN_ERR "xc5000: xc_SetTVStandard failed\n");
|
||||
return -EREMOTEIO;
|
||||
}
|
||||
|
||||
ret = xc_set_IF_frequency(priv, priv->cfg->if_khz);
|
||||
if (ret != XC_RESULT_SUCCESS) {
|
||||
printk(KERN_ERR "xc5000: xc_Set_IF_frequency(%d) failed\n",
|
||||
priv->cfg->if_khz);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
xc_tune_channel(priv, priv->freq_hz);
|
||||
|
||||
if (debug)
|
||||
xc_debug_dump(priv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe);
|
||||
|
||||
static int xc5000_set_analog_params(struct dvb_frontend *fe,
|
||||
struct analog_parameters *params)
|
||||
{
|
||||
struct xc5000_priv *priv = fe->tuner_priv;
|
||||
int ret;
|
||||
|
||||
if(priv->fwloaded == 0)
|
||||
xc_load_fw_and_init_tuner(fe);
|
||||
|
||||
dprintk(1, "%s() frequency=%d (in units of 62.5khz)\n",
|
||||
__FUNCTION__, params->frequency);
|
||||
|
||||
priv->rf_mode = XC_RF_MODE_CABLE; /* Fix me: it could be air. */
|
||||
|
||||
/* params->frequency is in units of 62.5khz */
|
||||
priv->freq_hz = params->frequency * 62500;
|
||||
|
||||
/* FIX ME: Some video standards may have several possible audio
|
||||
standards. We simply default to one of them here.
|
||||
*/
|
||||
if(params->std & V4L2_STD_MN) {
|
||||
/* default to BTSC audio standard */
|
||||
priv->video_standard = MN_NTSC_PAL_BTSC;
|
||||
goto tune_channel;
|
||||
}
|
||||
|
||||
if(params->std & V4L2_STD_PAL_BG) {
|
||||
/* default to NICAM audio standard */
|
||||
priv->video_standard = BG_PAL_NICAM;
|
||||
goto tune_channel;
|
||||
}
|
||||
|
||||
if(params->std & V4L2_STD_PAL_I) {
|
||||
/* default to NICAM audio standard */
|
||||
priv->video_standard = I_PAL_NICAM;
|
||||
goto tune_channel;
|
||||
}
|
||||
|
||||
if(params->std & V4L2_STD_PAL_DK) {
|
||||
/* default to NICAM audio standard */
|
||||
priv->video_standard = DK_PAL_NICAM;
|
||||
goto tune_channel;
|
||||
}
|
||||
|
||||
if(params->std & V4L2_STD_SECAM_DK) {
|
||||
/* default to A2 DK1 audio standard */
|
||||
priv->video_standard = DK_SECAM_A2DK1;
|
||||
goto tune_channel;
|
||||
}
|
||||
|
||||
if(params->std & V4L2_STD_SECAM_L) {
|
||||
priv->video_standard = L_SECAM_NICAM;
|
||||
goto tune_channel;
|
||||
}
|
||||
|
||||
if(params->std & V4L2_STD_SECAM_LC) {
|
||||
priv->video_standard = LC_SECAM_NICAM;
|
||||
goto tune_channel;
|
||||
}
|
||||
|
||||
tune_channel:
|
||||
ret = xc_SetSignalSource(priv, priv->rf_mode);
|
||||
if (ret != XC_RESULT_SUCCESS) {
|
||||
printk(KERN_ERR
|
||||
"xc5000: xc_SetSignalSource(%d) failed\n",
|
||||
priv->rf_mode);
|
||||
return -EREMOTEIO;
|
||||
}
|
||||
|
||||
ret = xc_SetTVStandard(priv,
|
||||
XC5000_Standard[priv->video_standard].VideoMode,
|
||||
XC5000_Standard[priv->video_standard].AudioMode);
|
||||
if (ret != XC_RESULT_SUCCESS) {
|
||||
printk(KERN_ERR "xc5000: xc_SetTVStandard failed\n");
|
||||
return -EREMOTEIO;
|
||||
}
|
||||
|
||||
xc_tune_channel(priv, priv->freq_hz);
|
||||
|
||||
if (debug)
|
||||
xc_debug_dump(priv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int xc5000_get_frequency(struct dvb_frontend *fe, u32 *freq)
|
||||
{
|
||||
struct xc5000_priv *priv = fe->tuner_priv;
|
||||
dprintk(1, "%s()\n", __FUNCTION__);
|
||||
*freq = priv->freq_hz;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int xc5000_get_bandwidth(struct dvb_frontend *fe, u32 *bw)
|
||||
{
|
||||
struct xc5000_priv *priv = fe->tuner_priv;
|
||||
dprintk(1, "%s()\n", __FUNCTION__);
|
||||
|
||||
*bw = priv->bandwidth;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int xc5000_get_status(struct dvb_frontend *fe, u32 *status)
|
||||
{
|
||||
struct xc5000_priv *priv = fe->tuner_priv;
|
||||
u16 lock_status = 0;
|
||||
|
||||
xc_get_lock_status(priv, &lock_status);
|
||||
|
||||
dprintk(1, "%s() lock_status = 0x%08x\n", __FUNCTION__, lock_status);
|
||||
|
||||
*status = lock_status;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe)
|
||||
{
|
||||
struct xc5000_priv *priv = fe->tuner_priv;
|
||||
int ret = 0;
|
||||
|
||||
if (priv->fwloaded == 0) {
|
||||
ret = xc5000_fwupload(fe);
|
||||
if (ret != XC_RESULT_SUCCESS)
|
||||
return ret;
|
||||
priv->fwloaded = 1;
|
||||
}
|
||||
|
||||
/* Start the tuner self-calibration process */
|
||||
ret |= xc_initialize(priv);
|
||||
|
||||
/* Wait for calibration to complete.
|
||||
* We could continue but XC5000 will clock stretch subsequent
|
||||
* I2C transactions until calibration is complete. This way we
|
||||
* don't have to rely on clock stretching working.
|
||||
*/
|
||||
xc_wait( 100 );
|
||||
|
||||
/* Default to "CABLE" mode */
|
||||
ret |= xc_write_reg(priv, XREG_SIGNALSOURCE, XC_RF_MODE_CABLE);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int xc5000_sleep(struct dvb_frontend *fe)
|
||||
{
|
||||
struct xc5000_priv *priv = fe->tuner_priv;
|
||||
int ret;
|
||||
|
||||
dprintk(1, "%s()\n", __FUNCTION__);
|
||||
|
||||
/* On Pinnacle PCTV HD 800i, the tuner cannot be reinitialized
|
||||
* once shutdown without reloading the driver. Maybe I am not
|
||||
* doing something right.
|
||||
*
|
||||
*/
|
||||
|
||||
ret = xc_shutdown(priv);
|
||||
if(ret != XC_RESULT_SUCCESS) {
|
||||
printk(KERN_ERR
|
||||
"xc5000: %s() unable to shutdown tuner\n",
|
||||
__FUNCTION__);
|
||||
return -EREMOTEIO;
|
||||
}
|
||||
else {
|
||||
/* priv->fwloaded = 0; */
|
||||
return XC_RESULT_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
static int xc5000_init(struct dvb_frontend *fe)
|
||||
{
|
||||
struct xc5000_priv *priv = fe->tuner_priv;
|
||||
dprintk(1, "%s()\n", __FUNCTION__);
|
||||
|
||||
if (xc_load_fw_and_init_tuner(fe) != XC_RESULT_SUCCESS) {
|
||||
printk(KERN_ERR "xc5000: Unable to initialise tuner\n");
|
||||
return -EREMOTEIO;
|
||||
}
|
||||
|
||||
if (debug)
|
||||
xc_debug_dump(priv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int xc5000_release(struct dvb_frontend *fe)
|
||||
{
|
||||
dprintk(1, "%s()\n", __FUNCTION__);
|
||||
kfree(fe->tuner_priv);
|
||||
fe->tuner_priv = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct dvb_tuner_ops xc5000_tuner_ops = {
|
||||
.info = {
|
||||
.name = "Xceive XC5000",
|
||||
.frequency_min = 1000000,
|
||||
.frequency_max = 1023000000,
|
||||
.frequency_step = 50000,
|
||||
},
|
||||
|
||||
.release = xc5000_release,
|
||||
.init = xc5000_init,
|
||||
.sleep = xc5000_sleep,
|
||||
|
||||
.set_params = xc5000_set_params,
|
||||
.set_analog_params = xc5000_set_analog_params,
|
||||
.get_frequency = xc5000_get_frequency,
|
||||
.get_bandwidth = xc5000_get_bandwidth,
|
||||
.get_status = xc5000_get_status
|
||||
};
|
||||
|
||||
struct dvb_frontend * xc5000_attach(struct dvb_frontend *fe,
|
||||
struct i2c_adapter *i2c,
|
||||
struct xc5000_config *cfg)
|
||||
{
|
||||
struct xc5000_priv *priv = NULL;
|
||||
u16 id = 0;
|
||||
|
||||
dprintk(1, "%s()\n", __FUNCTION__);
|
||||
|
||||
priv = kzalloc(sizeof(struct xc5000_priv), GFP_KERNEL);
|
||||
if (priv == NULL)
|
||||
return NULL;
|
||||
|
||||
priv->cfg = cfg;
|
||||
priv->bandwidth = BANDWIDTH_6_MHZ;
|
||||
priv->i2c = i2c;
|
||||
|
||||
/* Check if firmware has been loaded. It is possible that another
|
||||
instance of the driver has loaded the firmware.
|
||||
*/
|
||||
if (xc5000_readreg(priv, XREG_PRODUCT_ID, &id) != 0) {
|
||||
kfree(priv);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
switch(id) {
|
||||
case XC_PRODUCT_ID_FW_LOADED:
|
||||
printk(KERN_INFO
|
||||
"xc5000: Successfully identified at address 0x%02x\n",
|
||||
cfg->i2c_address);
|
||||
printk(KERN_INFO
|
||||
"xc5000: Firmware has been loaded previously\n");
|
||||
priv->fwloaded = 1;
|
||||
break;
|
||||
case XC_PRODUCT_ID_FW_NOT_LOADED:
|
||||
printk(KERN_INFO
|
||||
"xc5000: Successfully identified at address 0x%02x\n",
|
||||
cfg->i2c_address);
|
||||
printk(KERN_INFO
|
||||
"xc5000: Firmware has not been loaded previously\n");
|
||||
priv->fwloaded = 0;
|
||||
break;
|
||||
default:
|
||||
printk(KERN_ERR
|
||||
"xc5000: Device not found at addr 0x%02x (0x%x)\n",
|
||||
cfg->i2c_address, id);
|
||||
kfree(priv);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memcpy(&fe->ops.tuner_ops, &xc5000_tuner_ops,
|
||||
sizeof(struct dvb_tuner_ops));
|
||||
|
||||
fe->tuner_priv = priv;
|
||||
|
||||
return fe;
|
||||
}
|
||||
EXPORT_SYMBOL(xc5000_attach);
|
||||
|
||||
MODULE_AUTHOR("Steven Toth");
|
||||
MODULE_DESCRIPTION("Xceive xc5000 silicon tuner driver");
|
||||
MODULE_LICENSE("GPL");
|
62
drivers/media/dvb/frontends/xc5000.h
Normal file
62
drivers/media/dvb/frontends/xc5000.h
Normal file
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Driver for Xceive XC5000 "QAM/8VSB single chip tuner"
|
||||
*
|
||||
* Copyright (c) 2007 Steven Toth <stoth@hauppauge.com>
|
||||
*
|
||||
* 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 __XC5000_H__
|
||||
#define __XC5000_H__
|
||||
|
||||
#include <linux/firmware.h>
|
||||
|
||||
struct dvb_frontend;
|
||||
struct i2c_adapter;
|
||||
|
||||
struct xc5000_config {
|
||||
u8 i2c_address;
|
||||
u32 if_khz;
|
||||
|
||||
/* For each bridge framework, when it attaches either analog or digital,
|
||||
* it has to store a reference back to its _core equivalent structure,
|
||||
* so that it can service the hardware by steering gpio's etc.
|
||||
* Each bridge implementation is different so cast priv accordingly.
|
||||
* The xc5000 driver cares not for this value, other than ensuring
|
||||
* it's passed back to a bridge during tuner_callback().
|
||||
*/
|
||||
void *priv;
|
||||
int (*tuner_callback) (void *priv, int command, int arg);
|
||||
};
|
||||
|
||||
/* xc5000 callback command */
|
||||
#define XC5000_TUNER_RESET 0
|
||||
|
||||
#if defined(CONFIG_DVB_TUNER_XC5000) || defined(CONFIG_DVB_TUNER_XC5000_MODULE)
|
||||
extern struct dvb_frontend* xc5000_attach(struct dvb_frontend *fe,
|
||||
struct i2c_adapter *i2c,
|
||||
struct xc5000_config *cfg);
|
||||
#else
|
||||
static inline struct dvb_frontend* xc5000_attach(struct dvb_frontend *fe,
|
||||
struct i2c_adapter *i2c,
|
||||
struct xc5000_config *cfg)
|
||||
{
|
||||
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
|
||||
return NULL;
|
||||
}
|
||||
#endif // CONFIG_DVB_TUNER_XC5000
|
||||
|
||||
#endif // __XC5000_H__
|
36
drivers/media/dvb/frontends/xc5000_priv.h
Normal file
36
drivers/media/dvb/frontends/xc5000_priv.h
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Driver for Xceive XC5000 "QAM/8VSB single chip tuner"
|
||||
*
|
||||
* Copyright (c) 2007 Steven Toth <stoth@hauppauge.com>
|
||||
*
|
||||
* 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 XC5000_PRIV_H
|
||||
#define XC5000_PRIV_H
|
||||
|
||||
struct xc5000_priv {
|
||||
struct xc5000_config *cfg;
|
||||
struct i2c_adapter *i2c;
|
||||
|
||||
u32 freq_hz;
|
||||
u32 bandwidth;
|
||||
u8 video_standard;
|
||||
u8 rf_mode;
|
||||
u8 fwloaded;
|
||||
};
|
||||
|
||||
#endif
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Driver for Zarlink DVB-T ZL10353 demodulator
|
||||
*
|
||||
* Copyright (C) 2006 Christopher Pascoe <c.pascoe@itee.uq.edu.au>
|
||||
* Copyright (C) 2006, 2007 Christopher Pascoe <c.pascoe@itee.uq.edu.au>
|
||||
*
|
||||
* 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
|
||||
@ -16,7 +16,7 @@
|
||||
*
|
||||
* 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.=
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
@ -25,6 +25,7 @@
|
||||
#include <linux/delay.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/slab.h>
|
||||
#include <asm/div64.h>
|
||||
|
||||
#include "dvb_frontend.h"
|
||||
#include "zl10353_priv.h"
|
||||
@ -35,6 +36,8 @@ struct zl10353_state {
|
||||
struct dvb_frontend frontend;
|
||||
|
||||
struct zl10353_config config;
|
||||
|
||||
enum fe_bandwidth bandwidth;
|
||||
};
|
||||
|
||||
static int debug;
|
||||
@ -122,9 +125,10 @@ static void zl10353_calc_nominal_rate(struct dvb_frontend *fe,
|
||||
enum fe_bandwidth bandwidth,
|
||||
u16 *nominal_rate)
|
||||
{
|
||||
u32 adc_clock = 45056; /* 45.056 MHz */
|
||||
u8 bw;
|
||||
struct zl10353_state *state = fe->demodulator_priv;
|
||||
u32 adc_clock = 450560; /* 45.056 MHz */
|
||||
u64 value;
|
||||
u8 bw;
|
||||
|
||||
if (state->config.adc_clock)
|
||||
adc_clock = state->config.adc_clock;
|
||||
@ -142,12 +146,44 @@ static void zl10353_calc_nominal_rate(struct dvb_frontend *fe,
|
||||
break;
|
||||
}
|
||||
|
||||
*nominal_rate = (bw * (1 << 23) / 7 * 125 + adc_clock / 2) / adc_clock;
|
||||
value = (u64)10 * (1 << 23) / 7 * 125;
|
||||
value = (bw * value) + adc_clock / 2;
|
||||
do_div(value, adc_clock);
|
||||
*nominal_rate = value;
|
||||
|
||||
dprintk("%s: bw %d, adc_clock %d => 0x%x\n",
|
||||
__FUNCTION__, bw, adc_clock, *nominal_rate);
|
||||
}
|
||||
|
||||
static void zl10353_calc_input_freq(struct dvb_frontend *fe,
|
||||
u16 *input_freq)
|
||||
{
|
||||
struct zl10353_state *state = fe->demodulator_priv;
|
||||
u32 adc_clock = 450560; /* 45.056 MHz */
|
||||
int if2 = 361667; /* 36.1667 MHz */
|
||||
int ife;
|
||||
u64 value;
|
||||
|
||||
if (state->config.adc_clock)
|
||||
adc_clock = state->config.adc_clock;
|
||||
if (state->config.if2)
|
||||
if2 = state->config.if2;
|
||||
|
||||
if (adc_clock >= if2 * 2)
|
||||
ife = if2;
|
||||
else {
|
||||
ife = adc_clock - (if2 % adc_clock);
|
||||
if (ife > adc_clock / 2)
|
||||
ife = adc_clock - ife;
|
||||
}
|
||||
value = (u64)65536 * ife + adc_clock / 2;
|
||||
do_div(value, adc_clock);
|
||||
*input_freq = -value;
|
||||
|
||||
dprintk("%s: if2 %d, ife %d, adc_clock %d => %d / 0x%x\n",
|
||||
__FUNCTION__, if2, ife, adc_clock, -(int)value, *input_freq);
|
||||
}
|
||||
|
||||
static int zl10353_sleep(struct dvb_frontend *fe)
|
||||
{
|
||||
static u8 zl10353_softdown[] = { 0x50, 0x0C, 0x44 };
|
||||
@ -160,64 +196,276 @@ static int zl10353_set_parameters(struct dvb_frontend *fe,
|
||||
struct dvb_frontend_parameters *param)
|
||||
{
|
||||
struct zl10353_state *state = fe->demodulator_priv;
|
||||
u16 nominal_rate;
|
||||
u8 pllbuf[6] = { 0x67 };
|
||||
u16 nominal_rate, input_freq;
|
||||
u8 pllbuf[6] = { 0x67 }, acq_ctl = 0;
|
||||
u16 tps = 0;
|
||||
struct dvb_ofdm_parameters *op = ¶m->u.ofdm;
|
||||
|
||||
/* These settings set "auto-everything" and start the FSM. */
|
||||
zl10353_single_write(fe, 0x55, 0x80);
|
||||
zl10353_single_write(fe, RESET, 0x80);
|
||||
udelay(200);
|
||||
zl10353_single_write(fe, 0xEA, 0x01);
|
||||
udelay(200);
|
||||
zl10353_single_write(fe, 0xEA, 0x00);
|
||||
|
||||
zl10353_single_write(fe, 0x56, 0x28);
|
||||
zl10353_single_write(fe, 0x89, 0x20);
|
||||
zl10353_single_write(fe, 0x5E, 0x00);
|
||||
zl10353_single_write(fe, AGC_TARGET, 0x28);
|
||||
|
||||
zl10353_calc_nominal_rate(fe, param->u.ofdm.bandwidth, &nominal_rate);
|
||||
if (op->transmission_mode != TRANSMISSION_MODE_AUTO)
|
||||
acq_ctl |= (1 << 0);
|
||||
if (op->guard_interval != GUARD_INTERVAL_AUTO)
|
||||
acq_ctl |= (1 << 1);
|
||||
zl10353_single_write(fe, ACQ_CTL, acq_ctl);
|
||||
|
||||
switch (op->bandwidth) {
|
||||
case BANDWIDTH_6_MHZ:
|
||||
/* These are extrapolated from the 7 and 8MHz values */
|
||||
zl10353_single_write(fe, MCLK_RATIO, 0x97);
|
||||
zl10353_single_write(fe, 0x64, 0x34);
|
||||
break;
|
||||
case BANDWIDTH_7_MHZ:
|
||||
zl10353_single_write(fe, MCLK_RATIO, 0x86);
|
||||
zl10353_single_write(fe, 0x64, 0x35);
|
||||
break;
|
||||
case BANDWIDTH_8_MHZ:
|
||||
default:
|
||||
zl10353_single_write(fe, MCLK_RATIO, 0x75);
|
||||
zl10353_single_write(fe, 0x64, 0x36);
|
||||
}
|
||||
|
||||
zl10353_calc_nominal_rate(fe, op->bandwidth, &nominal_rate);
|
||||
zl10353_single_write(fe, TRL_NOMINAL_RATE_1, msb(nominal_rate));
|
||||
zl10353_single_write(fe, TRL_NOMINAL_RATE_0, lsb(nominal_rate));
|
||||
state->bandwidth = op->bandwidth;
|
||||
|
||||
zl10353_calc_input_freq(fe, &input_freq);
|
||||
zl10353_single_write(fe, INPUT_FREQ_1, msb(input_freq));
|
||||
zl10353_single_write(fe, INPUT_FREQ_0, lsb(input_freq));
|
||||
|
||||
/* Hint at TPS settings */
|
||||
switch (op->code_rate_HP) {
|
||||
case FEC_2_3:
|
||||
tps |= (1 << 7);
|
||||
break;
|
||||
case FEC_3_4:
|
||||
tps |= (2 << 7);
|
||||
break;
|
||||
case FEC_5_6:
|
||||
tps |= (3 << 7);
|
||||
break;
|
||||
case FEC_7_8:
|
||||
tps |= (4 << 7);
|
||||
break;
|
||||
case FEC_1_2:
|
||||
case FEC_AUTO:
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
switch (op->code_rate_LP) {
|
||||
case FEC_2_3:
|
||||
tps |= (1 << 4);
|
||||
break;
|
||||
case FEC_3_4:
|
||||
tps |= (2 << 4);
|
||||
break;
|
||||
case FEC_5_6:
|
||||
tps |= (3 << 4);
|
||||
break;
|
||||
case FEC_7_8:
|
||||
tps |= (4 << 4);
|
||||
break;
|
||||
case FEC_1_2:
|
||||
case FEC_AUTO:
|
||||
break;
|
||||
case FEC_NONE:
|
||||
if (op->hierarchy_information == HIERARCHY_AUTO ||
|
||||
op->hierarchy_information == HIERARCHY_NONE)
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
switch (op->constellation) {
|
||||
case QPSK:
|
||||
break;
|
||||
case QAM_AUTO:
|
||||
case QAM_16:
|
||||
tps |= (1 << 13);
|
||||
break;
|
||||
case QAM_64:
|
||||
tps |= (2 << 13);
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
switch (op->transmission_mode) {
|
||||
case TRANSMISSION_MODE_2K:
|
||||
case TRANSMISSION_MODE_AUTO:
|
||||
break;
|
||||
case TRANSMISSION_MODE_8K:
|
||||
tps |= (1 << 0);
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
switch (op->guard_interval) {
|
||||
case GUARD_INTERVAL_1_32:
|
||||
case GUARD_INTERVAL_AUTO:
|
||||
break;
|
||||
case GUARD_INTERVAL_1_16:
|
||||
tps |= (1 << 2);
|
||||
break;
|
||||
case GUARD_INTERVAL_1_8:
|
||||
tps |= (2 << 2);
|
||||
break;
|
||||
case GUARD_INTERVAL_1_4:
|
||||
tps |= (3 << 2);
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
switch (op->hierarchy_information) {
|
||||
case HIERARCHY_AUTO:
|
||||
case HIERARCHY_NONE:
|
||||
break;
|
||||
case HIERARCHY_1:
|
||||
tps |= (1 << 10);
|
||||
break;
|
||||
case HIERARCHY_2:
|
||||
tps |= (2 << 10);
|
||||
break;
|
||||
case HIERARCHY_4:
|
||||
tps |= (3 << 10);
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
zl10353_single_write(fe, TPS_GIVEN_1, msb(tps));
|
||||
zl10353_single_write(fe, TPS_GIVEN_0, lsb(tps));
|
||||
|
||||
zl10353_single_write(fe, 0x6C, 0xCD);
|
||||
zl10353_single_write(fe, 0x6D, 0x7E);
|
||||
if (fe->ops.i2c_gate_ctrl)
|
||||
fe->ops.i2c_gate_ctrl(fe, 0);
|
||||
|
||||
// if there is no attached secondary tuner, we call set_params to program
|
||||
// a potential tuner attached somewhere else
|
||||
/*
|
||||
* If there is no tuner attached to the secondary I2C bus, we call
|
||||
* set_params to program a potential tuner attached somewhere else.
|
||||
* Otherwise, we update the PLL registers via calc_regs.
|
||||
*/
|
||||
if (state->config.no_tuner) {
|
||||
if (fe->ops.tuner_ops.set_params) {
|
||||
fe->ops.tuner_ops.set_params(fe, param);
|
||||
if (fe->ops.i2c_gate_ctrl)
|
||||
fe->ops.i2c_gate_ctrl(fe, 0);
|
||||
}
|
||||
}
|
||||
|
||||
// if pllbuf is defined, retrieve the settings
|
||||
if (fe->ops.tuner_ops.calc_regs) {
|
||||
fe->ops.tuner_ops.calc_regs(fe, param, pllbuf+1, 5);
|
||||
} else if (fe->ops.tuner_ops.calc_regs) {
|
||||
fe->ops.tuner_ops.calc_regs(fe, param, pllbuf + 1, 5);
|
||||
pllbuf[1] <<= 1;
|
||||
} else {
|
||||
// fake pllbuf settings
|
||||
pllbuf[1] = 0x61 << 1;
|
||||
pllbuf[2] = 0;
|
||||
pllbuf[3] = 0;
|
||||
pllbuf[3] = 0;
|
||||
pllbuf[4] = 0;
|
||||
}
|
||||
|
||||
// there is no call to _just_ start decoding, so we send the pllbuf anyway
|
||||
// even if there isn't a PLL attached to the secondary bus
|
||||
zl10353_write(fe, pllbuf, sizeof(pllbuf));
|
||||
}
|
||||
|
||||
zl10353_single_write(fe, 0x5F, 0x13);
|
||||
zl10353_single_write(fe, 0x70, 0x01);
|
||||
udelay(250);
|
||||
zl10353_single_write(fe, 0xE4, 0x00);
|
||||
zl10353_single_write(fe, 0xE5, 0x2A);
|
||||
zl10353_single_write(fe, 0xE9, 0x02);
|
||||
zl10353_single_write(fe, 0xE7, 0x40);
|
||||
zl10353_single_write(fe, 0xE8, 0x10);
|
||||
|
||||
/* If no attached tuner or invalid PLL registers, just start the FSM. */
|
||||
if (state->config.no_tuner || fe->ops.tuner_ops.calc_regs == NULL)
|
||||
zl10353_single_write(fe, FSM_GO, 0x01);
|
||||
else
|
||||
zl10353_single_write(fe, TUNER_GO, 0x01);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int zl10353_get_parameters(struct dvb_frontend *fe,
|
||||
struct dvb_frontend_parameters *param)
|
||||
{
|
||||
struct zl10353_state *state = fe->demodulator_priv;
|
||||
struct dvb_ofdm_parameters *op = ¶m->u.ofdm;
|
||||
int s6, s9;
|
||||
u16 tps;
|
||||
static const u8 tps_fec_to_api[8] = {
|
||||
FEC_1_2,
|
||||
FEC_2_3,
|
||||
FEC_3_4,
|
||||
FEC_5_6,
|
||||
FEC_7_8,
|
||||
FEC_AUTO,
|
||||
FEC_AUTO,
|
||||
FEC_AUTO
|
||||
};
|
||||
|
||||
s6 = zl10353_read_register(state, STATUS_6);
|
||||
s9 = zl10353_read_register(state, STATUS_9);
|
||||
if (s6 < 0 || s9 < 0)
|
||||
return -EREMOTEIO;
|
||||
if ((s6 & (1 << 5)) == 0 || (s9 & (1 << 4)) == 0)
|
||||
return -EINVAL; /* no FE or TPS lock */
|
||||
|
||||
tps = zl10353_read_register(state, TPS_RECEIVED_1) << 8 |
|
||||
zl10353_read_register(state, TPS_RECEIVED_0);
|
||||
|
||||
op->code_rate_HP = tps_fec_to_api[(tps >> 7) & 7];
|
||||
op->code_rate_LP = tps_fec_to_api[(tps >> 4) & 7];
|
||||
|
||||
switch ((tps >> 13) & 3) {
|
||||
case 0:
|
||||
op->constellation = QPSK;
|
||||
break;
|
||||
case 1:
|
||||
op->constellation = QAM_16;
|
||||
break;
|
||||
case 2:
|
||||
op->constellation = QAM_64;
|
||||
break;
|
||||
default:
|
||||
op->constellation = QAM_AUTO;
|
||||
break;
|
||||
}
|
||||
|
||||
op->transmission_mode = (tps & 0x01) ? TRANSMISSION_MODE_8K :
|
||||
TRANSMISSION_MODE_2K;
|
||||
|
||||
switch ((tps >> 2) & 3) {
|
||||
case 0:
|
||||
op->guard_interval = GUARD_INTERVAL_1_32;
|
||||
break;
|
||||
case 1:
|
||||
op->guard_interval = GUARD_INTERVAL_1_16;
|
||||
break;
|
||||
case 2:
|
||||
op->guard_interval = GUARD_INTERVAL_1_8;
|
||||
break;
|
||||
case 3:
|
||||
op->guard_interval = GUARD_INTERVAL_1_4;
|
||||
break;
|
||||
default:
|
||||
op->guard_interval = GUARD_INTERVAL_AUTO;
|
||||
break;
|
||||
}
|
||||
|
||||
switch ((tps >> 10) & 7) {
|
||||
case 0:
|
||||
op->hierarchy_information = HIERARCHY_NONE;
|
||||
break;
|
||||
case 1:
|
||||
op->hierarchy_information = HIERARCHY_1;
|
||||
break;
|
||||
case 2:
|
||||
op->hierarchy_information = HIERARCHY_2;
|
||||
break;
|
||||
case 3:
|
||||
op->hierarchy_information = HIERARCHY_4;
|
||||
break;
|
||||
default:
|
||||
op->hierarchy_information = HIERARCHY_AUTO;
|
||||
break;
|
||||
}
|
||||
|
||||
param->frequency = 0;
|
||||
op->bandwidth = state->bandwidth;
|
||||
param->inversion = INVERSION_AUTO;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -406,6 +654,7 @@ static struct dvb_frontend_ops zl10353_ops = {
|
||||
.write = zl10353_write,
|
||||
|
||||
.set_frontend = zl10353_set_parameters,
|
||||
.get_frontend = zl10353_get_parameters,
|
||||
.get_tune_settings = zl10353_get_tune_settings,
|
||||
|
||||
.read_status = zl10353_read_status,
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Driver for Zarlink DVB-T ZL10353 demodulator
|
||||
*
|
||||
* Copyright (C) 2006 Christopher Pascoe <c.pascoe@itee.uq.edu.au>
|
||||
* Copyright (C) 2006, 2007 Christopher Pascoe <c.pascoe@itee.uq.edu.au>
|
||||
*
|
||||
* 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
|
||||
@ -29,8 +29,9 @@ struct zl10353_config
|
||||
/* demodulator's I2C address */
|
||||
u8 demod_address;
|
||||
|
||||
/* frequencies in kHz */
|
||||
int adc_clock; /* default: 45056 */
|
||||
/* frequencies in units of 0.1kHz */
|
||||
int adc_clock; /* default: 450560 (45.056 MHz) */
|
||||
int if2; /* default: 361667 (36.1667 MHz) */
|
||||
|
||||
/* set if no pll is connected to the secondary i2c bus */
|
||||
int no_tuner;
|
||||
@ -49,6 +50,6 @@ static inline struct dvb_frontend* zl10353_attach(const struct zl10353_config *c
|
||||
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
|
||||
return NULL;
|
||||
}
|
||||
#endif // CONFIG_DVB_ZL10353
|
||||
#endif /* CONFIG_DVB_ZL10353 */
|
||||
|
||||
#endif /* ZL10353_H */
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Driver for Zarlink DVB-T ZL10353 demodulator
|
||||
*
|
||||
* Copyright (C) 2006 Christopher Pascoe <c.pascoe@itee.uq.edu.au>
|
||||
* Copyright (C) 2006, 2007 Christopher Pascoe <c.pascoe@itee.uq.edu.au>
|
||||
*
|
||||
* 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
|
||||
@ -16,7 +16,7 @@
|
||||
*
|
||||
* 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.=
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef _ZL10353_PRIV_
|
||||
@ -46,9 +46,28 @@ enum zl10353_reg_addr {
|
||||
RS_ERR_CNT_0 = 0x13,
|
||||
RS_UBC_1 = 0x14,
|
||||
RS_UBC_0 = 0x15,
|
||||
TPS_RECEIVED_1 = 0x1D,
|
||||
TPS_RECEIVED_0 = 0x1E,
|
||||
TPS_CURRENT_1 = 0x1F,
|
||||
TPS_CURRENT_0 = 0x20,
|
||||
RESET = 0x55,
|
||||
AGC_TARGET = 0x56,
|
||||
MCLK_RATIO = 0x5C,
|
||||
ACQ_CTL = 0x5E,
|
||||
TRL_NOMINAL_RATE_1 = 0x65,
|
||||
TRL_NOMINAL_RATE_0 = 0x66,
|
||||
INPUT_FREQ_1 = 0x6C,
|
||||
INPUT_FREQ_0 = 0x6D,
|
||||
TPS_GIVEN_1 = 0x6E,
|
||||
TPS_GIVEN_0 = 0x6F,
|
||||
TUNER_GO = 0x70,
|
||||
FSM_GO = 0x71,
|
||||
CHIP_ID = 0x7F,
|
||||
CHAN_STEP_1 = 0xE4,
|
||||
CHAN_STEP_0 = 0xE5,
|
||||
OFDM_LOCK_TIME = 0xE7,
|
||||
FEC_LOCK_TIME = 0xE8,
|
||||
ACQ_DELAY = 0xE9,
|
||||
};
|
||||
|
||||
#endif /* _ZL10353_PRIV_ */
|
||||
|
@ -1,8 +1,14 @@
|
||||
config TTPCI_EEPROM
|
||||
tristate
|
||||
default n
|
||||
|
||||
config DVB_AV7110
|
||||
tristate "AV7110 cards"
|
||||
depends on DVB_CORE && PCI && I2C && VIDEO_V4L1
|
||||
depends on DVB_CORE && PCI && I2C
|
||||
select FW_LOADER if !DVB_AV7110_FIRMWARE
|
||||
select TTPCI_EEPROM
|
||||
select VIDEO_SAA7146_VV
|
||||
depends on VIDEO_DEV # dependencies of VIDEO_SAA7146_VV
|
||||
select DVB_VES1820 if !DVB_FE_CUSTOMISE
|
||||
select DVB_VES1X93 if !DVB_FE_CUSTOMISE
|
||||
select DVB_STV0299 if !DVB_FE_CUSTOMISE
|
||||
@ -57,10 +63,19 @@ config DVB_AV7110_OSD
|
||||
|
||||
All other people say N.
|
||||
|
||||
config DVB_BUDGET_CORE
|
||||
tristate "SAA7146 DVB cards (aka Budget, Nova-PCI)"
|
||||
depends on DVB_CORE && PCI && I2C
|
||||
select VIDEO_SAA7146
|
||||
select TTPCI_EEPROM
|
||||
help
|
||||
Support for simple SAA7146 based DVB cards
|
||||
(so called Budget- or Nova-PCI cards) without onboard
|
||||
MPEG2 decoder.
|
||||
|
||||
config DVB_BUDGET
|
||||
tristate "Budget cards"
|
||||
depends on DVB_CORE && PCI && I2C && VIDEO_V4L1
|
||||
select VIDEO_SAA7146
|
||||
depends on DVB_BUDGET_CORE && I2C
|
||||
select DVB_STV0299 if !DVB_FE_CUSTOMISE
|
||||
select DVB_VES1X93 if !DVB_FE_CUSTOMISE
|
||||
select DVB_VES1820 if !DVB_FE_CUSTOMISE
|
||||
@ -73,9 +88,9 @@ config DVB_BUDGET
|
||||
select DVB_TDA826X if !DVB_FE_CUSTOMISE
|
||||
select DVB_LNBP21 if !DVB_FE_CUSTOMISE
|
||||
help
|
||||
Support for simple SAA7146 based DVB cards
|
||||
(so called Budget- or Nova-PCI cards) without onboard
|
||||
MPEG2 decoder.
|
||||
Support for simple SAA7146 based DVB cards (so called Budget-
|
||||
or Nova-PCI cards) without onboard MPEG2 decoder, and without
|
||||
analog inputs or an onboard Common Interface connector.
|
||||
|
||||
Say Y if you own such a card and want to use it.
|
||||
|
||||
@ -84,8 +99,7 @@ config DVB_BUDGET
|
||||
|
||||
config DVB_BUDGET_CI
|
||||
tristate "Budget cards with onboard CI connector"
|
||||
depends on DVB_CORE && PCI && I2C && VIDEO_V4L1 && INPUT
|
||||
select VIDEO_SAA7146
|
||||
depends on DVB_BUDGET_CORE && I2C
|
||||
select DVB_STV0297 if !DVB_FE_CUSTOMISE
|
||||
select DVB_STV0299 if !DVB_FE_CUSTOMISE
|
||||
select DVB_TDA1004X if !DVB_FE_CUSTOMISE
|
||||
@ -106,8 +120,9 @@ config DVB_BUDGET_CI
|
||||
|
||||
config DVB_BUDGET_AV
|
||||
tristate "Budget cards with analog video inputs"
|
||||
depends on DVB_CORE && PCI && I2C && VIDEO_V4L1
|
||||
depends on DVB_BUDGET_CORE && I2C
|
||||
select VIDEO_SAA7146_VV
|
||||
depends on VIDEO_DEV # dependencies of VIDEO_SAA7146_VV
|
||||
select DVB_PLL if !DVB_FE_CUSTOMISE
|
||||
select DVB_STV0299 if !DVB_FE_CUSTOMISE
|
||||
select DVB_TDA1004X if !DVB_FE_CUSTOMISE
|
||||
@ -127,8 +142,8 @@ config DVB_BUDGET_AV
|
||||
|
||||
config DVB_BUDGET_PATCH
|
||||
tristate "AV7110 cards with Budget Patch"
|
||||
depends on DVB_CORE && DVB_BUDGET && VIDEO_V4L1
|
||||
select DVB_AV7110
|
||||
depends on DVB_BUDGET_CORE && I2C
|
||||
depends on DVB_AV7110
|
||||
select DVB_STV0299 if !DVB_FE_CUSTOMISE
|
||||
select DVB_VES1X93 if !DVB_FE_CUSTOMISE
|
||||
select DVB_TDA8083 if !DVB_FE_CUSTOMISE
|
||||
|
@ -5,11 +5,13 @@
|
||||
|
||||
dvb-ttpci-objs := av7110_hw.o av7110_v4l.o av7110_av.o av7110_ca.o av7110.o av7110_ipack.o av7110_ir.o
|
||||
|
||||
obj-$(CONFIG_DVB_BUDGET) += budget-core.o budget.o ttpci-eeprom.o
|
||||
obj-$(CONFIG_DVB_BUDGET_AV) += budget-core.o budget-av.o ttpci-eeprom.o
|
||||
obj-$(CONFIG_DVB_BUDGET_CI) += budget-core.o budget-ci.o ttpci-eeprom.o
|
||||
obj-$(CONFIG_DVB_BUDGET_PATCH) += budget-core.o budget-patch.o ttpci-eeprom.o
|
||||
obj-$(CONFIG_DVB_AV7110) += dvb-ttpci.o ttpci-eeprom.o
|
||||
obj-$(CONFIG_TTPCI_EEPROM) += ttpci-eeprom.o
|
||||
obj-$(CONFIG_DVB_BUDGET_CORE) += budget-core.o
|
||||
obj-$(CONFIG_DVB_BUDGET) += budget.o
|
||||
obj-$(CONFIG_DVB_BUDGET_AV) += budget-av.o
|
||||
obj-$(CONFIG_DVB_BUDGET_CI) += budget-ci.o
|
||||
obj-$(CONFIG_DVB_BUDGET_PATCH) += budget-patch.o
|
||||
obj-$(CONFIG_DVB_AV7110) += dvb-ttpci.o
|
||||
|
||||
EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/
|
||||
|
||||
|
@ -2595,7 +2595,8 @@ static int __devinit av7110_attach(struct saa7146_dev* dev,
|
||||
mutex_init(&av7110->osd_mutex);
|
||||
|
||||
/* TV standard */
|
||||
av7110->vidmode = tv_standard == 1 ? VIDEO_MODE_NTSC : VIDEO_MODE_PAL;
|
||||
av7110->vidmode = tv_standard == 1 ? AV7110_VIDEO_MODE_NTSC
|
||||
: AV7110_VIDEO_MODE_PAL;
|
||||
|
||||
/* ARM "watchdog" */
|
||||
init_waitqueue_head(&av7110->arm_wait);
|
||||
|
@ -46,6 +46,11 @@ extern int av7110_debug;
|
||||
|
||||
enum {AV_PES_STREAM, PS_STREAM, TS_STREAM, PES_STREAM};
|
||||
|
||||
enum av7110_video_mode {
|
||||
AV7110_VIDEO_MODE_PAL = 0,
|
||||
AV7110_VIDEO_MODE_NTSC = 1
|
||||
};
|
||||
|
||||
struct av7110_p2t {
|
||||
u8 pes[TS_SIZE];
|
||||
u8 counter;
|
||||
@ -170,7 +175,7 @@ struct av7110 {
|
||||
|
||||
ca_slot_info_t ci_slot[2];
|
||||
|
||||
int vidmode;
|
||||
enum av7110_video_mode vidmode;
|
||||
struct dmxdev dmxdev;
|
||||
struct dvb_demux demux;
|
||||
|
||||
|
@ -329,7 +329,7 @@ int av7110_set_volume(struct av7110 *av7110, int volleft, int volright)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int av7110_set_vidmode(struct av7110 *av7110, int mode)
|
||||
int av7110_set_vidmode(struct av7110 *av7110, enum av7110_video_mode mode)
|
||||
{
|
||||
int ret;
|
||||
dprintk(2, "av7110:%p, \n", av7110);
|
||||
@ -348,11 +348,15 @@ int av7110_set_vidmode(struct av7110 *av7110, int mode)
|
||||
}
|
||||
|
||||
|
||||
static int sw2mode[16] = {
|
||||
VIDEO_MODE_PAL, VIDEO_MODE_NTSC, VIDEO_MODE_NTSC, VIDEO_MODE_PAL,
|
||||
VIDEO_MODE_NTSC, VIDEO_MODE_NTSC, VIDEO_MODE_PAL, VIDEO_MODE_NTSC,
|
||||
VIDEO_MODE_PAL, VIDEO_MODE_PAL, VIDEO_MODE_PAL, VIDEO_MODE_PAL,
|
||||
VIDEO_MODE_PAL, VIDEO_MODE_PAL, VIDEO_MODE_PAL, VIDEO_MODE_PAL,
|
||||
static enum av7110_video_mode sw2mode[16] = {
|
||||
AV7110_VIDEO_MODE_PAL, AV7110_VIDEO_MODE_NTSC,
|
||||
AV7110_VIDEO_MODE_NTSC, AV7110_VIDEO_MODE_PAL,
|
||||
AV7110_VIDEO_MODE_NTSC, AV7110_VIDEO_MODE_NTSC,
|
||||
AV7110_VIDEO_MODE_PAL, AV7110_VIDEO_MODE_NTSC,
|
||||
AV7110_VIDEO_MODE_PAL, AV7110_VIDEO_MODE_PAL,
|
||||
AV7110_VIDEO_MODE_PAL, AV7110_VIDEO_MODE_PAL,
|
||||
AV7110_VIDEO_MODE_PAL, AV7110_VIDEO_MODE_PAL,
|
||||
AV7110_VIDEO_MODE_PAL, AV7110_VIDEO_MODE_PAL,
|
||||
};
|
||||
|
||||
static int get_video_format(struct av7110 *av7110, u8 *buf, int count)
|
||||
|
@ -3,7 +3,8 @@
|
||||
|
||||
struct av7110;
|
||||
|
||||
extern int av7110_set_vidmode(struct av7110 *av7110, int mode);
|
||||
extern int av7110_set_vidmode(struct av7110 *av7110,
|
||||
enum av7110_video_mode mode);
|
||||
|
||||
extern int av7110_record_cb(struct dvb_filter_pes2ts *p2t, u8 *buf, size_t len);
|
||||
extern int av7110_pes_play(void *dest, struct dvb_ringbuffer *buf, int dlen);
|
||||
|
@ -876,11 +876,11 @@ static int std_callback(struct saa7146_dev* dev, struct saa7146_standard *std)
|
||||
struct av7110 *av7110 = (struct av7110*) dev->ext_priv;
|
||||
|
||||
if (std->id & V4L2_STD_PAL) {
|
||||
av7110->vidmode = VIDEO_MODE_PAL;
|
||||
av7110->vidmode = AV7110_VIDEO_MODE_PAL;
|
||||
av7110_set_vidmode(av7110, av7110->vidmode);
|
||||
}
|
||||
else if (std->id & V4L2_STD_NTSC) {
|
||||
av7110->vidmode = VIDEO_MODE_NTSC;
|
||||
av7110->vidmode = AV7110_VIDEO_MODE_NTSC;
|
||||
av7110_set_vidmode(av7110, av7110->vidmode);
|
||||
}
|
||||
else
|
||||
|
@ -351,4 +351,14 @@ config USB_DSBR
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called dsbr100.
|
||||
|
||||
config USB_SI470X
|
||||
tristate "Silicon Labs Si470x FM Radio Receiver support"
|
||||
depends on USB && VIDEO_V4L2
|
||||
---help---
|
||||
Say Y here if you want to connect this type of radio to your
|
||||
computer's USB port.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called radio-silabs.
|
||||
|
||||
endif # RADIO_ADAPTERS
|
||||
|
@ -21,5 +21,6 @@ obj-$(CONFIG_RADIO_GEMTEK_PCI) += radio-gemtek-pci.o
|
||||
obj-$(CONFIG_RADIO_TRUST) += radio-trust.o
|
||||
obj-$(CONFIG_RADIO_MAESTRO) += radio-maestro.o
|
||||
obj-$(CONFIG_USB_DSBR) += dsbr100.o
|
||||
obj-$(CONFIG_USB_SI470X) += radio-si470x.o
|
||||
|
||||
EXTRA_CFLAGS += -Isound
|
||||
|
@ -33,6 +33,9 @@
|
||||
|
||||
History:
|
||||
|
||||
Version 0.43:
|
||||
Oliver Neukum: avoided DMA coherency issue
|
||||
|
||||
Version 0.42:
|
||||
Converted dsbr100 to use video_ioctl2
|
||||
by Douglas Landgraf <dougsland@gmail.com>
|
||||
@ -135,7 +138,7 @@ module_param(radio_nr, int, 0);
|
||||
struct dsbr100_device {
|
||||
struct usb_device *usbdev;
|
||||
struct video_device *videodev;
|
||||
unsigned char transfer_buffer[TB_LEN];
|
||||
u8 *transfer_buffer;
|
||||
int curfreq;
|
||||
int stereo;
|
||||
int users;
|
||||
@ -237,10 +240,7 @@ static void dsbr100_getstat(struct dsbr100_device *radio)
|
||||
/* handle unplugging of the device, release data structures
|
||||
if nothing keeps us from doing it. If something is still
|
||||
keeping us busy, the release callback of v4l will take care
|
||||
of releasing it. stv680.c does not relase its private
|
||||
data, so I don't do this here either. Checking out the
|
||||
code I'd expect I better did that, but if there's a memory
|
||||
leak here it's tiny (~50 bytes per disconnect) */
|
||||
of releasing it. */
|
||||
static void usb_dsbr100_disconnect(struct usb_interface *intf)
|
||||
{
|
||||
struct dsbr100_device *radio = usb_get_intfdata(intf);
|
||||
@ -250,6 +250,7 @@ static void usb_dsbr100_disconnect(struct usb_interface *intf)
|
||||
video_unregister_device(radio->videodev);
|
||||
radio->videodev = NULL;
|
||||
if (radio->users) {
|
||||
kfree(radio->transfer_buffer);
|
||||
kfree(radio);
|
||||
} else {
|
||||
radio->removed = 1;
|
||||
@ -425,6 +426,7 @@ static int usb_dsbr100_close(struct inode *inode, struct file *file)
|
||||
return -ENODEV;
|
||||
radio->users = 0;
|
||||
if (radio->removed) {
|
||||
kfree(radio->transfer_buffer);
|
||||
kfree(radio);
|
||||
}
|
||||
return 0;
|
||||
@ -471,7 +473,12 @@ static int usb_dsbr100_probe(struct usb_interface *intf,
|
||||
|
||||
if (!(radio = kmalloc(sizeof(struct dsbr100_device), GFP_KERNEL)))
|
||||
return -ENOMEM;
|
||||
if (!(radio->transfer_buffer = kmalloc(TB_LEN, GFP_KERNEL))) {
|
||||
kfree(radio);
|
||||
return -ENOMEM;
|
||||
}
|
||||
if (!(radio->videodev = video_device_alloc())) {
|
||||
kfree(radio->transfer_buffer);
|
||||
kfree(radio);
|
||||
return -ENOMEM;
|
||||
}
|
||||
@ -485,6 +492,7 @@ static int usb_dsbr100_probe(struct usb_interface *intf,
|
||||
if (video_register_device(radio->videodev, VFL_TYPE_RADIO,radio_nr)) {
|
||||
warn("Could not register video device");
|
||||
video_device_release(radio->videodev);
|
||||
kfree(radio->transfer_buffer);
|
||||
kfree(radio);
|
||||
return -EIO;
|
||||
}
|
||||
|
@ -58,10 +58,10 @@ static int initmute = 1;
|
||||
static int radio_nr = -1;
|
||||
|
||||
module_param(io, int, 0444);
|
||||
MODULE_PARM_DESC(io, "Force I/O port for the GemTek Radio card if automatic"
|
||||
MODULE_PARM_DESC(io, "Force I/O port for the GemTek Radio card if automatic "
|
||||
"probing is disabled or fails. The most common I/O ports are: 0x20c "
|
||||
"0x30c, 0x24c or 0x34c (0x20c, 0x248 and 0x28c have been reported to "
|
||||
" work for the combined sound/radiocard).");
|
||||
"work for the combined sound/radiocard).");
|
||||
|
||||
module_param(probe, bool, 0444);
|
||||
MODULE_PARM_DESC(probe, "Enable automatic device probing. Note: only the most "
|
||||
@ -392,7 +392,7 @@ static struct v4l2_queryctrl radio_qctrl[] = {
|
||||
}
|
||||
};
|
||||
|
||||
static struct file_operations gemtek_fops = {
|
||||
static const struct file_operations gemtek_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = video_exclusive_open,
|
||||
.release = video_exclusive_release,
|
||||
|
@ -423,7 +423,7 @@ static int __devinit maestro_probe(struct pci_dev *pdev,
|
||||
errunr:
|
||||
video_unregister_device(maestro_radio_inst);
|
||||
errfr1:
|
||||
kfree(maestro_radio_inst);
|
||||
video_device_release(maestro_radio_inst);
|
||||
errfr:
|
||||
kfree(radio_unit);
|
||||
err:
|
||||
|
@ -321,7 +321,7 @@ static struct isapnp_device_id id_table[] __devinitdata = {
|
||||
|
||||
MODULE_DEVICE_TABLE(isapnp, id_table);
|
||||
|
||||
static int isapnp_fmi_probe(void)
|
||||
static int __init isapnp_fmi_probe(void)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
|
@ -476,8 +476,7 @@ static int __init fmr2_init(void)
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
if(video_register_device(&fmr2_radio, VFL_TYPE_RADIO, radio_nr)==-1)
|
||||
{
|
||||
if (video_register_device(&fmr2_radio, VFL_TYPE_RADIO, radio_nr) < 0) {
|
||||
release_region(io, 2);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
1432
drivers/media/radio/radio-si470x.c
Normal file
1432
drivers/media/radio/radio-si470x.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -45,7 +45,7 @@ comment "Audio decoders"
|
||||
|
||||
config VIDEO_TVAUDIO
|
||||
tristate "Simple audio decoder chips"
|
||||
depends on VIDEO_V4L1 && I2C
|
||||
depends on VIDEO_V4L2 && I2C
|
||||
---help---
|
||||
Support for several audio decoder chips found on some bt8xx boards:
|
||||
Philips: tda9840, tda9873h, tda9874h/a, tda9850, tda985x, tea6300,
|
||||
@ -57,7 +57,7 @@ config VIDEO_TVAUDIO
|
||||
|
||||
config VIDEO_TDA7432
|
||||
tristate "Philips TDA7432 audio processor"
|
||||
depends on VIDEO_V4L1 && I2C
|
||||
depends on VIDEO_V4L2 && I2C
|
||||
---help---
|
||||
Support for tda7432 audio decoder chip found on some bt8xx boards.
|
||||
|
||||
@ -75,7 +75,7 @@ config VIDEO_TDA9840
|
||||
|
||||
config VIDEO_TDA9875
|
||||
tristate "Philips TDA9875 audio processor"
|
||||
depends on VIDEO_V4L1 && I2C
|
||||
depends on VIDEO_V4L2 && I2C
|
||||
---help---
|
||||
Support for tda9875 audio decoder chip found on some bt8xx boards.
|
||||
|
||||
@ -109,9 +109,19 @@ config VIDEO_MSP3400
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called msp3400.
|
||||
|
||||
config VIDEO_CS5345
|
||||
tristate "Cirrus Logic CS5345 audio ADC"
|
||||
depends on VIDEO_V4L2 && I2C && EXPERIMENTAL
|
||||
---help---
|
||||
Support for the Cirrus Logic CS5345 24-bit, 192 kHz
|
||||
stereo A/D converter.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called cs5345.
|
||||
|
||||
config VIDEO_CS53L32A
|
||||
tristate "Cirrus Logic CS53L32A audio ADC"
|
||||
depends on VIDEO_V4L2 && I2C && EXPERIMENTAL
|
||||
depends on VIDEO_V4L2 && I2C
|
||||
---help---
|
||||
Support for the Cirrus Logic CS53L32A low voltage
|
||||
stereo A/D converter.
|
||||
@ -119,6 +129,15 @@ config VIDEO_CS53L32A
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called cs53l32a.
|
||||
|
||||
config VIDEO_M52790
|
||||
tristate "Mitsubishi M52790 A/V switch"
|
||||
depends on VIDEO_V4L2 && I2C && EXPERIMENTAL
|
||||
---help---
|
||||
Support for the Mitsubishi M52790 A/V switch.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called m52790.
|
||||
|
||||
config VIDEO_TLV320AIC23B
|
||||
tristate "Texas Instruments TLV320AIC23B audio codec"
|
||||
depends on VIDEO_V4L2 && I2C && EXPERIMENTAL
|
||||
@ -130,7 +149,7 @@ config VIDEO_TLV320AIC23B
|
||||
|
||||
config VIDEO_WM8775
|
||||
tristate "Wolfson Microelectronics WM8775 audio ADC with input mixer"
|
||||
depends on VIDEO_V4L2 && I2C && EXPERIMENTAL
|
||||
depends on VIDEO_V4L2 && I2C
|
||||
---help---
|
||||
Support for the Wolfson Microelectronics WM8775 high
|
||||
performance stereo A/D Converter with a 4 channel input mixer.
|
||||
@ -140,7 +159,7 @@ config VIDEO_WM8775
|
||||
|
||||
config VIDEO_WM8739
|
||||
tristate "Wolfson Microelectronics WM8739 stereo audio ADC"
|
||||
depends on VIDEO_V4L2 && I2C && EXPERIMENTAL
|
||||
depends on VIDEO_V4L2 && I2C
|
||||
---help---
|
||||
Support for the Wolfson Microelectronics WM8739
|
||||
stereo A/D Converter.
|
||||
@ -244,7 +263,7 @@ config VIDEO_SAA7114
|
||||
|
||||
config VIDEO_SAA711X
|
||||
tristate "Philips SAA7113/4/5 video decoders"
|
||||
depends on VIDEO_V4L2 && I2C && EXPERIMENTAL
|
||||
depends on VIDEO_V4L2 && I2C
|
||||
---help---
|
||||
Support for the Philips SAA7113/4/5 video decoders.
|
||||
|
||||
@ -300,7 +319,7 @@ comment "Video encoders"
|
||||
|
||||
config VIDEO_SAA7127
|
||||
tristate "Philips SAA7127/9 digital video encoders"
|
||||
depends on VIDEO_V4L2 && I2C && EXPERIMENTAL
|
||||
depends on VIDEO_V4L2 && I2C
|
||||
---help---
|
||||
Support for the Philips SAA7127/9 digital video encoders.
|
||||
|
||||
@ -338,7 +357,7 @@ comment "Video improvement chips"
|
||||
|
||||
config VIDEO_UPD64031A
|
||||
tristate "NEC Electronics uPD64031A Ghost Reduction"
|
||||
depends on VIDEO_V4L2 && I2C && EXPERIMENTAL
|
||||
depends on VIDEO_V4L2 && I2C
|
||||
---help---
|
||||
Support for the NEC Electronics uPD64031A Ghost Reduction
|
||||
video chip. It is most often found in NTSC TV cards made for
|
||||
@ -350,7 +369,7 @@ config VIDEO_UPD64031A
|
||||
|
||||
config VIDEO_UPD64083
|
||||
tristate "NEC Electronics uPD64083 3-Dimensional Y/C separation"
|
||||
depends on VIDEO_V4L2 && I2C && EXPERIMENTAL
|
||||
depends on VIDEO_V4L2 && I2C
|
||||
---help---
|
||||
Support for the NEC Electronics uPD64083 3-Dimensional Y/C
|
||||
separation video chip. It is used to improve the quality of
|
||||
@ -802,6 +821,19 @@ config USB_ZR364XX
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called zr364xx.
|
||||
|
||||
config USB_STKWEBCAM
|
||||
tristate "USB Syntek DC1125 Camera support"
|
||||
depends on VIDEO_V4L2 && EXPERIMENTAL
|
||||
---help---
|
||||
Say Y here if you want to use this type of camera.
|
||||
Supported devices are typically found in some Asus laptops,
|
||||
with USB id 174f:a311 and 05e1:0501. Other Syntek cameras
|
||||
may be supported by the stk11xx driver, from which this is
|
||||
derived, see http://stk11xx.sourceforge.net
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called stkwebcam.
|
||||
|
||||
endif # V4L_USB_DRIVERS
|
||||
|
||||
endif # VIDEO_CAPTURE_DRIVERS
|
||||
|
@ -4,10 +4,12 @@
|
||||
|
||||
zr36067-objs := zoran_procfs.o zoran_device.o \
|
||||
zoran_driver.o zoran_card.o
|
||||
tuner-objs := tuner-core.o tuner-types.o tda9887.o
|
||||
tuner-objs := tuner-core.o tuner-types.o
|
||||
|
||||
msp3400-objs := msp3400-driver.o msp3400-kthreads.o
|
||||
|
||||
stkwebcam-objs := stk-webcam.o stk-sensor.o
|
||||
|
||||
obj-$(CONFIG_VIDEO_DEV) += videodev.o v4l2-common.o compat_ioctl32.o \
|
||||
v4l2-int-device.o
|
||||
|
||||
@ -66,7 +68,9 @@ obj-$(CONFIG_VIDEO_USBVISION) += usbvision/
|
||||
obj-$(CONFIG_VIDEO_TVP5150) += tvp5150.o
|
||||
obj-$(CONFIG_VIDEO_PVRUSB2) += pvrusb2/
|
||||
obj-$(CONFIG_VIDEO_MSP3400) += msp3400.o
|
||||
obj-$(CONFIG_VIDEO_CS5345) += cs5345.o
|
||||
obj-$(CONFIG_VIDEO_CS53L32A) += cs53l32a.o
|
||||
obj-$(CONFIG_VIDEO_M52790) += m52790.o
|
||||
obj-$(CONFIG_VIDEO_TLV320AIC23B) += tlv320aic23b.o
|
||||
obj-$(CONFIG_VIDEO_WM8775) += wm8775.o
|
||||
obj-$(CONFIG_VIDEO_WM8739) += wm8739.o
|
||||
@ -81,11 +85,13 @@ obj-$(CONFIG_TUNER_3036) += tuner-3036.o
|
||||
|
||||
obj-$(CONFIG_VIDEO_TUNER) += tuner.o
|
||||
|
||||
obj-$(CONFIG_TUNER_XC2028) += tuner-xc2028.o
|
||||
obj-$(CONFIG_TUNER_SIMPLE) += tuner-simple.o
|
||||
obj-$(CONFIG_TUNER_MT20XX) += mt20xx.o
|
||||
obj-$(CONFIG_TUNER_TDA8290) += tda8290.o
|
||||
obj-$(CONFIG_TUNER_TEA5767) += tea5767.o
|
||||
obj-$(CONFIG_TUNER_TEA5761) += tea5761.o
|
||||
obj-$(CONFIG_TUNER_TDA9887) += tda9887.o
|
||||
|
||||
obj-$(CONFIG_VIDEOBUF_GEN) += videobuf-core.o
|
||||
obj-$(CONFIG_VIDEOBUF_DMA_SG) += videobuf-dma-sg.o
|
||||
@ -112,6 +118,7 @@ obj-$(CONFIG_USB_SE401) += se401.o
|
||||
obj-$(CONFIG_USB_STV680) += stv680.o
|
||||
obj-$(CONFIG_USB_W9968CF) += w9968cf.o
|
||||
obj-$(CONFIG_USB_ZR364XX) += zr364xx.o
|
||||
obj-$(CONFIG_USB_STKWEBCAM) += stkwebcam.o
|
||||
|
||||
obj-$(CONFIG_USB_SN9C102) += sn9c102/
|
||||
obj-$(CONFIG_USB_ET61X251) += et61x251/
|
||||
@ -129,3 +136,4 @@ obj-$(CONFIG_VIDEO_VIVI) += vivi.o
|
||||
obj-$(CONFIG_VIDEO_CX23885) += cx23885/
|
||||
|
||||
EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
|
||||
EXTRA_CFLAGS += -Idrivers/media/dvb/frontends
|
||||
|
@ -1,6 +1,6 @@
|
||||
config VIDEO_BT848
|
||||
tristate "BT848 Video For Linux"
|
||||
depends on VIDEO_DEV && PCI && I2C && VIDEO_V4L1
|
||||
depends on VIDEO_DEV && PCI && I2C && VIDEO_V4L2 && INPUT
|
||||
select I2C_ALGOBIT
|
||||
select FW_LOADER
|
||||
select VIDEO_BTCX
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
bttv-objs := bttv-driver.o bttv-cards.o bttv-if.o \
|
||||
bttv-risc.o bttv-vbi.o bttv-i2c.o bttv-gpio.o \
|
||||
bttv-input.o
|
||||
bttv-input.o bttv-audio-hook.o
|
||||
|
||||
obj-$(CONFIG_VIDEO_BT848) += bttv.o
|
||||
|
||||
|
382
drivers/media/video/bt8xx/bttv-audio-hook.c
Normal file
382
drivers/media/video/bt8xx/bttv-audio-hook.c
Normal file
@ -0,0 +1,382 @@
|
||||
/*
|
||||
* Handlers for board audio hooks, splitted from bttv-cards
|
||||
*
|
||||
* Copyright (c) 2006 Mauro Carvalho Chehab (mchehab@infradead.org)
|
||||
* This code is placed under the terms of the GNU General Public License
|
||||
*/
|
||||
|
||||
#include "bttv-audio-hook.h"
|
||||
|
||||
#include <linux/delay.h>
|
||||
|
||||
/* ----------------------------------------------------------------------- */
|
||||
/* winview */
|
||||
|
||||
void winview_volume(struct bttv *btv, __u16 volume)
|
||||
{
|
||||
/* PT2254A programming Jon Tombs, jon@gte.esi.us.es */
|
||||
int bits_out, loops, vol, data;
|
||||
|
||||
/* 32 levels logarithmic */
|
||||
vol = 32 - ((volume>>11));
|
||||
/* units */
|
||||
bits_out = (PT2254_DBS_IN_2>>(vol%5));
|
||||
/* tens */
|
||||
bits_out |= (PT2254_DBS_IN_10>>(vol/5));
|
||||
bits_out |= PT2254_L_CHANNEL | PT2254_R_CHANNEL;
|
||||
data = gpio_read();
|
||||
data &= ~(WINVIEW_PT2254_CLK| WINVIEW_PT2254_DATA|
|
||||
WINVIEW_PT2254_STROBE);
|
||||
for (loops = 17; loops >= 0 ; loops--) {
|
||||
if (bits_out & (1<<loops))
|
||||
data |= WINVIEW_PT2254_DATA;
|
||||
else
|
||||
data &= ~WINVIEW_PT2254_DATA;
|
||||
gpio_write(data);
|
||||
udelay(5);
|
||||
data |= WINVIEW_PT2254_CLK;
|
||||
gpio_write(data);
|
||||
udelay(5);
|
||||
data &= ~WINVIEW_PT2254_CLK;
|
||||
gpio_write(data);
|
||||
}
|
||||
data |= WINVIEW_PT2254_STROBE;
|
||||
data &= ~WINVIEW_PT2254_DATA;
|
||||
gpio_write(data);
|
||||
udelay(10);
|
||||
data &= ~WINVIEW_PT2254_STROBE;
|
||||
gpio_write(data);
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------- */
|
||||
/* mono/stereo control for various cards (which don't use i2c chips but */
|
||||
/* connect something to the GPIO pins */
|
||||
|
||||
void gvbctv3pci_audio(struct bttv *btv, struct v4l2_tuner *t, int set)
|
||||
{
|
||||
unsigned int con = 0;
|
||||
|
||||
if (set) {
|
||||
gpio_inout(0x300, 0x300);
|
||||
if (t->audmode & V4L2_TUNER_MODE_LANG1)
|
||||
con = 0x000;
|
||||
if (t->audmode & V4L2_TUNER_MODE_LANG2)
|
||||
con = 0x300;
|
||||
if (t->audmode & V4L2_TUNER_MODE_STEREO)
|
||||
con = 0x200;
|
||||
/* if (t->audmode & V4L2_TUNER_MODE_MONO)
|
||||
* con = 0x100; */
|
||||
gpio_bits(0x300, con);
|
||||
} else {
|
||||
t->audmode = V4L2_TUNER_MODE_STEREO |
|
||||
V4L2_TUNER_MODE_LANG1 | V4L2_TUNER_MODE_LANG2;
|
||||
}
|
||||
}
|
||||
|
||||
void gvbctv5pci_audio(struct bttv *btv, struct v4l2_tuner *t, int set)
|
||||
{
|
||||
unsigned int val, con;
|
||||
|
||||
if (btv->radio_user)
|
||||
return;
|
||||
|
||||
val = gpio_read();
|
||||
if (set) {
|
||||
con = 0x000;
|
||||
if (t->audmode & V4L2_TUNER_MODE_LANG2) {
|
||||
if (t->audmode & V4L2_TUNER_MODE_LANG1) {
|
||||
/* LANG1 + LANG2 */
|
||||
con = 0x100;
|
||||
}
|
||||
else {
|
||||
/* LANG2 */
|
||||
con = 0x300;
|
||||
}
|
||||
}
|
||||
if (con != (val & 0x300)) {
|
||||
gpio_bits(0x300, con);
|
||||
if (bttv_gpio)
|
||||
bttv_gpio_tracking(btv,"gvbctv5pci");
|
||||
}
|
||||
} else {
|
||||
switch (val & 0x70) {
|
||||
case 0x10:
|
||||
t->rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
|
||||
break;
|
||||
case 0x30:
|
||||
t->rxsubchans = V4L2_TUNER_SUB_LANG2;
|
||||
break;
|
||||
case 0x50:
|
||||
t->rxsubchans = V4L2_TUNER_SUB_LANG1;
|
||||
break;
|
||||
case 0x60:
|
||||
t->rxsubchans = V4L2_TUNER_SUB_STEREO;
|
||||
break;
|
||||
case 0x70:
|
||||
t->rxsubchans = V4L2_TUNER_SUB_MONO;
|
||||
break;
|
||||
default:
|
||||
t->rxsubchans = V4L2_TUNER_SUB_MONO |
|
||||
V4L2_TUNER_SUB_STEREO |
|
||||
V4L2_TUNER_SUB_LANG1 |
|
||||
V4L2_TUNER_SUB_LANG2;
|
||||
}
|
||||
t->audmode = V4L2_TUNER_MODE_STEREO |
|
||||
V4L2_TUNER_MODE_LANG1 | V4L2_TUNER_MODE_LANG2;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Mario Medina Nussbaum <medisoft@alohabbs.org.mx>
|
||||
* I discover that on BT848_GPIO_DATA address a byte 0xcce enable stereo,
|
||||
* 0xdde enables mono and 0xccd enables sap
|
||||
*
|
||||
* Petr Vandrovec <VANDROVE@vc.cvut.cz>
|
||||
* P.S.: At least mask in line above is wrong - GPIO pins 3,2 select
|
||||
* input/output sound connection, so both must be set for output mode.
|
||||
*
|
||||
* Looks like it's needed only for the "tvphone", the "tvphone 98"
|
||||
* handles this with a tda9840
|
||||
*
|
||||
*/
|
||||
|
||||
void avermedia_tvphone_audio(struct bttv *btv, struct v4l2_tuner *t, int set)
|
||||
{
|
||||
int val = 0;
|
||||
|
||||
if (set) {
|
||||
if (t->audmode & V4L2_TUNER_MODE_LANG2) /* SAP */
|
||||
val = 0x02;
|
||||
if (t->audmode & V4L2_TUNER_MODE_STEREO)
|
||||
val = 0x01;
|
||||
if (val) {
|
||||
gpio_bits(0x03,val);
|
||||
if (bttv_gpio)
|
||||
bttv_gpio_tracking(btv,"avermedia");
|
||||
}
|
||||
} else {
|
||||
t->audmode = V4L2_TUNER_MODE_MONO | V4L2_TUNER_MODE_STEREO |
|
||||
V4L2_TUNER_MODE_LANG1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void avermedia_tv_stereo_audio(struct bttv *btv, struct v4l2_tuner *t, int set)
|
||||
{
|
||||
int val = 0;
|
||||
|
||||
if (set) {
|
||||
if (t->audmode & V4L2_TUNER_MODE_LANG2) /* SAP */
|
||||
val = 0x01;
|
||||
if (t->audmode & V4L2_TUNER_MODE_STEREO) /* STEREO */
|
||||
val = 0x02;
|
||||
btaor(val, ~0x03, BT848_GPIO_DATA);
|
||||
if (bttv_gpio)
|
||||
bttv_gpio_tracking(btv,"avermedia");
|
||||
} else {
|
||||
t->audmode = V4L2_TUNER_MODE_MONO | V4L2_TUNER_MODE_STEREO |
|
||||
V4L2_TUNER_MODE_LANG1 | V4L2_TUNER_MODE_LANG2;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Lifetec 9415 handling */
|
||||
|
||||
void lt9415_audio(struct bttv *btv, struct v4l2_tuner *t, int set)
|
||||
{
|
||||
int val = 0;
|
||||
|
||||
if (gpio_read() & 0x4000) {
|
||||
t->audmode = V4L2_TUNER_MODE_MONO;
|
||||
return;
|
||||
}
|
||||
|
||||
if (set) {
|
||||
if (t->audmode & V4L2_TUNER_MODE_LANG2) /* A2 SAP */
|
||||
val = 0x0080;
|
||||
if (t->audmode & V4L2_TUNER_MODE_STEREO) /* A2 stereo */
|
||||
val = 0x0880;
|
||||
if ((t->audmode & V4L2_TUNER_MODE_LANG1) ||
|
||||
(t->audmode & V4L2_TUNER_MODE_MONO))
|
||||
val = 0;
|
||||
gpio_bits(0x0880, val);
|
||||
if (bttv_gpio)
|
||||
bttv_gpio_tracking(btv,"lt9415");
|
||||
} else {
|
||||
/* autodetect doesn't work with this card :-( */
|
||||
t->audmode = V4L2_TUNER_MODE_MONO | V4L2_TUNER_MODE_STEREO |
|
||||
V4L2_TUNER_MODE_LANG1 | V4L2_TUNER_MODE_LANG2;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* TDA9821 on TerraTV+ Bt848, Bt878 */
|
||||
void terratv_audio(struct bttv *btv, struct v4l2_tuner *t, int set)
|
||||
{
|
||||
unsigned int con = 0;
|
||||
|
||||
if (set) {
|
||||
gpio_inout(0x180000,0x180000);
|
||||
if (t->audmode & V4L2_TUNER_MODE_LANG2)
|
||||
con = 0x080000;
|
||||
if (t->audmode & V4L2_TUNER_MODE_STEREO)
|
||||
con = 0x180000;
|
||||
gpio_bits(0x180000, con);
|
||||
if (bttv_gpio)
|
||||
bttv_gpio_tracking(btv,"terratv");
|
||||
} else {
|
||||
t->audmode = V4L2_TUNER_MODE_MONO | V4L2_TUNER_MODE_STEREO |
|
||||
V4L2_TUNER_MODE_LANG1 | V4L2_TUNER_MODE_LANG2;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void winfast2000_audio(struct bttv *btv, struct v4l2_tuner *t, int set)
|
||||
{
|
||||
unsigned long val = 0;
|
||||
|
||||
if (set) {
|
||||
/*btor (0xc32000, BT848_GPIO_OUT_EN);*/
|
||||
if (t->audmode & V4L2_TUNER_MODE_MONO) /* Mono */
|
||||
val = 0x420000;
|
||||
if (t->audmode & V4L2_TUNER_MODE_LANG1) /* Mono */
|
||||
val = 0x420000;
|
||||
if (t->audmode & V4L2_TUNER_MODE_LANG2) /* SAP */
|
||||
val = 0x410000;
|
||||
if (t->audmode & V4L2_TUNER_MODE_STEREO) /* Stereo */
|
||||
val = 0x020000;
|
||||
if (val) {
|
||||
gpio_bits(0x430000, val);
|
||||
if (bttv_gpio)
|
||||
bttv_gpio_tracking(btv,"winfast2000");
|
||||
}
|
||||
} else {
|
||||
t->audmode = V4L2_TUNER_MODE_MONO | V4L2_TUNER_MODE_STEREO |
|
||||
V4L2_TUNER_MODE_LANG1 | V4L2_TUNER_MODE_LANG2;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Dariusz Kowalewski <darekk@automex.pl>
|
||||
* sound control for Prolink PV-BT878P+9B (PixelView PlayTV Pro FM+NICAM
|
||||
* revision 9B has on-board TDA9874A sound decoder).
|
||||
*
|
||||
* Note: There are card variants without tda9874a. Forcing the "stereo sound route"
|
||||
* will mute this cards.
|
||||
*/
|
||||
void pvbt878p9b_audio(struct bttv *btv, struct v4l2_tuner *t, int set)
|
||||
{
|
||||
unsigned int val = 0;
|
||||
|
||||
if (btv->radio_user)
|
||||
return;
|
||||
|
||||
if (set) {
|
||||
if (t->audmode & V4L2_TUNER_MODE_MONO) {
|
||||
val = 0x01;
|
||||
}
|
||||
if ((t->audmode & (V4L2_TUNER_MODE_LANG1 | V4L2_TUNER_MODE_LANG2))
|
||||
|| (t->audmode & V4L2_TUNER_MODE_STEREO)) {
|
||||
val = 0x02;
|
||||
}
|
||||
if (val) {
|
||||
gpio_bits(0x03,val);
|
||||
if (bttv_gpio)
|
||||
bttv_gpio_tracking(btv,"pvbt878p9b");
|
||||
}
|
||||
} else {
|
||||
t->audmode = V4L2_TUNER_MODE_MONO | V4L2_TUNER_MODE_STEREO |
|
||||
V4L2_TUNER_MODE_LANG1 | V4L2_TUNER_MODE_LANG2;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Dariusz Kowalewski <darekk@automex.pl>
|
||||
* sound control for FlyVideo 2000S (with tda9874 decoder)
|
||||
* based on pvbt878p9b_audio() - this is not tested, please fix!!!
|
||||
*/
|
||||
void fv2000s_audio(struct bttv *btv, struct v4l2_tuner *t, int set)
|
||||
{
|
||||
unsigned int val = 0xffff;
|
||||
|
||||
if (btv->radio_user)
|
||||
return;
|
||||
|
||||
if (set) {
|
||||
if (t->audmode & V4L2_TUNER_MODE_MONO) {
|
||||
val = 0x0000;
|
||||
}
|
||||
if ((t->audmode & (V4L2_TUNER_MODE_LANG1 | V4L2_TUNER_MODE_LANG2))
|
||||
|| (t->audmode & V4L2_TUNER_MODE_STEREO)) {
|
||||
val = 0x1080; /*-dk-???: 0x0880, 0x0080, 0x1800 ... */
|
||||
}
|
||||
if (val != 0xffff) {
|
||||
gpio_bits(0x1800, val);
|
||||
if (bttv_gpio)
|
||||
bttv_gpio_tracking(btv,"fv2000s");
|
||||
}
|
||||
} else {
|
||||
t->audmode = V4L2_TUNER_MODE_MONO | V4L2_TUNER_MODE_STEREO |
|
||||
V4L2_TUNER_MODE_LANG1 | V4L2_TUNER_MODE_LANG2;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* sound control for Canopus WinDVR PCI
|
||||
* Masaki Suzuki <masaki@btree.org>
|
||||
*/
|
||||
void windvr_audio(struct bttv *btv, struct v4l2_tuner *t, int set)
|
||||
{
|
||||
unsigned long val = 0;
|
||||
|
||||
if (set) {
|
||||
if (t->audmode & V4L2_TUNER_MODE_MONO)
|
||||
val = 0x040000;
|
||||
if (t->audmode & V4L2_TUNER_MODE_LANG1)
|
||||
val = 0;
|
||||
if (t->audmode & V4L2_TUNER_MODE_LANG2)
|
||||
val = 0x100000;
|
||||
if (t->audmode & V4L2_TUNER_MODE_STEREO)
|
||||
val = 0;
|
||||
if (val) {
|
||||
gpio_bits(0x140000, val);
|
||||
if (bttv_gpio)
|
||||
bttv_gpio_tracking(btv,"windvr");
|
||||
}
|
||||
} else {
|
||||
t->audmode = V4L2_TUNER_MODE_MONO | V4L2_TUNER_MODE_STEREO |
|
||||
V4L2_TUNER_MODE_LANG1 | V4L2_TUNER_MODE_LANG2;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* sound control for AD-TVK503
|
||||
* Hiroshi Takekawa <sian@big.or.jp>
|
||||
*/
|
||||
void adtvk503_audio(struct bttv *btv, struct v4l2_tuner *t, int set)
|
||||
{
|
||||
unsigned int con = 0xffffff;
|
||||
|
||||
/* btaor(0x1e0000, ~0x1e0000, BT848_GPIO_OUT_EN); */
|
||||
|
||||
if (set) {
|
||||
/* btor(***, BT848_GPIO_OUT_EN); */
|
||||
if (t->audmode & V4L2_TUNER_MODE_LANG1)
|
||||
con = 0x00000000;
|
||||
if (t->audmode & V4L2_TUNER_MODE_LANG2)
|
||||
con = 0x00180000;
|
||||
if (t->audmode & V4L2_TUNER_MODE_STEREO)
|
||||
con = 0x00000000;
|
||||
if (t->audmode & V4L2_TUNER_MODE_MONO)
|
||||
con = 0x00060000;
|
||||
if (con != 0xffffff) {
|
||||
gpio_bits(0x1e0000,con);
|
||||
if (bttv_gpio)
|
||||
bttv_gpio_tracking(btv, "adtvk503");
|
||||
}
|
||||
} else {
|
||||
t->audmode = V4L2_TUNER_MODE_MONO | V4L2_TUNER_MODE_STEREO |
|
||||
V4L2_TUNER_MODE_LANG1 | V4L2_TUNER_MODE_LANG2;
|
||||
}
|
||||
}
|
23
drivers/media/video/bt8xx/bttv-audio-hook.h
Normal file
23
drivers/media/video/bt8xx/bttv-audio-hook.h
Normal file
@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Handlers for board audio hooks, splitted from bttv-cards
|
||||
*
|
||||
* Copyright (c) 2006 Mauro Carvalho Chehab (mchehab@infradead.org)
|
||||
* This code is placed under the terms of the GNU General Public License
|
||||
*/
|
||||
|
||||
#include "bttvp.h"
|
||||
|
||||
void winview_volume (struct bttv *btv, __u16 volume);
|
||||
|
||||
void lt9415_audio(struct bttv *btv, struct v4l2_tuner *tuner, int set);
|
||||
void avermedia_tvphone_audio(struct bttv *btv, struct v4l2_tuner *tuner, int set);
|
||||
void avermedia_tv_stereo_audio(struct bttv *btv, struct v4l2_tuner *tuner, int set);
|
||||
void terratv_audio(struct bttv *btv, struct v4l2_tuner *tuner, int set);
|
||||
void gvbctv3pci_audio(struct bttv *btv, struct v4l2_tuner *tuner, int set);
|
||||
void gvbctv5pci_audio(struct bttv *btv, struct v4l2_tuner *tuner, int set);
|
||||
void winfast2000_audio(struct bttv *btv, struct v4l2_tuner *tuner, int set);
|
||||
void pvbt878p9b_audio(struct bttv *btv, struct v4l2_tuner *tuner, int set);
|
||||
void fv2000s_audio(struct bttv *btv, struct v4l2_tuner *tuner, int set);
|
||||
void windvr_audio(struct bttv *btv, struct v4l2_tuner *tuner, int set);
|
||||
void adtvk503_audio(struct bttv *btv, struct v4l2_tuner *tuner, int set);
|
||||
|
@ -39,6 +39,7 @@
|
||||
#include "bttvp.h"
|
||||
#include <media/v4l2-common.h>
|
||||
#include <media/tvaudio.h>
|
||||
#include "bttv-audio-hook.h"
|
||||
|
||||
/* fwd decl */
|
||||
static void boot_msp34xx(struct bttv *btv, int pin);
|
||||
@ -50,20 +51,6 @@ static void modtec_eeprom(struct bttv *btv);
|
||||
static void init_PXC200(struct bttv *btv);
|
||||
static void init_RTV24(struct bttv *btv);
|
||||
|
||||
static void winview_audio(struct bttv *btv, struct video_audio *v, int set);
|
||||
static void lt9415_audio(struct bttv *btv, struct video_audio *v, int set);
|
||||
static void avermedia_tvphone_audio(struct bttv *btv, struct video_audio *v,
|
||||
int set);
|
||||
static void avermedia_tv_stereo_audio(struct bttv *btv, struct video_audio *v,
|
||||
int set);
|
||||
static void terratv_audio(struct bttv *btv, struct video_audio *v, int set);
|
||||
static void gvbctv3pci_audio(struct bttv *btv, struct video_audio *v, int set);
|
||||
static void gvbctv5pci_audio(struct bttv *btv, struct video_audio *v, int set);
|
||||
static void winfast2000_audio(struct bttv *btv, struct video_audio *v, int set);
|
||||
static void pvbt878p9b_audio(struct bttv *btv, struct video_audio *v, int set);
|
||||
static void fv2000s_audio(struct bttv *btv, struct video_audio *v, int set);
|
||||
static void windvr_audio(struct bttv *btv, struct video_audio *v, int set);
|
||||
static void adtvk503_audio(struct bttv *btv, struct video_audio *v, int set);
|
||||
static void rv605_muxsel(struct bttv *btv, unsigned int input);
|
||||
static void eagle_muxsel(struct bttv *btv, unsigned int input);
|
||||
static void xguard_muxsel(struct bttv *btv, unsigned int input);
|
||||
@ -427,7 +414,7 @@ struct tvcard bttv_tvcards[] = {
|
||||
.tuner_type = UNSET,
|
||||
.tuner_addr = ADDR_UNSET,
|
||||
.radio_addr = ADDR_UNSET,
|
||||
.audio_hook = avermedia_tvphone_audio,
|
||||
.audio_mode_gpio= avermedia_tvphone_audio,
|
||||
.has_remote = 1,
|
||||
},
|
||||
[BTTV_BOARD_MATRIX_VISION] = {
|
||||
@ -539,7 +526,7 @@ struct tvcard bttv_tvcards[] = {
|
||||
.tuner_type = TUNER_PHILIPS_PAL,
|
||||
.tuner_addr = ADDR_UNSET,
|
||||
.radio_addr = ADDR_UNSET,
|
||||
.audio_hook = avermedia_tv_stereo_audio,
|
||||
.audio_mode_gpio= avermedia_tv_stereo_audio,
|
||||
.no_gpioirq = 1,
|
||||
},
|
||||
[BTTV_BOARD_VHX] = {
|
||||
@ -604,7 +591,7 @@ struct tvcard bttv_tvcards[] = {
|
||||
.tuner_type = UNSET,
|
||||
.tuner_addr = ADDR_UNSET,
|
||||
.radio_addr = ADDR_UNSET,
|
||||
.audio_hook = winview_audio,
|
||||
.volume_gpio = winview_volume,
|
||||
.has_radio = 1,
|
||||
},
|
||||
[BTTV_BOARD_AVEC_INTERCAP] = {
|
||||
@ -728,7 +715,7 @@ struct tvcard bttv_tvcards[] = {
|
||||
.tuner_type = TUNER_PHILIPS_PAL,
|
||||
.tuner_addr = ADDR_UNSET,
|
||||
.radio_addr = ADDR_UNSET,
|
||||
.audio_hook = terratv_audio,
|
||||
.audio_mode_gpio= terratv_audio,
|
||||
},
|
||||
[BTTV_BOARD_HAUPPAUG_WCAM] = {
|
||||
.name = "Hauppauge WinCam newer (bt878)",
|
||||
@ -776,7 +763,7 @@ struct tvcard bttv_tvcards[] = {
|
||||
.tuner_type = TUNER_PHILIPS_PAL,
|
||||
.tuner_addr = ADDR_UNSET,
|
||||
.radio_addr = ADDR_UNSET,
|
||||
.audio_hook = terratv_audio,
|
||||
.audio_mode_gpio= terratv_audio,
|
||||
/* GPIO wiring:
|
||||
External 20 pin connector (for Active Radio Upgrade board)
|
||||
gpio00: i2c-sda
|
||||
@ -915,7 +902,7 @@ struct tvcard bttv_tvcards[] = {
|
||||
.tuner_type = TUNER_PHILIPS_PAL, /* default for now, gpio reads BFFF06 for Pal bg+dk */
|
||||
.tuner_addr = ADDR_UNSET,
|
||||
.radio_addr = ADDR_UNSET,
|
||||
.audio_hook = winfast2000_audio,
|
||||
.audio_mode_gpio= winfast2000_audio,
|
||||
.has_remote = 1,
|
||||
},
|
||||
[BTTV_BOARD_CHRONOS_VS2] = {
|
||||
@ -1035,7 +1022,7 @@ struct tvcard bttv_tvcards[] = {
|
||||
.tuner_addr = ADDR_UNSET,
|
||||
.radio_addr = ADDR_UNSET,
|
||||
.has_radio = 1,
|
||||
.audio_hook = avermedia_tvphone_audio,
|
||||
.audio_mode_gpio= avermedia_tvphone_audio,
|
||||
},
|
||||
[BTTV_BOARD_PV951] = {
|
||||
.name = "ProVideo PV951", /* pic16c54 */
|
||||
@ -1167,7 +1154,7 @@ struct tvcard bttv_tvcards[] = {
|
||||
.tuner_type = TUNER_ALPS_TSHC6_NTSC,
|
||||
.tuner_addr = ADDR_UNSET,
|
||||
.radio_addr = ADDR_UNSET,
|
||||
.audio_hook = gvbctv3pci_audio,
|
||||
.audio_mode_gpio= gvbctv3pci_audio,
|
||||
},
|
||||
[BTTV_BOARD_PXELVWPLTVPAK] = {
|
||||
.name = "Prolink PV-BT878P+4E / PixelView PlayTV PAK / Lenco MXTV-9578 CP",
|
||||
@ -1472,7 +1459,7 @@ struct tvcard bttv_tvcards[] = {
|
||||
/* -dk-???: set mute=0x1800 for tda9874h daughterboard */
|
||||
.gpiomux = { 0x0000,0x0800,0x1000,0x1000 },
|
||||
.gpiomute = 0x1800,
|
||||
.audio_hook = fv2000s_audio,
|
||||
.audio_mode_gpio= fv2000s_audio,
|
||||
.no_msp34xx = 1,
|
||||
.no_tda9875 = 1,
|
||||
.needs_tvaudio = 1,
|
||||
@ -1513,7 +1500,7 @@ struct tvcard bttv_tvcards[] = {
|
||||
.tuner_type = TUNER_SHARP_2U5JF5540_NTSC,
|
||||
.tuner_addr = ADDR_UNSET,
|
||||
.radio_addr = ADDR_UNSET,
|
||||
.audio_hook = gvbctv3pci_audio,
|
||||
.audio_mode_gpio= gvbctv3pci_audio,
|
||||
},
|
||||
|
||||
/* ---- card 0x44 ---------------------------------- */
|
||||
@ -1632,7 +1619,7 @@ struct tvcard bttv_tvcards[] = {
|
||||
.tuner_type = TUNER_PHILIPS_PAL,
|
||||
.tuner_addr = ADDR_UNSET,
|
||||
.radio_addr = ADDR_UNSET,
|
||||
.audio_hook = pvbt878p9b_audio, /* Note: not all cards have stereo */
|
||||
.audio_mode_gpio= pvbt878p9b_audio, /* Note: not all cards have stereo */
|
||||
.has_radio = 1, /* Note: not all cards have radio */
|
||||
.has_remote = 1,
|
||||
/* GPIO wiring:
|
||||
@ -1710,7 +1697,7 @@ struct tvcard bttv_tvcards[] = {
|
||||
.tuner_type = TUNER_PHILIPS_NTSC,
|
||||
.tuner_addr = ADDR_UNSET,
|
||||
.radio_addr = ADDR_UNSET,
|
||||
.audio_hook = windvr_audio,
|
||||
.audio_mode_gpio= windvr_audio,
|
||||
},
|
||||
[BTTV_BOARD_GRANDTEC_MULTI] = {
|
||||
.name = "GrandTec Multi Capture Card (Bt878)",
|
||||
@ -1807,7 +1794,7 @@ struct tvcard bttv_tvcards[] = {
|
||||
.tuner_type = TUNER_PHILIPS_NTSC_M,
|
||||
.tuner_addr = ADDR_UNSET,
|
||||
.radio_addr = ADDR_UNSET,
|
||||
.audio_hook = gvbctv5pci_audio,
|
||||
.audio_mode_gpio= gvbctv5pci_audio,
|
||||
.has_radio = 1,
|
||||
},
|
||||
[BTTV_BOARD_OSPREY1x0] = {
|
||||
@ -2106,7 +2093,7 @@ struct tvcard bttv_tvcards[] = {
|
||||
.tuner_type = TUNER_PHILIPS_NTSC,
|
||||
.tuner_addr = ADDR_UNSET,
|
||||
.radio_addr = ADDR_UNSET,
|
||||
.audio_hook = adtvk503_audio,
|
||||
.audio_mode_gpio= adtvk503_audio,
|
||||
},
|
||||
|
||||
/* ---- card 0x64 ---------------------------------- */
|
||||
@ -3173,8 +3160,8 @@ static void flyvideo_gpio(struct bttv *btv)
|
||||
/* LR90 Audio Routing is done by 2 hef4052, so Audio_Mask has 4 bits: 0x001c80
|
||||
* LR26/LR50 only has 1 hef4052, Audio_Mask 0x000c00
|
||||
* Audio options: from tuner, from tda9821/tda9821(mono,stereo,sap), from tda9874, ext., mute */
|
||||
if(has_tda9820_tda9821) btv->audio_hook = lt9415_audio;
|
||||
/* todo: if(has_tda9874) btv->audio_hook = fv2000s_audio; */
|
||||
if(has_tda9820_tda9821) btv->audio_mode_gpio = lt9415_audio;
|
||||
/* todo: if(has_tda9874) btv->audio_mode_gpio = fv2000s_audio; */
|
||||
}
|
||||
|
||||
static int miro_tunermap[] = { 0,6,2,3, 4,5,6,0, 3,0,4,5, 5,2,16,1,
|
||||
@ -3574,8 +3561,12 @@ void __devinit bttv_init_card2(struct bttv *btv)
|
||||
}
|
||||
|
||||
if (btv->tda9887_conf) {
|
||||
bttv_call_i2c_clients(btv, TDA9887_SET_CONFIG,
|
||||
&btv->tda9887_conf);
|
||||
struct v4l2_priv_tun_config tda9887_cfg;
|
||||
|
||||
tda9887_cfg.tuner = TUNER_TDA9887;
|
||||
tda9887_cfg.priv = &btv->tda9887_conf;
|
||||
|
||||
bttv_call_i2c_clients(btv, TUNER_SET_CONFIG, &tda9887_cfg);
|
||||
}
|
||||
|
||||
btv->svhs = bttv_tvcards[btv->c.type].svhs;
|
||||
@ -3590,8 +3581,10 @@ void __devinit bttv_init_card2(struct bttv *btv)
|
||||
btv->has_remote=1;
|
||||
if (!bttv_tvcards[btv->c.type].no_gpioirq)
|
||||
btv->gpioirq=1;
|
||||
if (bttv_tvcards[btv->c.type].audio_hook)
|
||||
btv->audio_hook=bttv_tvcards[btv->c.type].audio_hook;
|
||||
if (bttv_tvcards[btv->c.type].volume_gpio)
|
||||
btv->volume_gpio=bttv_tvcards[btv->c.type].volume_gpio;
|
||||
if (bttv_tvcards[btv->c.type].audio_mode_gpio)
|
||||
btv->audio_mode_gpio=bttv_tvcards[btv->c.type].audio_mode_gpio;
|
||||
|
||||
if (bttv_tvcards[btv->c.type].digital_mode == DIGITAL_MODE_CAMERA) {
|
||||
/* detect Bt832 chip for quartzsight digital camera */
|
||||
@ -3950,7 +3943,7 @@ static void __devinit avermedia_eeprom(struct bttv *btv)
|
||||
void bttv_tda9880_setnorm(struct bttv *btv, int norm)
|
||||
{
|
||||
/* fix up our card entry */
|
||||
if(norm==VIDEO_MODE_NTSC) {
|
||||
if(norm==V4L2_STD_NTSC) {
|
||||
bttv_tvcards[BTTV_BOARD_VOODOOTV_FM].gpiomux[TVAUDIO_INPUT_TUNER]=0x957fff;
|
||||
bttv_tvcards[BTTV_BOARD_VOODOOTV_FM].gpiomute=0x957fff;
|
||||
bttv_tvcards[BTTV_BOARD_VOODOOTV_200].gpiomux[TVAUDIO_INPUT_TUNER]=0x957fff;
|
||||
@ -4319,387 +4312,6 @@ void tea5757_set_freq(struct bttv *btv, unsigned short freq)
|
||||
tea5757_write(btv, 5 * freq + 0x358); /* add 10.7MHz (see docs) */
|
||||
}
|
||||
|
||||
|
||||
/* ----------------------------------------------------------------------- */
|
||||
/* winview */
|
||||
|
||||
static void winview_audio(struct bttv *btv, struct video_audio *v, int set)
|
||||
{
|
||||
/* PT2254A programming Jon Tombs, jon@gte.esi.us.es */
|
||||
int bits_out, loops, vol, data;
|
||||
|
||||
if (!set) {
|
||||
/* Fixed by Leandro Lucarella <luca@linuxmendoza.org.ar (07/31/01) */
|
||||
v->flags |= VIDEO_AUDIO_VOLUME;
|
||||
return;
|
||||
}
|
||||
|
||||
/* 32 levels logarithmic */
|
||||
vol = 32 - ((v->volume>>11));
|
||||
/* units */
|
||||
bits_out = (PT2254_DBS_IN_2>>(vol%5));
|
||||
/* tens */
|
||||
bits_out |= (PT2254_DBS_IN_10>>(vol/5));
|
||||
bits_out |= PT2254_L_CHANNEL | PT2254_R_CHANNEL;
|
||||
data = gpio_read();
|
||||
data &= ~(WINVIEW_PT2254_CLK| WINVIEW_PT2254_DATA|
|
||||
WINVIEW_PT2254_STROBE);
|
||||
for (loops = 17; loops >= 0 ; loops--) {
|
||||
if (bits_out & (1<<loops))
|
||||
data |= WINVIEW_PT2254_DATA;
|
||||
else
|
||||
data &= ~WINVIEW_PT2254_DATA;
|
||||
gpio_write(data);
|
||||
udelay(5);
|
||||
data |= WINVIEW_PT2254_CLK;
|
||||
gpio_write(data);
|
||||
udelay(5);
|
||||
data &= ~WINVIEW_PT2254_CLK;
|
||||
gpio_write(data);
|
||||
}
|
||||
data |= WINVIEW_PT2254_STROBE;
|
||||
data &= ~WINVIEW_PT2254_DATA;
|
||||
gpio_write(data);
|
||||
udelay(10);
|
||||
data &= ~WINVIEW_PT2254_STROBE;
|
||||
gpio_write(data);
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------- */
|
||||
/* mono/stereo control for various cards (which don't use i2c chips but */
|
||||
/* connect something to the GPIO pins */
|
||||
|
||||
static void
|
||||
gvbctv3pci_audio(struct bttv *btv, struct video_audio *v, int set)
|
||||
{
|
||||
unsigned int con = 0;
|
||||
|
||||
if (set) {
|
||||
gpio_inout(0x300, 0x300);
|
||||
if (v->mode & VIDEO_SOUND_LANG1)
|
||||
con = 0x000;
|
||||
if (v->mode & VIDEO_SOUND_LANG2)
|
||||
con = 0x300;
|
||||
if (v->mode & VIDEO_SOUND_STEREO)
|
||||
con = 0x200;
|
||||
/* if (v->mode & VIDEO_SOUND_MONO)
|
||||
* con = 0x100; */
|
||||
gpio_bits(0x300, con);
|
||||
} else {
|
||||
v->mode = VIDEO_SOUND_STEREO |
|
||||
VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gvbctv5pci_audio(struct bttv *btv, struct video_audio *v, int set)
|
||||
{
|
||||
unsigned int val, con;
|
||||
|
||||
if (btv->radio_user)
|
||||
return;
|
||||
|
||||
val = gpio_read();
|
||||
if (set) {
|
||||
con = 0x000;
|
||||
if (v->mode & VIDEO_SOUND_LANG2) {
|
||||
if (v->mode & VIDEO_SOUND_LANG1) {
|
||||
/* LANG1 + LANG2 */
|
||||
con = 0x100;
|
||||
}
|
||||
else {
|
||||
/* LANG2 */
|
||||
con = 0x300;
|
||||
}
|
||||
}
|
||||
if (con != (val & 0x300)) {
|
||||
gpio_bits(0x300, con);
|
||||
if (bttv_gpio)
|
||||
bttv_gpio_tracking(btv,"gvbctv5pci");
|
||||
}
|
||||
} else {
|
||||
switch (val & 0x70) {
|
||||
case 0x10:
|
||||
v->mode = VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
|
||||
break;
|
||||
case 0x30:
|
||||
v->mode = VIDEO_SOUND_LANG2;
|
||||
break;
|
||||
case 0x50:
|
||||
v->mode = VIDEO_SOUND_LANG1;
|
||||
break;
|
||||
case 0x60:
|
||||
v->mode = VIDEO_SOUND_STEREO;
|
||||
break;
|
||||
case 0x70:
|
||||
v->mode = VIDEO_SOUND_MONO;
|
||||
break;
|
||||
default:
|
||||
v->mode = VIDEO_SOUND_MONO | VIDEO_SOUND_STEREO |
|
||||
VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Mario Medina Nussbaum <medisoft@alohabbs.org.mx>
|
||||
* I discover that on BT848_GPIO_DATA address a byte 0xcce enable stereo,
|
||||
* 0xdde enables mono and 0xccd enables sap
|
||||
*
|
||||
* Petr Vandrovec <VANDROVE@vc.cvut.cz>
|
||||
* P.S.: At least mask in line above is wrong - GPIO pins 3,2 select
|
||||
* input/output sound connection, so both must be set for output mode.
|
||||
*
|
||||
* Looks like it's needed only for the "tvphone", the "tvphone 98"
|
||||
* handles this with a tda9840
|
||||
*
|
||||
*/
|
||||
static void
|
||||
avermedia_tvphone_audio(struct bttv *btv, struct video_audio *v, int set)
|
||||
{
|
||||
int val = 0;
|
||||
|
||||
if (set) {
|
||||
if (v->mode & VIDEO_SOUND_LANG2) /* SAP */
|
||||
val = 0x02;
|
||||
if (v->mode & VIDEO_SOUND_STEREO)
|
||||
val = 0x01;
|
||||
if (val) {
|
||||
gpio_bits(0x03,val);
|
||||
if (bttv_gpio)
|
||||
bttv_gpio_tracking(btv,"avermedia");
|
||||
}
|
||||
} else {
|
||||
v->mode = VIDEO_SOUND_MONO | VIDEO_SOUND_STEREO |
|
||||
VIDEO_SOUND_LANG1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
avermedia_tv_stereo_audio(struct bttv *btv, struct video_audio *v, int set)
|
||||
{
|
||||
int val = 0;
|
||||
|
||||
if (set) {
|
||||
if (v->mode & VIDEO_SOUND_LANG2) /* SAP */
|
||||
val = 0x01;
|
||||
if (v->mode & VIDEO_SOUND_STEREO) /* STEREO */
|
||||
val = 0x02;
|
||||
btaor(val, ~0x03, BT848_GPIO_DATA);
|
||||
if (bttv_gpio)
|
||||
bttv_gpio_tracking(btv,"avermedia");
|
||||
} else {
|
||||
v->mode = VIDEO_SOUND_MONO | VIDEO_SOUND_STEREO |
|
||||
VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Lifetec 9415 handling */
|
||||
static void
|
||||
lt9415_audio(struct bttv *btv, struct video_audio *v, int set)
|
||||
{
|
||||
int val = 0;
|
||||
|
||||
if (gpio_read() & 0x4000) {
|
||||
v->mode = VIDEO_SOUND_MONO;
|
||||
return;
|
||||
}
|
||||
|
||||
if (set) {
|
||||
if (v->mode & VIDEO_SOUND_LANG2) /* A2 SAP */
|
||||
val = 0x0080;
|
||||
if (v->mode & VIDEO_SOUND_STEREO) /* A2 stereo */
|
||||
val = 0x0880;
|
||||
if ((v->mode & VIDEO_SOUND_LANG1) ||
|
||||
(v->mode & VIDEO_SOUND_MONO))
|
||||
val = 0;
|
||||
gpio_bits(0x0880, val);
|
||||
if (bttv_gpio)
|
||||
bttv_gpio_tracking(btv,"lt9415");
|
||||
} else {
|
||||
/* autodetect doesn't work with this card :-( */
|
||||
v->mode = VIDEO_SOUND_MONO | VIDEO_SOUND_STEREO |
|
||||
VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* TDA9821 on TerraTV+ Bt848, Bt878 */
|
||||
static void
|
||||
terratv_audio(struct bttv *btv, struct video_audio *v, int set)
|
||||
{
|
||||
unsigned int con = 0;
|
||||
|
||||
if (set) {
|
||||
gpio_inout(0x180000,0x180000);
|
||||
if (v->mode & VIDEO_SOUND_LANG2)
|
||||
con = 0x080000;
|
||||
if (v->mode & VIDEO_SOUND_STEREO)
|
||||
con = 0x180000;
|
||||
gpio_bits(0x180000, con);
|
||||
if (bttv_gpio)
|
||||
bttv_gpio_tracking(btv,"terratv");
|
||||
} else {
|
||||
v->mode = VIDEO_SOUND_MONO | VIDEO_SOUND_STEREO |
|
||||
VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
winfast2000_audio(struct bttv *btv, struct video_audio *v, int set)
|
||||
{
|
||||
unsigned long val = 0;
|
||||
|
||||
if (set) {
|
||||
/*btor (0xc32000, BT848_GPIO_OUT_EN);*/
|
||||
if (v->mode & VIDEO_SOUND_MONO) /* Mono */
|
||||
val = 0x420000;
|
||||
if (v->mode & VIDEO_SOUND_LANG1) /* Mono */
|
||||
val = 0x420000;
|
||||
if (v->mode & VIDEO_SOUND_LANG2) /* SAP */
|
||||
val = 0x410000;
|
||||
if (v->mode & VIDEO_SOUND_STEREO) /* Stereo */
|
||||
val = 0x020000;
|
||||
if (val) {
|
||||
gpio_bits(0x430000, val);
|
||||
if (bttv_gpio)
|
||||
bttv_gpio_tracking(btv,"winfast2000");
|
||||
}
|
||||
} else {
|
||||
v->mode = VIDEO_SOUND_MONO | VIDEO_SOUND_STEREO |
|
||||
VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Dariusz Kowalewski <darekk@automex.pl>
|
||||
* sound control for Prolink PV-BT878P+9B (PixelView PlayTV Pro FM+NICAM
|
||||
* revision 9B has on-board TDA9874A sound decoder).
|
||||
*
|
||||
* Note: There are card variants without tda9874a. Forcing the "stereo sound route"
|
||||
* will mute this cards.
|
||||
*/
|
||||
static void
|
||||
pvbt878p9b_audio(struct bttv *btv, struct video_audio *v, int set)
|
||||
{
|
||||
unsigned int val = 0;
|
||||
|
||||
if (btv->radio_user)
|
||||
return;
|
||||
|
||||
if (set) {
|
||||
if (v->mode & VIDEO_SOUND_MONO) {
|
||||
val = 0x01;
|
||||
}
|
||||
if ((v->mode & (VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2))
|
||||
|| (v->mode & VIDEO_SOUND_STEREO)) {
|
||||
val = 0x02;
|
||||
}
|
||||
if (val) {
|
||||
gpio_bits(0x03,val);
|
||||
if (bttv_gpio)
|
||||
bttv_gpio_tracking(btv,"pvbt878p9b");
|
||||
}
|
||||
} else {
|
||||
v->mode = VIDEO_SOUND_MONO | VIDEO_SOUND_STEREO |
|
||||
VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Dariusz Kowalewski <darekk@automex.pl>
|
||||
* sound control for FlyVideo 2000S (with tda9874 decoder)
|
||||
* based on pvbt878p9b_audio() - this is not tested, please fix!!!
|
||||
*/
|
||||
static void
|
||||
fv2000s_audio(struct bttv *btv, struct video_audio *v, int set)
|
||||
{
|
||||
unsigned int val = 0xffff;
|
||||
|
||||
if (btv->radio_user)
|
||||
return;
|
||||
if (set) {
|
||||
if (v->mode & VIDEO_SOUND_MONO) {
|
||||
val = 0x0000;
|
||||
}
|
||||
if ((v->mode & (VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2))
|
||||
|| (v->mode & VIDEO_SOUND_STEREO)) {
|
||||
val = 0x1080; /*-dk-???: 0x0880, 0x0080, 0x1800 ... */
|
||||
}
|
||||
if (val != 0xffff) {
|
||||
gpio_bits(0x1800, val);
|
||||
if (bttv_gpio)
|
||||
bttv_gpio_tracking(btv,"fv2000s");
|
||||
}
|
||||
} else {
|
||||
v->mode = VIDEO_SOUND_MONO | VIDEO_SOUND_STEREO |
|
||||
VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* sound control for Canopus WinDVR PCI
|
||||
* Masaki Suzuki <masaki@btree.org>
|
||||
*/
|
||||
static void
|
||||
windvr_audio(struct bttv *btv, struct video_audio *v, int set)
|
||||
{
|
||||
unsigned long val = 0;
|
||||
|
||||
if (set) {
|
||||
if (v->mode & VIDEO_SOUND_MONO)
|
||||
val = 0x040000;
|
||||
if (v->mode & VIDEO_SOUND_LANG1)
|
||||
val = 0;
|
||||
if (v->mode & VIDEO_SOUND_LANG2)
|
||||
val = 0x100000;
|
||||
if (v->mode & VIDEO_SOUND_STEREO)
|
||||
val = 0;
|
||||
if (val) {
|
||||
gpio_bits(0x140000, val);
|
||||
if (bttv_gpio)
|
||||
bttv_gpio_tracking(btv,"windvr");
|
||||
}
|
||||
} else {
|
||||
v->mode = VIDEO_SOUND_MONO | VIDEO_SOUND_STEREO |
|
||||
VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* sound control for AD-TVK503
|
||||
* Hiroshi Takekawa <sian@big.or.jp>
|
||||
*/
|
||||
static void
|
||||
adtvk503_audio(struct bttv *btv, struct video_audio *v, int set)
|
||||
{
|
||||
unsigned int con = 0xffffff;
|
||||
|
||||
/* btaor(0x1e0000, ~0x1e0000, BT848_GPIO_OUT_EN); */
|
||||
|
||||
if (set) {
|
||||
/* btor(***, BT848_GPIO_OUT_EN); */
|
||||
if (v->mode & VIDEO_SOUND_LANG1)
|
||||
con = 0x00000000;
|
||||
if (v->mode & VIDEO_SOUND_LANG2)
|
||||
con = 0x00180000;
|
||||
if (v->mode & VIDEO_SOUND_STEREO)
|
||||
con = 0x00000000;
|
||||
if (v->mode & VIDEO_SOUND_MONO)
|
||||
con = 0x00060000;
|
||||
if (con != 0xffffff) {
|
||||
gpio_bits(0x1e0000,con);
|
||||
if (bttv_gpio)
|
||||
bttv_gpio_tracking(btv, "adtvk503");
|
||||
}
|
||||
} else {
|
||||
v->mode = VIDEO_SOUND_MONO | VIDEO_SOUND_STEREO |
|
||||
VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
|
||||
}
|
||||
}
|
||||
|
||||
/* RemoteVision MX (rv605) muxsel helper [Miguel Freitas]
|
||||
*
|
||||
* This is needed because rv605 don't use a normal multiplex, but a crosspoint
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -69,6 +69,11 @@ static void ir_handle_key(struct bttv *btv)
|
||||
(ir->mask_keyup && (0 == (gpio & ir->mask_keyup)))) {
|
||||
ir_input_keydown(ir->dev,&ir->ir,data,data);
|
||||
} else {
|
||||
/* HACK: Probably, ir->mask_keydown is missing
|
||||
for this board */
|
||||
if (btv->c.type == BTTV_BOARD_WINFAST2000)
|
||||
ir_input_keydown(ir->dev, &ir->ir, data, data);
|
||||
|
||||
ir_input_nokey(ir->dev,&ir->ir);
|
||||
}
|
||||
|
||||
|
@ -582,7 +582,7 @@ bttv_dma_free(struct videobuf_queue *q,struct bttv *btv, struct bttv_buffer *buf
|
||||
videobuf_dma_free(dma);
|
||||
btcx_riscmem_free(btv->c.pci,&buf->bottom);
|
||||
btcx_riscmem_free(btv->c.pci,&buf->top);
|
||||
buf->vb.state = STATE_NEEDS_INIT;
|
||||
buf->vb.state = VIDEOBUF_NEEDS_INIT;
|
||||
}
|
||||
|
||||
int
|
||||
@ -602,7 +602,7 @@ bttv_buffer_activate_vbi(struct bttv *btv,
|
||||
if (vbi) {
|
||||
unsigned int crop, vdelay;
|
||||
|
||||
vbi->vb.state = STATE_ACTIVE;
|
||||
vbi->vb.state = VIDEOBUF_ACTIVE;
|
||||
list_del(&vbi->vb.queue);
|
||||
|
||||
/* VDELAY is start of video, end of VBI capturing. */
|
||||
@ -644,12 +644,12 @@ bttv_buffer_activate_video(struct bttv *btv,
|
||||
/* video capture */
|
||||
if (NULL != set->top && NULL != set->bottom) {
|
||||
if (set->top == set->bottom) {
|
||||
set->top->vb.state = STATE_ACTIVE;
|
||||
set->top->vb.state = VIDEOBUF_ACTIVE;
|
||||
if (set->top->vb.queue.next)
|
||||
list_del(&set->top->vb.queue);
|
||||
} else {
|
||||
set->top->vb.state = STATE_ACTIVE;
|
||||
set->bottom->vb.state = STATE_ACTIVE;
|
||||
set->top->vb.state = VIDEOBUF_ACTIVE;
|
||||
set->bottom->vb.state = VIDEOBUF_ACTIVE;
|
||||
if (set->top->vb.queue.next)
|
||||
list_del(&set->top->vb.queue);
|
||||
if (set->bottom->vb.queue.next)
|
||||
@ -666,7 +666,7 @@ bttv_buffer_activate_video(struct bttv *btv,
|
||||
btaor((set->top->btswap & 0x0a) | (set->bottom->btswap & 0x05),
|
||||
~0x0f, BT848_COLOR_CTL);
|
||||
} else if (NULL != set->top) {
|
||||
set->top->vb.state = STATE_ACTIVE;
|
||||
set->top->vb.state = VIDEOBUF_ACTIVE;
|
||||
if (set->top->vb.queue.next)
|
||||
list_del(&set->top->vb.queue);
|
||||
bttv_apply_geo(btv, &set->top->geo,1);
|
||||
@ -677,7 +677,7 @@ bttv_buffer_activate_video(struct bttv *btv,
|
||||
btaor(set->top->btformat & 0xff, ~0xff, BT848_COLOR_FMT);
|
||||
btaor(set->top->btswap & 0x0f, ~0x0f, BT848_COLOR_CTL);
|
||||
} else if (NULL != set->bottom) {
|
||||
set->bottom->vb.state = STATE_ACTIVE;
|
||||
set->bottom->vb.state = VIDEOBUF_ACTIVE;
|
||||
if (set->bottom->vb.queue.next)
|
||||
list_del(&set->bottom->vb.queue);
|
||||
bttv_apply_geo(btv, &set->bottom->geo,1);
|
||||
|
@ -142,7 +142,7 @@ static int vbi_buffer_prepare(struct videobuf_queue *q,
|
||||
redo_dma_risc = 1;
|
||||
}
|
||||
|
||||
if (STATE_NEEDS_INIT == buf->vb.state) {
|
||||
if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
|
||||
redo_dma_risc = 1;
|
||||
if (0 != (rc = videobuf_iolock(q, &buf->vb, NULL)))
|
||||
goto fail;
|
||||
@ -189,7 +189,7 @@ static int vbi_buffer_prepare(struct videobuf_queue *q,
|
||||
/* For bttv_buffer_activate_vbi(). */
|
||||
buf->geo.vdelay = min_vdelay;
|
||||
|
||||
buf->vb.state = STATE_PREPARED;
|
||||
buf->vb.state = VIDEOBUF_PREPARED;
|
||||
buf->vb.field = field;
|
||||
dprintk("buf prepare %p: top=%p bottom=%p field=%s\n",
|
||||
vb, &buf->top, &buf->bottom,
|
||||
@ -209,7 +209,7 @@ vbi_buffer_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
|
||||
struct bttv_buffer *buf = container_of(vb,struct bttv_buffer,vb);
|
||||
|
||||
dprintk("queue %p\n",vb);
|
||||
buf->vb.state = STATE_QUEUED;
|
||||
buf->vb.state = VIDEOBUF_QUEUED;
|
||||
list_add_tail(&buf->vb.queue,&btv->vcapture);
|
||||
if (NULL == btv->cvbi) {
|
||||
fh->btv->loop_irq |= 4;
|
||||
@ -236,9 +236,7 @@ struct videobuf_queue_ops bttv_vbi_qops = {
|
||||
|
||||
/* ----------------------------------------------------------------------- */
|
||||
|
||||
static int
|
||||
try_fmt (struct v4l2_vbi_format * f,
|
||||
const struct bttv_tvnorm * tvnorm,
|
||||
static int try_fmt(struct v4l2_vbi_format *f, const struct bttv_tvnorm *tvnorm,
|
||||
__s32 crop_start)
|
||||
{
|
||||
__s32 min_start, max_start, max_end, f2_offset;
|
||||
@ -305,10 +303,9 @@ try_fmt (struct v4l2_vbi_format * f,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
bttv_vbi_try_fmt (struct bttv_fh * fh,
|
||||
struct v4l2_vbi_format * f)
|
||||
int bttv_try_fmt_vbi(struct file *file, void *f, struct v4l2_format *frt)
|
||||
{
|
||||
struct bttv_fh *fh = f;
|
||||
struct bttv *btv = fh->btv;
|
||||
const struct bttv_tvnorm *tvnorm;
|
||||
__s32 crop_start;
|
||||
@ -320,13 +317,13 @@ bttv_vbi_try_fmt (struct bttv_fh * fh,
|
||||
|
||||
mutex_unlock(&btv->lock);
|
||||
|
||||
return try_fmt(f, tvnorm, crop_start);
|
||||
return try_fmt(&frt->fmt.vbi, tvnorm, crop_start);
|
||||
}
|
||||
|
||||
int
|
||||
bttv_vbi_set_fmt (struct bttv_fh * fh,
|
||||
struct v4l2_vbi_format * f)
|
||||
|
||||
int bttv_s_fmt_vbi(struct file *file, void *f, struct v4l2_format *frt)
|
||||
{
|
||||
struct bttv_fh *fh = f;
|
||||
struct bttv *btv = fh->btv;
|
||||
const struct bttv_tvnorm *tvnorm;
|
||||
__s32 start1, end;
|
||||
@ -340,11 +337,12 @@ bttv_vbi_set_fmt (struct bttv_fh * fh,
|
||||
|
||||
tvnorm = &bttv_tvnorms[btv->tvnorm];
|
||||
|
||||
rc = try_fmt(f, tvnorm, btv->crop_start);
|
||||
rc = try_fmt(&frt->fmt.vbi, tvnorm, btv->crop_start);
|
||||
if (0 != rc)
|
||||
goto fail;
|
||||
|
||||
start1 = f->start[1] - tvnorm->vbistart[1] + tvnorm->vbistart[0];
|
||||
start1 = frt->fmt.vbi.start[1] - tvnorm->vbistart[1] +
|
||||
tvnorm->vbistart[0];
|
||||
|
||||
/* First possible line of video capturing. Should be
|
||||
max(f->start[0] + f->count[0], start1 + f->count[1]) * 2
|
||||
@ -352,11 +350,11 @@ bttv_vbi_set_fmt (struct bttv_fh * fh,
|
||||
pretend the VBI and video capture window may overlap,
|
||||
so end = start + 1, the lowest possible value, times two
|
||||
because vbi_fmt.end counts field lines times two. */
|
||||
end = max(f->start[0], start1) * 2 + 2;
|
||||
end = max(frt->fmt.vbi.start[0], start1) * 2 + 2;
|
||||
|
||||
mutex_lock(&fh->vbi.lock);
|
||||
|
||||
fh->vbi_fmt.fmt = *f;
|
||||
fh->vbi_fmt.fmt = frt->fmt.vbi;
|
||||
fh->vbi_fmt.tvnorm = tvnorm;
|
||||
fh->vbi_fmt.end = end;
|
||||
|
||||
@ -370,13 +368,13 @@ bttv_vbi_set_fmt (struct bttv_fh * fh,
|
||||
return rc;
|
||||
}
|
||||
|
||||
void
|
||||
bttv_vbi_get_fmt (struct bttv_fh * fh,
|
||||
struct v4l2_vbi_format * f)
|
||||
|
||||
int bttv_g_fmt_vbi(struct file *file, void *f, struct v4l2_format *frt)
|
||||
{
|
||||
struct bttv_fh *fh = f;
|
||||
const struct bttv_tvnorm *tvnorm;
|
||||
|
||||
*f = fh->vbi_fmt.fmt;
|
||||
frt->fmt.vbi = fh->vbi_fmt.fmt;
|
||||
|
||||
tvnorm = &bttv_tvnorms[fh->btv->tvnorm];
|
||||
|
||||
@ -391,28 +389,28 @@ bttv_vbi_get_fmt (struct bttv_fh * fh,
|
||||
max_end = (tvnorm->cropcap.bounds.top
|
||||
+ tvnorm->cropcap.bounds.height) >> 1;
|
||||
|
||||
f->sampling_rate = tvnorm->Fsc;
|
||||
frt->fmt.vbi.sampling_rate = tvnorm->Fsc;
|
||||
|
||||
for (i = 0; i < 2; ++i) {
|
||||
__s32 new_start;
|
||||
|
||||
new_start = f->start[i]
|
||||
new_start = frt->fmt.vbi.start[i]
|
||||
+ tvnorm->vbistart[i]
|
||||
- fh->vbi_fmt.tvnorm->vbistart[i];
|
||||
|
||||
f->start[i] = min(new_start, max_end - 1);
|
||||
f->count[i] = min((__s32) f->count[i],
|
||||
max_end - f->start[i]);
|
||||
frt->fmt.vbi.start[i] = min(new_start, max_end - 1);
|
||||
frt->fmt.vbi.count[i] =
|
||||
min((__s32) frt->fmt.vbi.count[i],
|
||||
max_end - frt->fmt.vbi.start[i]);
|
||||
|
||||
max_end += tvnorm->vbistart[1]
|
||||
- tvnorm->vbistart[0];
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
bttv_vbi_fmt_reset (struct bttv_vbi_fmt * f,
|
||||
int norm)
|
||||
void bttv_vbi_fmt_reset(struct bttv_vbi_fmt *f, int norm)
|
||||
{
|
||||
const struct bttv_tvnorm *tvnorm;
|
||||
unsigned int real_samples_per_line;
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user