| | 2846 | } |
| | 2847 | |
| | 2848 | # $_[0]: A reference to the file descriptor to access this chip. |
| | 2849 | # We assume an i2c_set_slave_addr was already done. |
| | 2850 | # $_[1]: Address |
| | 2851 | # Returns: undef if not detected, 2 to 5 if detected; |
| | 2852 | # 5 means that the LM77 was found in its default power up state; |
| | 2853 | # 3 means that the LM77 was found in a probable state (temperatures |
| | 2854 | # make sense); |
| | 2855 | # 2 means that the configuration register passes the test; |
| | 2856 | # Registers used: |
| | 2857 | # 0x00: Temperature |
| | 2858 | # 0x01: Configuration |
| | 2859 | # 0x02: Hysteresis |
| | 2860 | # 0x03: Overtemperature Shutdown |
| | 2861 | # 0x04: Low limit |
| | 2862 | # 0x05: High limit |
| | 2863 | # The first detection step is only based on the fact that the LM77 has only |
| | 2864 | # six registers. Any other chip in the valid address range with only six |
| | 2865 | # registers will be detected too. |
| | 2866 | # Note that register $00 may change, so we can't use the modulo trick on it. |
| | 2867 | sub lm77_detect |
| | 2868 | { |
| | 2869 | my $i; |
| | 2870 | my ($file,$addr) = @_; |
| | 2871 | my $cur = i2c_smbus_read_word_data($file,0x00); |
| | 2872 | my $cur_varies = 0; |
| | 2873 | my $conf = i2c_smbus_read_byte_data($file,0x01); |
| | 2874 | my $hyst = i2c_smbus_read_word_data($file,0x02); |
| | 2875 | my $os = i2c_smbus_read_word_data($file,0x03); |
| | 2876 | my $low = i2c_smbus_read_word_data($file,0x04); |
| | 2877 | my $high = i2c_smbus_read_word_data($file,0x05); |
| | 2878 | for ($i = 0x00; $i <= 0x1f; $i += 1) { |
| | 2879 | return if i2c_smbus_read_byte_data($file,($i * 0x08) + 0x01) != $conf; |
| | 2880 | return if i2c_smbus_read_word_data($file,($i * 0x08) + 0x02) != $hyst; |
| | 2881 | return if i2c_smbus_read_word_data($file,($i * 0x08) + 0x03) != $os; |
| | 2882 | return if i2c_smbus_read_word_data($file,($i * 0x08) + 0x04) != $low; |
| | 2883 | return if i2c_smbus_read_word_data($file,($i * 0x08) + 0x05) != $high; |
| | 2884 | $cur_varies = 1 |
| | 2885 | if (! $cur_varies) and |
| | 2886 | i2c_smbus_read_word_data($file,($i * 0x08)) != $cur; |
| | 2887 | } |
| | 2888 | |
| | 2889 | $cur = swap_bytes($cur) >> 4; |
| | 2890 | $os = swap_bytes($os) >> 4; |
| | 2891 | $hyst = swap_bytes($hyst) >> 4; |
| | 2892 | $low = swap_bytes($low) >> 4; |
| | 2893 | $high = swap_bytes($high) >> 4; |
| | 2894 | |
| | 2895 | # Default power up state (from specs) |
| | 2896 | return 5 |
| | 2897 | if $conf == 0 and ($hyst&0xfff8) == 0x0020 and ($os&0xfff8) == 0x0500 |
| | 2898 | and ($low&0xfff8) == 0x00a0 and ($high&0xfff8) == 0x0400; |
| | 2899 | # All registers hold the same value, obviously a misdetection |
| | 2900 | return |
| | 2901 | if (! $cur_varies) and $conf == ($cur>>8) and $cur == $hyst |
| | 2902 | and $cur == $os and $cur == $low and $cur == $high; |
| | 2903 | # Unused bits in conf register |
| | 2904 | return |
| | 2905 | if ($conf&0xe0) != 0; |
| | 2906 | # Most probable value ranges |
| | 2907 | return 3 |
| | 2908 | if $cur <= 125 and $hyst <= 30 and $os <= 125 and $low <= 30 |
| | 2909 | and $high <= 125; |
| | 2910 | return 2; |