• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

Firmware of Silead Touchscreen Controller for Jumper EZpad 6 Pro.


Commit MetaInfo

Révision671fc6739bcc3b632d2b417b262a7892fe84d2f4 (tree)
l'heure2016-02-03 03:44:33
AuteurGregor Riepl <onitake@gmai...>
CommiterGregor Riepl

Message de Log

Copied firmware conversion tools from gslx680-acpi, corrected license (GPL2)

Change Summary

Modification

--- a/README.md
+++ b/README.md
@@ -16,7 +16,7 @@ distribution such as Debian or Ubuntu.
1616 The files may be covered by proprietary licenses or copyright.
1717
1818 Conversely, everything in the tools directory published under
19-the GNU General Public license v3, as laid out in tools/LICENSE
19+the GNU General Public license v2, as laid out in tools/LICENSE
2020
2121
2222 Device list
--- /dev/null
+++ b/tools/Firmware/Silead.pm
@@ -0,0 +1,530 @@
1+package Firmware::Silead;
2+
3+use strict;
4+use IO::File;
5+
6+our $MAGIC = 'GSLX';
7+our $FORMAT = 1;
8+our $HEADER_SIZE = 24;
9+our $PAGE_SIZE = 132;
10+
11+sub _unpack_header {
12+ my ($header) = @_;
13+ return (unpack '(a4a4S4C4L)<', $header);
14+}
15+
16+sub _unpack_page {
17+ my ($buffer) = @_;
18+ return (unpack '(S2a128)<', $buffer);
19+}
20+
21+sub _pack_header {
22+ my ($model, @params) = @_;
23+ return pack '(a4a4S4C4L)<', $MAGIC, $model, $FORMAT, @params
24+}
25+
26+sub _pack_page {
27+ my ($page, $data) = @_;
28+ return pack '(S2a128)<', $page, length $data, $data;
29+}
30+
31+sub new {
32+ my ($class) = @_;
33+ return bless {
34+ pages => { },
35+ model => '',
36+ touches => 0,
37+ width => 0,
38+ height => 0,
39+ swapped => 0,
40+ xmirrored => 0,
41+ ymirrored => 0,
42+ tracking => 0,
43+ }, ref $class ? ref $class : $class;
44+}
45+
46+sub load {
47+ my ($class, $handle) = @_;
48+ if (!ref $handle) {
49+ $handle = IO::File->new($handle, 'r');
50+ }
51+ if (!defined $handle) {
52+ $@ = "Invalid file handle";
53+ return undef;
54+ }
55+ binmode $handle;
56+ read $handle, my $header, $HEADER_SIZE;
57+ my ($magic, $model, $format, $touches, $width, $height, $swapped, $xmirrored, $ymirrored, $tracking, $pages) = _unpack_header $header;
58+ if ($magic ne $MAGIC) {
59+ $@ = "Invalid magic $magic";
60+ return undef;
61+ }
62+ if ($format ne $FORMAT) {
63+ $@ = "Invalid file format $format";
64+ return undef;
65+ }
66+ my $self = bless {
67+ pages => { },
68+ model => $model,
69+ touches => $touches,
70+ width => $width,
71+ height => $height,
72+ swapped => $swapped,
73+ xmirrored => $xmirrored,
74+ ymirrored => $ymirrored,
75+ tracking => $tracking,
76+ }, ref $class ? ref $class : $class;
77+ for (my $i = 0; $i < $pages; $i++) {
78+ read $handle, my $buffer, $PAGE_SIZE;
79+ my ($address, $size, $data) = _unpack_page $buffer;
80+ if (!$self->set_page($address, substr $data, 0, $size)) {
81+ return undef;
82+ }
83+ }
84+ return $self;
85+}
86+
87+sub save {
88+ my ($self, $handle) = @_;
89+ if (!ref $handle) {
90+ $handle = IO::File->new($handle, 'w');
91+ }
92+ if (!defined $handle) {
93+ $@ = "Invalid file handle";
94+ return 0;
95+ }
96+ binmode $handle;
97+ my @pages = $self->get_pages;
98+ my $header = _pack_header $self->model, $self->touches, $self->width, $self->height, $self->swapped, $self->xmirrored, $self->ymirrored, $self->tracking, scalar(@pages);
99+ print $handle $header;
100+ for my $page (@pages) {
101+ my $pagedata = $self->get_page($page);
102+ my $buffer = _pack_page $page, $pagedata;
103+ print $handle $buffer;
104+ }
105+ return 1;
106+}
107+
108+sub unpack {
109+ my ($class, $data) = @_;
110+ my $header = substr $data, 0, $HEADER_SIZE;
111+ my ($magic, $model, $format, $touches, $width, $height, $swapped, $xmirrored, $ymirrored, $tracking, $pages) = _unpack_header $header;
112+ if ($magic ne $MAGIC) {
113+ $@ = "Invalid magic $magic";
114+ return undef;
115+ }
116+ if ($format ne $FORMAT) {
117+ $@ = "Invalid file format $format";
118+ return undef;
119+ }
120+ my $self = bless {
121+ pages => { },
122+ model => $model,
123+ touches => $touches,
124+ width => $width,
125+ height => $height,
126+ swapped => $swapped,
127+ xmirrored => $xmirrored,
128+ ymirrored => $ymirrored,
129+ tracking => $tracking,
130+ }, ref $class ? ref $class : $class;
131+ for (my $i = 0; $i < $pages; $i++) {
132+ my $buffer = substr $HEADER_SIZE + $i * $PAGE_SIZE, $PAGE_SIZE;
133+ my ($address, $size, $data) = _unpack_page $buffer ;
134+ if (!$self->set_page($address, substr $data, 0, $size)) {
135+ return undef;
136+ }
137+ }
138+ return $self;
139+}
140+
141+sub pack {
142+ my ($self) = @_;
143+ my $data = '';
144+ my @pages = $self->get_pages;
145+ my $header = _pack_header $self->model, $self->touches, $self->width, $self->height, $self->swapped, $self->xmirrored, $self->ymirrored, $self->tracking, scalar(@pages);
146+ $data .= $header;
147+ for my $page (@pages) {
148+ my $pagedata = $self->get_page($page);
149+ my $buffer = _pack_page $page, $pagedata;
150+ $data .= $buffer;
151+ }
152+ return $data;
153+}
154+
155+sub import_scrambled {
156+ my ($self, $input) = @_;
157+ my $tscfg = '';
158+ for my $byte (split //, $input) {
159+ my $descrambled = chr(ord($byte) ^ 0x88);
160+ $tscfg .= $descrambled;
161+ }
162+ return $self->import_tscfg($tscfg);
163+}
164+
165+sub import_tscfg {
166+ my ($self, $input) = @_;
167+ my ($cfg, $fw) = (0, '');
168+ for my $line (split /\n/, $input) {
169+ if ($cfg and $line =~ /};/) {
170+ $cfg = 0;
171+ }
172+ if ($line =~ /TS_CFG_DATA/) {
173+ $cfg = 1;
174+ }
175+ if ($cfg) {
176+ $line =~ s/\s//g;
177+ $line = lc($line);
178+ if ($line =~ /{0x([0-9a-f]+),0x([0-9a-f]+)},/) {
179+ my $address = hex($1);
180+ my $data = hex($2);
181+ $fw .= pack '(LL)<', $address, $data;
182+ }
183+ }
184+ }
185+ return $self->import_fw($fw);
186+}
187+
188+sub import_fw {
189+ my ($self, $input) = @_;
190+
191+ my $length = length $input;
192+
193+ my ($page, $lastaddr, $data);
194+ for (my $offset = 0; $offset + 7 < $length; $offset += 8) {
195+ my $buffer = substr $input, $offset, 8;
196+ my ($addr, $value) = unpack '(L2)<', $buffer;
197+ if ($addr == 0xf0) {
198+ if (defined $data) {
199+ $self->set_page($page, $data) or return 0;
200+ }
201+ $page = $value;
202+ $lastaddr = undef;
203+ $data = '';
204+ printf "Got page 0x%02x\n", $page;
205+ } else {
206+ if (!defined $page) {
207+ $@ = "Invalid firmware: page command missing at start";
208+ return 0;
209+ }
210+ if ($addr > 128) {
211+ $@ = sprintf "Invalid firmware: invalid address %d at page 0x%02x, max 128", $addr, $page;
212+ return 0;
213+ }
214+ if (defined $lastaddr and $addr != $lastaddr + 4) {
215+ $@ = sprintf "Invalid firmware: non-consecutive at page 0x%02x, address 0x%02x, expected 0x%02x", $page, $addr, $lastaddr + 4;
216+ return 0;
217+ }
218+ $data .= substr $buffer, 4, 4;
219+ $lastaddr = $addr;
220+ }
221+ }
222+ if (defined $page and defined $data) {
223+ # the last page has not been stored yet
224+ return $self->set_page($page, $data);
225+ }
226+ return 1;
227+}
228+
229+sub export_fw {
230+ my ($self) = @_;
231+ my $data = '';
232+ my @pages = $self->get_pages;
233+ for my $page (@pages) {
234+ my $pagedata = $self->get_page($page);
235+ $data .= pack '(L2)<', 0xf0, $page;
236+ my $length = length $pagedata;
237+ for (my $offset = 0; $offset + 3 < $length; $offset += 4) {
238+ my $word = substr $pagedata, $offset, 4;
239+ $data .= pack '(La4)<', $offset, $word;
240+ }
241+ }
242+ return $data;
243+}
244+
245+sub set_page {
246+ my ($self, $page, $data) = @_;
247+ if ($page > 0xff) {
248+ $@ = "Invalid page number $page";
249+ return 0;
250+ }
251+ if (length $data > 128) {
252+ $@ = "Page too large";
253+ return 0;
254+ }
255+ $self->{pages}->{$page} = $data;
256+ return 1;
257+}
258+
259+sub delete_page {
260+ my ($self, $page) = @_;
261+ if (!exists $self->{pages}->{$page}) {
262+ $@ = "Page number $page does not exist";
263+ return 0;
264+ }
265+ delete $self->{pages}->{$page};
266+ return 1;
267+}
268+
269+sub get_pages {
270+ my ($self) = @_;
271+ return sort { $a <=> $b } keys %{$self->{pages}};
272+}
273+
274+sub get_page {
275+ my ($self, $page) = @_;
276+ return $self->{pages}->{$page};
277+}
278+
279+sub touches {
280+ return shift->{touches};
281+}
282+
283+sub set_touches {
284+ my ($self, $value) = @_;
285+ $self->{touches} = $value;
286+}
287+
288+sub model {
289+ return shift->{model};
290+}
291+
292+sub set_model {
293+ my ($self, $value) = @_;
294+ $self->{model} = $value;
295+}
296+
297+sub width {
298+ return shift->{width};
299+}
300+
301+sub set_width {
302+ my ($self, $value) = @_;
303+ $self->{width} = $value;
304+}
305+
306+sub height {
307+ return shift->{height};
308+}
309+
310+sub set_height {
311+ my ($self, $value) = @_;
312+ $self->{height} = $value;
313+}
314+
315+sub swapped {
316+ return shift->{swapped};
317+}
318+
319+sub set_swapped {
320+ my ($self, $value) = @_;
321+ $self->{swapped} = $value;
322+}
323+
324+sub xmirrored {
325+ return shift->{xmirrored};
326+}
327+
328+sub set_xmirrored {
329+ my ($self, $value) = @_;
330+ $self->{xmirrored} = $value;
331+}
332+
333+sub ymirrored {
334+ return shift->{ymirrored};
335+}
336+
337+sub set_ymirrored {
338+ my ($self, $value) = @_;
339+ $self->{ymirrored} = $value;
340+}
341+
342+sub tracking {
343+ return shift->{tracking};
344+}
345+
346+sub set_tracking {
347+ my ($self, $value) = @_;
348+ $self->{tracking} = $value;
349+}
350+
351+=head1 NAME
352+
353+Firmware::Silead - Silead touchscren firmware packager
354+
355+=head1 SYNOPSIS
356+
357+ use Firmware::Silead;
358+ my $rep = Firmware::Silead->new();
359+ printf "width=%d height=%d num_touches=%d\n", $req->width, $rep->height, $rep->touches;
360+ $rep->add_page(0x00, "\0" x 128);
361+ $rep->save('firmware.fw');
362+
363+ $rep = Firmware::Silead->load('firmware.fw');
364+ print unpack('H*', $req->get_page(0x00));
365+
366+=head1 DESCRIPTION
367+
368+=head2 Constructors
369+
370+On error, all constructors set C<$@> to a description
371+of the error and return C<undef>.
372+
373+=head3 C<new>
374+
375+Creates a new firmware image without data.
376+
377+=head3 C<load($io)>
378+
379+Loads a firmware image from a file.
380+C<$io> may be a file handle or a file name.
381+
382+=head3 C<unpack($string)>
383+
384+Unpacks a firmware image from a byte string.
385+
386+=head2 Import/Export
387+
388+These methods allow importing firmware data from various formats.
389+Limited export is also available.
390+
391+Note: Page order is not preserved when importing firmware.
392+Pages are always sorted sequentially.
393+
394+=head3 C<import_scrambled($string)>
395+
396+Import a firmware image from a scrambled TS_CFG.h byte string, as used in the form
397+of SileadTouch.fw by newer Windows drivers.
398+
399+=head3 C<import_tscfg($string)>
400+
401+Import a firmware image from a plain TS_CFG.h byte string, as used by older
402+Windows drivers.
403+
404+=head3 C<import_fw($string)>
405+
406+Import a firmware image in legacy format, as used by most other Linux and
407+Android drivers.
408+
409+=head3 C<export_fw>
410+
411+Export a firmware image into legacy format, as usable by most other Linux and
412+Android drivers. A binary string is returned.
413+
414+=head2 Storage
415+
416+=head3 C<save($io)>
417+
418+Saves the firmware data to a file.
419+C<$io> may be a file handle or a file name.
420+
421+=head3 C<pack>
422+
423+Packs a firmware image into a byte string and returns it.
424+
425+=head2 Accessors
426+
427+=head3 C<model>
428+ C<set_model($model)>
429+
430+Gets/sets the controller model ID.
431+The ID is a 4-character ASCII string identifying the
432+particular controller supported by this firmware.
433+
434+Examples: 1680, 3682
435+
436+=head3 C<width>
437+ C<set_width($width)>
438+
439+Gets/sets the panel width.
440+
441+=head3 C<height>
442+ C<set_height($height)>
443+
444+Gets/sets the panel height.
445+
446+=head3 C<touches>
447+ C<set_touches($num_touches)>
448+
449+Gets/sets the number of supported touch points.
450+
451+=head3 C<swapped>
452+ C<set_swapped($is_swapped)>
453+
454+Gets/sets the axis swapping flag.
455+If true, the X and Y axes are swapped.
456+
457+=head3 C<xmirrored>
458+ C<set_xmirrored($is_mirrored)>
459+
460+Gets/sets the X axis mirroring flag.
461+If true, the X axis is inverted.
462+
463+=head3 C<ymirrored>
464+ C<set_ymirrored($is_mirrored)>
465+
466+Gets/sets the y axis mirroring flag.
467+If true, the Y axis is inverted.
468+
469+=head3 C<tracking>
470+ C<set_tracking($need_tracking)>
471+
472+Gets/sets the software tracking flag.
473+If true, hardware finger tracking is not available and
474+driver finger tracking will be used instead.
475+
476+=head2 Page access
477+
478+On error, all page accessors set C<$@> to a description
479+of the error. They return 1 on success, 0 on error.
480+
481+=head3 C<get_pages>
482+
483+Returns the list of defined pages (their page addresses, actually).
484+
485+=head3 C<get_page($page_no)>
486+
487+Returns the binary data for page number C<$page_no>.
488+
489+=head3 C<set_page($page_no, $data)>
490+
491+Stores the data of page number C<$page_no>. Automatically defines
492+the page if it did not exist previously.
493+
494+=head3 C<delete_page($page_no)>
495+
496+Removes page C<$page_no>.
497+
498+=head1 FIRMWARE FORMAT
499+
500+=head2 New-style firmware file format, version 1
501+
502+ Offset | Type | Description
503+ -------------------------------------------------------------------
504+ 0 | u8[4] | ASCII 'GSLX' (magic)
505+ 4 | u8[4] | Touchscreen model (ASCII string)
506+ 8 | u16le | File format version (1)
507+ 10 | u16le | Number of supported touch events
508+ 12 | u16le | Panel width (0..4095)
509+ 14 | u16le | Panel height (0..4095)
510+ 16 | u8 | 1 if X and Y axis are swapped, 0 otherwise
511+ 17 | u8 | 1 if X axis is mirrored, 0 otherwise
512+ 18 | u8 | 1 if Y axis is mirrored, 0 otherwise
513+ 19 | u8 | 0 if finger tracking is supported by hardware,
514+ | | 1 if the driver needs to provide it
515+ 20 | u32le | Number of memory pages that follow (N)
516+ 24 | u16le | Memory page 1: Page address
517+ 26 | u16le | Memory page 1: Effective size in bytes
518+ 28 | u8[128] | Memory page 1: Data (must be 0 padded)
519+ ...
520+ 24+N*132 | u16le | Memory page N: Page address
521+ 26+N*132 | u16le | Memory page N: Effective size in bytes
522+ 28+N*132 | u8[128] | Memory page N: Data (must be 0 padded)
523+
524+=head1 AUTHOR
525+
526+Gregor Riepl <onitake@gmail.com>
527+
528+=cut
529+
530+1;
--- /dev/null
+++ b/tools/LICENSE
@@ -0,0 +1,339 @@
1+ GNU GENERAL PUBLIC LICENSE
2+ Version 2, June 1991
3+
4+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
5+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
6+ Everyone is permitted to copy and distribute verbatim copies
7+ of this license document, but changing it is not allowed.
8+
9+ Preamble
10+
11+ The licenses for most software are designed to take away your
12+freedom to share and change it. By contrast, the GNU General Public
13+License is intended to guarantee your freedom to share and change free
14+software--to make sure the software is free for all its users. This
15+General Public License applies to most of the Free Software
16+Foundation's software and to any other program whose authors commit to
17+using it. (Some other Free Software Foundation software is covered by
18+the GNU Lesser General Public License instead.) You can apply it to
19+your programs, too.
20+
21+ When we speak of free software, we are referring to freedom, not
22+price. Our General Public Licenses are designed to make sure that you
23+have the freedom to distribute copies of free software (and charge for
24+this service if you wish), that you receive source code or can get it
25+if you want it, that you can change the software or use pieces of it
26+in new free programs; and that you know you can do these things.
27+
28+ To protect your rights, we need to make restrictions that forbid
29+anyone to deny you these rights or to ask you to surrender the rights.
30+These restrictions translate to certain responsibilities for you if you
31+distribute copies of the software, or if you modify it.
32+
33+ For example, if you distribute copies of such a program, whether
34+gratis or for a fee, you must give the recipients all the rights that
35+you have. You must make sure that they, too, receive or can get the
36+source code. And you must show them these terms so they know their
37+rights.
38+
39+ We protect your rights with two steps: (1) copyright the software, and
40+(2) offer you this license which gives you legal permission to copy,
41+distribute and/or modify the software.
42+
43+ Also, for each author's protection and ours, we want to make certain
44+that everyone understands that there is no warranty for this free
45+software. If the software is modified by someone else and passed on, we
46+want its recipients to know that what they have is not the original, so
47+that any problems introduced by others will not reflect on the original
48+authors' reputations.
49+
50+ Finally, any free program is threatened constantly by software
51+patents. We wish to avoid the danger that redistributors of a free
52+program will individually obtain patent licenses, in effect making the
53+program proprietary. To prevent this, we have made it clear that any
54+patent must be licensed for everyone's free use or not licensed at all.
55+
56+ The precise terms and conditions for copying, distribution and
57+modification follow.
58+
59+ GNU GENERAL PUBLIC LICENSE
60+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
61+
62+ 0. This License applies to any program or other work which contains
63+a notice placed by the copyright holder saying it may be distributed
64+under the terms of this General Public License. The "Program", below,
65+refers to any such program or work, and a "work based on the Program"
66+means either the Program or any derivative work under copyright law:
67+that is to say, a work containing the Program or a portion of it,
68+either verbatim or with modifications and/or translated into another
69+language. (Hereinafter, translation is included without limitation in
70+the term "modification".) Each licensee is addressed as "you".
71+
72+Activities other than copying, distribution and modification are not
73+covered by this License; they are outside its scope. The act of
74+running the Program is not restricted, and the output from the Program
75+is covered only if its contents constitute a work based on the
76+Program (independent of having been made by running the Program).
77+Whether that is true depends on what the Program does.
78+
79+ 1. You may copy and distribute verbatim copies of the Program's
80+source code as you receive it, in any medium, provided that you
81+conspicuously and appropriately publish on each copy an appropriate
82+copyright notice and disclaimer of warranty; keep intact all the
83+notices that refer to this License and to the absence of any warranty;
84+and give any other recipients of the Program a copy of this License
85+along with the Program.
86+
87+You may charge a fee for the physical act of transferring a copy, and
88+you may at your option offer warranty protection in exchange for a fee.
89+
90+ 2. You may modify your copy or copies of the Program or any portion
91+of it, thus forming a work based on the Program, and copy and
92+distribute such modifications or work under the terms of Section 1
93+above, provided that you also meet all of these conditions:
94+
95+ a) You must cause the modified files to carry prominent notices
96+ stating that you changed the files and the date of any change.
97+
98+ b) You must cause any work that you distribute or publish, that in
99+ whole or in part contains or is derived from the Program or any
100+ part thereof, to be licensed as a whole at no charge to all third
101+ parties under the terms of this License.
102+
103+ c) If the modified program normally reads commands interactively
104+ when run, you must cause it, when started running for such
105+ interactive use in the most ordinary way, to print or display an
106+ announcement including an appropriate copyright notice and a
107+ notice that there is no warranty (or else, saying that you provide
108+ a warranty) and that users may redistribute the program under
109+ these conditions, and telling the user how to view a copy of this
110+ License. (Exception: if the Program itself is interactive but
111+ does not normally print such an announcement, your work based on
112+ the Program is not required to print an announcement.)
113+
114+These requirements apply to the modified work as a whole. If
115+identifiable sections of that work are not derived from the Program,
116+and can be reasonably considered independent and separate works in
117+themselves, then this License, and its terms, do not apply to those
118+sections when you distribute them as separate works. But when you
119+distribute the same sections as part of a whole which is a work based
120+on the Program, the distribution of the whole must be on the terms of
121+this License, whose permissions for other licensees extend to the
122+entire whole, and thus to each and every part regardless of who wrote it.
123+
124+Thus, it is not the intent of this section to claim rights or contest
125+your rights to work written entirely by you; rather, the intent is to
126+exercise the right to control the distribution of derivative or
127+collective works based on the Program.
128+
129+In addition, mere aggregation of another work not based on the Program
130+with the Program (or with a work based on the Program) on a volume of
131+a storage or distribution medium does not bring the other work under
132+the scope of this License.
133+
134+ 3. You may copy and distribute the Program (or a work based on it,
135+under Section 2) in object code or executable form under the terms of
136+Sections 1 and 2 above provided that you also do one of the following:
137+
138+ a) Accompany it with the complete corresponding machine-readable
139+ source code, which must be distributed under the terms of Sections
140+ 1 and 2 above on a medium customarily used for software interchange; or,
141+
142+ b) Accompany it with a written offer, valid for at least three
143+ years, to give any third party, for a charge no more than your
144+ cost of physically performing source distribution, a complete
145+ machine-readable copy of the corresponding source code, to be
146+ distributed under the terms of Sections 1 and 2 above on a medium
147+ customarily used for software interchange; or,
148+
149+ c) Accompany it with the information you received as to the offer
150+ to distribute corresponding source code. (This alternative is
151+ allowed only for noncommercial distribution and only if you
152+ received the program in object code or executable form with such
153+ an offer, in accord with Subsection b above.)
154+
155+The source code for a work means the preferred form of the work for
156+making modifications to it. For an executable work, complete source
157+code means all the source code for all modules it contains, plus any
158+associated interface definition files, plus the scripts used to
159+control compilation and installation of the executable. However, as a
160+special exception, the source code distributed need not include
161+anything that is normally distributed (in either source or binary
162+form) with the major components (compiler, kernel, and so on) of the
163+operating system on which the executable runs, unless that component
164+itself accompanies the executable.
165+
166+If distribution of executable or object code is made by offering
167+access to copy from a designated place, then offering equivalent
168+access to copy the source code from the same place counts as
169+distribution of the source code, even though third parties are not
170+compelled to copy the source along with the object code.
171+
172+ 4. You may not copy, modify, sublicense, or distribute the Program
173+except as expressly provided under this License. Any attempt
174+otherwise to copy, modify, sublicense or distribute the Program is
175+void, and will automatically terminate your rights under this License.
176+However, parties who have received copies, or rights, from you under
177+this License will not have their licenses terminated so long as such
178+parties remain in full compliance.
179+
180+ 5. You are not required to accept this License, since you have not
181+signed it. However, nothing else grants you permission to modify or
182+distribute the Program or its derivative works. These actions are
183+prohibited by law if you do not accept this License. Therefore, by
184+modifying or distributing the Program (or any work based on the
185+Program), you indicate your acceptance of this License to do so, and
186+all its terms and conditions for copying, distributing or modifying
187+the Program or works based on it.
188+
189+ 6. Each time you redistribute the Program (or any work based on the
190+Program), the recipient automatically receives a license from the
191+original licensor to copy, distribute or modify the Program subject to
192+these terms and conditions. You may not impose any further
193+restrictions on the recipients' exercise of the rights granted herein.
194+You are not responsible for enforcing compliance by third parties to
195+this License.
196+
197+ 7. If, as a consequence of a court judgment or allegation of patent
198+infringement or for any other reason (not limited to patent issues),
199+conditions are imposed on you (whether by court order, agreement or
200+otherwise) that contradict the conditions of this License, they do not
201+excuse you from the conditions of this License. If you cannot
202+distribute so as to satisfy simultaneously your obligations under this
203+License and any other pertinent obligations, then as a consequence you
204+may not distribute the Program at all. For example, if a patent
205+license would not permit royalty-free redistribution of the Program by
206+all those who receive copies directly or indirectly through you, then
207+the only way you could satisfy both it and this License would be to
208+refrain entirely from distribution of the Program.
209+
210+If any portion of this section is held invalid or unenforceable under
211+any particular circumstance, the balance of the section is intended to
212+apply and the section as a whole is intended to apply in other
213+circumstances.
214+
215+It is not the purpose of this section to induce you to infringe any
216+patents or other property right claims or to contest validity of any
217+such claims; this section has the sole purpose of protecting the
218+integrity of the free software distribution system, which is
219+implemented by public license practices. Many people have made
220+generous contributions to the wide range of software distributed
221+through that system in reliance on consistent application of that
222+system; it is up to the author/donor to decide if he or she is willing
223+to distribute software through any other system and a licensee cannot
224+impose that choice.
225+
226+This section is intended to make thoroughly clear what is believed to
227+be a consequence of the rest of this License.
228+
229+ 8. If the distribution and/or use of the Program is restricted in
230+certain countries either by patents or by copyrighted interfaces, the
231+original copyright holder who places the Program under this License
232+may add an explicit geographical distribution limitation excluding
233+those countries, so that distribution is permitted only in or among
234+countries not thus excluded. In such case, this License incorporates
235+the limitation as if written in the body of this License.
236+
237+ 9. The Free Software Foundation may publish revised and/or new versions
238+of the General Public License from time to time. Such new versions will
239+be similar in spirit to the present version, but may differ in detail to
240+address new problems or concerns.
241+
242+Each version is given a distinguishing version number. If the Program
243+specifies a version number of this License which applies to it and "any
244+later version", you have the option of following the terms and conditions
245+either of that version or of any later version published by the Free
246+Software Foundation. If the Program does not specify a version number of
247+this License, you may choose any version ever published by the Free Software
248+Foundation.
249+
250+ 10. If you wish to incorporate parts of the Program into other free
251+programs whose distribution conditions are different, write to the author
252+to ask for permission. For software which is copyrighted by the Free
253+Software Foundation, write to the Free Software Foundation; we sometimes
254+make exceptions for this. Our decision will be guided by the two goals
255+of preserving the free status of all derivatives of our free software and
256+of promoting the sharing and reuse of software generally.
257+
258+ NO WARRANTY
259+
260+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
261+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
262+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
263+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
264+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
265+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
266+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
267+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
268+REPAIR OR CORRECTION.
269+
270+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
271+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
272+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
273+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
274+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
275+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
276+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
277+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
278+POSSIBILITY OF SUCH DAMAGES.
279+
280+ END OF TERMS AND CONDITIONS
281+
282+ How to Apply These Terms to Your New Programs
283+
284+ If you develop a new program, and you want it to be of the greatest
285+possible use to the public, the best way to achieve this is to make it
286+free software which everyone can redistribute and change under these terms.
287+
288+ To do so, attach the following notices to the program. It is safest
289+to attach them to the start of each source file to most effectively
290+convey the exclusion of warranty; and each file should have at least
291+the "copyright" line and a pointer to where the full notice is found.
292+
293+ <one line to give the program's name and a brief idea of what it does.>
294+ Copyright (C) <year> <name of author>
295+
296+ This program is free software; you can redistribute it and/or modify
297+ it under the terms of the GNU General Public License as published by
298+ the Free Software Foundation; either version 2 of the License, or
299+ (at your option) any later version.
300+
301+ This program is distributed in the hope that it will be useful,
302+ but WITHOUT ANY WARRANTY; without even the implied warranty of
303+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
304+ GNU General Public License for more details.
305+
306+ You should have received a copy of the GNU General Public License along
307+ with this program; if not, write to the Free Software Foundation, Inc.,
308+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
309+
310+Also add information on how to contact you by electronic and paper mail.
311+
312+If the program is interactive, make it output a short notice like this
313+when it starts in an interactive mode:
314+
315+ Gnomovision version 69, Copyright (C) year name of author
316+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
317+ This is free software, and you are welcome to redistribute it
318+ under certain conditions; type `show c' for details.
319+
320+The hypothetical commands `show w' and `show c' should show the appropriate
321+parts of the General Public License. Of course, the commands you use may
322+be called something other than `show w' and `show c'; they could even be
323+mouse-clicks or menu items--whatever suits your program.
324+
325+You should also get your employer (if you work as a programmer) or your
326+school, if any, to sign a "copyright disclaimer" for the program, if
327+necessary. Here is a sample; alter the names:
328+
329+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
330+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
331+
332+ <signature of Ty Coon>, 1 April 1989
333+ Ty Coon, President of Vice
334+
335+This General Public License does not permit incorporating your program into
336+proprietary programs. If your program is a subroutine library, you may
337+consider it more useful to permit linking proprietary applications with the
338+library. If this is what you want to do, use the GNU Lesser General
339+Public License instead of this License.
--- /dev/null
+++ b/tools/fw_extractor
@@ -0,0 +1,33 @@
1+#! /usr/bin/python
2+from subprocess import *
3+import sys
4+import os
5+
6+if len(sys.argv) != 2:
7+ print "Firware extractor.\n"
8+ print "Requires elf file (driver) argument"
9+ sys.exit(1)
10+
11+filename = sys.argv[1]
12+
13+p = Popen(['/bin/sh', '-c', 'readelf -S '+ filename + ' | grep \ \.rodata\ '], stdout=PIPE)
14+
15+args = p.stdout.readlines()
16+
17+if len(args) != 1:
18+ print "No simple .rodata section found"
19+ sys.exit(1)
20+
21+rodata = args[0]
22+
23+args = rodata.split()
24+
25+offset = int(args[4], 16)
26+
27+p = Popen(['/bin/sh', '-c', 'readelf -s '+ filename +' | grep -i fw'], stdout=PIPE)
28+
29+for line in p.stdout:
30+ args = line.split()
31+
32+ print "Found", args[7], "offset", offset + int(args[1],16), "count", args[2]
33+ call(['dd','if='+filename,'bs=1','count='+args[2], 'skip='+str(offset + int(args[1],16)),'of='+args[7] + ".fw"])
--- /dev/null
+++ b/tools/fwtool
@@ -0,0 +1,141 @@
1+#!/usr/bin/perl
2+
3+use strict;
4+use warnings;
5+use IO::File;
6+use Getopt::Long;
7+use Firmware::Silead;
8+
9+sub usage() {
10+ print STDERR "Usage: fwtool {-i | -c <original.fw> | -s | -x <legacy.fw>} [ -1 | -2 | -3 ] [-w <width>] [-h <height>] [-t <num_touches>] [-f <flags>] <firmware.fw>\n";
11+ print STDERR "-i Prints statistics and information about new-style firmware.fw\n";
12+ print STDERR "-c Converts any older firmware format into new-style firmware.fw\n";
13+ print STDERR "-s Sets parameters and flags\n";
14+ print STDERR "-x Exports a firmware into plain format, to use with other Linux/Android drivers\n";
15+ print STDERR " The source firmware format can be specified with these parameters:\n";
16+ print STDERR "-1 Plain firmware, as used with the Android driver (default)\n";
17+ print STDERR "-2 Windows GSL_TS_CFG.h firmware\n";
18+ print STDERR "-3 Scrambled Windows SileadTouch.fw firmware\n";
19+ print STDERR " For the -c and -s modes, the following parameters may be set:\n";
20+ print STDERR "-m Sets the controller model (4-byte ASCII string, ex.: 1680)\n";
21+ print STDERR "-w Sets the width parameter\n";
22+ print STDERR "-h Sets the height parameter\n";
23+ print STDERR "-t Sets the number of supported touch points parameter\n";
24+ print STDERR "-f Sets flags, separated by commas (optional, supported flags: xflip, yflip, swap, track)\n";
25+ print STDERR " xflip enables horizontal flipping\n";
26+ print STDERR " yflip enables vertical flipping\n";
27+ print STDERR " swap enables axis swapping\n";
28+ print STDERR " track enables in-driver finger tracking (use for controllers that don't support it)\n";
29+ print STDERR " Each flag may be prefixed with 'no' to disable it.\n";
30+ -1;
31+}
32+
33+my ($mode, $format, $tscfg, $model, $width, $height, $touches, $flags, $plain) = ('info', 'plain');
34+GetOptions(
35+ 'info' => sub { $mode = 'info'; },
36+ 'convert=s' => sub { $mode = 'convert'; $tscfg = $_[1]; },
37+ 'set' => sub { $mode = 'set'; },
38+ 'xport=s' => sub { $mode = 'export'; $plain = $_[1]; },
39+ 'model=s' => \$model,
40+ 'width=i' => \$width,
41+ 'height=i' => \$height,
42+ 'touches=i' => \$touches,
43+ 'flags=s' => \$flags,
44+ '1' => sub { $format = 'plain' },
45+ '2' => sub { $format = 'tscfg' },
46+ '3' => sub { $format = 'scrambled' },
47+) or exit usage;
48+
49+my $fwfile = $ARGV[0] or exit usage;
50+
51+sub set_params {
52+ my ($rep) = @_;
53+ if (defined $model) {
54+ $rep->set_model($model);
55+ }
56+ if (defined $width) {
57+ $rep->set_width($width);
58+ }
59+ if (defined $height) {
60+ $rep->set_height($height);
61+ }
62+ if (defined $touches) {
63+ $rep->set_touches($touches);
64+ }
65+ if (defined $flags) {
66+ for my $flag (split /,\s*/, $flags) {
67+ if ($flag =~ /^(no)?xflip$/) {
68+ $rep->set_xmirrored($flag !~ /^no/);
69+ } elsif ($flag =~ /^(no)?yflip$/) {
70+ $rep->set_ymirrored($flag !~ /^no/);
71+ } elsif ($flag =~ /^(no)?swap$/) {
72+ $rep->set_swapped($flag !~ /^no/);
73+ } elsif ($flag =~ /^(no)?track$/) {
74+ $rep->set_tracking($flag !~ /^no/);
75+ } else {
76+ warn "Invalid flag: $flag";
77+ }
78+ }
79+ }
80+}
81+
82+if ($mode eq 'info') {
83+ print "Loading $fwfile...\n";
84+ my $rep = Firmware::Silead->load($fwfile) or die "Can't load firmware $fwfile: $@";
85+ print "Controller model: " . $rep->model . "\n";
86+ print "Panel width: " . $rep->width . "\n";
87+ print "Panel height: " . $rep->height . "\n";
88+ print "Number of touch points: " . $rep->touches . "\n";
89+ print "X axis flipped: " . ($rep->xmirrored ? "yes" : "no") . "\n";
90+ print "Y axis flipped: " . ($rep->ymirrored ? "yes" : "no") . "\n";
91+ print "X and Y axes swapped: " . ($rep->swapped ? "yes" : "no") . "\n";
92+ print "Software tracking enabled: " . ($rep->tracking ? "yes" : "no") . "\n";
93+ my @pages = $rep->get_pages;
94+ print "Number of pages: ". scalar(@pages) . "\n";
95+ print "Page list:";
96+ for my $page (@pages) {
97+ printf " %02x", $page;
98+ }
99+ print "\n";
100+} elsif ($mode eq 'set') {
101+ print "Loading $fwfile...\n";
102+ my $rep = Firmware::Silead->load($fwfile) or die "Can't load firmware $fwfile: $@";
103+ print "Setting parameters...\n";
104+ set_params($rep);
105+ print "Saving $fwfile...\n";
106+ $rep->save($fwfile);
107+} elsif ($mode eq 'convert') {
108+ print "Loading $tscfg...\n";
109+ my $data;
110+ do {
111+ my $in = IO::File->new($tscfg, 'r') or die "Can't open $tscfg: $!";
112+ $in->binmode;
113+ local $/ = undef;
114+ $data = <$in>;
115+ defined($data) or die "Can't load firmware: $!";
116+ $in->close();
117+ };
118+
119+ my $rep = Firmware::Silead->new();
120+ if ($format eq 'plain') {
121+ $rep->import_fw($data) or die "Can't parse firmware: $@";
122+ } elsif ($format eq 'tscfg') {
123+ $rep->import_tscfg($data) or die "Can't parse firmware: $@";
124+ } elsif ($format eq 'scrambled') {
125+ $rep->import_scrambled($data) or die "Can't parse firmware: $@";
126+ }
127+
128+ print "Setting parameters...\n";
129+ set_params($rep);
130+
131+ print "Saving $fwfile...\n";
132+ $rep->save($fwfile) or die "Can't write firmware: $@";
133+} elsif ($mode eq 'export') {
134+ print "Loading $fwfile...\n";
135+ my $rep = Firmware::Silead->load($fwfile) or die "Can't load firmware $fwfile: $@";
136+ print "Exporting to $plain...\n";
137+ my $out = IO::File->new($plain, 'w') or die "Can't open $plain: $!";
138+ my $data = $rep->export_fw();
139+ $out->print($data) or die "Can't write firmware: $!";
140+ $out->close();
141+}
--- /dev/null
+++ b/tools/unscramble
@@ -0,0 +1,52 @@
1+#!/usr/bin/perl
2+
3+use strict;
4+use warnings;
5+use IO::File;
6+
7+sub usage() {
8+ print STDERR "Usage: unscramble SileadTouch.fw gsl_ts.fw\n";
9+ print STDERR "Converts a scrambled Silead Windows driver firmware image into legacy binary format.\n";
10+ -1;
11+}
12+
13+my $scrfile = $ARGV[0] or exit usage;
14+my $fwfile = $ARGV[1] or exit usage;
15+
16+my $scrambled = '';
17+do {
18+ my $in = IO::File->new($scrfile, 'r') or die "Can't open $scrfile: $!";
19+ $in->binmode();
20+ local $/;
21+ $scrambled = <$in>;
22+ defined $scrambled or die "Can't read firmware: $!";
23+ $in->close();
24+};
25+
26+my $unscrambled = '';
27+for my $char (split //, $scrambled) {
28+ $unscrambled .= chr(ord($char) ^ 0x88);
29+}
30+
31+my $out = IO::File->new($fwfile, 'w') or die "Can't open $fwfile: $!";
32+
33+my $cfg = 0;
34+for my $line (split /\n/, $unscrambled) {
35+ if ($cfg and $line =~ /};/) {
36+ $cfg = 0;
37+ }
38+ if ($line =~ /TS_CFG_DATA/) {
39+ $cfg = 1;
40+ }
41+ if ($cfg) {
42+ $line =~ s/\s//g;
43+ $line = lc($line);
44+ if ($line =~ /{0x([0-9a-f]+),0x([0-9a-f]+)},/) {
45+ my $address = hex($1);
46+ my $data = hex($2);
47+ print $out pack('(LL)<', $address, $data) or die "Can't write to output: $!";;
48+ }
49+ }
50+}
51+
52+$out->close();