|
|
@ -1,6 +1,6 @@ |
|
|
|
#!/usr/bin/perl -w |
|
|
|
# |
|
|
|
# Copyright (C) 2007 Jean Delvare <khali@linux-fr.org> |
|
|
|
# Copyright (C) 2007-2008 Jean Delvare <khali@linux-fr.org> |
|
|
|
# |
|
|
|
# This program is free software; you can redistribute it and/or modify |
|
|
|
# it under the terms of the GNU General Public License as published by |
|
|
@ -22,7 +22,7 @@ |
|
|
|
# a device you do not have access to, but of which you have a dump. |
|
|
|
|
|
|
|
use strict; |
|
|
|
use vars qw($bus_nr $addr $count); |
|
|
|
use vars qw($bus_nr $addr $bytes $words); |
|
|
|
|
|
|
|
# Kernel version detection code by Mark M. Hoffman, |
|
|
|
# copied from sensors-detect. |
|
|
@ -66,6 +66,42 @@ sub get_i2c_stub_bus_number |
|
|
|
return $nr; |
|
|
|
} |
|
|
|
|
|
|
|
sub process_dump |
|
|
|
{ |
|
|
|
my $dump = shift; |
|
|
|
|
|
|
|
open(DUMP, $dump) || die "Can't open $dump: $!\n"; |
|
|
|
OUTER_LOOP: |
|
|
|
while (<DUMP>) { |
|
|
|
if (m/^([0-9a-f]0):(( [0-9a-f]{2}){16})/) { |
|
|
|
# Byte dump |
|
|
|
my $offset = hex($1); |
|
|
|
my @values = split(/ /, $2); |
|
|
|
shift(@values); |
|
|
|
for (my $i = 0; $i < 16 && (my $val = shift(@values)); $i++) { |
|
|
|
last OUTER_LOOP if system("i2cset", "-y", |
|
|
|
$bus_nr, $addr, |
|
|
|
sprintf("0x\%02x", $offset+$i), |
|
|
|
"0x$val", "b"); |
|
|
|
$bytes++; |
|
|
|
} |
|
|
|
} elsif (m/^([0-9a-f][08]):(( [0-9a-f]{4}){8})/) { |
|
|
|
# Word dump |
|
|
|
my $offset = hex($1); |
|
|
|
my @values = split(/ /, $2); |
|
|
|
shift(@values); |
|
|
|
for (my $i = 0; $i < 8 && (my $val = shift(@values)); $i++) { |
|
|
|
last OUTER_LOOP if system("i2cset", "-y", |
|
|
|
$bus_nr, $addr, |
|
|
|
sprintf("0x\%02x", $offset+$i), |
|
|
|
"0x$val", "w"); |
|
|
|
$words++; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
close(DUMP); |
|
|
|
} |
|
|
|
|
|
|
|
if ($>) { |
|
|
|
print "You must be root to use this script\n"; |
|
|
|
exit 1; |
|
|
@ -95,33 +131,22 @@ if (kernel_version_at_least(2, 6, 19)) { |
|
|
|
sleep(1); # udev may take some time to create the device node |
|
|
|
|
|
|
|
$bus_nr = get_i2c_stub_bus_number(); |
|
|
|
$bytes = $words = 0; |
|
|
|
|
|
|
|
# We don't want to see the output of 256 i2cset |
|
|
|
open(SAVEOUT, ">&STDOUT"); |
|
|
|
open(STDOUT, ">/dev/null"); |
|
|
|
process_dump($ARGV[1]); |
|
|
|
close(STDOUT); |
|
|
|
|
|
|
|
$count = 0; |
|
|
|
open(DUMP, $ARGV[1]) || die "Can't open $ARGV[1]: $!\n"; |
|
|
|
OUTER_LOOP: |
|
|
|
while (<DUMP>) { |
|
|
|
next unless m/^([0-9a-f]0):(( [0-9a-f]{2}){16})/; |
|
|
|
my $offset = hex($1); |
|
|
|
my @values = split(/ /, $2); |
|
|
|
shift(@values); |
|
|
|
for (my $i = 0; $i < 16 && (my $val = shift(@values)); $i++) { |
|
|
|
last OUTER_LOOP if system("i2cset", "-y", |
|
|
|
$bus_nr, $addr, |
|
|
|
sprintf("0x\%02x", $offset+$i), |
|
|
|
sprintf("0x\%02x", hex($val)), "b"); |
|
|
|
$count++; |
|
|
|
} |
|
|
|
if ($bytes) { |
|
|
|
printf SAVEOUT "$bytes byte values written to \%d-\%04x\n", |
|
|
|
$bus_nr, oct($addr); |
|
|
|
} |
|
|
|
close(DUMP); |
|
|
|
close(STDOUT); |
|
|
|
|
|
|
|
if ($count) { |
|
|
|
printf SAVEOUT "$count byte values written to \%d-\%04x\n", |
|
|
|
if ($words) { |
|
|
|
printf SAVEOUT "$words word values written to \%d-\%04x\n", |
|
|
|
$bus_nr, oct($addr); |
|
|
|
} |
|
|
|
|
|
|
|
exit($count == 0); |
|
|
|
exit($bytes + $words == 0); |