| 5273 | | # Check the checksum for validity (works for most DIMMs and RIMMs) |
| 5274 | | for (my $i = 0; $i <= 62; $i++) { |
| 5275 | | $checksum += i2c_smbus_read_byte_data($file, $i); |
| 5276 | | } |
| 5277 | | $checksum &= 255; |
| 5278 | | |
| 5279 | | return 8 if $checksum == i2c_smbus_read_byte_data($file, 63); |
| | 5275 | # Check the checksum or CRC16 for validity |
| | 5276 | if ($device_type >= 1 and $device_type <= 8) { |
| | 5277 | for (my $i = 0; $i < 63; $i++) { |
| | 5278 | $checksum += i2c_smbus_read_byte_data($file, $i); |
| | 5279 | } |
| | 5280 | $checksum &= 0xff; |
| | 5281 | |
| | 5282 | return 8 if $checksum == i2c_smbus_read_byte_data($file, 63); |
| | 5283 | } elsif ($device_type => 9 && $device_type <= 11) { |
| | 5284 | # see JEDEC 21-C 4.1.2.11 2.4 |
| | 5285 | my $crc_coverage = i2c_smbus_read_byte_data($file, 0); |
| | 5286 | $crc_coverage = ($crc_coverage & 0x80) ? 117 : 126; |
| | 5287 | for (my $i = 0; $i < $crc_coverage; $i++) { |
| | 5288 | $checksum ^= i2c_smbus_read_byte_data($file, $i) << 8; |
| | 5289 | for (my $bit = 0; $bit < 8; $bit++) { |
| | 5290 | if ($checksum & 0x8000) { |
| | 5291 | $checksum = ($checksum << 1) ^ 0x1021; |
| | 5292 | } else { |
| | 5293 | $checksum <<= 1; |
| | 5294 | } |
| | 5295 | } |
| | 5296 | } |
| | 5297 | $checksum &= 0xffff; |
| | 5298 | |
| | 5299 | return 8 if ($checksum & 0xff) == i2c_smbus_read_byte_data($file, 126) and |
| | 5300 | ($checksum >> 8) == i2c_smbus_read_byte_data($file, 127); |
| | 5301 | |
| | 5302 | # note: if bit 7 of byte 32 is set, a jc42 sensor is at $addr-0x38 |
| | 5303 | } |
| | 5304 | |