Changeset 5248
- Timestamp:
- 05/11/08 19:16:27 (6 months ago)
- Files:
-
- lm-sensors/trunk/CHANGES (modified) (1 diff)
- lm-sensors/trunk/prog/detect/sensors-detect (modified) (8 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
lm-sensors/trunk/CHANGES
r5247 r5248 20 20 Fix the parsing of I2C addresses not to scan 21 21 Detect and skip 1-register-only I2C devices 22 Avoid SMBus word transactions where possible 22 23 23 24 2.10.6 "Welcome Home Lina" (20080306) lm-sensors/trunk/prog/detect/sensors-detect
r5247 r5248 2725 2725 # $_[1]: Command byte (usually register number) 2726 2726 # Returns: -1 on failure, the read word on success. 2727 # Use this function with care, some devices don't like word reads, 2728 # so you should do as much of the detection as possible using byte reads, 2729 # and only start using word reads when there is a good chance that 2730 # the detection will succeed. 2727 2731 # Note: some devices use the wrong endiannes; use swap_bytes to correct for 2728 2732 # this. … … 3588 3592 # all register addresses from 0x04 to 0x0f behave like 0x04-0x07 do for 3589 3593 # the LM75. 3594 # Not all devices enjoy SMBus read word transactions, so we use read byte 3595 # transactions even for the 16-bit registers. The low bits aren't very 3596 # useful for detection anyway. 3590 3597 sub lm75_detect 3591 3598 { 3592 3599 my $i; 3593 3600 my ($chip, $file, $addr) = @_; 3594 my $cur = i2c_smbus_read_ word_data($file,0x00);3601 my $cur = i2c_smbus_read_byte_data($file, 0x00); 3595 3602 my $conf = i2c_smbus_read_byte_data($file,0x01); 3596 3603 3597 my $hyst = i2c_smbus_read_ word_data($file,0x02);3604 my $hyst = i2c_smbus_read_byte_data($file, 0x02); 3598 3605 my $maxreg = $chip == 1 ? 0x0f : 0x07; 3599 3606 for $i (0x04 .. $maxreg) { 3600 return if i2c_smbus_read_ word_data($file, $i) != $hyst;3601 } 3602 3603 my $os = i2c_smbus_read_ word_data($file,0x03);3607 return if i2c_smbus_read_byte_data($file, $i) != $hyst; 3608 } 3609 3610 my $os = i2c_smbus_read_byte_data($file, 0x03); 3604 3611 for $i (0x04 .. $maxreg) { 3605 return if i2c_smbus_read_ word_data($file, $i) != $os;3612 return if i2c_smbus_read_byte_data($file, $i) != $os; 3606 3613 } 3607 3614 … … 3609 3616 for ($i = 8; $i <= 248; $i += 40) { 3610 3617 return if i2c_smbus_read_byte_data($file, $i + 0x01) != $conf 3611 or i2c_smbus_read_ word_data($file, $i + 0x02) != $hyst3612 or i2c_smbus_read_ word_data($file, $i + 0x03) != $os;3618 or i2c_smbus_read_byte_data($file, $i + 0x02) != $hyst 3619 or i2c_smbus_read_byte_data($file, $i + 0x03) != $os; 3613 3620 } 3614 3621 } 3615 3622 3616 3623 # All registers hold the same value, obviously a misdetection 3617 return if $conf == ($cur & 0xff) and $cur == $hyst 3618 and $cur == $os; 3619 3620 $cur = swap_bytes($cur); 3621 $hyst = swap_bytes($hyst); 3622 $os = swap_bytes($os); 3624 return if $conf == $cur and $cur == $hyst and $cur == $os; 3625 3623 3626 # Unused bits 3624 3627 return if $chip == 0 and ($conf & 0xe0); 3625 3628 return if $chip == 1 and ($conf & 0x80); 3626 3629 3627 $cur = $cur >> 8;3628 $hyst = $hyst >> 8;3629 $os = $os >> 8;3630 3630 # Most probable value ranges 3631 3631 return 6 if $cur <= 100 and ($hyst >= 10 && $hyst <= 125) … … 3646 3646 # 0x04: Low limit 3647 3647 # 0x05: High limit 3648 # 0x0 4-0x07: No registers3648 # 0x06-0x07: No registers 3649 3649 # The first detection step is based on the fact that the LM77 has only 3650 3650 # six registers, and cycles addresses over 8-byte boundaries. We use the … … 3653 3653 # documented. 3654 3654 # Note that register 0x00 may change, so we can't use the modulo trick on it. 3655 # Not all devices enjoy SMBus read word transactions, so we use read byte 3656 # transactions even for the 16-bit registers at first. We only use read word 3657 # transactions in the end when we are already almost certain that we have an 3658 # LM77 chip. 3655 3659 sub lm77_detect 3656 3660 { 3657 3661 my $i; 3658 3662 my ($file,$addr) = @_; 3659 my $cur = i2c_smbus_read_ word_data($file,0x00);3663 my $cur = i2c_smbus_read_byte_data($file, 0x00); 3660 3664 my $conf = i2c_smbus_read_byte_data($file,0x01); 3661 my $hyst = i2c_smbus_read_ word_data($file,0x02);3662 my $os = i2c_smbus_read_ word_data($file,0x03);3663 3664 my $low = i2c_smbus_read_ word_data($file,0x04);3665 return if i2c_smbus_read_ word_data($file,0x06) != $low;3666 return if i2c_smbus_read_ word_data($file,0x07) != $low;3667 3668 my $high = i2c_smbus_read_ word_data($file,0x05);3669 return if i2c_smbus_read_ word_data($file,0x06) != $high;3670 return if i2c_smbus_read_ word_data($file,0x07) != $high;3665 my $hyst = i2c_smbus_read_byte_data($file, 0x02); 3666 my $os = i2c_smbus_read_byte_data($file, 0x03); 3667 3668 my $low = i2c_smbus_read_byte_data($file, 0x04); 3669 return if i2c_smbus_read_byte_data($file, 0x06) != $low; 3670 return if i2c_smbus_read_byte_data($file, 0x07) != $low; 3671 3672 my $high = i2c_smbus_read_byte_data($file, 0x05); 3673 return if i2c_smbus_read_byte_data($file, 0x06) != $high; 3674 return if i2c_smbus_read_byte_data($file, 0x07) != $high; 3671 3675 3672 3676 for ($i = 8; $i <= 248; $i += 40) { 3673 3677 return if i2c_smbus_read_byte_data($file, $i + 0x01) != $conf; 3674 return if i2c_smbus_read_ word_data($file, $i + 0x02) != $hyst;3675 return if i2c_smbus_read_ word_data($file, $i + 0x03) != $os;3676 return if i2c_smbus_read_ word_data($file, $i + 0x04) != $low;3677 return if i2c_smbus_read_ word_data($file, $i + 0x05) != $high;3678 return if i2c_smbus_read_byte_data($file, $i + 0x02) != $hyst; 3679 return if i2c_smbus_read_byte_data($file, $i + 0x03) != $os; 3680 return if i2c_smbus_read_byte_data($file, $i + 0x04) != $low; 3681 return if i2c_smbus_read_byte_data($file, $i + 0x05) != $high; 3678 3682 } 3679 3683 3680 3684 # All registers hold the same value, obviously a misdetection 3681 return if $conf == ($cur & 0xff)and $cur == $hyst3685 return if $conf == $cur and $cur == $hyst 3682 3686 and $cur == $os and $cur == $low and $cur == $high; 3683 3687 3684 $cur = swap_bytes($cur);3685 $os = swap_bytes($os);3686 $hyst = swap_bytes($hyst);3687 $low = swap_bytes($low);3688 $high = swap_bytes($high);3689 3688 # Unused bits 3690 3689 return if ($conf & 0xe0) 3691 or (($cur >> 12) != 0 && ($cur >> 12) != 0xf) 3692 or (($hyst >> 12) != 0 && ($hyst >> 12) != 0xf) 3693 or (($os >> 12) != 0 && ($os >> 12) != 0xf) 3694 or (($low >> 12) != 0 && ($low >> 12) != 0xf) 3695 or (($high >> 12) != 0 && ($high >> 12) != 0xf); 3690 or (($cur >> 4) != 0 && ($cur >> 4) != 0xf) 3691 or (($hyst >> 4) != 0 && ($hyst >> 4) != 0xf) 3692 or (($os >> 4) != 0 && ($os >> 4) != 0xf) 3693 or (($low >> 4) != 0 && ($low >> 4) != 0xf) 3694 or (($high >> 4) != 0 && ($high >> 4) != 0xf); 3695 3696 # Make sure the chip supports SMBus read word transactions 3697 $cur = i2c_smbus_read_word_data($file, 0x00); 3698 return if $cur < 0; 3699 $hyst = i2c_smbus_read_word_data($file, 0x02); 3700 return if $hyst < 0; 3701 $os = i2c_smbus_read_word_data($file, 0x03); 3702 return if $os < 0; 3703 $low = i2c_smbus_read_word_data($file, 0x04); 3704 return if $low < 0; 3705 $high = i2c_smbus_read_word_data($file, 0x05); 3706 return if $high < 0; 3696 3707 3697 3708 $cur /= 16; … … 3721 3732 # limited number of registers, which cycle modulo 16 address values. 3722 3733 # Note that register 0x00 may change, so we can't use the modulo trick on it. 3734 # Not all devices enjoy SMBus read word transactions, so we use read byte 3735 # transactions even for the 16-bit registers at first. We only use read 3736 # word transactions in the end when we are already almost certain that we 3737 # have an LM92 chip or compatible. 3723 3738 sub lm92_detect 3724 3739 { … … 3726 3741 3727 3742 my $conf = i2c_smbus_read_byte_data($file, 0x01); 3728 my $hyst = i2c_smbus_read_ word_data($file, 0x02);3729 my $crit = i2c_smbus_read_ word_data($file, 0x03);3730 my $low = i2c_smbus_read_ word_data($file, 0x04);3731 my $high = i2c_smbus_read_ word_data($file, 0x05);3743 my $hyst = i2c_smbus_read_byte_data($file, 0x02); 3744 my $crit = i2c_smbus_read_byte_data($file, 0x03); 3745 my $low = i2c_smbus_read_byte_data($file, 0x04); 3746 my $high = i2c_smbus_read_byte_data($file, 0x05); 3732 3747 3733 3748 return if $conf == 0 and $hyst == 0 and $crit == 0 3734 3749 and $low == 0 and $high == 0; 3735 3750 3751 # Unused bits 3752 return if ($chip == 0 || $chip == 1) 3753 and ($conf & 0xE0); 3754 3755 for (my $i = 0; $i <= 240; $i += 16) { 3756 return if i2c_smbus_read_byte_data($file, $i + 0x01) != $conf; 3757 return if i2c_smbus_read_byte_data($file, $i + 0x02) != $hyst; 3758 return if i2c_smbus_read_byte_data($file, $i + 0x03) != $crit; 3759 return if i2c_smbus_read_byte_data($file, $i + 0x04) != $low; 3760 return if i2c_smbus_read_byte_data($file, $i + 0x05) != $high; 3761 } 3762 3736 3763 return if $chip == 0 3737 3764 and i2c_smbus_read_word_data($file, 0x07) != 0x0180; 3738 3739 return if ($chip == 0 || $chip == 1) 3740 and ($conf & 0xE0); 3741 3742 for (my $i = 0; $i < 8; $i++) { 3743 return if i2c_smbus_read_byte_data($file, $i*16+0x01) != $conf; 3744 return if i2c_smbus_read_word_data($file, $i*16+0x02) != $hyst; 3745 return if i2c_smbus_read_word_data($file, $i*16+0x03) != $crit; 3746 return if i2c_smbus_read_word_data($file, $i*16+0x04) != $low; 3747 return if i2c_smbus_read_word_data($file, $i*16+0x05) != $high; 3748 } 3749 3765 3766 # Make sure the chip supports SMBus read word transactions 3767 $hyst = i2c_smbus_read_word_data($file, 0x02); 3768 return if $hyst < 0; 3769 $crit = i2c_smbus_read_word_data($file, 0x03); 3770 return if $crit < 0; 3771 $low = i2c_smbus_read_word_data($file, 0x04); 3772 return if $low < 0; 3773 $high = i2c_smbus_read_word_data($file, 0x05); 3774 return if $high < 0; 3775 3750 3776 foreach my $temp ($hyst, $crit, $low, $high) { 3751 3777 return if $chip == 2 and ($temp & 0x7F00); … … 3764 3790 # 0xA1: High limit 3765 3791 # 0xA2: Low limit 3792 # 0xA8: Counter 3793 # 0xA9: Slope 3766 3794 # 0xAC: Configuration 3767 3795 # Detection is weak. We check if bit 4 (NVB) is clear, because it is 3768 3796 # unlikely to be set (would mean that EEPROM is currently being accessed). 3769 # Temperature checkings will hopefully prevent LM75 or other chips from 3770 # being detected as a DS1621. 3797 # We also check the value of the counter and slope registers, the datasheet 3798 # doesn't mention the possible values but the conversion formula together 3799 # with experimental evidence suggest possible sanity checks. 3800 # Not all devices enjoy SMBus read word transactions, so we do as much as 3801 # possible with read byte transactions first, and only use read word 3802 # transactions second. 3771 3803 sub ds1621_detect 3772 3804 { 3773 my $i;3774 3805 my ($file,$addr) = @_; 3806 3807 my $conf = i2c_smbus_read_byte_data($file, 0xAC); 3808 return if ($conf & 0x10); 3809 3810 my $counter = i2c_smbus_read_byte_data($file, 0xA8); 3811 my $slope = i2c_smbus_read_byte_data($file, 0xA9); 3812 return if ($slope != 0x10 || $counter > $slope); 3813 3775 3814 my $temp = i2c_smbus_read_word_data($file,0xAA); 3815 return if $temp < 0 || ($temp & 0x7f00); 3776 3816 my $high = i2c_smbus_read_word_data($file,0xA1); 3817 return if $high < 0 || ($high & 0x7f00); 3777 3818 my $low = i2c_smbus_read_word_data($file,0xA2); 3778 return if ($temp | $high | $low) & 0x7F00;3779 my $conf = i2c_smbus_read_byte_data($file,0xAC); 3819 return if $low < 0 || ($low & 0x7f00); 3820 3780 3821 return if ($temp == 0 && $high == 0 && $low == 0 && $conf == 0); 3781 return 3 if ($conf & 0x10) == 0x00; 3782 return ;3822 3823 return 3; 3783 3824 } 3784 3825
