2
0
mirror of https://github.com/lm-sensors/lm-sensors synced 2025-09-02 23:35:57 +00:00

Rework adm1021 and clones detection. Should hopefully prevent more

misdetections.


git-svn-id: http://lm-sensors.org/svn/lm-sensors/trunk@2393 7894878c-1315-0410-8ee3-d5d059ff63e0
This commit is contained in:
Jean Delvare
2004-03-27 09:19:31 +00:00
parent 6dd6a90af5
commit a1b40ade8b

View File

@@ -3369,58 +3369,90 @@ sub adm1024_detect
# 0xfe: Company ID (all but LM84 and MAX1617) # 0xfe: Company ID (all but LM84 and MAX1617)
# 0xff: Revision (ADM1021, ADM1021A/ADM1023 and MAX1617A) # 0xff: Revision (ADM1021, ADM1021A/ADM1023 and MAX1617A)
# 0x02: Status # 0x02: Status
# 0x03: Configuration
# 0x04: Conversion rate
# 0x00-0x01, 0x05-0x08: Temperatures (MAX1617 and LM84) # 0x00-0x01, 0x05-0x08: Temperatures (MAX1617 and LM84)
# Note: Especially the MAX1617 has very bad detection; we give it a low # Note: Especially the MAX1617 has very bad detection; we give it a low
# confidence value. # confidence value.
sub adm1021_detect sub adm1021_detect
{ {
my ($chip, $file,$addr) = @_; my ($chip, $file, $addr) = @_;
return if $chip == 0 and i2c_smbus_read_byte_data($file,0xfe) != 0x41 || my $man_id = i2c_smbus_read_byte_data($file, 0xfe);
(i2c_smbus_read_byte_data($file,0xff) & 0xf0) != 0x00; my $rev = i2c_smbus_read_byte_data($file, 0xff);
return if $chip == 1 and i2c_smbus_read_byte_data($file,0xfe) != 0x41 || my $conf = i2c_smbus_read_byte_data($file, 0x03);
(i2c_smbus_read_byte_data($file,0xff) & 0xf0) != 0x30; my $status = i2c_smbus_read_byte_data($file, 0x02);
return if $chip == 4 and i2c_smbus_read_byte_data($file,0xfe) != 0x49; my $convrate = i2c_smbus_read_byte_data($file, 0x04);
return if $chip == 5 and i2c_smbus_read_byte_data($file,0x04) != 0x00;
return if $chip == 6 and i2c_smbus_read_byte_data($file,0xfe) != 0x23; # Check manufacturer IDs and product revisions when available
return if $chip == 3 and i2c_smbus_read_byte_data($file,0xfe) != 0x4d || return if $chip == 0 and $man_id != 0x41 ||
i2c_smbus_read_byte_data($file,0xff) != 0x01; ($rev & 0xf0) != 0x00;
return if $chip == 7 and i2c_smbus_read_byte_data($file,0xfe) != 0x54; return if $chip == 1 and $man_id != 0x41 ||
# The remaining things are flaky at best. Perhaps something can be done ($rev & 0xf0) != 0x30;
# with the fact that some registers are unreadable? return if $chip == 3 and $man_id != 0x4d ||
return if (i2c_smbus_read_byte_data($file,0x02) & 0x03) != 0; $rev != 0x01;
return if $chip == 4 and $man_id != 0x49;
return if $chip == 5 and $convrate != 0x00;
return if $chip == 6 and $man_id != 0x23;
return if $chip == 7 and $man_id != 0x54;
# Check unused bits
if ($chip == 5) # LM84
{
return if ($status & 0xab) != 0;
return if ($conf & 0x7f) != 0;
}
else
{
return if ($status & 0x03) != 0;
return if ($conf & 0x3f) != 0;
return if ($convrate & 0xf8) != 0;
}
# Extra checks for MAX1617 and LM84, since those are often misdetected # Extra checks for MAX1617 and LM84, since those are often misdetected
# We verify 6 assertions and discard the chip if too many (2 for the
# MAX1617, 4 for the LM84) fail. Not that these checks are not done
# by the adm1021 driver.
if ($chip == 2 || $chip == 5) if ($chip == 2 || $chip == 5)
{ {
my $lte = i2c_smbus_read_byte_data($file, 0x00);
my $rte = i2c_smbus_read_byte_data($file, 0x01);
my $lhi = i2c_smbus_read_byte_data($file, 0x05);
my $rhi = i2c_smbus_read_byte_data($file, 0x07);
my $llo = i2c_smbus_read_byte_data($file, 0x06);
my $rlo = i2c_smbus_read_byte_data($file, 0x08);
# If all registers hold the same value, it has to be a misdetection
return if $lte == $rte and $lte == $lhi and $lte == $rhi
and $lte == $llo and $lte == $rlo;
# Increase the misdetect value each time a temperature doesn't # Increase the misdetect value each time a temperature doesn't
# match reasonable expectations # match reasonable expectations
my $misdetect = 0; my $misdetect = 0;
# Negative temperatures # Negative temperatures
$misdetect++ if ((my $lte=i2c_smbus_read_byte_data($file,0x00)) & 0x80); $misdetect++ if ($lte & 0x80);
$misdetect++ if ((my $rte=i2c_smbus_read_byte_data($file,0x01)) & 0x80); $misdetect++ if ($rte & 0x80);
# Negative high limits # Negative high limits
my ($lhi, $rhi); if ($lhi & 0x80)
if (($lhi=i2c_smbus_read_byte_data($file,0x05)) & 0x80)
{ {
$misdetect++; $misdetect++;
$lhi-=256; $lhi-=256;
} }
if (($rhi=i2c_smbus_read_byte_data($file,0x07)) & 0x80) if ($rhi & 0x80)
{ {
$misdetect++; $misdetect++;
$rhi-=256; $rhi-=256;
} }
# Low limits over high limits # Low limits over high limits
my $llo=i2c_smbus_read_byte_data($file,0x06); if ($chip != 5) # LM84 doesn't have low limits
my $rlo=i2c_smbus_read_byte_data($file,0x08); {
$llo-=256 if ($llo & 0x80); $llo-=256 if ($llo & 0x80);
$rlo-=256 if ($rlo & 0x80); $rlo-=256 if ($rlo & 0x80);
$misdetect++ if $llo > $lhi; $misdetect++ if $llo > $lhi;
$misdetect++ if $rlo > $rhi; $misdetect++ if $rlo > $rhi;
return if $misdetect >= 4; }
# Also return if all six bytes have the same value return if $misdetect > 2;
return if $lte == $rte and $lte == $lhi and $lte == $rhi
and $lte == $llo and $lte == $rlo;
} }
return 3 if $chip == 2; return 3 if $chip == 2;
return 7 if $chip <= 3; return 7 if $chip <= 3;
return 5; return 5;