Make sensors-detect no longer depend on i2cdetect. Parsing /proc/bus/i2c or

walking sysfs for the same information (i2c adapter names) is not that
difficult.


git-svn-id: http://lm-sensors.org/svn/lm-sensors/branches/lm-sensors-3.0.0@4472 7894878c-1315-0410-8ee3-d5d059ff63e0
This commit is contained in:
Jean Delvare committed 2007-06-26 07:47:30 +00:00
1 parent 220aa2649a
commit 617e759d94
2 files changed
+57 -32

No files matched your search

+1
View File
@@ -46,6 +46,7 @@ SVN HEAD
Add IT8726F detection
Fix IPMI support for 2.6 kernels
Add detection for non-standard SMSC Super-I/Os
No longer depend on i2cdetect
2.10.3 (20070319)
+56 -32
View File
@@ -34,7 +34,7 @@ use Fcntl;
use POSIX;
use File::Basename;
# We will call modprobe and i2cdetect, which typically live in either /sbin,
# We will call modprobe, which typically lives in either /sbin,
# /usr/sbin or /usr/local/bin. So make sure these are all in the PATH.
foreach ('/usr/sbin', '/usr/local/sbin', '/sbin') {
$ENV{PATH} = "$_:".$ENV{PATH}
@@ -2297,6 +2297,45 @@ sub initialize_cpu_list
close INPUTFILE;
}
# @i2c_adapters is a list of references to hashes, one hash per I2C/SMBus
# adapter present on the system. Each entry has the following keys: name
# (directly taken from either /proc/bus/i2c or /sys/class/i2c-adapter) and
# driver.
use vars qw(@i2c_adapters);
sub initialize_i2c_adapters_list
{
my $entry;
local $_;
if (defined $sysfs_root) {
my $class_dir = "${sysfs_root}/class/i2c-adapter";
opendir(local *ADAPTERS, $class_dir) or return;
while (defined($_ = readdir(ADAPTERS))) {
next unless m/^i2c-(\d+)$/;
$entry = {}; # New entry
$entry->{'name'} = sysfs_device_attribute("${class_dir}/i2c-$1", "name")
|| sysfs_device_attribute("${class_dir}/i2c-$1/device", "name");
$entry->{'driver'} = find_adapter_driver($entry->{'name'});
$i2c_adapters[$1] = $entry;
}
closedir(ADAPTERS);
} else {
open(local *INPUTFILE, "/proc/bus/i2c") or return;
while (<INPUTFILE>) {
my ($nr, $type, $name) = /^i2c-(\d+)\s+(\S+)\s+(.*?) *(\t|$)/;
next if ($type eq "dummy" || $type eq "isa");
$entry = {}; # New entry
$entry->{'name'} = $name;
$entry->{'driver'} = find_adapter_driver($name);
$i2c_adapters[$nr] = $entry;
}
close(INPUTFILE);
}
}
###########
# MODULES #
###########
@@ -2542,7 +2581,7 @@ sub adapter_pci_detection
return @res;
}
# $_[0]: Adapter description as found in /proc/bus/i2c
# $_[0]: Adapter description as found in /proc/bus/i2c or sysfs
sub find_adapter_driver
{
my $adapter;
@@ -5495,7 +5534,6 @@ sub generate_modprobes
my ($chip,$detection,$nr,$i,@optionlist,@probelist,$driver,$isa,$adap);
my $ipmi = 0;
my @adapters;
my $modprobes = "";
my $configfile = "";
@@ -5503,18 +5541,6 @@ sub generate_modprobes
$configfile .= "# I2C module options\n";
$configfile .= "alias char-major-89 i2c-dev\n";
# Collect all loaded adapters
# i2cdetect -l either cats /proc/bus/i2c or scans sysfs for the same information
open(local *INPUTFILE, "i2cdetect -l |") or die "Couldn't find i2cdetect program!!";
local $_;
while (<INPUTFILE>) {
my ($dev_nr, $type, $adap) = /^i2c-(\d+)\s+(\S+)\s+(.*?) *(\t|$)/;
next if ($type eq "dummy" || $type eq "isa");
$adapters[$dev_nr]->{driver} = find_adapter_driver($adap);
$adapters[$dev_nr]->{adapname} = $adap;
}
close INPUTFILE;
# Collect all adapters used
$nr = 0;
$isa = 0;
@@ -5523,9 +5549,9 @@ sub generate_modprobes
# If there is more than one bus detected by a driver, they are
# still all added. So we number them in the correct order
if (exists $detection->{i2c_driver} and
not exists $adapters[$detection->{i2c_devnr}]->{nr_later} and
not exists $i2c_adapters[$detection->{i2c_devnr}]->{nr_later} and
not (exists $detection->{isa_addr} and $prefer_isa)) {
foreach $adap (@adapters) {
foreach $adap (@i2c_adapters) {
next unless exists $adap->{driver};
$adap->{nr_later} = $nr++ if $adap->{driver} eq $detection->{i2c_driver};
}
@@ -5543,14 +5569,14 @@ sub generate_modprobes
$modprobes .= "# I2C adapter drivers\n" if $nr;
for ($i = 0; $i < $nr; $i++) {
foreach $adap (@adapters) {
foreach $adap (@i2c_adapters) {
next unless exists $adap->{nr_later} and $adap->{nr_later} == $i;
if ($adap->{driver} eq "UNKNOWN") {
$modprobes .= "# modprobe unknown adapter ".$adap->{adapname}."\n";
$modprobes .= "# modprobe unknown adapter ".$adap->{name}."\n";
} elsif ($adap->{driver} eq "DISABLED") {
$modprobes .= "# modprobe disabled adapter ".$adap->{adapname}."\n";
$modprobes .= "# modprobe disabled adapter ".$adap->{name}."\n";
} elsif ($adap->{driver} eq "to-be-written") {
$modprobes .= "# no driver available for adapter ".$adap->{adapname}."\n";
$modprobes .= "# no driver available for adapter ".$adap->{name}."\n";
} else {
$modprobes .= "modprobe $adap->{driver}\n"
unless $modprobes =~ /modprobe $adap->{driver}\n/;
@@ -5602,10 +5628,10 @@ sub generate_modprobes
# Handle misdetects
foreach $detection (@{$chip->{misdetected}}) {
push @optionlist, $adapters[$detection->{i2c_devnr}]->{nr_later},
push @optionlist, $i2c_adapters[$detection->{i2c_devnr}]->{nr_later},
$detection->{i2c_addr}
if exists $detection->{i2c_addr} and
exists $adapters[$detection->{i2c_devnr}]->{nr_later};
exists $i2c_adapters[$detection->{i2c_devnr}]->{nr_later};
push @optionlist, -1, $detection->{isa_addr}
if exists $detection->{isa_addr} and $isa;
}
@@ -5614,10 +5640,10 @@ sub generate_modprobes
foreach $detection (@{$chip->{detected}}) {
if (exists $detection->{i2c_driver} and
exists $detection->{isa_addr} and
exists $adapters[$detection->{i2c_devnr}]->{nr_later} and
exists $i2c_adapters[$detection->{i2c_devnr}]->{nr_later} and
$isa) {
if ($prefer_isa) {
push @optionlist,$adapters[$detection->{i2c_devnr}]->{nr_later},
push @optionlist, $i2c_adapters[$detection->{i2c_devnr}]->{nr_later},
$detection->{i2c_addr};
} else {
push @optionlist, -1, $detection->{isa_addr}
@@ -5703,6 +5729,7 @@ sub main
print "If you have undetectable or unsupported adapters, you can have them\n".
"scanned by manually loading the modules before running this script.\n\n";
initialize_i2c_adapters_list();
if (!exists($modules_list{"i2c-dev"})
&& !(defined $sysfs_root && -e "$sysfs_root/class/i2c-dev")) {
@@ -5732,12 +5759,9 @@ sub main
"you can specify that address to remain unprobed.\n";
my ($inp,@not_to_scan,$inp2);
# i2cdetect -l either cats /proc/bus/i2c or scans sysfs for the same information
open(local *INPUTFILE, "i2cdetect -l |") or die "Couldn't find i2cdetect program!!";
local $_;
while (<INPUTFILE>) {
my ($dev_nr, $type, $adap) = /^i2c-(\d+)\s+(\S+)\s+(.*?) *(\t|$)/;
next if ($type eq "dummy" || $type eq "isa");
for (my $dev_nr = 0; $dev_nr < @i2c_adapters; $dev_nr++) {
next unless exists $i2c_adapters[$dev_nr];
my $adap = $i2c_adapters[$dev_nr]->{'name'};
print "\n";
print "Next adapter: $adap (i2c-$dev_nr)\n";
print "Do you want to scan it? (YES/no/selectively): ";
@@ -5754,7 +5778,7 @@ sub main
chop $inp2;
@not_to_scan = parse_not_to_scan 0,0x7f,$inp2;
}
scan_adapter $dev_nr, $adap, find_adapter_driver($adap),
scan_adapter $dev_nr, $adap, $i2c_adapters[$dev_nr]->{'driver'},
\@not_to_scan unless $inp =~ /^\s*[Nn]/;
}
print "\n";