Show
Ignore:
Timestamp:
08/09/06 08:45:48 (7 years ago)
Author:
khali
Message:

sensors-detect: Check i2c adapter functionalities before probing, so that
we don't use SMBus transactions the adapter doesn't support. This could
be extended to the transactions used during detection itself.

Files:
1 modified

Legend:

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

    r4085 r4086  
    24382438 
    24392439use constant IOCTL_I2C_SLAVE    => 0x0703; 
     2440use constant IOCTL_I2C_FUNCS    => 0x0705; 
    24402441use constant IOCTL_I2C_SMBUS    => 0x0720; 
    24412442 
     
    24472448use constant SMBUS_BYTE_DATA    => 2; 
    24482449use constant SMBUS_WORD_DATA    => 3; 
     2450 
     2451use constant I2C_FUNC_SMBUS_QUICK       => 0x00010000; 
     2452use constant I2C_FUNC_SMBUS_READ_BYTE   => 0x00020000; 
     2453 
     2454# Get the i2c adapter's functionalities 
     2455# $_[0]: Reference to an opened filehandle 
     2456# Returns: -1 on failure, functionality bitfield on success. 
     2457sub i2c_get_funcs($) 
     2458{ 
     2459  my $file = shift; 
     2460  my $funcs; 
     2461 
     2462  ioctl $file, IOCTL_I2C_FUNCS, $funcs='' or return -1; 
     2463  $funcs = unpack "L", $funcs; 
     2464 
     2465  return $funcs; 
     2466} 
    24492467 
    24502468# Select the device to communicate with through its address. 
     
    25332551# $_[0]: Reference to an opened filehandle 
    25342552# $_[1]: Address 
     2553# $_[2]: Functionalities of this i2c adapter 
    25352554# Returns: 1 on successful probing, 0 else. 
    25362555# This function is meant to prevent AT24RF08 corruption and write-only 
    25372556# chips locks. This is done by choosing the best probing method depending 
    25382557# on the address range. 
    2539 sub i2c_probe 
    2540 { 
    2541   my ($file, $addr) = @_; 
     2558sub i2c_probe($$$) 
     2559{ 
     2560  my ($file, $addr, $funcs) = @_; 
    25422561  my $data = []; 
    25432562  if (($addr >= 0x50 && $addr <= 0x5F) 
     
    25482567    # some EEPROMs write-protect themselves permanently on almost any write to 
    25492568    # their page protection address. 
     2569    return 0 unless ($funcs & I2C_FUNC_SMBUS_READ_BYTE); 
    25502570    return i2c_smbus_access($file, SMBUS_READ, 0, SMBUS_BYTE, $data); 
    25512571  } else { 
     2572    return 0 unless ($funcs & I2C_FUNC_SMBUS_QUICK); 
    25522573    return i2c_smbus_access($file, SMBUS_WRITE, 0, SMBUS_QUICK, $data); 
    25532574  } 
     
    28002821{ 
    28012822  my ($adapter_nr, $adapter_name, $adapter_driver, $not_to_scan) = @_; 
    2802   my ($chip, $addr, $conf,@chips,$new_hash,$other_addr); 
     2823  my ($funcs, $chip, $addr, $conf, @chips, $new_hash, $other_addr); 
    28032824 
    28042825  # As we modify it, we need a copy 
     
    28082829    (print "Can't open $dev_i2c$adapter_nr\n"), return; 
    28092830  binmode FILE; 
     2831 
     2832  # Can we probe this adapter? 
     2833  $funcs = i2c_get_funcs(\*FILE); 
     2834  if ($funcs < 0) { 
     2835    print "Adapter failed to provide its functionalities, skipping.\n"; 
     2836    return; 
     2837  } 
     2838  if (!($funcs & (I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_READ_BYTE))) { 
     2839    print "Adapter cannot be probed, skipping.\n"; 
     2840    return; 
     2841  } 
     2842  if (~$funcs & (I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_READ_BYTE)) { 
     2843    print "Adapter doesn't support all probing functions.\n", 
     2844          "Some addresses won't be probed.\n"; 
     2845  } 
    28102846 
    28112847  # Now scan each address in turn 
     
    28562892    } 
    28572893 
    2858     next unless i2c_probe(\*FILE, $addr); 
     2894    next unless i2c_probe(\*FILE, $addr, $funcs); 
    28592895    printf "Client found at address 0x%02x\n",$addr; 
    28602896