linux/Documentation/dvb/get_dvb_firmware
Kirk Lapray 04a45929e7 [PATCH] dvb: add nxt200x frontend module
* nxt200x.c, nxt200x.h
- New frontend module that supports both NXT2002 and NXT2004.
  So far, only tested on NXT2004.  After testing on NXT2002, we should
  deprecate the nxt2002 module, and implement this one instead on the
  applicable cards.

* get_dvb_firmware:
- Added support for the NXT2004 firmware. This firmware works with both
  the ATI HDTV Wonder and the AVerTVHD MCE a180.
  This was originally written by Jean-Francois Thibert

* dvb-pll.c
- Fixed minimum frequency for tuv1236d. It seems that the data sheets
  are wrong.

Signed-off-by: Kirk Lapray <kirk.lapray@gmail.com>
Signed-off-by: Michael Krufky <mkrufky@m1k.net>
Cc: Johannes Stezenbach <js@linuxtv.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-11-09 07:56:05 -08:00

415 lines
11 KiB
Perl

#!/usr/bin/perl
# DVB firmware extractor
#
# (c) 2004 Andrew de Quincey
#
# 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.
use File::Temp qw/ tempdir /;
use IO::Handle;
@components = ( "sp8870", "sp887x", "tda10045", "tda10046", "av7110", "dec2000t",
"dec2540t", "dec3000s", "vp7041", "dibusb", "nxt2002", "nxt2004",
"or51211", "or51132_qam", "or51132_vsb");
# Check args
syntax() if (scalar(@ARGV) != 1);
$cid = $ARGV[0];
# Do it!
for ($i=0; $i < scalar(@components); $i++) {
if ($cid eq $components[$i]) {
$outfile = eval($cid);
die $@ if $@;
print STDERR "Firmware $outfile extracted successfully. Now copy it to either /lib/firmware or /usr/lib/hotplug/firmware/ (depending on your hotplug version).\n";
exit(0);
}
}
# If we get here, it wasn't found
print STDERR "Unknown component \"$cid\"\n";
syntax();
# ---------------------------------------------------------------
# Firmware-specific extraction subroutines
sub sp8870 {
my $sourcefile = "tt_Premium_217g.zip";
my $url = "http://www.technotrend.de/new/217g/$sourcefile";
my $hash = "53970ec17a538945a6d8cb608a7b3899";
my $outfile = "dvb-fe-sp8870.fw";
my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1);
checkstandard();
wgetfile($sourcefile, $url);
unzip($sourcefile, $tmpdir);
verify("$tmpdir/software/OEM/HE/App/boot/SC_MAIN.MC", $hash);
copy("$tmpdir/software/OEM/HE/App/boot/SC_MAIN.MC", $outfile);
$outfile;
}
sub sp887x {
my $sourcefile = "Dvbt1.3.57.6.zip";
my $url = "http://www.avermedia.com/software/$sourcefile";
my $cabfile = "DVBT Net Ver1.3.57.6/disk1/data1.cab";
my $hash = "237938d53a7f834c05c42b894ca68ac3";
my $outfile = "dvb-fe-sp887x.fw";
my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1);
checkstandard();
checkunshield();
wgetfile($sourcefile, $url);
unzip($sourcefile, $tmpdir);
unshield("$tmpdir/$cabfile", $tmpdir);
verify("$tmpdir/ZEnglish/sc_main.mc", $hash);
copy("$tmpdir/ZEnglish/sc_main.mc", $outfile);
$outfile;
}
sub tda10045 {
my $sourcefile = "tt_budget_217g.zip";
my $url = "http://www.technotrend.de/new/217g/$sourcefile";
my $hash = "2105fd5bf37842fbcdfa4bfd58f3594a";
my $outfile = "dvb-fe-tda10045.fw";
my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1);
checkstandard();
wgetfile($sourcefile, $url);
unzip($sourcefile, $tmpdir);
extract("$tmpdir/software/OEM/PCI/App/ttlcdacc.dll", 0x37ef9, 30555, "$tmpdir/fwtmp");
verify("$tmpdir/fwtmp", $hash);
copy("$tmpdir/fwtmp", $outfile);
$outfile;
}
sub tda10046 {
my $sourcefile = "tt_budget_217g.zip";
my $url = "http://www.technotrend.de/new/217g/$sourcefile";
my $hash = "6a7e1e2f2644b162ff0502367553c72d";
my $outfile = "dvb-fe-tda10046.fw";
my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1);
checkstandard();
wgetfile($sourcefile, $url);
unzip($sourcefile, $tmpdir);
extract("$tmpdir/software/OEM/PCI/App/ttlcdacc.dll", 0x3f731, 24478, "$tmpdir/fwtmp");
verify("$tmpdir/fwtmp", $hash);
copy("$tmpdir/fwtmp", $outfile);
$outfile;
}
sub av7110 {
my $sourcefile = "dvb-ttpci-01.fw-261d";
my $url = "http://www.linuxtv.org/downloads/firmware/$sourcefile";
my $hash = "603431b6259715a8e88f376a53b64e2f";
my $outfile = "dvb-ttpci-01.fw";
checkstandard();
wgetfile($sourcefile, $url);
verify($sourcefile, $hash);
copy($sourcefile, $outfile);
$outfile;
}
sub dec2000t {
my $sourcefile = "dec217g.exe";
my $url = "http://hauppauge.lightpath.net/de/$sourcefile";
my $hash = "bd86f458cee4a8f0a8ce2d20c66215a9";
my $outfile = "dvb-ttusb-dec-2000t.fw";
my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1);
checkstandard();
wgetfile($sourcefile, $url);
unzip($sourcefile, $tmpdir);
verify("$tmpdir/software/OEM/STB/App/Boot/STB_PC_T.bin", $hash);
copy("$tmpdir/software/OEM/STB/App/Boot/STB_PC_T.bin", $outfile);
$outfile;
}
sub dec2540t {
my $sourcefile = "dec217g.exe";
my $url = "http://hauppauge.lightpath.net/de/$sourcefile";
my $hash = "53e58f4f5b5c2930beee74a7681fed92";
my $outfile = "dvb-ttusb-dec-2540t.fw";
my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1);
checkstandard();
wgetfile($sourcefile, $url);
unzip($sourcefile, $tmpdir);
verify("$tmpdir/software/OEM/STB/App/Boot/STB_PC_X.bin", $hash);
copy("$tmpdir/software/OEM/STB/App/Boot/STB_PC_X.bin", $outfile);
$outfile;
}
sub dec3000s {
my $sourcefile = "dec217g.exe";
my $url = "http://hauppauge.lightpath.net/de/$sourcefile";
my $hash = "b013ececea83f4d6d8d2a29ac7c1b448";
my $outfile = "dvb-ttusb-dec-3000s.fw";
my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1);
checkstandard();
wgetfile($sourcefile, $url);
unzip($sourcefile, $tmpdir);
verify("$tmpdir/software/OEM/STB/App/Boot/STB_PC_S.bin", $hash);
copy("$tmpdir/software/OEM/STB/App/Boot/STB_PC_S.bin", $outfile);
$outfile;
}
sub vp7041 {
my $sourcefile = "2.422.zip";
my $url = "http://www.twinhan.com/files/driver/USB-Ter/$sourcefile";
my $hash = "e88c9372d1f66609a3e7b072c53fbcfe";
my $outfile = "dvb-vp7041-2.422.fw";
my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1);
checkstandard();
wgetfile($sourcefile, $url);
unzip($sourcefile, $tmpdir);
extract("$tmpdir/VisionDTV/Drivers/Win2K&XP/UDTTload.sys", 12503, 3036, "$tmpdir/fwtmp1");
extract("$tmpdir/VisionDTV/Drivers/Win2K&XP/UDTTload.sys", 2207, 10274, "$tmpdir/fwtmp2");
my $CMD = "\000\001\000\222\177\000";
my $PAD = "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000";
my ($FW);
open $FW, ">$tmpdir/fwtmp3";
print $FW "$CMD\001$PAD";
print $FW "$CMD\001$PAD";
appendfile($FW, "$tmpdir/fwtmp1");
print $FW "$CMD\000$PAD";
print $FW "$CMD\001$PAD";
appendfile($FW, "$tmpdir/fwtmp2");
print $FW "$CMD\001$PAD";
print $FW "$CMD\000$PAD";
close($FW);
verify("$tmpdir/fwtmp3", $hash);
copy("$tmpdir/fwtmp3", $outfile);
$outfile;
}
sub dibusb {
my $url = "http://www.linuxtv.org/downloads/firmware/dvb-dibusb-5.0.0.11.fw";
my $outfile = "dvb-dibusb-5.0.0.11.fw";
my $hash = "fa490295a527360ca16dcdf3224ca243";
checkstandard();
wgetfile($outfile, $url);
verify($outfile,$hash);
$outfile;
}
sub nxt2002 {
my $sourcefile = "Broadband4PC_4_2_11.zip";
my $url = "http://www.bbti.us/download/windows/$sourcefile";
my $hash = "c6d2ea47a8f456d887ada0cfb718ff2a";
my $outfile = "dvb-fe-nxt2002.fw";
my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1);
checkstandard();
wgetfile($sourcefile, $url);
unzip($sourcefile, $tmpdir);
verify("$tmpdir/SkyNETU.sys", $hash);
extract("$tmpdir/SkyNETU.sys", 375832, 5908, $outfile);
$outfile;
}
sub nxt2004 {
my $sourcefile = "AVerTVHD_MCE_A180_Drv_v1.2.2.16.zip";
my $url = "http://www.aver.com/support/Drivers/$sourcefile";
my $hash = "111cb885b1e009188346d72acfed024c";
my $outfile = "dvb-fe-nxt2004.fw";
my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1);
checkstandard();
wgetfile($sourcefile, $url);
unzip($sourcefile, $tmpdir);
verify("$tmpdir/3xHybrid.sys", $hash);
extract("$tmpdir/3xHybrid.sys", 465304, 9584, $outfile);
$outfile;
}
sub or51211 {
my $fwfile = "dvb-fe-or51211.fw";
my $url = "http://linuxtv.org/downloads/firmware/$fwfile";
my $hash = "d830949c771a289505bf9eafc225d491";
checkstandard();
wgetfile($fwfile, $url);
verify($fwfile, $hash);
$fwfile;
}
sub or51132_qam {
my $fwfile = "dvb-fe-or51132-qam.fw";
my $url = "http://linuxtv.org/downloads/firmware/$fwfile";
my $hash = "7702e8938612de46ccadfe9b413cb3b5";
checkstandard();
wgetfile($fwfile, $url);
verify($fwfile, $hash);
$fwfile;
}
sub or51132_vsb {
my $fwfile = "dvb-fe-or51132-vsb.fw";
my $url = "http://linuxtv.org/downloads/firmware/$fwfile";
my $hash = "c16208e02f36fc439a557ad4c613364a";
checkstandard();
wgetfile($fwfile, $url);
verify($fwfile, $hash);
$fwfile;
}
# ---------------------------------------------------------------
# Utilities
sub checkstandard {
if (system("which unzip > /dev/null 2>&1")) {
die "This firmware requires the unzip command - see ftp://ftp.info-zip.org/pub/infozip/UnZip.html\n";
}
if (system("which md5sum > /dev/null 2>&1")) {
die "This firmware requires the md5sum command - see http://www.gnu.org/software/coreutils/\n";
}
if (system("which wget > /dev/null 2>&1")) {
die "This firmware requires the wget command - see http://wget.sunsite.dk/\n";
}
}
sub checkunshield {
if (system("which unshield > /dev/null 2>&1")) {
die "This firmware requires the unshield command - see http://sourceforge.net/projects/synce/\n";
}
}
sub wgetfile {
my ($sourcefile, $url) = @_;
if (! -f $sourcefile) {
system("wget -O \"$sourcefile\" \"$url\"") and die "wget failed - unable to download firmware";
}
}
sub unzip {
my ($sourcefile, $todir) = @_;
$status = system("unzip -q -o -d \"$todir\" \"$sourcefile\" 2>/dev/null" );
if ((($status >> 8) > 2) || (($status & 0xff) != 0)) {
die ("unzip failed - unable to extract firmware");
}
}
sub unshield {
my ($sourcefile, $todir) = @_;
system("unshield x -d \"$todir\" \"$sourcefile\" > /dev/null" ) and die ("unshield failed - unable to extract firmware");
}
sub verify {
my ($filename, $hash) = @_;
my ($testhash);
open(CMD, "md5sum \"$filename\"|");
$testhash = <CMD>;
$testhash =~ /([a-zA-Z0-9]*)/;
$testhash = $1;
close CMD;
die "Hash of extracted file does not match!\n" if ($testhash ne $hash);
}
sub copy {
my ($from, $to) = @_;
system("cp -f \"$from\" \"$to\"") and die ("cp failed");
}
sub extract {
my ($infile, $offset, $length, $outfile) = @_;
my ($chunklength, $buf, $rcount);
open INFILE, "<$infile";
open OUTFILE, ">$outfile";
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);
syswrite(OUTFILE, $buf);
$length -= $rcount;
}
close INFILE;
close OUTFILE;
}
sub appendfile {
my ($FH, $infile) = @_;
my ($buf);
open INFILE, "<$infile";
while(1) {
$rcount = sysread(INFILE, $buf, 2048);
last if ($rcount == 0);
print $FH $buf;
}
close(INFILE);
}
sub syntax() {
print STDERR "syntax: get_dvb_firmware <component>\n";
print STDERR "Supported components:\n";
for($i=0; $i < scalar(@components); $i++) {
print STDERR "\t" . $components[$i] . "\n";
}
exit(1);
}