Changeset 250

Show
Ignore:
Timestamp:
02/18/99 19:09:14 (14 years ago)
Author:
frodo
Message:

Detect script: actually works for chip detection!

Well, it still takes some tinkering, and I need to create a user-interface.
If you want to play with it already:

  • Uncomment the line beneath test, and put the adapter number (as corresponding with /dev/i2c-*) behind it as argument;
  • It only detects LM78, LM78-J, LM79 and LM80 at of this moment;
  • Only LM75 detection is really tested, as I don't have my LM78 connected to the SMBus.
Location:
lm-sensors/trunk/prog/detect
Files:
2 modified

Legend:

Unmodified
Added
Removed
  • lm-sensors/trunk/prog/detect/detect.pl

    r244 r250  
    7070); 
    7171 
     72use subs qw(lm78_detect lm75_detect lm80_detect); 
    7273 
    7374# This is a list of all recognized chips.  
    7475# Each entry must have a name (Full Chip Name), an array i2c_addrs (Valid 
    7576# I2C Addresses; may be omitted if this is a pure ISA chip), an array  
    76 # isa_addrs (Valid ISA Addresses; may be omitted if this is a pure I2C chip) 
    77 # ,... 
     77# isa_addrs (Valid ISA Addresses; may be omitted if this is a pure I2C chip), 
     78# i2c_detect (I2C Detetction Routine, may be omitted if this is a pure ISA 
     79# chip), ... 
    7880# If no driver is written yet, omit the driver (Driver Name) field. 
    7981@chip_ids = ( 
     
    8183       name => "National Semiconductors LM78", 
    8284       driver => "lm78", 
    83        i2c_addrs => (0x00..0x7f),  
     85       i2c_addrs => [0x00..0x7f],  
     86       i2c_detect => sub { lm78_detect 0, @_}, 
    8487       isa_addrs => (0x290),  # Theoretically anyway, but this will do 
    8588     } , 
     
    8790       name => "National Semiconductors LM78-J", 
    8891       driver => "lm78", 
    89        i2c_addrs => (0x00..0x7f), 
     92       i2c_addrs => [0x00..0x7f], 
     93       i2c_detect => sub { lm78_detect 1, @_ }, 
    9094       isa_addrs => (0x290),  # Theoretically anyway, but this will do 
    9195     } , 
     
    9397       name => "National Semiconductors LM79", 
    9498       driver => "lm78", 
    95        i2c_addrs => (0x00..0x7f), 
     99       i2c_addrs => [0x00..0x7f], 
     100       i2c_detect => sub { lm78_detect 2, @_ }, 
    96101       isa_addrs => (0x290),  # Theoretically anyway, but this will do 
    97102     } , 
     
    99104       name => "National Semiconductors LM75", 
    100105       driver => "lm75", 
    101        i2c_addrs => (0x48..0x4f), 
     106       i2c_addrs => [0x48..0x4f], 
     107       i2c_detect => sub { lm75_detect @_}, 
    102108     } , 
    103109     { 
    104110       name => "National Semiconductors LM80", 
    105111       driver => "lm80", 
    106        i2c_addrs => (0x28..0x2f), 
     112       i2c_addrs => [0x28..0x2f], 
     113       i2c_detect => sub { lm80_detect @_} , 
    107114     } 
    108115); 
     
    118125} 
    119126 
     127# $_[0] is the sought value 
     128# @_[1..] is the list to seek in 
     129# Returns: 0 on failure, 1 if found. 
     130sub contains 
     131{ 
     132  my $sought = shift; 
     133  foreach (@_) { 
     134    return 1 if $sought eq $_; 
     135  } 
     136  return 0; 
     137} 
    120138 
    121139############## 
     
    434452sub scan_adapter 
    435453{ 
    436   open FILE,"/dev/i2c-".$_[0] or die "Can't open /dev/i2c-".$_[0]; 
    437   foreach (0..0x7f) { 
    438     i2c_set_slave_addr(\*FILE,$_) or print("Can't set address to $_?!?\n"),  
     454  my ($chip, $addr, $conf); 
     455  open FILE,"/dev/i2c-$_[0]" or die "Can't open /dev/i2c-$_[0]"; 
     456  foreach $addr (0..0x7f) { 
     457    i2c_set_slave_addr(\*FILE,$addr) or print("Can't set address to $_?!?\n"),  
    439458                                     next; 
    440     printf ("Client found at address 0x%02x\n",$_)  
    441                                   if i2c_smbus_read_byte(\*FILE) >= 0; 
    442   } 
    443 } 
     459    next unless i2c_smbus_read_byte(\*FILE) >= 0; 
     460    printf "Client found at address 0x%02x\n",$addr; 
     461    foreach $chip (@chip_ids) { 
     462      if (contains $addr, @{$$chip{i2c_addrs}}) { 
     463        print "Probing for $$chip{name}... "; 
     464        if ($conf = &{$$chip{i2c_detect}} (\*FILE ,$addr)) { 
     465          printf "Success! (confidence %d)\n", $conf 
     466        } else { 
     467          print "Failed!\n"  
     468        } 
     469      } 
     470    } 
     471  } 
     472} 
     473 
    444474 
    445475################## 
     
    447477################## 
    448478 
    449 # $_[0]: 0 for ISA, 1 for I2C 
     479# Each function returns a confidence value. The higher this value, the more 
     480# sure we are about this chip. 
     481 
     482# If there are devices which get confused if they are only read from, then 
     483# this program will surely confuse them. But we guarantee never to write to 
     484# any of these devices. 
     485 
     486 
     487# $_[0]: Chip to detect (0 = LM78, 1 = LM78-J, 2 = LM79) 
     488# $_[1]: A reference to the file descriptor to access this chip. 
     489#        We may assume an i2c_set_slave_addr was already done. 
     490# $_[2]: Address 
     491# Returns: 0 if not detected, 7 if detected. 
     492# Registers used: 
     493#   0x48: Full I2C Address 
     494#   0x49: Device ID 
     495sub lm78_detect 
     496{ 
     497  my $reg; 
     498  my ($chip,$file,$addr) = @_; 
     499  return 0 unless i2c_smbus_read_byte_data($file,0x48) == $addr; 
     500  $reg = i2c_smbus_read_byte_data($file,0x49); 
     501  return 0 unless ($chip == 0 and $reg == 0x00) or 
     502                  ($chip == 1 and $reg == 0x40) or 
     503                  ($chip == 2 and $reg & 0xfe == 0xc0); 
     504  return 7; 
     505} 
     506 
     507# $_[0]: A reference to the file descriptor to access this chip. 
     508#        We may assume an i2c_set_slave_addr was already done. 
    450509# $_[1]: Address 
    451 # $_[2]: For I2C, a reference to the file descriptor to access this chip. 
    452 #        We may assume an i2c_set_slave_addr was aleady done. 
    453 #sub lm78_detect 
    454 #{ 
    455 #  $@lm78_read =  
     510# Returns: 0 if not detected, 3 if detected. 
     511# Registers used: 
     512#   0x01: Configuration 
     513#   0x02: Hysteris 
     514#   0x03: Overtemperature Shutdown 
     515# Detection really sucks! It is only based on the fact that the LM75 has only 
     516# four registers. Any other chip in the valid address range with only four 
     517# registers will be detected too. 
     518# Note that register $00 may change, so we can't use the modulo trick on it. 
     519sub lm75_detect 
     520{ 
     521  my $i; 
     522  my ($file,$addr) = @_; 
     523  my $conf = i2c_smbus_read_byte_data($file,0x01); 
     524  my $hyst = i2c_smbus_read_word_data($file,0x02); 
     525  my $os = i2c_smbus_read_word_data($file,0x03); 
     526  for ($i = 0x00; $i <= 0xff; $i += 4) { 
     527    return 0 if i2c_smbus_read_byte_data($file,$i + 0x01) != $conf; 
     528    return 0 if i2c_smbus_read_word_data($file,$i + 0x02) != $hyst; 
     529    return 0 if i2c_smbus_read_word_data($file,$i + 0x03) != $os; 
     530  } 
     531  return 3; 
     532} 
     533   
     534 
     535# $_[0]: A reference to the file descriptor to access this chip. 
     536#        We may assume an i2c_set_slave_addr was already done. 
     537# $_[1]: Address 
     538# Returns: 0 if not detected, 3 if detected. 
     539# Registers used: 
     540# Registers used: 
     541#   0x02: Interrupt state register 
     542# How to detect this beast?  
     543sub lm80_detect 
     544{ 
     545  my $i; 
     546  my ($file,$addr) = @_; 
     547  return 0 if i2c_smbus_read_byte_data($file,$0x02) & 0xc0 != 0; 
     548  for ($i = 0x2a; $i <= 0x3d; $i++) { 
     549    my $reg = i2c_smbus_read_byte_data($file,$i); 
     550    return 0 if i2c_smbus_read_byte_data($file,$i+0x40) != $reg; 
     551    return 0 if i2c_smbus_read_byte_data($file,$i+0x80) != $reg; 
     552    return 0 if i2c_smbus_read_byte_data($file,$i+0xc0) != $reg; 
     553  } 
     554  return 3; 
     555} 
     556   
    456557 
    457558################ 
     
    464565 
    465566# TEST! 
    466 #scan_adapter 0; 
     567# scan_adapter 0; 
  • lm-sensors/trunk/prog/detect/sensors-detect

    r244 r250  
    7070); 
    7171 
     72use subs qw(lm78_detect lm75_detect lm80_detect); 
    7273 
    7374# This is a list of all recognized chips.  
    7475# Each entry must have a name (Full Chip Name), an array i2c_addrs (Valid 
    7576# I2C Addresses; may be omitted if this is a pure ISA chip), an array  
    76 # isa_addrs (Valid ISA Addresses; may be omitted if this is a pure I2C chip) 
    77 # ,... 
     77# isa_addrs (Valid ISA Addresses; may be omitted if this is a pure I2C chip), 
     78# i2c_detect (I2C Detetction Routine, may be omitted if this is a pure ISA 
     79# chip), ... 
    7880# If no driver is written yet, omit the driver (Driver Name) field. 
    7981@chip_ids = ( 
     
    8183       name => "National Semiconductors LM78", 
    8284       driver => "lm78", 
    83        i2c_addrs => (0x00..0x7f),  
     85       i2c_addrs => [0x00..0x7f],  
     86       i2c_detect => sub { lm78_detect 0, @_}, 
    8487       isa_addrs => (0x290),  # Theoretically anyway, but this will do 
    8588     } , 
     
    8790       name => "National Semiconductors LM78-J", 
    8891       driver => "lm78", 
    89        i2c_addrs => (0x00..0x7f), 
     92       i2c_addrs => [0x00..0x7f], 
     93       i2c_detect => sub { lm78_detect 1, @_ }, 
    9094       isa_addrs => (0x290),  # Theoretically anyway, but this will do 
    9195     } , 
     
    9397       name => "National Semiconductors LM79", 
    9498       driver => "lm78", 
    95        i2c_addrs => (0x00..0x7f), 
     99       i2c_addrs => [0x00..0x7f], 
     100       i2c_detect => sub { lm78_detect 2, @_ }, 
    96101       isa_addrs => (0x290),  # Theoretically anyway, but this will do 
    97102     } , 
     
    99104       name => "National Semiconductors LM75", 
    100105       driver => "lm75", 
    101        i2c_addrs => (0x48..0x4f), 
     106       i2c_addrs => [0x48..0x4f], 
     107       i2c_detect => sub { lm75_detect @_}, 
    102108     } , 
    103109     { 
    104110       name => "National Semiconductors LM80", 
    105111       driver => "lm80", 
    106        i2c_addrs => (0x28..0x2f), 
     112       i2c_addrs => [0x28..0x2f], 
     113       i2c_detect => sub { lm80_detect @_} , 
    107114     } 
    108115); 
     
    118125} 
    119126 
     127# $_[0] is the sought value 
     128# @_[1..] is the list to seek in 
     129# Returns: 0 on failure, 1 if found. 
     130sub contains 
     131{ 
     132  my $sought = shift; 
     133  foreach (@_) { 
     134    return 1 if $sought eq $_; 
     135  } 
     136  return 0; 
     137} 
    120138 
    121139############## 
     
    434452sub scan_adapter 
    435453{ 
    436   open FILE,"/dev/i2c-".$_[0] or die "Can't open /dev/i2c-".$_[0]; 
    437   foreach (0..0x7f) { 
    438     i2c_set_slave_addr(\*FILE,$_) or print("Can't set address to $_?!?\n"),  
     454  my ($chip, $addr, $conf); 
     455  open FILE,"/dev/i2c-$_[0]" or die "Can't open /dev/i2c-$_[0]"; 
     456  foreach $addr (0..0x7f) { 
     457    i2c_set_slave_addr(\*FILE,$addr) or print("Can't set address to $_?!?\n"),  
    439458                                     next; 
    440     printf ("Client found at address 0x%02x\n",$_)  
    441                                   if i2c_smbus_read_byte(\*FILE) >= 0; 
    442   } 
    443 } 
     459    next unless i2c_smbus_read_byte(\*FILE) >= 0; 
     460    printf "Client found at address 0x%02x\n",$addr; 
     461    foreach $chip (@chip_ids) { 
     462      if (contains $addr, @{$$chip{i2c_addrs}}) { 
     463        print "Probing for $$chip{name}... "; 
     464        if ($conf = &{$$chip{i2c_detect}} (\*FILE ,$addr)) { 
     465          printf "Success! (confidence %d)\n", $conf 
     466        } else { 
     467          print "Failed!\n"  
     468        } 
     469      } 
     470    } 
     471  } 
     472} 
     473 
    444474 
    445475################## 
     
    447477################## 
    448478 
    449 # $_[0]: 0 for ISA, 1 for I2C 
     479# Each function returns a confidence value. The higher this value, the more 
     480# sure we are about this chip. 
     481 
     482# If there are devices which get confused if they are only read from, then 
     483# this program will surely confuse them. But we guarantee never to write to 
     484# any of these devices. 
     485 
     486 
     487# $_[0]: Chip to detect (0 = LM78, 1 = LM78-J, 2 = LM79) 
     488# $_[1]: A reference to the file descriptor to access this chip. 
     489#        We may assume an i2c_set_slave_addr was already done. 
     490# $_[2]: Address 
     491# Returns: 0 if not detected, 7 if detected. 
     492# Registers used: 
     493#   0x48: Full I2C Address 
     494#   0x49: Device ID 
     495sub lm78_detect 
     496{ 
     497  my $reg; 
     498  my ($chip,$file,$addr) = @_; 
     499  return 0 unless i2c_smbus_read_byte_data($file,0x48) == $addr; 
     500  $reg = i2c_smbus_read_byte_data($file,0x49); 
     501  return 0 unless ($chip == 0 and $reg == 0x00) or 
     502                  ($chip == 1 and $reg == 0x40) or 
     503                  ($chip == 2 and $reg & 0xfe == 0xc0); 
     504  return 7; 
     505} 
     506 
     507# $_[0]: A reference to the file descriptor to access this chip. 
     508#        We may assume an i2c_set_slave_addr was already done. 
    450509# $_[1]: Address 
    451 # $_[2]: For I2C, a reference to the file descriptor to access this chip. 
    452 #        We may assume an i2c_set_slave_addr was aleady done. 
    453 #sub lm78_detect 
    454 #{ 
    455 #  $@lm78_read =  
     510# Returns: 0 if not detected, 3 if detected. 
     511# Registers used: 
     512#   0x01: Configuration 
     513#   0x02: Hysteris 
     514#   0x03: Overtemperature Shutdown 
     515# Detection really sucks! It is only based on the fact that the LM75 has only 
     516# four registers. Any other chip in the valid address range with only four 
     517# registers will be detected too. 
     518# Note that register $00 may change, so we can't use the modulo trick on it. 
     519sub lm75_detect 
     520{ 
     521  my $i; 
     522  my ($file,$addr) = @_; 
     523  my $conf = i2c_smbus_read_byte_data($file,0x01); 
     524  my $hyst = i2c_smbus_read_word_data($file,0x02); 
     525  my $os = i2c_smbus_read_word_data($file,0x03); 
     526  for ($i = 0x00; $i <= 0xff; $i += 4) { 
     527    return 0 if i2c_smbus_read_byte_data($file,$i + 0x01) != $conf; 
     528    return 0 if i2c_smbus_read_word_data($file,$i + 0x02) != $hyst; 
     529    return 0 if i2c_smbus_read_word_data($file,$i + 0x03) != $os; 
     530  } 
     531  return 3; 
     532} 
     533   
     534 
     535# $_[0]: A reference to the file descriptor to access this chip. 
     536#        We may assume an i2c_set_slave_addr was already done. 
     537# $_[1]: Address 
     538# Returns: 0 if not detected, 3 if detected. 
     539# Registers used: 
     540# Registers used: 
     541#   0x02: Interrupt state register 
     542# How to detect this beast?  
     543sub lm80_detect 
     544{ 
     545  my $i; 
     546  my ($file,$addr) = @_; 
     547  return 0 if i2c_smbus_read_byte_data($file,$0x02) & 0xc0 != 0; 
     548  for ($i = 0x2a; $i <= 0x3d; $i++) { 
     549    my $reg = i2c_smbus_read_byte_data($file,$i); 
     550    return 0 if i2c_smbus_read_byte_data($file,$i+0x40) != $reg; 
     551    return 0 if i2c_smbus_read_byte_data($file,$i+0x80) != $reg; 
     552    return 0 if i2c_smbus_read_byte_data($file,$i+0xc0) != $reg; 
     553  } 
     554  return 3; 
     555} 
     556   
    456557 
    457558################ 
     
    464565 
    465566# TEST! 
    466 #scan_adapter 0; 
     567# scan_adapter 0;