summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJean Delvare <jdelvare@suse.de>2007-11-01 17:54:57 +0000
committerJean Delvare <jdelvare@suse.de>2007-11-01 17:54:57 +0000
commit87c129180fcc6ea651d479e230186e50089ee612 (patch)
tree59af10e557409b622f0e4f027adb6054fe7c43fa
parentafff1260ebea7bc3dcbba762a1f19ce9ab9db9f1 (diff)
downloadi2c-tools-git-87c129180fcc6ea651d479e230186e50089ee612.tar.gz
i2c-stub-from-dump: New helper script to use with the i2c-stub kernel
driver. git-svn-id: http://lm-sensors.org/svn/i2c-tools/trunk@5002 7894878c-1315-0410-8ee3-d5d059ff63e0
-rw-r--r--CHANGES1
-rw-r--r--Makefile1
-rw-r--r--README4
-rw-r--r--stub/Module.mk22
-rwxr-xr-xstub/i2c-stub-from-dump100
5 files changed, 128 insertions, 0 deletions
diff --git a/CHANGES b/CHANGES
index baedcd5..fb1336b 100644
--- a/CHANGES
+++ b/CHANGES
@@ -4,6 +4,7 @@ i2c-tools CHANGES
SVN
i2cset: Final status messages go to stdout
Return success even when readback fails or doesn't match
+ i2c-stub-from-dump: Helper script to use with i2c-stub
3.0.0 (2007-10-14)
Initial release
diff --git a/Makefile b/Makefile
index 71119e7..a2bf718 100644
--- a/Makefile
+++ b/Makefile
@@ -33,4 +33,5 @@ all:
include eeprom/Module.mk
include include/Module.mk
+include stub/Module.mk
include tools/Module.mk
diff --git a/README b/README
index ee118f4..700bf88 100644
--- a/README
+++ b/README
@@ -27,6 +27,10 @@ category has its own sub-directory:
* py-smbus
Python wrapper for SMBus access over i2c-dev. Not installed by default.
+* stub
+ A helper script to use with the i2c-stub kernel driver. Installed by
+ default.
+
* tools
I2C device detection and register dump tools. These tools rely on the
"i2c-dev" kernel driver. They are installed by default.
diff --git a/stub/Module.mk b/stub/Module.mk
new file mode 100644
index 0000000..144c90e
--- /dev/null
+++ b/stub/Module.mk
@@ -0,0 +1,22 @@
+# Helper for the Linux i2c-stub bus driver
+#
+# Copyright (C) 2007 Jean Delvare <khali@linux-fr.org>
+#
+# Licensed under the GNU General Public License.
+
+STUB_DIR := stub
+
+#
+# Commands
+#
+
+install-stub: $(STUB_DIR)/i2c-stub-from-dump
+ $(INSTALL_DIR) $(DESTDIR)$(bindir)
+ $(INSTALL_PROGRAM) $(STUB_DIR)/i2c-stub-from-dump $(DESTDIR)$(bindir)
+
+uninstall-stub:
+ $(RM) $(DESTDIR)$(bindir)/i2c-stub-from-dump
+
+install: install-stub
+
+uninstall: uninstall-stub
diff --git a/stub/i2c-stub-from-dump b/stub/i2c-stub-from-dump
new file mode 100755
index 0000000..4c14faf
--- /dev/null
+++ b/stub/i2c-stub-from-dump
@@ -0,0 +1,100 @@
+#!/usr/bin/perl -w
+#
+# Copyright (C) 2007 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
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+# MA 02110-1301, USA
+#
+# This script feeds the i2c-stub driver with dump data from a real
+# I2C or SMBus chip. This can be useful when writing a driver for
+# a device you do not have access to, but of which you have a dump.
+
+use strict;
+use vars qw($bus_nr $addr $count);
+
+# Find out the i2c bus number of i2c-stub
+sub get_i2c_stub_bus_number
+{
+ my $nr;
+
+ open(FH, "i2cdetect -l |") || die "Can't run i2cdetect";
+ while (<FH>) {
+ next unless m/^i2c-(\d+).*\tSMBus stub/;
+ $nr = $1;
+ last;
+ }
+ close(FH);
+
+ if (!defined($nr)) {
+ print STDERR "Please load i2c-stub first\n";
+ exit 2;
+ }
+
+ return $nr;
+}
+
+if ($>) {
+ print "You must be root to use this script\n";
+ exit 1;
+}
+
+if (@ARGV != 2) {
+ print STDERR "Usage: i2c-stub-from-dump <addr> <dump file>\n";
+ exit 1;
+}
+
+# Check the parameters
+$addr = $ARGV[0];
+if ($addr !~ m/^0x[0-7][0-9a-f]$/i) {
+ print STDERR "Invalid address $addr\n";
+ exit 1;
+}
+
+# Load the required kernel drivers if needed
+system("/sbin/modprobe", "i2c-dev") == 0 || exit 1;
+system("/sbin/modprobe", "i2c-stub", "chip_addr=$addr") == 0 || exit 1;
+sleep(1); # udev may take some time to create the device node
+
+$bus_nr = get_i2c_stub_bus_number();
+
+# We don't want to see the output of 256 i2cset
+open(SAVEOUT, ">&STDOUT");
+open(STDOUT, ">/dev/null");
+
+$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++;
+ }
+}
+close(DUMP);
+close(STDOUT);
+
+if ($count) {
+ printf SAVEOUT "$count byte values written to \%d-\%04x\n",
+ $bus_nr, oct($addr);
+}
+
+exit($count == 0);