Firmware of Silead Touchscreen Controller for Jumper EZpad 6 Pro.
Révision | 671fc6739bcc3b632d2b417b262a7892fe84d2f4 (tree) |
---|---|
l'heure | 2016-02-03 03:44:33 |
Auteur | Gregor Riepl <onitake@gmai...> |
Commiter | Gregor Riepl |
Copied firmware conversion tools from gslx680-acpi, corrected license (GPL2)
@@ -16,7 +16,7 @@ distribution such as Debian or Ubuntu. | ||
16 | 16 | The files may be covered by proprietary licenses or copyright. |
17 | 17 | |
18 | 18 | 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 | |
20 | 20 | |
21 | 21 | |
22 | 22 | Device list |
@@ -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; |
@@ -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. |
@@ -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"]) |
@@ -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 | +} |
@@ -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(); |