#!/usr/bin/perl use strict; use warnings; use IO::File; use Getopt::Long; use File::Basename; use lib dirname (__FILE__); use Firmware::Silead; sub usage() { print STDERR "Usage: fwtool {-i | -c | -s | -x } [ -1 | -2 | -3 ] [-w ] [-h ] [-t ] [-f ] \n"; print STDERR "-i Prints statistics and information about new-style firmware.fw\n"; print STDERR "-c Converts any older firmware format into new-style firmware.fw\n"; print STDERR "-s Sets parameters and flags\n"; print STDERR "-x Exports a firmware into plain format, to use with other Linux/Android drivers\n"; print STDERR " The source firmware format can be specified with these parameters:\n"; print STDERR "-1 Plain firmware, as used with the Android driver (default)\n"; print STDERR "-2 Windows GSL_TS_CFG.h firmware\n"; print STDERR "-3 Scrambled Windows SileadTouch.fw firmware\n"; print STDERR " For the -c and -s modes, the following parameters may be set:\n"; print STDERR "-m Sets the controller model (4-byte ASCII string, ex.: 1680)\n"; print STDERR "-w Sets the width parameter\n"; print STDERR "-h Sets the height parameter\n"; print STDERR "-t Sets the number of supported touch points parameter\n"; print STDERR "-f Sets flags, separated by commas (optional, supported flags: xflip, yflip, swap, track)\n"; print STDERR " xflip enables horizontal flipping\n"; print STDERR " yflip enables vertical flipping\n"; print STDERR " swap enables axis swapping\n"; print STDERR " track enables in-driver finger tracking (use for controllers that don't support it)\n"; print STDERR " Each flag may be prefixed with 'no' to disable it.\n"; -1; } my ($mode, $format, $tscfg, $model, $width, $height, $touches, $flags, $plain) = ('info', 'plain'); GetOptions( 'info' => sub { $mode = 'info'; }, 'convert=s' => sub { $mode = 'convert'; $tscfg = $_[1]; }, 'set' => sub { $mode = 'set'; }, 'xport=s' => sub { $mode = 'export'; $plain = $_[1]; }, 'model=s' => \$model, 'width=i' => \$width, 'height=i' => \$height, 'touches=i' => \$touches, 'flags=s' => \$flags, '1' => sub { $format = 'plain' }, '2' => sub { $format = 'tscfg' }, '3' => sub { $format = 'scrambled' }, ) or exit usage; my $fwfile = $ARGV[0] or exit usage; sub set_params { my ($rep) = @_; if (defined $model) { $rep->set_model($model); } if (defined $width) { $rep->set_width($width); } if (defined $height) { $rep->set_height($height); } if (defined $touches) { $rep->set_touches($touches); } if (defined $flags) { for my $flag (split /,\s*/, $flags) { if ($flag =~ /^(no)?xflip$/) { $rep->set_xmirrored($flag !~ /^no/); } elsif ($flag =~ /^(no)?yflip$/) { $rep->set_ymirrored($flag !~ /^no/); } elsif ($flag =~ /^(no)?swap$/) { $rep->set_swapped($flag !~ /^no/); } elsif ($flag =~ /^(no)?track$/) { $rep->set_tracking($flag !~ /^no/); } else { warn "Invalid flag: $flag"; } } } } if ($mode eq 'info') { print "Loading $fwfile...\n"; my $rep = Firmware::Silead->load($fwfile) or die "Can't load firmware $fwfile: $@"; print "Controller model: " . $rep->model . "\n"; print "Panel width: " . $rep->width . "\n"; print "Panel height: " . $rep->height . "\n"; print "Number of touch points: " . $rep->touches . "\n"; print "X axis flipped: " . ($rep->xmirrored ? "yes" : "no") . "\n"; print "Y axis flipped: " . ($rep->ymirrored ? "yes" : "no") . "\n"; print "X and Y axes swapped: " . ($rep->swapped ? "yes" : "no") . "\n"; print "Software tracking enabled: " . ($rep->tracking ? "yes" : "no") . "\n"; my @pages = $rep->get_pages; print "Number of pages: ". scalar(@pages) . "\n"; print "Page list:"; for my $page (@pages) { printf " %02x", $page; } print "\n"; } elsif ($mode eq 'set') { print "Loading $fwfile...\n"; my $rep = Firmware::Silead->load($fwfile) or die "Can't load firmware $fwfile: $@"; print "Setting parameters...\n"; set_params($rep); print "Saving $fwfile...\n"; $rep->save($fwfile); } elsif ($mode eq 'convert') { print "Loading $tscfg...\n"; my $data; do { my $in = IO::File->new($tscfg, 'r') or die "Can't open $tscfg: $!"; $in->binmode; local $/ = undef; $data = <$in>; defined($data) or die "Can't load firmware: $!"; $in->close(); }; my $rep = Firmware::Silead->new(); if ($format eq 'plain') { $rep->import_fw($data) or die "Can't parse firmware: $@"; } elsif ($format eq 'tscfg') { $rep->import_tscfg($data) or die "Can't parse firmware: $@"; } elsif ($format eq 'scrambled') { $rep->import_scrambled($data) or die "Can't parse firmware: $@"; } print "Setting parameters...\n"; set_params($rep); print "Saving $fwfile...\n"; $rep->save($fwfile) or die "Can't write firmware: $@"; } elsif ($mode eq 'export') { print "Loading $fwfile...\n"; my $rep = Firmware::Silead->load($fwfile) or die "Can't load firmware $fwfile: $@"; print "Exporting to $plain...\n"; my $out = IO::File->new($plain, 'w') or die "Can't open $plain: $!"; my $data = $rep->export_fw(); $out->print($data) or die "Can't write firmware: $!"; $out->close(); }